@igea/oac_frontend 1.0.59 → 1.0.60

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@igea/oac_frontend",
3
- "version": "1.0.59",
3
+ "version": "1.0.60",
4
4
  "description": "Frontend service for the OAC project",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -0,0 +1,18 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const DataModel = require('../models/DataModel');
4
+
5
+ module.exports = function(serviceName) {
6
+
7
+ router.get('/view', (req, res) => {
8
+
9
+ let data = new DataModel(req, {
10
+ root: serviceName,
11
+ title: 'RDF viewer',
12
+ iri: req.query.iri
13
+ });
14
+ res.render('rdf/view.twig', data.toJson());
15
+ });
16
+
17
+ return router
18
+ }
package/src/index.js CHANGED
@@ -91,6 +91,9 @@ getPort.default({
91
91
  const investigationRouter = require('./controllers/investigation.js')(serviceName);
92
92
  app.use(`/${serviceName}/investigation`, investigationRouter);
93
93
 
94
+ const rdfRouter = require('./controllers/rdf.js')(serviceName);
95
+ app.use(`/${serviceName}/rdf`, rdfRouter);
96
+
94
97
  const captchaRouter = require('./controllers/captcha.js');
95
98
  app.use(`/${serviceName}/captcha`, captchaRouter);
96
99
  // ---------------------------------------------------------------------
@@ -0,0 +1,249 @@
1
+ const { createApp, ref } = Vue;
2
+
3
+ const appId = 'rdf-viewer-app';
4
+
5
+ const classColors = {
6
+ 'E55_Type': 'rgba(0,255,0,0.70)',
7
+ 'E7_Activity': 'rgba(174, 93, 56, 0.5)',
8
+ 'E42_Identifier': 'rgba(0,0,255,0.5)',
9
+ };
10
+
11
+ const splitName = function(name){
12
+ name = name.split("/").pop();
13
+ name = name.split(":").pop();
14
+ name = name.split("#").pop();
15
+ return name;
16
+ }
17
+
18
+ const LoadingStatus = {
19
+ TODO: "todo",
20
+ PROGRESS: "progress",
21
+ DONE: "done"
22
+ }
23
+
24
+ document.addEventListener('DOMContentLoaded', function() {
25
+ const el = document.getElementById(appId);
26
+
27
+ // Definisci il componente TreeNode
28
+ const TreeNode = {
29
+ template: `
30
+ <div class="tree-node"
31
+ :style="{ 'padding-left': depth * 0 + 'px' }"
32
+ >
33
+ <div class="node-label" @click="toggleExpand" :style="styleNode(node)">
34
+ <span v-if="(node.predicates && node.predicates.length > 0) || (node.children && node.children.length > 0)">
35
+ {{ expanded ? '▼' : '▶' }}
36
+ </span>
37
+ <i v-if="node.loadStatus == 'todo'"
38
+ class="fa-brands fa-searchengin"
39
+ style="cursor:pointer;"
40
+ @click="loadNode(node)"
41
+ ></i>
42
+ <img v-else-if="node.loadStatus == 'progress'"
43
+ src="/frontend/images/loading_icon.gif"
44
+ style="width:32px; height:32px;"
45
+ >
46
+ <i v-else style="margin-left:10px;"></i>
47
+ {{ node.label + ' ' + classesLabelFor(node) }}
48
+ </div>
49
+ <div v-if="expanded">
50
+ <template v-if="node.predicates && node.predicates.length > 0">
51
+ <div v-for="(predicate, index) in node.predicates" :key="index"
52
+ style="margin-left:20px;">
53
+ <div>
54
+ {{ predicate.label }}
55
+ </div>
56
+ <tree-node v-for="(child, index) in predicate.children"
57
+ :key="index"
58
+ :node="child"
59
+ :depth="depth + 1"
60
+ ></tree-node>
61
+ </div>
62
+ </template>
63
+ <template v-else>
64
+ <tree-node v-for="(child, index) in node.children"
65
+ :key="index"
66
+ :node="child"
67
+ :depth="depth + 1"
68
+ ></tree-node>
69
+ </template>
70
+ </div>
71
+ </div>`,
72
+ props: {
73
+ node: {
74
+ type: Object,
75
+ required: true
76
+ },
77
+ depth: {
78
+ type: Number,
79
+ default: 0
80
+ }
81
+ },
82
+ data() {
83
+ return {
84
+ expanded: true
85
+ };
86
+ },
87
+ methods: {
88
+ loadNode(node){
89
+ //this.$emit('load-node', node);
90
+ let event = new Event('load-node');
91
+ event.node = node;
92
+ el.dispatchEvent(event);
93
+ },
94
+ styleNode(node) {
95
+ var color = '#bbccdd';
96
+ if (node.classes && node.classes.length > 0) {
97
+ for(var i=0; i<node.classes.length; i++){
98
+ var clazz = node.classes[i];
99
+ if(classColors.hasOwnProperty(clazz)){
100
+ color = classColors[clazz];
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ return {
106
+ 'background-color': `${color}`
107
+ };
108
+ },
109
+ classesLabelFor(node){
110
+ var label = "";
111
+ if(node.classes && node.classes.length > 0){
112
+ var int_label = "";
113
+ for(var i=0; i<node.classes.length; i++){
114
+ var part = splitName(node.classes[i]);
115
+ if(i>0) int_label += ",";
116
+ int_label += part;
117
+ }
118
+ if(int_label.trim()!=""){
119
+ label = "[" + int_label + "]";
120
+ }
121
+ }
122
+ return label;
123
+ },
124
+ toggleExpand() {
125
+ if ((this.node.predicates && this.node.predicates.length > 0) ||
126
+ (this.node.children && this.node.children.length > 0)) {
127
+ this.expanded = !this.expanded;
128
+ }
129
+ }
130
+ }
131
+ };
132
+
133
+ // Definisci il componente TreeView
134
+ const TreeView = {
135
+ template: `
136
+ <div class="tree-view">
137
+ <tree-node
138
+ v-for="(node, index) in treeData"
139
+ :key="index"
140
+ :node="node"
141
+ :depth="0"
142
+ ></tree-node>
143
+ </div>
144
+ `,
145
+ props: {
146
+ treeData: {
147
+ type: Array,
148
+ required: true
149
+ }
150
+ },
151
+ components: {
152
+ TreeNode
153
+ }
154
+ };
155
+
156
+ // Crea l'applicazione Vue
157
+ const app = Vue.createApp({
158
+ data() {
159
+ return {
160
+ rootIri: el.dataset.root_iri,
161
+ treeData: []
162
+ };
163
+ },
164
+ mounted() {
165
+ this.loadRoot();
166
+ el.addEventListener("load-node", (function(event) {
167
+ this.loadNodeData(event.node);
168
+ }).bind(this));
169
+ },
170
+ methods:{
171
+ loadRoot(){
172
+ var _this = this;
173
+ var url = "/backend/fuseki/rdf/rootResource?iri=" + this.rootIri;
174
+ fetch(url)
175
+ .then(response => response.json())
176
+ .then(r => {
177
+ if(r.success){
178
+ var data = r.data;
179
+ var classes = data.classes.split(",");
180
+ for(var i=0; i<classes.length; i++){
181
+ classes[i] = splitName(classes[i]);
182
+ }
183
+ _this.treeData = [{
184
+ label: data.label.split("/").pop(),
185
+ iri: decodeURIComponent(_this.rootIri),
186
+ classes: classes,
187
+ loadStatus: LoadingStatus.TODO,
188
+ predicates:[]
189
+ }];
190
+ }else{
191
+ alert('Error:', r.message);
192
+ }
193
+ })
194
+ .catch(error => {
195
+ console.log(error);
196
+ //alert('Errore durante il caricamento dei dati radice:', error);
197
+ });
198
+ },
199
+ loadNodeData(node){
200
+ var _this = this;
201
+ node.predicates=[];
202
+ var url = "/backend/fuseki/rdf/resourceOf?iri=" + encodeURIComponent(node.iri);
203
+ console.log(url)
204
+ node.loadStatus = LoadingStatus.PROGRESS;
205
+ fetch(url).then(response => response.json()).then(r => {
206
+ if(r.success){
207
+ var data = r.data;
208
+ var prev_predicate = null;
209
+ var index_predicate = -1;
210
+ for(var i=0; data.length; i++){
211
+ var predicate = splitName(data[i].predicate);
212
+ if(predicate != prev_predicate){
213
+ node.predicates.push({
214
+ label: predicate,
215
+ children: []
216
+ });
217
+ prev_predicate = predicate;
218
+ index_predicate++;
219
+ }
220
+ var classes = data[i].object.classes.split(",");
221
+ for(var j=0; j<classes.length; j++){
222
+ classes[j] = splitName(classes[j]);
223
+ }
224
+ node.predicates[index_predicate].children.push({
225
+ label: splitName(data[i].object.label),
226
+ iri: "<" + data[i].object.iri + ">",
227
+ classes: classes,
228
+ loadStatus: LoadingStatus.TODO
229
+ });
230
+ }
231
+ }else{
232
+ alert('Error:', r.message);
233
+ }
234
+ node.loadStatus = LoadingStatus.DONE;
235
+ }).catch(error => {
236
+ node.loadStatus = LoadingStatus.DONE;
237
+ });
238
+ }
239
+ }
240
+ });
241
+
242
+ // Registra il componente TreeView globalmente
243
+ app.component('tree-view', TreeView);
244
+ app.component('tree-node', TreeNode);
245
+
246
+ // Monta l'applicazione
247
+ app.mount(`#${appId}`);
248
+
249
+ });
@@ -33,8 +33,8 @@ const yasr = new Yasr(document.getElementById("yasr"), {
33
33
  });
34
34
 
35
35
  yasr.plugins["TableX"].config.uriHrefAdapter = function(uri) {
36
- if(uri.startsWith("http://diagnostica/")) {
37
- return "/frontend/investigation/form/" + uri.split("/").pop();
36
+ if(uri.startsWith("http://diagnostica/") || uri.startsWith("http://indagine/")) {
37
+ return "/frontend/rdf/view?iri=" + encodeURIComponent("<" + uri + ">");
38
38
  } else {
39
39
  return uri;
40
40
  }
@@ -0,0 +1,35 @@
1
+ {% set showSidebar = false %}
2
+ {% extends "../base.twig" %}
3
+
4
+ {% block extendHead %}
5
+
6
+ <!-- Font Awesome -->
7
+ <link rel="stylesheet" href="/{{ root }}/css/fa/css/all.min.css" />
8
+
9
+ <style>
10
+ .tree-node {
11
+ margin: 4px 0px;
12
+ margin-left: 20px;
13
+ border: solid 1px gray;
14
+ }
15
+ .node-label {
16
+ cursor: pointer;
17
+ }
18
+ .node-label:hover {
19
+ font-weight: bold;
20
+ }
21
+ </style>
22
+
23
+ {% endblock %}
24
+
25
+ {% block content %}
26
+
27
+ <div id="rdf-viewer-app"
28
+ data-root_iri="{{ iri }}"
29
+ style="margin-top:1rem!important; margin-bottom:1rem!important;">
30
+ <tree-view :tree-data="treeData"></tree-view>
31
+ </div>
32
+
33
+ <script src="/{{ root }}/js/app/vue-rdf.js"></script>
34
+
35
+ {% endblock %}