@igea/oac_frontend 1.0.95 → 1.0.96
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/package.json +1 -1
- package/src/controllers/investigation.js +19 -1
- package/src/index.js +1 -0
- package/src/public/js/app/vue-investigation.js +33 -24
- package/src/public/js/lib/sparnatural-main.js +281 -85
- package/src/public/v2/css/v2.css +57 -1
- package/src/public/v2/images/banner.pdn +0 -0
- package/src/public/v2/images/banner.png +0 -0
- package/src/public/v2/images/dip_sdara.jpg +0 -0
- package/src/public/v2/js/v2.js +39 -1
- package/src/views/investigation/view.twig +155 -0
- package/src/views/v2/investigation/form.twig +2 -1
- package/src/views/v2/investigation/form_content.twig +4 -2
- package/src/views/v2/investigation/view.twig +28 -0
- package/src/views/v2/partials/header.twig +1 -1
- package/src/views/v2/presentazione/contatti.twig +7 -1
- package/src/views/v2/presentazione/crediti.twig +41 -8
- package/src/views/v2/presentazione/finalita.twig +1 -1
- package/src/views/v2/presentazione/partecipanti.twig +44 -11
- package/src/views/v2/search/advanced.twig +13 -0
- package/src/views/v2/search/index.twig +5 -1
- package/src/views/v2/sidebars/investigation.twig +10 -3
- package/src/views/v2/users/index.twig +1 -1
- package/src/views/v2/users/manage.twig +1 -1
- package/src/views/v2/vocabolaries/edit.twig +3 -1
package/package.json
CHANGED
|
@@ -12,7 +12,8 @@ module.exports = function(serviceName) {
|
|
|
12
12
|
root: serviceName,
|
|
13
13
|
title: 'Investigation Creation',
|
|
14
14
|
currentPath: req.baseUrl +req.path,
|
|
15
|
-
uuid
|
|
15
|
+
uuid,
|
|
16
|
+
mode: 'edit'
|
|
16
17
|
});
|
|
17
18
|
res.render('investigation/form.twig', data.toJson());
|
|
18
19
|
}
|
|
@@ -25,6 +26,23 @@ module.exports = function(serviceName) {
|
|
|
25
26
|
renderForm(req, res, req.params.uuid);
|
|
26
27
|
});
|
|
27
28
|
|
|
29
|
+
router.get('/view/:uuid', (req, res) => {
|
|
30
|
+
const { uuid } = req.params;
|
|
31
|
+
|
|
32
|
+
let data = new DataModel(req, {
|
|
33
|
+
root: serviceName,
|
|
34
|
+
title: 'Indagine viewer',
|
|
35
|
+
uuid,
|
|
36
|
+
|
|
37
|
+
// 👇 NASCONDE MENU E SIDEBAR
|
|
38
|
+
activeMenu: null,
|
|
39
|
+
activeSidebar: null,
|
|
40
|
+
activeSidebarItem: null
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
res.render('investigation/view.twig', data.toJson());
|
|
44
|
+
});
|
|
45
|
+
|
|
28
46
|
return router
|
|
29
47
|
}
|
|
30
48
|
|
package/src/index.js
CHANGED
|
@@ -36,7 +36,11 @@ const KEEP_LOCK_EVERY = 45*1000;
|
|
|
36
36
|
document.addEventListener('DOMContentLoaded', () => {
|
|
37
37
|
|
|
38
38
|
// App separata per l'autocomplete
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
const elSearch = document.getElementById(searchId);
|
|
41
|
+
|
|
42
|
+
if (elSearch && typeof __AUTO_COMPLETE_COMPONENT__ !== 'undefined') {
|
|
43
|
+
//if (typeof __AUTO_COMPLETE_COMPONENT__ !== 'undefined') {
|
|
40
44
|
try {
|
|
41
45
|
const elSearch = document.getElementById(searchId);
|
|
42
46
|
const searchApp = createApp({
|
|
@@ -131,9 +135,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
131
135
|
} catch (error) {
|
|
132
136
|
console.error('Error mounting search app:', error);
|
|
133
137
|
}
|
|
134
|
-
} else {
|
|
138
|
+
} /*else {
|
|
135
139
|
console.error('__AUTO_COMPLETE_COMPONENT__ not defined');
|
|
136
|
-
}
|
|
140
|
+
}*/
|
|
137
141
|
|
|
138
142
|
const el = document.getElementById(appId);
|
|
139
143
|
|
|
@@ -178,9 +182,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
178
182
|
}
|
|
179
183
|
},
|
|
180
184
|
mounted() {
|
|
181
|
-
|
|
185
|
+
console.log("UUID da dataset:", this.uuid);
|
|
186
|
+
if (showForm && this.uuid == null) {
|
|
182
187
|
this.resetShaclForm(null, true);
|
|
183
188
|
}
|
|
189
|
+
else
|
|
190
|
+
if (showForm && this.uuid) {
|
|
191
|
+
this.isVisible = true;
|
|
192
|
+
this.inEditing = true;
|
|
193
|
+
this.resetShaclForm(this.uuid, true); // ❌ uuid non definito
|
|
194
|
+
}
|
|
184
195
|
|
|
185
196
|
this.initShaclForm();
|
|
186
197
|
setInterval(this.autoSave.bind(this), 30*1000);
|
|
@@ -303,19 +314,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
303
314
|
form.remove();
|
|
304
315
|
},
|
|
305
316
|
resetShaclForm(uuid, edit) {
|
|
306
|
-
// Trova il form esistente
|
|
307
317
|
const oldForm = document.querySelector("shacl-form");
|
|
308
318
|
const parent = document.getElementById("shacl-container");
|
|
309
|
-
|
|
319
|
+
|
|
310
320
|
if (oldForm) oldForm.remove();
|
|
311
|
-
if(!parent){
|
|
312
|
-
setTimeout((
|
|
313
|
-
|
|
314
|
-
}
|
|
321
|
+
if (!parent) {
|
|
322
|
+
setTimeout(() => {
|
|
323
|
+
this.resetShaclForm(uuid, edit);
|
|
324
|
+
}, 150);
|
|
315
325
|
return;
|
|
316
326
|
}
|
|
317
327
|
|
|
318
|
-
// Crea un nuovo shacl-form con gli stessi attributi
|
|
319
328
|
const newForm = document.createElement("shacl-form");
|
|
320
329
|
newForm.id = "shacl-form";
|
|
321
330
|
newForm.dataset.collapse = "open";
|
|
@@ -323,27 +332,27 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
323
332
|
newForm.dataset.shapesUrl = "/backend/ontology/schema/editing";
|
|
324
333
|
newForm.dataset.generateNodeShapeReference = "";
|
|
325
334
|
|
|
326
|
-
|
|
327
|
-
if(!edit){
|
|
335
|
+
if (!edit) {
|
|
328
336
|
newForm.dataset.view = "";
|
|
329
337
|
}
|
|
330
|
-
|
|
331
|
-
newForm.dataset.shapeSubject=
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
338
|
+
|
|
339
|
+
newForm.dataset.shapeSubject =
|
|
340
|
+
"http://example.org/shapes/E7Activity01Shape";
|
|
341
|
+
|
|
342
|
+
// ✅ QUESTO È IL PEZZO MANCANTE
|
|
343
|
+
if (uuid) {
|
|
344
|
+
const rnd = Date.now();
|
|
345
|
+
newForm.dataset.valuesUrl =
|
|
346
|
+
"/backend/ontology/form/" + uuid + "?rnd=" + rnd;
|
|
347
|
+
newForm.dataset.valuesSubject =
|
|
348
|
+
"http://indagine/" + uuid;
|
|
337
349
|
}
|
|
338
350
|
|
|
339
|
-
// Inserisci il nuovo form
|
|
340
351
|
parent.appendChild(newForm);
|
|
341
352
|
|
|
342
|
-
// Resetta il riferimento e reinizializza
|
|
343
353
|
this.form = null;
|
|
344
354
|
this.initShaclForm(uuid);
|
|
345
|
-
|
|
346
|
-
},
|
|
355
|
+
},
|
|
347
356
|
initShaclForm(uuid) {
|
|
348
357
|
var _this = this;
|
|
349
358
|
setTimeout(async ()=>{
|
|
@@ -5,113 +5,309 @@
|
|
|
5
5
|
// reference to the sparnatural webcomponent
|
|
6
6
|
const sparnatural = document.querySelector("spar-natural");
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
/* =========================
|
|
9
|
+
VIEW MODE (radio buttons)
|
|
10
|
+
========================= */
|
|
11
|
+
|
|
12
|
+
let viewMode = "direct";
|
|
13
|
+
|
|
14
|
+
document.querySelectorAll('input[name="viewMode"]').forEach(radio => {
|
|
15
|
+
radio.addEventListener("change", e => {
|
|
16
|
+
viewMode = e.target.value;
|
|
17
|
+
sparnatural.enablePlayBtn();
|
|
18
|
+
console.log("View mode:", viewMode);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/* =========================
|
|
23
|
+
INDAGINE RESOLVERS MAP
|
|
24
|
+
========================= */
|
|
25
|
+
|
|
26
|
+
const INDAGINE_RESOLVERS = {
|
|
27
|
+
"crm:E39_Actor": {
|
|
28
|
+
property: "crm:P14_carried_out_by"
|
|
29
|
+
},
|
|
30
|
+
"crm:E42_Identifier": {
|
|
31
|
+
property: "crm:P48_has_preferred_identifier"
|
|
32
|
+
},
|
|
33
|
+
"crm:E55_Type": {
|
|
34
|
+
property: "crm:P2_has_type"
|
|
35
|
+
},
|
|
36
|
+
"base:I12_Adopted_Belief": {
|
|
37
|
+
property: "crm:P17_was_motivated_by"
|
|
38
|
+
},
|
|
39
|
+
"j.0:S13_Sample": {
|
|
40
|
+
property: "crm:P16_used_specific_object"
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/* =========================
|
|
45
|
+
YASQE INIT
|
|
46
|
+
========================= */
|
|
11
47
|
|
|
12
|
-
// init yasQE query editor
|
|
13
48
|
const yasqe = new Yasqe(document.getElementById("yasqe"), {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
copyEndpointOnNewTab: false
|
|
49
|
+
requestConfig: {
|
|
50
|
+
endpoint: sparnatural.getAttribute("endpoint"),
|
|
51
|
+
method: "GET",
|
|
52
|
+
header: {}
|
|
53
|
+
},
|
|
54
|
+
copyEndpointOnNewTab: false
|
|
21
55
|
});
|
|
22
56
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Yasr.registerPlugin("Grid",SparnaturalYasguiPlugins.GridPlugin);
|
|
27
|
-
delete Yasr.plugins['table'];
|
|
57
|
+
/* =========================
|
|
58
|
+
YASR INIT
|
|
59
|
+
========================= */
|
|
28
60
|
|
|
61
|
+
Yasr.registerPlugin("TableX", SparnaturalYasguiPlugins.TableX);
|
|
62
|
+
Yasr.registerPlugin("Grid", SparnaturalYasguiPlugins.GridPlugin);
|
|
63
|
+
delete Yasr.plugins['table'];
|
|
29
64
|
|
|
30
65
|
const yasr = new Yasr(document.getElementById("yasr"), {
|
|
31
|
-
|
|
32
|
-
|
|
66
|
+
pluginOrder: ["TableX", "Grid", "response"],
|
|
67
|
+
defaultPlugin: "TableX"
|
|
33
68
|
});
|
|
34
69
|
|
|
35
|
-
yasr.plugins["TableX"].config.uriHrefAdapter = function(uri) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
70
|
+
yasr.plugins["TableX"].config.uriHrefAdapter = function (uri) {
|
|
71
|
+
|
|
72
|
+
// modalità "indagine": link diretto al form SHACL
|
|
73
|
+
if (viewMode === "indagine" && uri.startsWith("http://indagine/")) {
|
|
74
|
+
const id = uri.split("/").pop();
|
|
75
|
+
return `/frontend/investigation/view/${id}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// modalità "direct": comportamento attuale
|
|
79
|
+
if (viewMode === "direct" && uri.startsWith("http://indagine/")) {
|
|
80
|
+
return "/frontend/v2/rdf/view?iri=" + encodeURIComponent("<" + uri + ">");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// fallback
|
|
84
|
+
return uri;
|
|
41
85
|
};
|
|
42
86
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
87
|
+
|
|
88
|
+
/* =========================
|
|
89
|
+
QUERY RESPONSE HANDLER
|
|
90
|
+
========================= */
|
|
91
|
+
|
|
92
|
+
yasqe.on("queryResponse", function (_yasqe, response, duration) {
|
|
93
|
+
yasr.setResponse(response, duration);
|
|
94
|
+
|
|
95
|
+
if (viewMode === "indagine") {
|
|
96
|
+
resolvedIndagini.clear();
|
|
97
|
+
const sparqlResponse = normalizeSparqlResponse(response);
|
|
98
|
+
if (sparqlResponse) {
|
|
99
|
+
resolveIndagini(sparqlResponse);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
sparnatural.enablePlayBtn();
|
|
48
105
|
});
|
|
49
106
|
|
|
107
|
+
/* =========================
|
|
108
|
+
RESOLVER PIPELINE
|
|
109
|
+
========================= */
|
|
110
|
+
|
|
111
|
+
function resolveIndagini(response) {
|
|
112
|
+
const uris = extractUrisFromResponse(response);
|
|
113
|
+
|
|
114
|
+
console.log("URIs trovate:", uris);
|
|
115
|
+
|
|
116
|
+
uris.forEach(uri => {
|
|
117
|
+
resolveIndagineFromUri(uri);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function resolveIndagineFromUri(uri) {
|
|
122
|
+
const typeQuery = `
|
|
123
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
124
|
+
|
|
125
|
+
SELECT DISTINCT ?type
|
|
126
|
+
WHERE {
|
|
127
|
+
<${uri}> rdf:type ?type .
|
|
128
|
+
}
|
|
129
|
+
LIMIT 10
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
fetchSparql(typeQuery).then(data => {
|
|
133
|
+
const types = data.results.bindings
|
|
134
|
+
.map(b => normalizeRdfType(b.type.value))
|
|
135
|
+
.filter(Boolean);
|
|
136
|
+
|
|
137
|
+
console.log("Tipi normalizzati:", types);
|
|
138
|
+
|
|
139
|
+
types.forEach(t => {
|
|
140
|
+
const resolver = INDAGINE_RESOLVERS[t];
|
|
141
|
+
if (!resolver) return;
|
|
142
|
+
|
|
143
|
+
const q = buildResolverQuery(uri, resolver.property);
|
|
144
|
+
fetchIndagini(q);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let resolvedIndagini = new Set();
|
|
151
|
+
|
|
152
|
+
function fetchIndagini(query) {
|
|
153
|
+
fetchSparql(query).then(data => {
|
|
154
|
+
const bindings = data.results?.bindings || [];
|
|
155
|
+
|
|
156
|
+
bindings.forEach(b => {
|
|
157
|
+
if (b.indagine?.type === "uri") {
|
|
158
|
+
resolvedIndagini.add(b.indagine.value);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// quando finiamo di risolvere, aggiorniamo la UI
|
|
163
|
+
renderIndaginiResults();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function renderIndaginiResults() {
|
|
168
|
+
const bindings = Array.from(resolvedIndagini).map(uri => ({
|
|
169
|
+
indagine: {
|
|
170
|
+
type: "uri",
|
|
171
|
+
value: uri
|
|
172
|
+
}
|
|
173
|
+
}));
|
|
174
|
+
|
|
175
|
+
const fakeResponse = {
|
|
176
|
+
head: {
|
|
177
|
+
vars: ["indagine"]
|
|
178
|
+
},
|
|
179
|
+
results: {
|
|
180
|
+
bindings
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
console.log("SPARQL response (indagini):", fakeResponse);
|
|
185
|
+
|
|
186
|
+
yasr.setResponse(fakeResponse);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
/* =========================
|
|
191
|
+
SPARQL HELPERS
|
|
192
|
+
========================= */
|
|
193
|
+
|
|
194
|
+
function fetchSparql(query) {
|
|
195
|
+
const url =
|
|
196
|
+
sparnatural.getAttribute("endpoint") +
|
|
197
|
+
"?query=" + encodeURIComponent(query);
|
|
198
|
+
|
|
199
|
+
return fetch(url).then(r => r.json());
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function extractUrisFromResponse(response) {
|
|
203
|
+
const vars = response.head.vars;
|
|
204
|
+
const results = response.results.bindings;
|
|
205
|
+
const uris = [];
|
|
206
|
+
|
|
207
|
+
results.forEach(row => {
|
|
208
|
+
vars.forEach(v => {
|
|
209
|
+
if (row[v]?.type === "uri") {
|
|
210
|
+
uris.push(row[v].value);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return [...new Set(uris)];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
function normalizeSparqlResponse(response) {
|
|
220
|
+
if (response?.head && response?.results) {
|
|
221
|
+
return response; // già ok
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (typeof response?.text === "string") {
|
|
225
|
+
try {
|
|
226
|
+
return JSON.parse(response.text);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.error("Errore parsing SPARQL JSON", response.text);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
console.warn("Formato response SPARQL non riconosciuto", response);
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function normalizeRdfType(uri) {
|
|
237
|
+
if (!uri) return null;
|
|
238
|
+
|
|
239
|
+
// CIDOC CRM
|
|
240
|
+
if (uri.startsWith("http://www.cidoc-crm.org/cidoc-crm/")) {
|
|
241
|
+
return "crm:" + uri.split("/").pop();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// CRMsci / j.0
|
|
245
|
+
if (uri.startsWith("http://www.cidoc-crm.org/extensions/crmsci/")) {
|
|
246
|
+
return "j.0:" + uri.split("/").pop();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// base CPM / CRMinf (adatta se necessario)
|
|
250
|
+
if (uri.startsWith("http://ontome.net/ns/cpm/")) {
|
|
251
|
+
return "base:" + uri.split("/").pop();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// fallback: ultimo frammento
|
|
255
|
+
return uri.split("/").pop();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* =========================
|
|
259
|
+
SPARQL QUERY BUILDER
|
|
260
|
+
========================= */
|
|
261
|
+
|
|
262
|
+
function buildResolverQuery(uri, property) {
|
|
263
|
+
return `
|
|
264
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
265
|
+
PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
|
|
266
|
+
|
|
267
|
+
SELECT DISTINCT ?indagine
|
|
268
|
+
WHERE {
|
|
269
|
+
?indagine rdf:type crm:E7_Activity ;
|
|
270
|
+
${property} <${uri}> .
|
|
271
|
+
}
|
|
272
|
+
`;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* =========================
|
|
276
|
+
SPARNATURAL EVENTS
|
|
277
|
+
========================= */
|
|
50
278
|
|
|
51
279
|
sparnatural.addEventListener("init", (event) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
280
|
+
for (const plugin in yasr.plugins) {
|
|
281
|
+
if (yasr.plugins[plugin].notifyConfiguration) {
|
|
282
|
+
yasr.plugins[plugin].notifyConfiguration(event.detail.config);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
60
285
|
});
|
|
61
286
|
|
|
62
|
-
// listener when sparnatural updates the query
|
|
63
|
-
// see http://docs.sparnatural.eu/Javascript-integration.html#sparnatural-events
|
|
64
287
|
sparnatural.addEventListener("queryUpdated", (event) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
yasqe.setValue(queryString);
|
|
68
|
-
// display the JSON query on the console
|
|
69
|
-
console.log("Sparnatural JSON query structure:");
|
|
70
|
-
console.dir(event.detail.queryJson);
|
|
71
|
-
|
|
72
|
-
// notify the query to yasr plugins
|
|
73
|
-
for (const plugin in yasr.plugins) {
|
|
74
|
-
if (yasr.plugins[plugin].notifyQuery) {
|
|
75
|
-
yasr.plugins[plugin].notifyQuery(event.detail.queryJson);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
});
|
|
288
|
+
const queryString = sparnatural.expandSparql(event.detail.queryString);
|
|
289
|
+
yasqe.setValue(queryString);
|
|
79
290
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
sparnatural.addEventListener("submit", (event) => {
|
|
83
|
-
// enable loader on button
|
|
84
|
-
sparnatural.disablePlayBtn() ;
|
|
85
|
-
// trigger the query from YasQE
|
|
86
|
-
yasqe.query();
|
|
291
|
+
console.log("Sparnatural JSON query:");
|
|
292
|
+
console.dir(event.detail.queryJson);
|
|
87
293
|
});
|
|
88
294
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// empties the SPARQL query on yasQE
|
|
93
|
-
yasqe.setValue("");
|
|
295
|
+
sparnatural.addEventListener("submit", () => {
|
|
296
|
+
sparnatural.disablePlayBtn();
|
|
297
|
+
yasqe.query();
|
|
94
298
|
});
|
|
95
299
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
document.getElementById('yasqe').style.display = 'block';
|
|
100
|
-
yasqe.setValue(yasqe.getValue());
|
|
101
|
-
yasqe.refresh();
|
|
102
|
-
} else {
|
|
103
|
-
document.getElementById('yasqe').style.display = 'none';
|
|
104
|
-
}
|
|
105
|
-
return false;
|
|
106
|
-
} ;
|
|
107
|
-
|
|
108
|
-
/*
|
|
109
|
-
const treeValues = [
|
|
110
|
-
{ label: "Fruit", children: ["Apple", "Orange", "Banana"] },
|
|
111
|
-
{ label: "Vegetables", children: ["Carrot", "Lettuce"] }
|
|
112
|
-
];
|
|
113
|
-
|
|
114
|
-
const widget = new TreeSelectWidget("myWidgetContainer", treeValues);
|
|
115
|
-
*/
|
|
300
|
+
sparnatural.addEventListener("reset", () => {
|
|
301
|
+
yasqe.setValue("");
|
|
302
|
+
});
|
|
116
303
|
|
|
304
|
+
/* =========================
|
|
305
|
+
TOGGLE SPARQL EDITOR
|
|
306
|
+
========================= */
|
|
117
307
|
|
|
308
|
+
document.getElementById('sparql-toggle').onclick = function () {
|
|
309
|
+
const el = document.getElementById('yasqe');
|
|
310
|
+
el.style.display = el.style.display === 'none' ? 'block' : 'none';
|
|
311
|
+
yasqe.refresh();
|
|
312
|
+
return false;
|
|
313
|
+
};
|
package/src/public/v2/css/v2.css
CHANGED
|
@@ -100,7 +100,7 @@ body.layout-v2 {
|
|
|
100
100
|
background-image: url('/frontend/v2/images/banner.png');
|
|
101
101
|
background-repeat: no-repeat;
|
|
102
102
|
background-size: contain;
|
|
103
|
-
background-position: top
|
|
103
|
+
background-position: top left;
|
|
104
104
|
background-color: #B1A891;
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -607,5 +607,61 @@ body.layout-v2 {
|
|
|
607
607
|
object-fit: contain;
|
|
608
608
|
flex-shrink: 0;
|
|
609
609
|
}
|
|
610
|
+
/* =====================================================
|
|
611
|
+
PARTECIPANTI – ACCORDION (SPAZIO BIANCO REALE)
|
|
612
|
+
===================================================== */
|
|
613
|
+
|
|
614
|
+
.department-banner {
|
|
615
|
+
position: relative;
|
|
616
|
+
height: 90px;
|
|
617
|
+
padding: 20px;
|
|
618
|
+
|
|
619
|
+
display: flex;
|
|
620
|
+
align-items: center;
|
|
621
|
+
|
|
622
|
+
background-size: cover;
|
|
623
|
+
background-position: center;
|
|
624
|
+
border-radius: 4px;
|
|
625
|
+
|
|
626
|
+
filter: grayscale(100%);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.department-name {
|
|
630
|
+
font-size: 0.9rem;
|
|
631
|
+
font-weight: 500;
|
|
632
|
+
color: rgba(255,255,255,0.9);
|
|
633
|
+
}
|
|
610
634
|
|
|
611
635
|
|
|
636
|
+
.department-people {
|
|
637
|
+
font-size: 1.05rem;
|
|
638
|
+
font-weight: 600;
|
|
639
|
+
|
|
640
|
+
color: #ffffff; /* 🔑 bianco pieno */
|
|
641
|
+
letter-spacing: 0.2px;
|
|
642
|
+
|
|
643
|
+
text-shadow:
|
|
644
|
+
0 1px 2px rgba(0,0,0,0.45); /* 🔑 aiuta molto */
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
.department-overlay {
|
|
649
|
+
position: relative;
|
|
650
|
+
z-index: 1;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
.department-banner::before {
|
|
655
|
+
content: '';
|
|
656
|
+
position: absolute;
|
|
657
|
+
inset: 0;
|
|
658
|
+
|
|
659
|
+
background: linear-gradient(
|
|
660
|
+
to right,
|
|
661
|
+
rgba(0,0,0,0.35),
|
|
662
|
+
rgba(0,0,0,0.10)
|
|
663
|
+
);
|
|
664
|
+
|
|
665
|
+
border-radius: 4px;
|
|
666
|
+
z-index: 0;
|
|
667
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/public/v2/js/v2.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
document.addEventListener('DOMContentLoaded', () => {
|
|
2
2
|
|
|
3
3
|
/* =========================
|
|
4
|
-
* TOP MENU
|
|
4
|
+
* TOP MENU
|
|
5
5
|
* ========================= */
|
|
6
6
|
const topMenuEl = document.querySelector('#top-menu');
|
|
7
7
|
if (topMenuEl) {
|
|
@@ -28,4 +28,42 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
28
28
|
}).mount(sidebarEl);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
|
|
32
|
+
/* =========================
|
|
33
|
+
* SIDEBAR PRESENTAZIONE
|
|
34
|
+
* ========================= */
|
|
35
|
+
const sidebarInd = document.querySelector('#sidebar-investigation');
|
|
36
|
+
if (sidebarInd) {
|
|
37
|
+
const activeItem = document.body.dataset.activeSidebarItem || '';
|
|
38
|
+
|
|
39
|
+
Vue.createApp({
|
|
40
|
+
data() {
|
|
41
|
+
return { activeItem };
|
|
42
|
+
}
|
|
43
|
+
}).mount(sidebarInd);
|
|
44
|
+
}
|
|
45
|
+
/* =========================
|
|
46
|
+
* PARTECIPANTI – ACCORDION
|
|
47
|
+
* ========================= */
|
|
48
|
+
const accordionHeaders = document.querySelectorAll('.accordion-trigger');
|
|
49
|
+
if (accordionHeaders.length) {
|
|
50
|
+
|
|
51
|
+
accordionHeaders.forEach(btn => {
|
|
52
|
+
btn.addEventListener('click', () => {
|
|
53
|
+
const item = btn.closest('.department-banner');
|
|
54
|
+
if (!item) return;
|
|
55
|
+
|
|
56
|
+
// Chiude gli altri accordion aperti
|
|
57
|
+
document.querySelectorAll('.department-banner.open')
|
|
58
|
+
.forEach(el => {
|
|
59
|
+
if (el !== item) el.classList.remove('open');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Toggle dell’elemento corrente
|
|
63
|
+
item.classList.toggle('open');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
31
69
|
});
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
{% extends "/v2/layout.twig" %}
|
|
2
|
+
|
|
3
|
+
{# --------------------------------------------------
|
|
4
|
+
Forziamo modalità viewer:
|
|
5
|
+
- niente sidebar
|
|
6
|
+
- header minimale
|
|
7
|
+
-------------------------------------------------- #}
|
|
8
|
+
{% set activeMenu = null %}
|
|
9
|
+
{% set activeSidebar = null %}
|
|
10
|
+
{% set activeSidebarItem = null %}
|
|
11
|
+
|
|
12
|
+
{% block extendHead %}
|
|
13
|
+
|
|
14
|
+
{# SHACL FORM web component #}
|
|
15
|
+
<script src="/frontend/js/lib/shacl-form.bundle.js" type="module"></script>
|
|
16
|
+
|
|
17
|
+
{# Vue investigation (stessa usata per editing) #}
|
|
18
|
+
<script src="/frontend/js/app/vue-investigation.js"></script>
|
|
19
|
+
|
|
20
|
+
<style>
|
|
21
|
+
.viewer-container {
|
|
22
|
+
max-width: 1100px;
|
|
23
|
+
margin: 20px auto;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.viewer-header {
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
align-items: center;
|
|
30
|
+
margin-bottom: 10px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.viewer-header h2 {
|
|
34
|
+
margin: 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.viewer-actions {
|
|
38
|
+
text-align: center;
|
|
39
|
+
margin-top: 20px;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
42
|
+
|
|
43
|
+
{% endblock %}
|
|
44
|
+
|
|
45
|
+
{% block content %}
|
|
46
|
+
|
|
47
|
+
<div class="viewer-container">
|
|
48
|
+
|
|
49
|
+
<div class="viewer-header">
|
|
50
|
+
<h2>Indagine</h2>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
{# --------------------------------------------------
|
|
54
|
+
Vue root (SENZA search)
|
|
55
|
+
UUID passato dal controller
|
|
56
|
+
-------------------------------------------------- #}
|
|
57
|
+
<div v-cloak
|
|
58
|
+
id="investigation-app"
|
|
59
|
+
data-cur_role="{{ user.role }}"
|
|
60
|
+
data-uuid="{{ uuid }}"
|
|
61
|
+
data-editing="{{ user.role != 3 }}"
|
|
62
|
+
data-show-form="true"
|
|
63
|
+
data-label_save_ok="{{ t('investigation.save_ok') }}"
|
|
64
|
+
data-label_save_err="{{ t('investigation.save_err') }}"
|
|
65
|
+
>
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<template v-if="isVisible">
|
|
69
|
+
|
|
70
|
+
{# ---------------- BUTTONS ---------------- #}
|
|
71
|
+
{% if user.role != 3 %}
|
|
72
|
+
<div class="col-12 text-center mt-4">
|
|
73
|
+
|
|
74
|
+
<button class="btn btn-secondary mx-2"
|
|
75
|
+
@click="download('xml')">
|
|
76
|
+
RDF/XML
|
|
77
|
+
</button>
|
|
78
|
+
|
|
79
|
+
<button class="btn btn-secondary mx-2"
|
|
80
|
+
@click="download('ttl')">
|
|
81
|
+
TURTLE
|
|
82
|
+
</button>
|
|
83
|
+
|
|
84
|
+
<button v-if="inEditing && validForm"
|
|
85
|
+
:disabled="saving"
|
|
86
|
+
class="btn btn-primary mx-2"
|
|
87
|
+
@click="save(false)">
|
|
88
|
+
<i v-if="saving" class="fa-solid fa-spinner"></i>
|
|
89
|
+
<i v-else class="fa-solid fa-save"></i>
|
|
90
|
+
</button>
|
|
91
|
+
|
|
92
|
+
</div>
|
|
93
|
+
{% endif %}
|
|
94
|
+
|
|
95
|
+
{# ---------------- SHACL FORM ---------------- #}
|
|
96
|
+
<div id="shacl-container"
|
|
97
|
+
style="margin-top:15px;
|
|
98
|
+
border:dashed 2px gray;
|
|
99
|
+
padding:15px;
|
|
100
|
+
border-radius:6px;">
|
|
101
|
+
|
|
102
|
+
<shacl-form id="shacl-form"
|
|
103
|
+
data-collapse="open"
|
|
104
|
+
data-values-namespace="indagine:"
|
|
105
|
+
data-shapes-url="/backend/ontology/schema/editing"
|
|
106
|
+
data-generate-node-shape-reference=""
|
|
107
|
+
></shacl-form>
|
|
108
|
+
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
{# ---------------- DEBUG OUTPUT (admin) ---------------- #}
|
|
112
|
+
{% if user.role in [0,1] %}
|
|
113
|
+
<fieldset v-if="inEditing"
|
|
114
|
+
style="margin-top:15px;
|
|
115
|
+
border: solid 1px gray;
|
|
116
|
+
border-radius: 6px;
|
|
117
|
+
padding: 10px;">
|
|
118
|
+
<legend>
|
|
119
|
+
Output SHACL
|
|
120
|
+
[{@ validForm ? 'valido' : 'non valido' @}]
|
|
121
|
+
</legend>
|
|
122
|
+
<pre :style="outputStyle">{@ serializedForm @}</pre>
|
|
123
|
+
</fieldset>
|
|
124
|
+
{% endif %}
|
|
125
|
+
|
|
126
|
+
</template>
|
|
127
|
+
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
{# ---------------- CLOSE TAB ---------------- #}
|
|
131
|
+
<div class="viewer-actions">
|
|
132
|
+
<button class="btn btn-outline-secondary"
|
|
133
|
+
onclick="tryCloseViewer()">
|
|
134
|
+
Chiudi
|
|
135
|
+
</button>
|
|
136
|
+
|
|
137
|
+
<div id="close-hint"
|
|
138
|
+
style="display:none; margin-top:6px; color:#666; font-size:0.9em;">
|
|
139
|
+
Puoi chiudere questa scheda dal browser.
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<script>
|
|
146
|
+
function tryCloseViewer() {
|
|
147
|
+
window.close();
|
|
148
|
+
setTimeout(() => {
|
|
149
|
+
const hint = document.getElementById('close-hint');
|
|
150
|
+
if (hint) hint.style.display = 'block';
|
|
151
|
+
}, 200);
|
|
152
|
+
}
|
|
153
|
+
</script>
|
|
154
|
+
|
|
155
|
+
{% endblock %}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
<div style="margin: 24px 32px;">
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
<style>
|
|
@@ -72,8 +72,9 @@
|
|
|
72
72
|
data-label_new="{{ t('investigation.new_item') }}"
|
|
73
73
|
data-label_search="{{ t('investigation.search') }}"
|
|
74
74
|
data-label_stop_edit="{{ t('investigation.stop_edit') }}"
|
|
75
|
+
data-label_edit_from_other_user="{{ t('investigation.edit_from_other_user') }}"
|
|
75
76
|
></div>
|
|
76
|
-
|
|
77
|
+
|
|
77
78
|
<div v-cloak id="investigation-app"
|
|
78
79
|
data-show-form="{{ showForm ? 'true' : 'false' }}"
|
|
79
80
|
data-cur_role="{{ user.role }}"
|
|
@@ -167,3 +168,4 @@
|
|
|
167
168
|
|
|
168
169
|
</div>
|
|
169
170
|
|
|
171
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{% extends "/v2/layout.twig" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
|
|
5
|
+
<div class="container my-4">
|
|
6
|
+
|
|
7
|
+
<h2>Indagine</h2>
|
|
8
|
+
|
|
9
|
+
<div id="shacl-container"
|
|
10
|
+
style="margin-top:10px;
|
|
11
|
+
border: solid 1px #ccc;
|
|
12
|
+
padding:15px;
|
|
13
|
+
border-radius:6px;">
|
|
14
|
+
|
|
15
|
+
<shacl-form
|
|
16
|
+
id="shacl-form"
|
|
17
|
+
data-collapse="open"
|
|
18
|
+
data-readonly="true"
|
|
19
|
+
data-values-namespace="indagine:"
|
|
20
|
+
data-node-iri="indagine:{{ uuid }}"
|
|
21
|
+
data-shapes-url="/backend/ontology/schema/view"
|
|
22
|
+
></shacl-form>
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
{% endblock %}
|
|
@@ -11,7 +11,13 @@
|
|
|
11
11
|
</header>
|
|
12
12
|
|
|
13
13
|
<p class="intro-text">
|
|
14
|
-
|
|
14
|
+
<p>
|
|
15
|
+
Per informazioni e contatti, è possibile inviare un’email all’indirizzo
|
|
16
|
+
<a href="mailto:hdlsd.info@gmail.com?subject=Richiesta%20informazioni">
|
|
17
|
+
hdlsd.info@gmail.com
|
|
18
|
+
</a>
|
|
19
|
+
|
|
20
|
+
</p>
|
|
15
21
|
</p>
|
|
16
22
|
|
|
17
23
|
|
|
@@ -2,18 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
{% block content %}
|
|
4
4
|
|
|
5
|
-
<section class="
|
|
5
|
+
<section class="models-section credits-section">
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
<header class="system-header">
|
|
7
|
+
<header class="models-header">
|
|
9
8
|
<h1>Crediti</h1>
|
|
9
|
+
<p class="models-intro">
|
|
10
|
+
La realizzazione di HD-LSD è il risultato di un lavoro interdisciplinare che ha
|
|
11
|
+
coinvolto competenze scientifiche, metodologiche e informatiche.
|
|
12
|
+
</p>
|
|
10
13
|
</header>
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
<!-- SVILUPPO MODELLI -->
|
|
16
|
+
<section class="credits-block">
|
|
17
|
+
<h2 class="credits-title">Analisi, progettazione e modellazione formale</h2>
|
|
18
|
+
<p class="credits-text">
|
|
19
|
+
Progettazione, definizione e validazione dei modelli concettuali e ontologici
|
|
20
|
+
per la rappresentazione dei dati diagnostici e del patrimonio culturale.
|
|
21
|
+
</p>
|
|
22
|
+
<ul class="credits-list">
|
|
23
|
+
<li>Donatella Fiorani</li>
|
|
24
|
+
<li>Chiara Porrovecchio</li>
|
|
25
|
+
<li>Alessia Vaccariello</li>
|
|
26
|
+
</ul>
|
|
27
|
+
</section>
|
|
28
|
+
|
|
29
|
+
<!-- SVILUPPO INFORMATICO -->
|
|
30
|
+
<section class="credits-block">
|
|
31
|
+
<h2 class="credits-title">Sviluppo del sistema informatico - IGeA Informatica Geografia e Ambiente</h2>
|
|
32
|
+
<p class="credits-text">
|
|
33
|
+
Progettazione e sviluppo dell’architettura software, delle interfacce web
|
|
34
|
+
e dei servizi di gestione e interrogazione dei dati.
|
|
35
|
+
</p>
|
|
36
|
+
<ul class="credits-list">
|
|
37
|
+
<li>Corrado Maddaluno</li>
|
|
38
|
+
<li>Armando De Filippo</li>
|
|
39
|
+
<li>Christian Picone</li>
|
|
40
|
+
</ul>
|
|
41
|
+
</section>
|
|
42
|
+
|
|
43
|
+
<!-- LOGHI -->
|
|
44
|
+
<section class="credits-block">
|
|
45
|
+
<h2 class="credits-title">Logo</h2>
|
|
46
|
+
<ul class="credits-list">
|
|
47
|
+
<li>Silvia Cutarelli</li>
|
|
48
|
+
</ul>
|
|
49
|
+
</section>
|
|
17
50
|
|
|
18
51
|
</section>
|
|
19
52
|
|
|
@@ -20,18 +20,51 @@
|
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
22
|
<ul class="department-banners">
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
|
|
24
|
+
<li class="department-banner banner-sdara">
|
|
25
|
+
<div class="department-overlay">
|
|
26
|
+
<div class="department-name">
|
|
27
|
+
Dipartimento di Storia, Disegno e Restauro dell'Architettura
|
|
28
|
+
</div>
|
|
29
|
+
<div class="department-people">
|
|
30
|
+
Donatella Fiorani · Chiara Porrovecchio · Silvia Cigognetti
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</li>
|
|
34
|
+
|
|
26
35
|
<li class="department-banner banner-antichita">
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
</
|
|
36
|
+
<div class="department-overlay">
|
|
37
|
+
<div class="department-name">
|
|
38
|
+
Dipartimento di Scienze dell'Antichità
|
|
39
|
+
</div>
|
|
40
|
+
<div class="department-people">
|
|
41
|
+
Cristina Lemorini · Giulia Previti
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</li>
|
|
45
|
+
|
|
46
|
+
<li class="department-banner banner-terra">
|
|
47
|
+
<div class="department-overlay">
|
|
48
|
+
<div class="department-name">
|
|
49
|
+
Dipartimento di Scienze della Terra
|
|
50
|
+
</div>
|
|
51
|
+
<div class="department-people">
|
|
52
|
+
Laura Medeghini · Melania Di Fazio
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</li>
|
|
56
|
+
|
|
57
|
+
<li class="department-banner banner-biologia">
|
|
58
|
+
<div class="department-overlay">
|
|
59
|
+
<div class="department-name">
|
|
60
|
+
Dipartimento di Biologia Ambientale
|
|
61
|
+
</div>
|
|
62
|
+
<div class="department-people">
|
|
63
|
+
Mauro Iberite · Laura Sadori · Alessia Masi · Eleonora Creafogli
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</li>
|
|
67
|
+
|
|
35
68
|
</ul>
|
|
36
69
|
|
|
37
70
|
|
|
@@ -44,6 +44,19 @@
|
|
|
44
44
|
debug="true"
|
|
45
45
|
></spar-natural>
|
|
46
46
|
|
|
47
|
+
<!-- Modalità risultati -->
|
|
48
|
+
<div class="mt-3 mb-2">
|
|
49
|
+
<label class="me-3">
|
|
50
|
+
<input type="radio" name="viewMode" value="direct" checked>
|
|
51
|
+
Risultati diretti
|
|
52
|
+
</label>
|
|
53
|
+
|
|
54
|
+
<label>
|
|
55
|
+
<input type="radio" name="viewMode" value="indagine">
|
|
56
|
+
Indagini collegate
|
|
57
|
+
</label>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
47
60
|
<span class="btn btn-primary" id="sparql-toggle">Toggle SPARQL query</span>
|
|
48
61
|
|
|
49
62
|
</div>
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
{% block content %}
|
|
4
4
|
<div class="system-page">
|
|
5
5
|
<h1>Ricerca</h1>
|
|
6
|
-
<p>
|
|
6
|
+
<p>Funzioni di ricerca SPARQL:</p>
|
|
7
|
+
<ul>
|
|
8
|
+
<li><strong>Veloce</strong>: solo per specifici oggetti predefiniti</li>
|
|
9
|
+
<li><strong>Avanzata</strong>: per tutti gli oggetti</li>
|
|
10
|
+
</ul>
|
|
7
11
|
</div>
|
|
8
12
|
{% endblock %}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
</div>
|
|
1
|
+
<aside class="sidebar"
|
|
2
|
+
id="sidebar-investigation">
|
|
4
3
|
|
|
4
|
+
<nav class="sidebar-nav">
|
|
5
|
+
|
|
6
|
+
<a
|
|
7
|
+
:class="{ active: activeItem === 'investigation' }">
|
|
8
|
+
Indagine
|
|
9
|
+
</a>
|
|
10
|
+
</nav>
|
|
11
|
+
</aside>
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
{% endblock %}
|
|
9
9
|
|
|
10
10
|
{% block content %}
|
|
11
|
+
<div style="margin: 30px;">
|
|
12
|
+
|
|
11
13
|
<div>
|
|
12
14
|
<h2 style="display:flex; justify-content:space-between; align-items:center;">
|
|
13
15
|
<span>{{ t('users.vocabolaries.title') }}:</span>
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
</div>
|
|
42
44
|
</div>
|
|
43
45
|
</div>
|
|
44
|
-
|
|
46
|
+
</div>
|
|
45
47
|
<script>
|
|
46
48
|
dropFilesInit({
|
|
47
49
|
labels: {
|