graphwise-reactodia 0.0.1-TR11 → 0.0.1-TR13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/graphwise-reactodia.cjs.entry.js +192 -26
- package/dist/cjs/graphwise-reactodia.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/graphwise-reactodia/graphwise-reactodia.css +3 -0
- package/dist/collection/components/graphwise-reactodia/graphwise-reactodia.js +13 -9
- package/dist/collection/components/graphwise-reactodia/i18n/translations.js +4 -1
- package/dist/collection/components/graphwise-reactodia/menu/graphwise-menu.js +37 -0
- package/dist/collection/components/graphwise-reactodia/reactodia-app.js +17 -10
- package/dist/collection/components/graphwise-reactodia/services/diagram/diagram.service.js +14 -0
- package/dist/collection/components/graphwise-reactodia/services/diagram-file/diagram-file.service.js +68 -0
- package/dist/collection/pages/graphwise-reactodia/main.js +6 -0
- package/dist/collection/pages/graphwise-reactodia/owl-rdfs-settings.js +195 -0
- package/dist/esm/graphwise-reactodia.entry.js +192 -26
- package/dist/esm/graphwise-reactodia.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/graphwise-reactodia/graphwise-reactodia.esm.js +1 -1
- package/dist/graphwise-reactodia/{p-81eeb4c3.entry.js → p-420b9dce.entry.js} +1 -1
- package/dist/types/components/graphwise-reactodia/graphwise-reactodia.d.ts +5 -5
- package/dist/types/components/graphwise-reactodia/menu/graphwise-menu.d.ts +9 -0
- package/dist/types/components/graphwise-reactodia/models/reactodia-app-props.d.ts +4 -4
- package/dist/types/components/graphwise-reactodia/reactodia-app.d.ts +3 -2
- package/dist/types/components/graphwise-reactodia/services/diagram/diagram.service.d.ts +11 -1
- package/dist/types/components/graphwise-reactodia/services/diagram-file/diagram-file.service.d.ts +24 -0
- package/dist/types/components.d.ts +2 -2
- package/package.json +2 -2
package/dist/collection/components/graphwise-reactodia/services/diagram-file/diagram-file.service.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
4
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else
|
|
6
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
7
|
+
if (d = decorators[i])
|
|
8
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
9
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
10
|
+
};
|
|
11
|
+
var DiagramFileService_1;
|
|
12
|
+
import { Service } from "../../providers/service/service";
|
|
13
|
+
import { service } from "../../providers/service/service-inject";
|
|
14
|
+
import { WindowService } from "../window/window.service";
|
|
15
|
+
/**
|
|
16
|
+
* Service for downloading and uploading the diagram as a file. The file content is the same
|
|
17
|
+
* {@link SerializedDiagram} that is persisted to the local store.
|
|
18
|
+
*/
|
|
19
|
+
let DiagramFileService = DiagramFileService_1 = class DiagramFileService {
|
|
20
|
+
/**
|
|
21
|
+
* Downloads the given diagram serialization as a file with the given name.
|
|
22
|
+
*/
|
|
23
|
+
download(diagram, fileName) {
|
|
24
|
+
const window = service(WindowService).getWindow();
|
|
25
|
+
const blob = new Blob([JSON.stringify(diagram)], { type: DiagramFileService_1.MIME_TYPE });
|
|
26
|
+
const url = window.URL.createObjectURL(blob);
|
|
27
|
+
const link = window.document.createElement('a');
|
|
28
|
+
link.href = url;
|
|
29
|
+
link.download = fileName;
|
|
30
|
+
link.click();
|
|
31
|
+
window.URL.revokeObjectURL(url);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Reads a diagram serialization from the given file.
|
|
35
|
+
*
|
|
36
|
+
* @throws Error when the file is not valid JSON or is not a serialized diagram.
|
|
37
|
+
*/
|
|
38
|
+
async read(file) {
|
|
39
|
+
let diagram;
|
|
40
|
+
try {
|
|
41
|
+
diagram = JSON.parse(await file.text());
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new Error(`File "${file.name}" is not valid JSON: ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
if (!this.isSerializedDiagram(diagram)) {
|
|
47
|
+
throw new Error(`File "${file.name}" is not a serialized diagram`);
|
|
48
|
+
}
|
|
49
|
+
return diagram;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Checks if the provided value is a serialized diagram
|
|
53
|
+
*/
|
|
54
|
+
isSerializedDiagram(value) {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
const diagram = value;
|
|
57
|
+
return (diagram === null || diagram === void 0 ? void 0 : diagram['@type']) === 'Diagram'
|
|
58
|
+
&& Array.isArray((_a = diagram.layoutData) === null || _a === void 0 ? void 0 : _a.elements)
|
|
59
|
+
&& Array.isArray((_b = diagram.layoutData) === null || _b === void 0 ? void 0 : _b.links);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
DiagramFileService.ID = 'DiagramFileService';
|
|
63
|
+
DiagramFileService.FILE_EXTENSION = '.json';
|
|
64
|
+
DiagramFileService.MIME_TYPE = 'application/json';
|
|
65
|
+
DiagramFileService = DiagramFileService_1 = __decorate([
|
|
66
|
+
Service
|
|
67
|
+
], DiagramFileService);
|
|
68
|
+
export { DiagramFileService };
|
|
@@ -27,6 +27,12 @@ function setQueryFunction() {
|
|
|
27
27
|
reactodia.config = {...reactodia.config, queryFunction: stubQueryFunction};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// The wrapper has no default preset, so the host always passes one. The demo uses Reactodia's generic
|
|
31
|
+
// OWL/RDFS preset, copied into `owl-rdfs-settings.js`.
|
|
32
|
+
function setProviderSettings() {
|
|
33
|
+
reactodia.providerSettings = OWL_RDFS_SETTINGS;
|
|
34
|
+
}
|
|
35
|
+
|
|
30
36
|
function setSeed() {
|
|
31
37
|
reactodia.config = {...reactodia.config, seedIris: SEED_NODES};
|
|
32
38
|
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// A copy of Reactodia's `OwlRdfsSettings` preset (`src/data/sparql/sparqlDataProviderSettings.ts` in the
|
|
2
|
+
// reactodia-workspace fork), which the demo page passes to the wrapper as its `providerSettings`. The wrapper
|
|
3
|
+
// requires the host to pass the settings, and this plain script can't import them from `@reactodia/workspace`.
|
|
4
|
+
// Keep it in sync with the fork: `RDF_SETTINGS` mirrors `RdfSettings`, `OWL_RDFS_SETTINGS_OVERRIDE` mirrors
|
|
5
|
+
// `OwlRdfsSettingsOverride`.
|
|
6
|
+
|
|
7
|
+
const RDF_SETTINGS = {
|
|
8
|
+
linkConfigurations: [],
|
|
9
|
+
openWorldLinks: false,
|
|
10
|
+
|
|
11
|
+
propertyConfigurations: [],
|
|
12
|
+
openWorldProperties: false,
|
|
13
|
+
|
|
14
|
+
linksInfoQuery: `SELECT ?source ?type ?target
|
|
15
|
+
WHERE {
|
|
16
|
+
\${linkConfigurations}
|
|
17
|
+
VALUES (?source) {\${sourceIris}}
|
|
18
|
+
VALUES (?target) {\${targetIris}}
|
|
19
|
+
}`,
|
|
20
|
+
|
|
21
|
+
defaultPrefix: '',
|
|
22
|
+
|
|
23
|
+
schemaLabelProperty: 'rdfs:label',
|
|
24
|
+
dataLabelProperty: 'rdfs:label',
|
|
25
|
+
|
|
26
|
+
fullTextSearch: {
|
|
27
|
+
prefix: '',
|
|
28
|
+
queryPattern: '',
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
classTreeQuery: '',
|
|
32
|
+
|
|
33
|
+
classInfoQuery:
|
|
34
|
+
`SELECT ?class ?label ?instcount WHERE {
|
|
35
|
+
VALUES(?class) {\${ids}}
|
|
36
|
+
OPTIONAL {
|
|
37
|
+
?class \${schemaLabelProperty} ?label
|
|
38
|
+
\${labelLanguageFilter}
|
|
39
|
+
}
|
|
40
|
+
BIND("" as ?instcount)
|
|
41
|
+
}`,
|
|
42
|
+
|
|
43
|
+
linkTypesQuery:
|
|
44
|
+
`SELECT DISTINCT ?link ?instcount ?label WHERE {
|
|
45
|
+
\${linkTypesPattern}
|
|
46
|
+
OPTIONAL {
|
|
47
|
+
?link \${schemaLabelProperty} ?label
|
|
48
|
+
\${labelLanguageFilter}
|
|
49
|
+
}
|
|
50
|
+
}`,
|
|
51
|
+
|
|
52
|
+
linkTypesPattern: '',
|
|
53
|
+
|
|
54
|
+
linkTypesInfoQuery:
|
|
55
|
+
`SELECT ?link ?label WHERE {
|
|
56
|
+
VALUES(?link) {\${ids}}
|
|
57
|
+
OPTIONAL {
|
|
58
|
+
?link \${schemaLabelProperty} ?label
|
|
59
|
+
\${labelLanguageFilter}
|
|
60
|
+
}
|
|
61
|
+
}`,
|
|
62
|
+
|
|
63
|
+
propertyInfoQuery:
|
|
64
|
+
`SELECT ?property ?label WHERE {
|
|
65
|
+
VALUES(?property) {\${ids}}
|
|
66
|
+
OPTIONAL {
|
|
67
|
+
?property \${schemaLabelProperty} ?label
|
|
68
|
+
\${labelLanguageFilter}
|
|
69
|
+
}
|
|
70
|
+
}`,
|
|
71
|
+
|
|
72
|
+
elementInfoQuery: '',
|
|
73
|
+
imageQueryPattern: '',
|
|
74
|
+
|
|
75
|
+
linkTypesOfQuery: '',
|
|
76
|
+
linkTypesStatisticsQuery: '',
|
|
77
|
+
|
|
78
|
+
lookupQuery:
|
|
79
|
+
`SELECT \${outerProjection} WHERE {
|
|
80
|
+
\${filterInnerPrelude}
|
|
81
|
+
{
|
|
82
|
+
SELECT DISTINCT \${innerProjection} WHERE {
|
|
83
|
+
\${filterByType}
|
|
84
|
+
\${filterByRefElementLink}
|
|
85
|
+
\${filterByText}
|
|
86
|
+
\${filterAdditionalRestriction}
|
|
87
|
+
} \${orderBy} \${limit}
|
|
88
|
+
}
|
|
89
|
+
\${queryTypes}
|
|
90
|
+
\${queryElementInfo}
|
|
91
|
+
} \${orderBy}`,
|
|
92
|
+
|
|
93
|
+
filterRefElementLinkPattern: '',
|
|
94
|
+
filterTypePattern: '',
|
|
95
|
+
filterAdditionalRestriction: '',
|
|
96
|
+
filterElementInfoPattern: '',
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const OWL_RDFS_SETTINGS_OVERRIDE = {
|
|
100
|
+
defaultPrefix:
|
|
101
|
+
`PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
102
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
103
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
104
|
+
`,
|
|
105
|
+
schemaLabelProperty: 'rdfs:label',
|
|
106
|
+
dataLabelProperty: 'rdfs:label',
|
|
107
|
+
fullTextSearch: {
|
|
108
|
+
prefix: '',
|
|
109
|
+
queryPattern:
|
|
110
|
+
`?inst \${dataLabelProperty} ?search1
|
|
111
|
+
FILTER regex(COALESCE(str(?search1)), "\${text}", "i")
|
|
112
|
+
BIND(0 as ?score)
|
|
113
|
+
`,
|
|
114
|
+
extractLabel: true,
|
|
115
|
+
},
|
|
116
|
+
classTreeQuery: `
|
|
117
|
+
SELECT ?class ?label ?parent
|
|
118
|
+
WHERE {
|
|
119
|
+
{
|
|
120
|
+
?class a rdfs:Class
|
|
121
|
+
} UNION {
|
|
122
|
+
?class a owl:Class
|
|
123
|
+
}
|
|
124
|
+
FILTER ISIRI(?class)
|
|
125
|
+
OPTIONAL {
|
|
126
|
+
?class rdfs:label ?label
|
|
127
|
+
\${labelLanguageFilter}
|
|
128
|
+
}
|
|
129
|
+
OPTIONAL {?class rdfs:subClassOf ?parent. FILTER ISIRI(?parent)}
|
|
130
|
+
}
|
|
131
|
+
`,
|
|
132
|
+
|
|
133
|
+
// todo: think more, maybe add a limit here?
|
|
134
|
+
linkTypesPattern: `
|
|
135
|
+
{ ?link a rdf:Property }
|
|
136
|
+
UNION
|
|
137
|
+
{ ?link a owl:ObjectProperty }
|
|
138
|
+
BIND('' as ?instcount)
|
|
139
|
+
`,
|
|
140
|
+
elementInfoQuery: `
|
|
141
|
+
CONSTRUCT {
|
|
142
|
+
?inst <urn:reactodia:sparql:type> ?class .
|
|
143
|
+
?inst <urn:reactodia:sparql:label> ?label .
|
|
144
|
+
?inst ?propType ?propValue.
|
|
145
|
+
} WHERE {
|
|
146
|
+
VALUES (?inst) {\${ids}}
|
|
147
|
+
OPTIONAL { ?inst a ?class }
|
|
148
|
+
OPTIONAL {
|
|
149
|
+
?inst \${dataLabelProperty} ?label
|
|
150
|
+
\${labelLanguageFilter}
|
|
151
|
+
}
|
|
152
|
+
OPTIONAL {
|
|
153
|
+
\${propertyConfigurations}
|
|
154
|
+
FILTER (isLiteral(?propValue))
|
|
155
|
+
\${valueLanguageFilter}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
`,
|
|
159
|
+
imageQueryPattern: '{ ?inst ?linkType ?image } UNION { [] ?linkType ?inst. BIND(?inst as ?image) }',
|
|
160
|
+
linkTypesOfQuery: `
|
|
161
|
+
SELECT DISTINCT ?link ?direction
|
|
162
|
+
WHERE {
|
|
163
|
+
\${linkConfigurations}
|
|
164
|
+
}
|
|
165
|
+
`,
|
|
166
|
+
linkTypesStatisticsQuery: `
|
|
167
|
+
SELECT ?link ?outCount ?inCount
|
|
168
|
+
WHERE {
|
|
169
|
+
{
|
|
170
|
+
SELECT (\${linkId} as ?link) (count(?outObject) as ?outCount) WHERE {
|
|
171
|
+
\${linkConfigurationOut}
|
|
172
|
+
\${navigateElementFilterOut}
|
|
173
|
+
} LIMIT 101
|
|
174
|
+
} {
|
|
175
|
+
SELECT (\${linkId} as ?link) (count(?inObject) as ?inCount) WHERE {
|
|
176
|
+
\${linkConfigurationIn}
|
|
177
|
+
\${navigateElementFilterIn}
|
|
178
|
+
} LIMIT 101
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
`,
|
|
182
|
+
filterRefElementLinkPattern: '',
|
|
183
|
+
filterTypePattern: '?inst a ?instType. ?instType rdfs:subClassOf* ?class',
|
|
184
|
+
filterElementInfoPattern: `
|
|
185
|
+
OPTIONAL {?inst rdf:type ?foundClass}
|
|
186
|
+
BIND (coalesce(?foundClass, owl:Thing) as ?class)
|
|
187
|
+
OPTIONAL {
|
|
188
|
+
?inst \${dataLabelProperty} ?label
|
|
189
|
+
\${labelLanguageFilter}
|
|
190
|
+
}
|
|
191
|
+
`,
|
|
192
|
+
filterAdditionalRestriction: '',
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const OWL_RDFS_SETTINGS = {...RDF_SETTINGS, ...OWL_RDFS_SETTINGS_OVERRIDE};
|
|
@@ -23866,6 +23866,35 @@ function ToolbarAction(props) {
|
|
|
23866
23866
|
});
|
|
23867
23867
|
}
|
|
23868
23868
|
/**
|
|
23869
|
+
* Toolbar action component to open a file selection dialog.
|
|
23870
|
+
*
|
|
23871
|
+
* @category Components
|
|
23872
|
+
*/
|
|
23873
|
+
function ToolbarActionOpen(props) {
|
|
23874
|
+
const { className, fileAccept, onSelect, children, ...otherProps } = props;
|
|
23875
|
+
const inputRef = reactExports.useRef(null);
|
|
23876
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [/* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarAction, {
|
|
23877
|
+
...otherProps,
|
|
23878
|
+
className: clsx(className, `${CLASS_NAME$8}__open`),
|
|
23879
|
+
onSelect: () => {
|
|
23880
|
+
inputRef.current?.click();
|
|
23881
|
+
},
|
|
23882
|
+
children
|
|
23883
|
+
}), /* @__PURE__ */ jsxRuntimeExports.jsx("input", {
|
|
23884
|
+
ref: inputRef,
|
|
23885
|
+
role: "none",
|
|
23886
|
+
type: "file",
|
|
23887
|
+
className: `${CLASS_NAME$8}__open-input`,
|
|
23888
|
+
accept: fileAccept,
|
|
23889
|
+
onChange: (e) => {
|
|
23890
|
+
if (e.currentTarget.files) {
|
|
23891
|
+
const file = e.currentTarget.files[0];
|
|
23892
|
+
onSelect(file);
|
|
23893
|
+
}
|
|
23894
|
+
}
|
|
23895
|
+
})] });
|
|
23896
|
+
}
|
|
23897
|
+
/**
|
|
23869
23898
|
* Toolbar action component to clear diagram content.
|
|
23870
23899
|
*
|
|
23871
23900
|
* Clearing the diagram adds a command to the command history.
|
|
@@ -30844,6 +30873,16 @@ function getContentFittingBoxForLayout(state) {
|
|
|
30844
30873
|
};
|
|
30845
30874
|
}
|
|
30846
30875
|
|
|
30876
|
+
const graphwise_toolbar_action$1 = {
|
|
30877
|
+
"download_diagram.label": "Export to JSON",
|
|
30878
|
+
"download_diagram.title": "Export the diagram to a JSON file",
|
|
30879
|
+
"upload_diagram.label": "Import from JSON",
|
|
30880
|
+
"upload_diagram.title": "Replace the diagram with one from a JSON file"
|
|
30881
|
+
};
|
|
30882
|
+
var enTranslation = {
|
|
30883
|
+
graphwise_toolbar_action: graphwise_toolbar_action$1
|
|
30884
|
+
};
|
|
30885
|
+
|
|
30847
30886
|
const authoring_state = {
|
|
30848
30887
|
"entity_action_delete.label": "supprimer",
|
|
30849
30888
|
"entity_action_delete.title": "Supprimer l'entité",
|
|
@@ -31098,6 +31137,12 @@ const standard_link = {
|
|
|
31098
31137
|
const toolbar = {
|
|
31099
31138
|
"menu_toggle.title": "Ouvrir le menu"
|
|
31100
31139
|
};
|
|
31140
|
+
const graphwise_toolbar_action = {
|
|
31141
|
+
"download_diagram.label": "Exporter en JSON",
|
|
31142
|
+
"download_diagram.title": "Exporter le diagramme en fichier JSON",
|
|
31143
|
+
"upload_diagram.label": "Importer depuis JSON",
|
|
31144
|
+
"upload_diagram.title": "Remplacer le diagramme par celui d'un fichier JSON"
|
|
31145
|
+
};
|
|
31101
31146
|
const toolbar_action = {
|
|
31102
31147
|
"clear_all.command": "Tout effacer",
|
|
31103
31148
|
"clear_all.title": "Supprimer tous les éléments et liens du diagramme",
|
|
@@ -31208,6 +31253,7 @@ var frTranslation = {
|
|
|
31208
31253
|
standard_element: standard_element,
|
|
31209
31254
|
standard_link: standard_link,
|
|
31210
31255
|
toolbar: toolbar,
|
|
31256
|
+
graphwise_toolbar_action: graphwise_toolbar_action,
|
|
31211
31257
|
toolbar_action: toolbar_action,
|
|
31212
31258
|
unified_search: unified_search,
|
|
31213
31259
|
visual_authoring: visual_authoring,
|
|
@@ -31222,8 +31268,10 @@ var LanguageKey;
|
|
|
31222
31268
|
LanguageKey["FR"] = "fr";
|
|
31223
31269
|
})(LanguageKey || (LanguageKey = {}));
|
|
31224
31270
|
|
|
31225
|
-
// English is provided by default from reactodia so
|
|
31271
|
+
// English is provided by default from reactodia, so the English bundle holds only our own keys and overrides. If
|
|
31272
|
+
// A key is missing, reactodia defaults to its own translation.
|
|
31226
31273
|
const TRANSLATIONS = {
|
|
31274
|
+
[LanguageKey.EN]: enTranslation,
|
|
31227
31275
|
[LanguageKey.FR]: frTranslation
|
|
31228
31276
|
};
|
|
31229
31277
|
|
|
@@ -31283,7 +31331,7 @@ function Service(_serviceClass) {
|
|
|
31283
31331
|
// no implementation needed. We only use the type checking of the parameter
|
|
31284
31332
|
}
|
|
31285
31333
|
|
|
31286
|
-
var __decorate$
|
|
31334
|
+
var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
31287
31335
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31288
31336
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31289
31337
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -31294,6 +31342,20 @@ var DiagramService_1;
|
|
|
31294
31342
|
* Service for diagram related operations and subscriptions
|
|
31295
31343
|
*/
|
|
31296
31344
|
let DiagramService = DiagramService_1 = class DiagramService {
|
|
31345
|
+
/**
|
|
31346
|
+
* Replaces the diagram content with the given serialization. Element data is requested from the data provider and
|
|
31347
|
+
* the links between the imported elements are validated against it.
|
|
31348
|
+
*
|
|
31349
|
+
* @param model The diagram model to import into.
|
|
31350
|
+
* @param dataProvider The data provider to bind to the diagram.
|
|
31351
|
+
* @param diagram The serialization to import. When `undefined`, the diagram is cleared.
|
|
31352
|
+
* @param signal Optional signal to abort the import.
|
|
31353
|
+
*/
|
|
31354
|
+
importDiagram(model, dataProvider, diagram, signal) {
|
|
31355
|
+
// selection is not cleared on import, so we clear it manually to avoid painting the previous selection
|
|
31356
|
+
model.setSelection([]);
|
|
31357
|
+
return model.importLayout({ dataProvider, diagram, signal, validateLinks: true });
|
|
31358
|
+
}
|
|
31297
31359
|
/**
|
|
31298
31360
|
* Subscribes to diagram changes. On every debounced change the current layout is
|
|
31299
31361
|
* exported and passed to the callback.
|
|
@@ -31328,11 +31390,11 @@ let DiagramService = DiagramService_1 = class DiagramService {
|
|
|
31328
31390
|
DiagramService.ID = 'DiagramService';
|
|
31329
31391
|
DiagramService.NOTIFY_DEBOUNCE_MS = 300;
|
|
31330
31392
|
DiagramService.HISTORY_CHANGED_EVENT = 'historyChanged';
|
|
31331
|
-
DiagramService = DiagramService_1 = __decorate$
|
|
31393
|
+
DiagramService = DiagramService_1 = __decorate$4([
|
|
31332
31394
|
Service
|
|
31333
31395
|
], DiagramService);
|
|
31334
31396
|
|
|
31335
|
-
var __decorate$
|
|
31397
|
+
var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
31336
31398
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31337
31399
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31338
31400
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -31347,11 +31409,11 @@ let WindowService = class WindowService {
|
|
|
31347
31409
|
}
|
|
31348
31410
|
};
|
|
31349
31411
|
WindowService.ID = 'WindowService';
|
|
31350
|
-
WindowService = __decorate$
|
|
31412
|
+
WindowService = __decorate$3([
|
|
31351
31413
|
Service
|
|
31352
31414
|
], WindowService);
|
|
31353
31415
|
|
|
31354
|
-
var __decorate$
|
|
31416
|
+
var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
31355
31417
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31356
31418
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31357
31419
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -31395,11 +31457,11 @@ let DiagramStorageService = DiagramStorageService_1 = class DiagramStorageServic
|
|
|
31395
31457
|
};
|
|
31396
31458
|
DiagramStorageService.ID = 'DiagramStorageService';
|
|
31397
31459
|
DiagramStorageService.STORAGE_KEY = 'diagram.state';
|
|
31398
|
-
DiagramStorageService = DiagramStorageService_1 = __decorate$
|
|
31460
|
+
DiagramStorageService = DiagramStorageService_1 = __decorate$2([
|
|
31399
31461
|
Service
|
|
31400
31462
|
], DiagramStorageService);
|
|
31401
31463
|
|
|
31402
|
-
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
31464
|
+
var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
31403
31465
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31404
31466
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31405
31467
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -31422,7 +31484,7 @@ let EventService = class EventService {
|
|
|
31422
31484
|
}
|
|
31423
31485
|
};
|
|
31424
31486
|
EventService.ID = 'EventService';
|
|
31425
|
-
EventService = __decorate([
|
|
31487
|
+
EventService = __decorate$1([
|
|
31426
31488
|
Service
|
|
31427
31489
|
], EventService);
|
|
31428
31490
|
|
|
@@ -31516,8 +31578,102 @@ const resetColors = () => {
|
|
|
31516
31578
|
typeToIndex.clear();
|
|
31517
31579
|
};
|
|
31518
31580
|
|
|
31581
|
+
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
31582
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
31583
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31584
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
31585
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
31586
|
+
};
|
|
31587
|
+
var DiagramFileService_1;
|
|
31588
|
+
/**
|
|
31589
|
+
* Service for downloading and uploading the diagram as a file. The file content is the same
|
|
31590
|
+
* {@link SerializedDiagram} that is persisted to the local store.
|
|
31591
|
+
*/
|
|
31592
|
+
let DiagramFileService = DiagramFileService_1 = class DiagramFileService {
|
|
31593
|
+
/**
|
|
31594
|
+
* Downloads the given diagram serialization as a file with the given name.
|
|
31595
|
+
*/
|
|
31596
|
+
download(diagram, fileName) {
|
|
31597
|
+
const window = service(WindowService).getWindow();
|
|
31598
|
+
const blob = new Blob([JSON.stringify(diagram)], { type: DiagramFileService_1.MIME_TYPE });
|
|
31599
|
+
const url = window.URL.createObjectURL(blob);
|
|
31600
|
+
const link = window.document.createElement('a');
|
|
31601
|
+
link.href = url;
|
|
31602
|
+
link.download = fileName;
|
|
31603
|
+
link.click();
|
|
31604
|
+
window.URL.revokeObjectURL(url);
|
|
31605
|
+
}
|
|
31606
|
+
/**
|
|
31607
|
+
* Reads a diagram serialization from the given file.
|
|
31608
|
+
*
|
|
31609
|
+
* @throws Error when the file is not valid JSON or is not a serialized diagram.
|
|
31610
|
+
*/
|
|
31611
|
+
async read(file) {
|
|
31612
|
+
let diagram;
|
|
31613
|
+
try {
|
|
31614
|
+
diagram = JSON.parse(await file.text());
|
|
31615
|
+
}
|
|
31616
|
+
catch (error) {
|
|
31617
|
+
throw new Error(`File "${file.name}" is not valid JSON: ${error.message}`);
|
|
31618
|
+
}
|
|
31619
|
+
if (!this.isSerializedDiagram(diagram)) {
|
|
31620
|
+
throw new Error(`File "${file.name}" is not a serialized diagram`);
|
|
31621
|
+
}
|
|
31622
|
+
return diagram;
|
|
31623
|
+
}
|
|
31624
|
+
/**
|
|
31625
|
+
* Checks if the provided value is a serialized diagram
|
|
31626
|
+
*/
|
|
31627
|
+
isSerializedDiagram(value) {
|
|
31628
|
+
var _a, _b;
|
|
31629
|
+
const diagram = value;
|
|
31630
|
+
return (diagram === null || diagram === void 0 ? void 0 : diagram['@type']) === 'Diagram'
|
|
31631
|
+
&& Array.isArray((_a = diagram.layoutData) === null || _a === void 0 ? void 0 : _a.elements)
|
|
31632
|
+
&& Array.isArray((_b = diagram.layoutData) === null || _b === void 0 ? void 0 : _b.links);
|
|
31633
|
+
}
|
|
31634
|
+
};
|
|
31635
|
+
DiagramFileService.ID = 'DiagramFileService';
|
|
31636
|
+
DiagramFileService.FILE_EXTENSION = '.json';
|
|
31637
|
+
DiagramFileService.MIME_TYPE = 'application/json';
|
|
31638
|
+
DiagramFileService = DiagramFileService_1 = __decorate([
|
|
31639
|
+
Service
|
|
31640
|
+
], DiagramFileService);
|
|
31641
|
+
|
|
31642
|
+
/**
|
|
31643
|
+
* The workspace main menu: Reactodia's default actions, followed by the diagram download and upload.
|
|
31644
|
+
*
|
|
31645
|
+
* Passing a `menu` to the `DefaultWorkspace` replaces its default actions, so they are listed here again.
|
|
31646
|
+
* Rendered inside the workspace, so the actions can use the workspace hooks.
|
|
31647
|
+
*/
|
|
31648
|
+
function GraphwiseMenu() {
|
|
31649
|
+
const { model } = useWorkspace();
|
|
31650
|
+
const t = useTranslation();
|
|
31651
|
+
const diagramFileService = service(DiagramFileService);
|
|
31652
|
+
const diagramService = service(DiagramService);
|
|
31653
|
+
const downloadDiagram = () => {
|
|
31654
|
+
const timestamp = new Date().toISOString().replace(/[-:]|\.\d+Z$/g, '');
|
|
31655
|
+
diagramFileService.download(model.exportLayout(), `diagram-${timestamp}${DiagramFileService.FILE_EXTENSION}`);
|
|
31656
|
+
};
|
|
31657
|
+
const uploadDiagram = async (file) => {
|
|
31658
|
+
try {
|
|
31659
|
+
const diagram = await diagramFileService.read(file);
|
|
31660
|
+
await diagramService.importDiagram(model, model.dataProvider, diagram);
|
|
31661
|
+
}
|
|
31662
|
+
catch (error) {
|
|
31663
|
+
console.error('Failed to upload the diagram', error);
|
|
31664
|
+
}
|
|
31665
|
+
};
|
|
31666
|
+
return reactExports.createElement(reactExports.Fragment, null, reactExports.createElement(ToolbarActionClearAll, {}), reactExports.createElement(ToolbarActionExport, { kind: 'exportRaster' }), reactExports.createElement(ToolbarActionExport, { kind: 'exportSvg' }), reactExports.createElement(ToolbarActionExport, { kind: 'print' }), reactExports.createElement(ToolbarAction,
|
|
31667
|
+
// The same icon as ToolbarActionSave. We dont use that action, since it disables saving on refresh
|
|
31668
|
+
{ className: 'reactodia-toolbar-action__save', title: t.text('graphwise_toolbar_action.download_diagram.title'), onSelect: downloadDiagram }, t.text('graphwise_toolbar_action.download_diagram.label')), reactExports.createElement(ToolbarActionOpen, {
|
|
31669
|
+
title: t.text('graphwise_toolbar_action.upload_diagram.title'),
|
|
31670
|
+
fileAccept: DiagramFileService.FILE_EXTENSION,
|
|
31671
|
+
onSelect: (file) => void uploadDiagram(file)
|
|
31672
|
+
}, t.text('graphwise_toolbar_action.upload_diagram.label')));
|
|
31673
|
+
}
|
|
31674
|
+
|
|
31519
31675
|
/**
|
|
31520
|
-
* Reactodia ships English as its built-in default bundle, so English
|
|
31676
|
+
* Reactodia ships English as its built-in default bundle, so the English bundle only adds our own keys.
|
|
31521
31677
|
* Other languages are layered on top as partial bundles; unknown codes fall back to English.
|
|
31522
31678
|
*
|
|
31523
31679
|
* Reactodia never re-reads the translations, so the component must be remounted
|
|
@@ -31541,8 +31697,7 @@ let workspaceContext = null;
|
|
|
31541
31697
|
const subscriptions = new SubscriptionList();
|
|
31542
31698
|
/**
|
|
31543
31699
|
* Builds a Reactodia {@link SparqlDataProvider} for the given endpoint using the supplied
|
|
31544
|
-
* query preset. The host owns the query configuration and passes it in via props
|
|
31545
|
-
* is provided we fall back to Reactodia's generic {@link OwlRdfsSettings} OWL/RDFS preset.
|
|
31700
|
+
* query preset. The host owns the query configuration and always passes it in via props.
|
|
31546
31701
|
*/
|
|
31547
31702
|
function createDataProvider(props) {
|
|
31548
31703
|
const { currentRepository, config, providerSettings } = props;
|
|
@@ -31635,10 +31790,12 @@ function ReactodiaApp(props) {
|
|
|
31635
31790
|
const dataProvider = createDataProvider(props);
|
|
31636
31791
|
const isReload = props.isReload;
|
|
31637
31792
|
const savedDiagram = service(DiagramStorageService).load();
|
|
31793
|
+
const diagramService = service(DiagramService);
|
|
31638
31794
|
if (isReload) {
|
|
31639
|
-
//
|
|
31640
|
-
//
|
|
31641
|
-
|
|
31795
|
+
// Reload the diagram that is currently on the canvas. This may happen when the host changes the provider
|
|
31796
|
+
// settings, or when the user switches the language at runtime, since there is no existing mechanism to
|
|
31797
|
+
// re-translate the UI at runtime (not for the UI labels at least)
|
|
31798
|
+
await diagramService.importDiagram(model, dataProvider, currentDiagram, signal);
|
|
31642
31799
|
}
|
|
31643
31800
|
else if ((_a = config.seedIris) === null || _a === void 0 ? void 0 : _a.length) {
|
|
31644
31801
|
await seedIrisToCanvas(context, dataProvider, config.seedIris, signal);
|
|
@@ -31649,7 +31806,7 @@ function ReactodiaApp(props) {
|
|
|
31649
31806
|
else {
|
|
31650
31807
|
// Restore the previously saved layout when present, otherwise start empty. Either way this binds the
|
|
31651
31808
|
// data provider (savedDiagram is undefined -> empty diagram), so the unified search/lookup works.
|
|
31652
|
-
await
|
|
31809
|
+
await diagramService.importDiagram(model, dataProvider, savedDiagram, signal);
|
|
31653
31810
|
}
|
|
31654
31811
|
}, [language]);
|
|
31655
31812
|
/**
|
|
@@ -31668,7 +31825,11 @@ function ReactodiaApp(props) {
|
|
|
31668
31825
|
defaultLanguage: language,
|
|
31669
31826
|
translations: translationsForLanguage(language),
|
|
31670
31827
|
typeStyleResolver: resolveTypeStyle
|
|
31671
|
-
}, reactExports.createElement(DefaultWorkspace, {
|
|
31828
|
+
}, reactExports.createElement(DefaultWorkspace, {
|
|
31829
|
+
menu: reactExports.createElement(GraphwiseMenu),
|
|
31830
|
+
// place Undo/redo/layout actions in top right corner.
|
|
31831
|
+
actionsToolbar: { dock: 'ne' }
|
|
31832
|
+
}));
|
|
31672
31833
|
}
|
|
31673
31834
|
/**
|
|
31674
31835
|
* Mounts the Reactodia application into the given container and returns the React root.
|
|
@@ -31679,8 +31840,9 @@ function mountReactodia(container, props) {
|
|
|
31679
31840
|
return root;
|
|
31680
31841
|
}
|
|
31681
31842
|
/**
|
|
31682
|
-
* Re-points the diagram at a new SPARQL endpoint
|
|
31683
|
-
*
|
|
31843
|
+
* Re-points the diagram at a new SPARQL endpoint by recreating it with a fresh data provider.
|
|
31844
|
+
* The canvas is reset to empty, matching the initial mount, since the data of another repository
|
|
31845
|
+
* has nothing to do with the current graph.
|
|
31684
31846
|
*/
|
|
31685
31847
|
async function updateReactodia(props) {
|
|
31686
31848
|
if (!workspaceContext) {
|
|
@@ -31705,7 +31867,7 @@ function unmountReactodia(root) {
|
|
|
31705
31867
|
root.unmount();
|
|
31706
31868
|
}
|
|
31707
31869
|
|
|
31708
|
-
const graphwiseReactodiaCss = "graphwise-reactodia{display:block;width:100%;height:75vh}graphwise-reactodia .reactodia-container{position:relative;width:100%;height:100%}";
|
|
31870
|
+
const graphwiseReactodiaCss = "graphwise-reactodia{display:block;width:100%;height:75vh}graphwise-reactodia .reactodia-container{position:relative;width:100%;height:100%}graphwise-reactodia .reactodia-selection-action__link{display:none}";
|
|
31709
31871
|
|
|
31710
31872
|
const GraphwiseReactodia = class {
|
|
31711
31873
|
constructor(hostRef) {
|
|
@@ -31715,12 +31877,13 @@ const GraphwiseReactodia = class {
|
|
|
31715
31877
|
*/
|
|
31716
31878
|
this.language = LanguageKey.EN;
|
|
31717
31879
|
}
|
|
31718
|
-
|
|
31880
|
+
onCurrentRepositoryChange() {
|
|
31719
31881
|
this.renderGraph();
|
|
31720
31882
|
}
|
|
31721
|
-
|
|
31883
|
+
onLanguageOrSettingsChange() {
|
|
31722
31884
|
// The translations are evaluated by the workspace at construction, so the only way
|
|
31723
31885
|
// to re-translate the UI is to re-create the graph.
|
|
31886
|
+
// Setting changes should keep the current diagram despite possible
|
|
31724
31887
|
this.renderGraph(true);
|
|
31725
31888
|
}
|
|
31726
31889
|
onThemeChange() {
|
|
@@ -31739,7 +31902,7 @@ const GraphwiseReactodia = class {
|
|
|
31739
31902
|
}
|
|
31740
31903
|
}
|
|
31741
31904
|
render() {
|
|
31742
|
-
return (h(Host, { key: '
|
|
31905
|
+
return (h(Host, { key: '6f1115b91eac308ef155978dfe1482f152c38b1b' }));
|
|
31743
31906
|
}
|
|
31744
31907
|
renderGraph(isReloading) {
|
|
31745
31908
|
var _a;
|
|
@@ -31749,6 +31912,9 @@ const GraphwiseReactodia = class {
|
|
|
31749
31912
|
if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.queryFunction)) {
|
|
31750
31913
|
throw new Error('config.queryFunction is required');
|
|
31751
31914
|
}
|
|
31915
|
+
if (!this.providerSettings) {
|
|
31916
|
+
throw new Error('providerSettings is required');
|
|
31917
|
+
}
|
|
31752
31918
|
if (!this.hostElement) {
|
|
31753
31919
|
return;
|
|
31754
31920
|
}
|
|
@@ -31768,9 +31934,9 @@ const GraphwiseReactodia = class {
|
|
|
31768
31934
|
}
|
|
31769
31935
|
get hostElement() { return getElement(this); }
|
|
31770
31936
|
static get watchers() { return {
|
|
31771
|
-
"currentRepository": ["
|
|
31772
|
-
"
|
|
31773
|
-
"
|
|
31937
|
+
"currentRepository": ["onCurrentRepositoryChange"],
|
|
31938
|
+
"language": ["onLanguageOrSettingsChange"],
|
|
31939
|
+
"providerSettings": ["onLanguageOrSettingsChange"],
|
|
31774
31940
|
"theme": ["onThemeChange"]
|
|
31775
31941
|
}; }
|
|
31776
31942
|
};
|
|
@@ -17,5 +17,5 @@ var patchBrowser = () => {
|
|
|
17
17
|
|
|
18
18
|
patchBrowser().then(async (options) => {
|
|
19
19
|
await globalScripts();
|
|
20
|
-
return bootstrapLazy([["graphwise-reactodia",[[0,"graphwise-reactodia",{"currentRepository":[1,"current-repository"],"config":[16],"language":[1],"providerSettings":[16,"provider-settings"],"theme":[1]},null,{"currentRepository":["
|
|
20
|
+
return bootstrapLazy([["graphwise-reactodia",[[0,"graphwise-reactodia",{"currentRepository":[1,"current-repository"],"config":[16],"language":[1],"providerSettings":[16,"provider-settings"],"theme":[1]},null,{"currentRepository":["onCurrentRepositoryChange"],"language":["onLanguageOrSettingsChange"],"providerSettings":["onLanguageOrSettingsChange"],"theme":["onThemeChange"]}]]]], options);
|
|
21
21
|
});
|
package/dist/esm/loader.js
CHANGED
|
@@ -5,7 +5,7 @@ import { g as globalScripts } from './app-globals-CalY52z6.js';
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await globalScripts();
|
|
8
|
-
return bootstrapLazy([["graphwise-reactodia",[[0,"graphwise-reactodia",{"currentRepository":[1,"current-repository"],"config":[16],"language":[1],"providerSettings":[16,"provider-settings"],"theme":[1]},null,{"currentRepository":["
|
|
8
|
+
return bootstrapLazy([["graphwise-reactodia",[[0,"graphwise-reactodia",{"currentRepository":[1,"current-repository"],"config":[16],"language":[1],"providerSettings":[16,"provider-settings"],"theme":[1]},null,{"currentRepository":["onCurrentRepositoryChange"],"language":["onLanguageOrSettingsChange"],"providerSettings":["onLanguageOrSettingsChange"],"theme":["onThemeChange"]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export { defineCustomElements };
|