@igea/oac_frontend 1.0.61 → 1.0.63

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.61",
3
+ "version": "1.0.63",
4
4
  "description": "Frontend service for the OAC project",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -27,9 +27,11 @@ document.addEventListener('DOMContentLoaded', () => {
27
27
  enabled: el.dataset.editing == "true",
28
28
  serializedForm: "",
29
29
  validForm: false,
30
- labels: {
31
-
32
- },
30
+ saving: false,
31
+ lastUpdateTs: 0,
32
+ lastSaveTs: 0,
33
+ isNew: true,
34
+ labels: {},
33
35
  search: {
34
36
  offset: 0,
35
37
  limit: 10,
@@ -43,6 +45,7 @@ document.addEventListener('DOMContentLoaded', () => {
43
45
  },
44
46
  mounted() {
45
47
  this.initShaclForm();
48
+ setInterval(this.autoSave.bind(this), 30*1000);
46
49
  },
47
50
  computed:{
48
51
  outputStyle(){
@@ -59,6 +62,16 @@ document.addEventListener('DOMContentLoaded', () => {
59
62
  }
60
63
  },
61
64
  methods: {
65
+ autoSave(){
66
+ // Form must be valid and change time after the last save time
67
+ if(this.lastUpdateTs > this.lastSaveTs && this.validForm){
68
+ // A new "indagine" must have to be saved manually
69
+ // from the user the first time
70
+ if(this.isNew && this.lastSaveTs==0)
71
+ return;
72
+ this.save(true);
73
+ }
74
+ },
62
75
  download(outFormat){
63
76
  this.openPostInNewTab("/backend/ontology/convert/ttl/" + outFormat, {
64
77
  file: this.serializedForm
@@ -94,6 +107,7 @@ document.addEventListener('DOMContentLoaded', () => {
94
107
  // check if form data validates according to the SHACL shapes
95
108
  _this.validForm = event.detail?.valid;
96
109
  _this.serializedForm = _this.form.serialize();
110
+ _this.lastUpdateTs = (new Date()).getTime();
97
111
  });
98
112
 
99
113
  _this.form.addEventListener("ready", () => {
@@ -321,18 +335,26 @@ document.addEventListener('DOMContentLoaded', () => {
321
335
  callback()
322
336
  },
323
337
 
324
- save() {
338
+ save(automatic) {
339
+ if(this.saving) return;
340
+ this.lastSaveTs = (new Date()).getTime();
341
+ automatic = automatic || false;
342
+ this.saving = true;
325
343
  var request = axios.post("/backend/ontology/form/save", {
326
344
  turtle: this.serializedForm,
327
345
  uuid: this.uuid
328
346
  });
329
347
  request.then(response => {
330
348
  var obj = response.data;
331
- if(obj.success)
332
- alert("Saved: OK")
333
- else
334
- alert("Error: " + obj.message)
349
+ if(!automatic){
350
+ if(obj.success)
351
+ alert("Saved: OK");
352
+ else
353
+ alert("Error: " + obj.message);
354
+ }
355
+ this.saving = false;
335
356
  }).catch(error => {
357
+ this.saving = false;
336
358
  console.log(error);
337
359
  });
338
360
  },
@@ -2,12 +2,34 @@ const { createApp, ref } = Vue;
2
2
 
3
3
  const appId = 'rdf-viewer-app';
4
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)',
5
+ //----------------------------------------------------------
6
+
7
+ const classConfig = {
8
+ 'E7_Activity': {
9
+ 'color': 'rgba(174, 93, 56, 0.5)',
10
+ 'label': 'Attività'
11
+ },
12
+ 'E42_Identifier': {
13
+ 'color': 'rgba(0,0,255,0.5)',
14
+ 'label': 'Identificatore'
15
+ },
16
+ 'E54_Dimension': {
17
+ 'label':'Dimensione'
18
+ },
19
+ 'E55_Type': {
20
+ 'color': 'rgba(0,255,0,0.70)',
21
+ 'label': 'Tipo'
22
+ },
23
+ 'P90_has_value': {
24
+ 'label': 'Ha valore'
25
+ },
26
+ 'S13_Sample': {
27
+ 'label': 'Campione'
28
+ }
9
29
  };
10
30
 
31
+ //----------------------------------------------------------
32
+
11
33
  const splitName = function(name){
12
34
  name = name.split("/").pop();
13
35
  name = name.split(":").pop();
@@ -48,7 +70,7 @@ document.addEventListener('DOMContentLoaded', function() {
48
70
  class="fa-solid fa-link-slash"
49
71
  style="margin-right:10px;"
50
72
  ></i>
51
- {{ node.label + ' ' + classesLabelFor(node) }}
73
+ {{ classesLabelFor(node) + ' ' + classesTagFor(node) }}
52
74
  </div>
53
75
  <div v-if="expanded">
54
76
  <template v-if="node.predicates && node.predicates.length > 0">
@@ -100,9 +122,13 @@ document.addEventListener('DOMContentLoaded', function() {
100
122
  if (node.classes && node.classes.length > 0) {
101
123
  for(var i=0; i<node.classes.length; i++){
102
124
  var clazz = node.classes[i];
103
- if(classColors.hasOwnProperty(clazz)){
104
- color = classColors[clazz];
105
- break;
125
+ if(classConfig.hasOwnProperty(clazz)){
126
+ var _color = classConfig[clazz].color || null;
127
+ if(_color){
128
+ color = _color;
129
+ break;
130
+ }
131
+
106
132
  }
107
133
  }
108
134
  }
@@ -110,7 +136,7 @@ document.addEventListener('DOMContentLoaded', function() {
110
136
  'background-color': `${color}`
111
137
  };
112
138
  },
113
- classesLabelFor(node){
139
+ classesTagFor(node){
114
140
  var label = "";
115
141
  if(node.classes && node.classes.length > 0){
116
142
  var int_label = "";
@@ -125,6 +151,22 @@ document.addEventListener('DOMContentLoaded', function() {
125
151
  }
126
152
  return label;
127
153
  },
154
+ classesLabelFor(node){
155
+ var label = node.label;
156
+ if(node.classes && node.classes.length > 0){
157
+ for(var i=0; i<node.classes.length; i++){
158
+ var part = splitName(node.classes[i]);
159
+ if(classConfig.hasOwnProperty(part)){
160
+ var _label = classConfig[part].label || null;
161
+ if(_label){
162
+ label = _label;
163
+ break;
164
+ }
165
+ }
166
+ }
167
+ }
168
+ return label;
169
+ },
128
170
  toggleExpand() {
129
171
  if ((this.node.predicates && this.node.predicates.length > 0) ||
130
172
  (this.node.children && this.node.children.length > 0)) {
@@ -83,12 +83,14 @@
83
83
  data-shapes-url="/backend/ontology/schema/ttl2"
84
84
  data-values-url="/backend/ontology/form/{{ uuid }}"
85
85
  data-shape-subject="http://example.org/shapes/E7ActivityShape"
86
- data-values-subject="http://diagnostica/e2d49af0-6c52-4fc5-8290-936b87472adf"
86
+ data-values-subject="http://diagnostica/e2d49af0-6c52-4fc5-8290-936b87472adf"
87
+ data-generate-node-shape-reference=""
87
88
  ></shacl-form>
88
89
  {% else %}
89
90
  <shacl-form id="shacl-form" data-collapse="open"
90
91
  data-values-namespace="pref:"
91
92
  data-shapes-url="/backend/ontology/schema/ttl2"
93
+ data-generate-node-shape-reference=""
92
94
  ></shacl-form>
93
95
  {% endif %}
94
96
 
@@ -112,9 +114,10 @@
112
114
  </button>
113
115
  -->
114
116
 
115
- <button v-if="validForm" style="margin-left:30px;" title="{{ t('investigation.new.confirm') }}"
116
- @click="save()" type="button" class="btn btn-primary">
117
- <i class="fa-solid fa-save"></i>
117
+ <button v-if="validForm" :disabled="saving" style="margin-left:30px;" title="{{ t('investigation.new.confirm') }}"
118
+ @click="save(false)" type="button" :class="['btn', saving ? 'btn-secondary' : 'btn-primary']">
119
+ <i v-if="saving"class="fa-solid fa-spinner"></i>
120
+ <i v-else class="fa-solid fa-save"></i>
118
121
  </button>
119
122
 
120
123
  <button style="margin-left:30px;" title="{{ t('investigation.new.reset') }}"
@@ -63,32 +63,32 @@
63
63
  <div class="menu-item has-submenu {% if '/search' in currentPath %}open{% endif %}">
64
64
  <a href="#" class="submenu-toggle">
65
65
  <i class="fa-solid fa-magnifying-glass"></i>
66
- <span>{{ t('search.title')|default('Ricerca') }}</span>
66
+ <span>{{ t('search.fast.title')|default('Ricerca') }}</span>
67
67
  <i class="fa-solid fa-chevron-down submenu-arrow"></i>
68
68
  </a>
69
69
  <div class="submenu">
70
- <a href="/{{ root }}/search/advanced" class="{% if '/search/advanced' in currentPath %}active{% endif %}">
71
- <i class="fa-solid fa-magnifying-glass-dollar"></i>
72
- <span>{{ t('search.advanced.title') }}</span>
73
- </a>
70
+
74
71
  <a href="/{{ root }}/search/fast/1" class="{% if '/search/fast/1' in currentPath %}active{% endif %}">
75
- <i class="fa-solid fa-magnifying-glass"></i>
76
- <span>{{ t('search.fast.investigations') }}</span>
72
+ <i></i><span>{{ t('search.fast.investigations') }}</span>
77
73
  </a>
78
74
  <a href="/{{ root }}/search/fast/2" class="{% if '/search/fast/2' in currentPath %}active{% endif %}">
79
- <i class="fa-solid fa-magnifying-glass"></i>
80
- <span>{{ t('search.fast.samples') }}</span>
75
+ <i></i><span>{{ t('search.fast.samples') }}</span>
81
76
  </a>
82
77
  <a href="/{{ root }}/search/fast/3" class="{% if '/search/fast/3' in currentPath %}active{% endif %}">
83
- <i class="fa-solid fa-magnifying-glass"></i>
84
- <span>{{ t('search.fast.diagnostics') }}</span>
78
+ <i></i><span>{{ t('search.fast.diagnostics') }}</span>
85
79
  </a>
86
80
  <a href="/{{ root }}/search/fast/4" class="{% if '/search/fast/4' in currentPath %}active{% endif %}">
87
- <i class="fa-solid fa-magnifying-glass"></i>
88
- <span>{{ t('search.fast.materials') }}</span>
89
- </a>
81
+ <i></i><span>{{ t('search.fast.materials') }}</span>
82
+ </a>
90
83
  </div>
91
84
  </div>
85
+
86
+ <div class="menu-item">
87
+ <a href="/{{ root }}/search/advanced" class="{% if '/search/advanced' in currentPath %}active{% endif %}">
88
+ <i class="fa-solid fa-magnifying-glass-dollar"></i>
89
+ <span>{{ t('search.advanced.title') }}</span>
90
+ </a>
91
+ </div>
92
92
 
93
93
  <hr class="menu-divider">
94
94