Commit 6a0d09d2 authored by Laurent Wouters's avatar Laurent Wouters
Browse files

[fix] Refactoring the popup UI

parent e0601307cb06
......@@ -78,7 +78,7 @@ export interface LDBrowserEventHandler {
*/
onContent(
registry: definition.ViewRegistry,
rendering: application.ViewRendering
rendering: application.RenderingResult
): void;
/**
......@@ -214,6 +214,7 @@ class LDBrowserImpl implements LDBrowser {
resource: resource,
observations: {},
command: new ResourceUserCommand(),
rendering: null,
supplements: []
};
let count = resource.uris.length;
......@@ -328,7 +329,8 @@ class LDBrowserImpl implements LDBrowser {
source.contentType,
undefined
);
resolve(store.statements.length - before);
source.loaded = store.statements.length - before;
resolve(source.loaded);
} catch (err) {
reject(err);
}
......@@ -463,10 +465,10 @@ class LDBrowserImpl implements LDBrowser {
let renderer = await this.renderer.refresh(registry);
this.handler.onLoad("Rendering");
try {
let rendering = renderer.render(context, context.root);
if (rendering != null) {
this.handler.onContent(registry, rendering);
this.onSuggestedResources(data, rendering.suggestedResources);
data.rendering = renderer.render(context, context.root);
if (data.rendering != null) {
this.handler.onContent(registry, data.rendering);
this.onSuggestedResources(data, data.rendering.suggestedResources);
} else {
this.handler.onError("Rendering failed: Cannot resolve a view");
}
......
......@@ -20,19 +20,17 @@
import React = require("react");
import { definition, application } from "@logilab/libview";
import {
ResourceData,
selectPrimaryTopic,
getSourcesFor,
DocumentSource
} from "../data";
import { ResourceData, selectPrimaryTopic } from "../data";
import * as LANGUAGES from "../data.iso639.json";
export interface ConfigCurrentTabProps {
export interface CurrentTabConfigProps {
data: ResourceData;
registry: definition.ViewRegistry;
onPaneSources: () => void;
onTunOff: () => void;
onClickSeeViews: () => void;
onClickSeeDataSources: () => void;
onClickSeeResources: () => void;
onClickGotoOptions: () => void;
onClickTurnOff: () => void;
onTabCommandAutomatic: (event: React.FormEvent<HTMLInputElement>) => void;
onTabCommandClearTopic: () => void;
onTabCommandSelectView: (event: React.FormEvent<HTMLSelectElement>) => void;
......@@ -41,11 +39,11 @@ export interface ConfigCurrentTabProps {
) => void;
}
export class ConfigCurrentTab extends React.Component<
ConfigCurrentTabProps,
export class CurrentTabConfig extends React.Component<
CurrentTabConfigProps,
{}
> {
constructor(props: ConfigCurrentTabProps) {
constructor(props: CurrentTabConfigProps) {
super(props);
}
......@@ -54,49 +52,47 @@ export class ConfigCurrentTab extends React.Component<
this.props.data.command.isAutomatic ||
this.props.data.command.selectedTopic == null;
let topic = selectPrimaryTopic(this.props.data);
let allSources = getSourcesFor(this.props.data);
let renderedSources = Object.keys(allSources).map(
(url: string, index: number) => {
let series = allSources[url];
return (
<div key={"series-" + index} style={{ marginTop: "10px" }}>
{series.map((source: DocumentSource, index: number) => (
<div key={"source-" + index} className="row">
<div className="col-12">
{index > 0 ? (
<span title="Fallback source">
{"\u00A0\u00A0\u00A0\u00A0\u21B3"}
</span>
) : (
<span title="Series head">{"\u25BA"}</span>
)}
{source.name}
</div>
</div>
))}
</div>
);
}
);
return (
<div className="container-fluid">
<div className="row">
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onPaneSources}
title="Configuration"
onClick={this.props.onClickSeeViews}
title="See data/views matching"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/settings.svg" />
<img width="24px" src="../icons/views.svg" />
</span>
</a>
</div>
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onClickSeeDataSources}
title="See data sources"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/sources.svg" />
</span>
</a>
</div>
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onClickSeeResources}
title="See the loaded supplementary resources"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/resources.svg" />
</span>
</a>
</div>
<div className="col-2" />
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onTunOff}
onClick={this.props.onClickTurnOff}
title="Turn off on this tab"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
......@@ -104,8 +100,20 @@ export class ConfigCurrentTab extends React.Component<
</span>
</a>
</div>
<div className="col-2" />
<div className="col-6">
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onClickGotoOptions}
title="Browser's options"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/settings.svg" />
</span>
</a>
</div>
</div>
<div className="row">
<div className="col-12">
<span style={{ fontSize: "17pt" }}>Current tab</span>
</div>
</div>
......@@ -227,30 +235,6 @@ export class ConfigCurrentTab extends React.Component<
</select>
</div>
</div>
<hr />
<div className="row">
<div className="col-12">Detected sources of data</div>
</div>
{renderedSources}
<hr />
<div className="row">
<div className="col-12">Supplementary resources</div>
</div>
{this.props.data.supplements.map(
(supplement: application.Resource, index: number) => (
<div key={"supplement-" + index} style={{ marginTop: "10px" }}>
{supplement.uris.map((uri: string, index: number) => (
<div key={"uri-" + index} className="row">
<div className="col-12">
<a href={uri} title={uri}>
{uri}
</a>
</div>
</div>
))}
</div>
)
)}
</div>
);
}
......
/*******************************************************************************
* Copyright 2003-2018 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
* contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
*
* This file is part of CubicWeb.
*
* CubicWeb is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 2.1 of the License, or (at your option)
* any later version.
*
* CubicWeb is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import React = require("react");
import { ResourceData, getSourcesFor, DocumentSource } from "../data";
export interface CurrentTabDataSourcesProps {
data: ResourceData;
onClickBack: () => void;
}
export class CurrentTabDataSources extends React.Component<
CurrentTabDataSourcesProps,
{}
> {
constructor(props: CurrentTabDataSourcesProps) {
super(props);
}
render() {
let allSources = getSourcesFor(this.props.data);
let renderedSources = Object.keys(allSources).map(
(url: string, index: number) => {
let series = allSources[url];
let totalLoaded = this.props.data.observations[url].totalLoaded;
return (
<div key={"series-" + index} style={{ marginTop: "10px" }}>
<div className="row">
<span>{"\u25BA"}</span>
<span
className="badge badge-primary"
title="Total loaded triples from this URI"
>
{totalLoaded}
</span>
<a href={url}>{url}</a>
</div>
{series.map((source: DocumentSource, index: number) => (
<div key={"source-" + index} className="row">
<div className="col-12">
<span>{"\u00A0\u00A0\u00A0\u00A0\u21B3"}</span>
<span
className="badge badge-secondary"
title="Total loaded triples from this source"
>
{source.loaded}
</span>
<span>{source.name}</span>
</div>
</div>
))}
</div>
);
}
);
return (
<div className="container-fluid">
<div className="row">
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onClickBack}
title="Back"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/back.svg" />
</span>
</a>
</div>
<div className="col-2" />
<div className="col-2" />
<div className="col-6" />
</div>
<div className="row">
<div className="col-12">
<span style={{ fontSize: "17pt" }}>Data sources</span>
</div>
</div>
<hr />
{renderedSources}
</div>
);
}
}
/*******************************************************************************
* Copyright 2003-2018 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
* contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
*
* This file is part of CubicWeb.
*
* CubicWeb is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 2.1 of the License, or (at your option)
* any later version.
*
* CubicWeb is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import React = require("react");
import { application } from "@logilab/libview";
import { ResourceData } from "../data";
export interface CurrentTabResourcesProps {
data: ResourceData;
onClickBack: () => void;
}
export class CurrentTabResources extends React.Component<
CurrentTabResourcesProps,
{}
> {
constructor(props: CurrentTabResourcesProps) {
super(props);
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onClickBack}
title="Back"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/back.svg" />
</span>
</a>
</div>
<div className="col-2" />
<div className="col-2" />
<div className="col-6" />
</div>
<div className="row">
<div className="col-12">
<span style={{ fontSize: "17pt" }}>Supplementary resources</span>
</div>
</div>
<hr />
{this.props.data.supplements.map(
(supplement: application.Resource, index: number) => (
<div key={"supplement-" + index} style={{ marginTop: "10px" }}>
{supplement.uris.map((uri: string, index: number) => (
<div key={"uri-" + index} className="row">
<div className="col-12">
<a href={uri} title={uri}>
{uri}
</a>
</div>
</div>
))}
</div>
)
)}
</div>
);
}
}
/*******************************************************************************
* Copyright 2003-2018 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
* contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
*
* This file is part of CubicWeb.
*
* CubicWeb is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 2.1 of the License, or (at your option)
* any later version.
*
* CubicWeb is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import React = require("react");
import { application, definition } from "@logilab/libview";
import { ResourceData } from "../data";
export interface CurrentTabViewsProps {
data: ResourceData;
registry: definition.ViewRegistry;
onClickBack: () => void;
}
export class CurrentTabViews extends React.Component<CurrentTabViewsProps, {}> {
constructor(props: CurrentTabViewsProps) {
super(props);
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-2">
<a
className="btn btn-outline-light"
onClick={this.props.onClickBack}
title="Back"
>
<span style={{ fontSize: "20pt", cursor: "pointer" }}>
<img width="24px" src="../icons/back.svg" />
</span>
</a>
</div>
<div className="col-2" />
<div className="col-2" />
<div className="col-6" />
</div>
<div className="row">
<div className="col-12">
<span style={{ fontSize: "17pt" }}>Evaluated views</span>
</div>
</div>
<hr />
{this.props.data.rendering.evaluations.map(
(evaluation: application.RenderingEvaluation, index: number) => {
let view = this.props.registry.descriptors[evaluation.viewId];
return (
<div key={"evaluation-" + index} className="row">
<div className="col-12">
<span>{view.name}</span>
<span
title="Priority for this view"
className="badge badge-primary"
>
{evaluation.priority}
</span>
</div>
</div>
);
}
)}
</div>
);
}
}
......@@ -343,6 +343,10 @@ export interface DocumentSource {
* The relative priority of this source (lower is better)
*/
priority: number;
/**
* The number of statements loaded from this source
*/
loaded: number;
}
/**
......@@ -355,12 +359,14 @@ export class DocumentSourceNone implements DocumentSource {
this.url = "";
this.contentType = "";
this.priority = Number.MAX_SAFE_INTEGER;
this.loaded = 0;
}
sourceType: string;
name: string;
url: string;
contentType: string;
priority: number;
loaded: number;
}
/**
......@@ -373,6 +379,7 @@ export class DocumentSourceInline implements DocumentSource {
this.url = url;
this.contentType = mime.mime;
this.priority = mime.priority;
this.loaded = 0;
this.content = content;
}
sourceType: string;
......@@ -380,6 +387,7 @@ export class DocumentSourceInline implements DocumentSource {
url: string;
contentType: string;
priority: number;
loaded: number;
/**
* The inline content
*/
......@@ -399,12 +407,14 @@ export class DocumentSourcePage implements DocumentSource {
this.url = url;
this.contentType = contentType;
this.priority = 1;
this.loaded = 0;
}
sourceType: string;
name: string;
url: string;
contentType: string;
priority: number;
loaded: number;
}
/**
......@@ -450,6 +460,7 @@ export class DocumentSourceLinked implements DocumentSource {
this.url = link.url;
this.contentType = mime.mime;
this.priority = mime.priority;
this.loaded = 0;
}
/**
* The various tags for this link
......@@ -460,6 +471,7 @@ export class DocumentSourceLinked implements DocumentSource {
url: string;
contentType: string;
priority: number;
loaded: number;
}
/**
......@@ -684,6 +696,10 @@ export class ResourceData {
* The associated user command
*/
command: ResourceUserCommand;
/**
* The current rendering for this resource
*/
rendering: application.RenderingResult;
/**
* The supplementary resources that have been merged into this one
*/
......
......@@ -39,7 +39,7 @@ export class RdfTriplesRendering implements implementation.ViewImplementation {
renderer: application.ViewRenderer,
context: application.RenderingContext,
resource: application.Resource
): application.ViewRendering {
): implementation.ViewRendering {
let result = document.createElement("div");
result.style.width = "100%";
......@@ -99,7 +99,6 @@ export class RdfTriplesRendering implements implementation.ViewImplementation {
return {
dom: result,
viewId: this.descriptor.identifier,
suggestedResources: []
};
}
......
......@@ -38,7 +38,7 @@ export interface Viewer {
*/
onContent(
registry: definition.ViewRegistry,
rendering: application.ViewRendering
rendering: application.RenderingResult
): void;
/**
......@@ -64,7 +64,7 @@ class State {
stateType: StateType;
message: string;
registry: definition.ViewRegistry;
rendering: application.ViewRendering;
rendering: application.RenderingResult;
}
/**
......@@ -103,7 +103,7 @@ class MainViewer implements Viewer {
*/