@abi-software/map-utilities 1.5.0-beta.0 → 1.5.0-beta.2

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.
@@ -1,5 +1,31 @@
1
1
  <template>
2
2
  <el-main class="main">
3
+ <div v-if="annotationEntry.length > 1" class="toggle-button">
4
+ <el-popover width="auto" trigger="hover" :teleported="false">
5
+ <template #reference>
6
+ <el-button
7
+ class="button"
8
+ @click="previous"
9
+ :disabled="this.entryIndex === 0"
10
+ >
11
+ Previous
12
+ </el-button>
13
+ </template>
14
+ <span>{{ previousLabel }}</span>
15
+ </el-popover>
16
+ <el-popover width="auto" trigger="hover" :teleported="false">
17
+ <template #reference>
18
+ <el-button
19
+ class="button"
20
+ @click="next"
21
+ :disabled="this.entryIndex === this.annotationEntry.length - 1"
22
+ >
23
+ Next
24
+ </el-button>
25
+ </template>
26
+ <span>{{ nextLabel }}</span>
27
+ </el-popover>
28
+ </div>
3
29
  <div class="block">
4
30
  <el-row class="info-field">
5
31
  <div class="title">Feature Annotations</div>
@@ -7,16 +33,16 @@
7
33
  <copy-to-clipboard :content="updatedCopyContent" />
8
34
  </div>
9
35
  </el-row>
10
- <template v-if="annotationEntry">
36
+ <template v-if="entry">
11
37
  <el-row
12
38
  v-for="(key, label) in displayPair"
13
- v-show="annotationEntry[key]"
39
+ v-show="entry[key]"
14
40
  class="dialog-text"
15
41
  :key="key"
16
42
  >
17
43
  <strong>{{ label }}: </strong>&nbsp;
18
- <span v-if="label !== 'Ontology'">{{ annotationEntry[key] }}</span>
19
- <a v-else :href="ontologyLink" target="_blank">{{ annotationEntry[key] }}</a>
44
+ <span v-if="label !== 'Ontology'">{{ entry[key] }}</span>
45
+ <a v-else :href="ontologyLink" target="_blank">{{ entry[key] }}</a>
20
46
  </el-row>
21
47
  <template v-if="prevSubs.length > 0">
22
48
  <div
@@ -158,7 +184,7 @@ export default {
158
184
  name: "AnnotationPopup",
159
185
  props: {
160
186
  annotationEntry: {
161
- type: Object,
187
+ type: Array,
162
188
  },
163
189
  },
164
190
  inject: ["$annotator", "userApiKey"],
@@ -187,41 +213,70 @@ export default {
187
213
  errorMessage: "",
188
214
  creator: undefined,
189
215
  copyContent: '',
216
+ entryIndex: 0,
190
217
  };
191
218
  },
192
219
  computed: {
220
+ entry: function () {
221
+ return this.annotationEntry[this.entryIndex];
222
+ },
223
+ previousLabel: function () {
224
+ if (this.entryIndex === 0) {
225
+ return "This is the first item. Click 'Next' to see more information.";
226
+ }
227
+ return this.annotationEntry[this.entryIndex - 1]?.label;
228
+ },
229
+ nextLabel: function () {
230
+ if (this.entryIndex === this.annotationEntry.length - 1) {
231
+ return "This is the last item. Click 'Previous' to see more information.";
232
+ }
233
+ return this.annotationEntry[this.entryIndex + 1]?.label;
234
+ },
193
235
  isEditable: function () {
194
236
  return (
195
- this.annotationEntry["resourceId"] && this.annotationEntry["featureId"]
237
+ this.entry["resourceId"] && this.entry["featureId"]
196
238
  );
197
239
  },
198
240
  isPositionUpdated: function () {
199
241
  return (
200
- this.annotationEntry["resourceId"] &&
201
- this.annotationEntry["type"] === "updated" &&
202
- this.annotationEntry["positionUpdated"]
242
+ this.entry["resourceId"] &&
243
+ this.entry["type"] === "updated" &&
244
+ this.entry["positionUpdated"]
203
245
  );
204
246
  },
205
247
  isDeleted: function () {
206
248
  return (
207
- this.annotationEntry["resourceId"] &&
208
- this.annotationEntry["type"] === "deleted"
249
+ this.entry["resourceId"] &&
250
+ this.entry["type"] === "deleted"
209
251
  );
210
252
  },
211
253
  ontologyLink: function () {
212
- const models = this.annotationEntry['models'];
254
+ const models = this.entry['models'];
213
255
  if (models && models.startsWith("UBERON")) {
214
- return `http://purl.obolibrary.org/obo/${this.annotationEntry.models.replace(":", "_")}`;
256
+ return `http://purl.obolibrary.org/obo/${this.entry.models.replace(":", "_")}`;
215
257
  }
216
258
  },
217
259
  updatedCopyContent: function () {
218
260
  return this.getUpdateCopyContent();
219
261
  },
220
262
  offlineAnnotationEnabled: function () {
221
- return this.annotationEntry["offline"];
263
+ if (this.entry) {
264
+ return this.entry["offline"];
265
+ }
266
+ return false;
222
267
  },
223
268
  },
224
269
  methods: {
270
+ previous: function () {
271
+ if (this.entryIndex !== 0) {
272
+ this.entryIndex = this.entryIndex - 1;
273
+ }
274
+ },
275
+ next: function () {
276
+ if (this.entryIndex !== this.annotationEntry.length - 1) {
277
+ this.entryIndex = this.entryIndex + 1;
278
+ }
279
+ },
225
280
  processEvidences: function(sub) {
226
281
  const evidences = [];
227
282
  if (sub?.body?.evidence) {
@@ -269,20 +324,20 @@ export default {
269
324
  const offlineAnnotations = JSON.parse(sessionStorage.getItem('anonymous-annotation')) || [];
270
325
  this.prevSubs = offlineAnnotations.filter((offline) => {
271
326
  return (
272
- offline.resource === this.annotationEntry.resourceId &&
273
- offline.item.id === this.annotationEntry.featureId
327
+ offline.resource === this.entry.resourceId &&
328
+ offline.item.id === this.entry.featureId
274
329
  )
275
330
  });
276
331
  } else if (this.$annotator && this.authenticated) {
277
332
  if (
278
- this.annotationEntry["resourceId"] &&
279
- this.annotationEntry["featureId"]
333
+ this.entry["resourceId"] &&
334
+ this.entry["featureId"]
280
335
  ) {
281
336
  this.$annotator
282
337
  ?.itemAnnotations(
283
338
  this.userApiKey,
284
- this.annotationEntry["resourceId"],
285
- this.annotationEntry["featureId"]
339
+ this.entry["resourceId"],
340
+ this.entry["featureId"]
286
341
  )
287
342
  .then((value) => {
288
343
  this.prevSubs = value;
@@ -297,13 +352,13 @@ export default {
297
352
  // User can either update/delete annotation directly
298
353
  // or provide extra comments for update/delete action
299
354
  if (
300
- this.annotationEntry["type"] === "updated" &&
301
- this.annotationEntry["positionUpdated"]
355
+ this.entry["type"] === "updated" &&
356
+ this.entry["positionUpdated"]
302
357
  ) {
303
358
  this.comment = this.comment
304
359
  ? `Position Updated: ${this.comment}`
305
360
  : "Position Updated";
306
- } else if (this.annotationEntry["type"] === "deleted") {
361
+ } else if (this.entry["type"] === "deleted") {
307
362
  this.comment = this.comment
308
363
  ? `Feature Deleted: ${this.comment}`
309
364
  : "Feature Deleted";
@@ -311,8 +366,8 @@ export default {
311
366
 
312
367
  if (this.evidence.length > 0 || this.comment) {
313
368
  if (
314
- this.annotationEntry["resourceId"] &&
315
- this.annotationEntry["featureId"]
369
+ this.entry["resourceId"] &&
370
+ this.entry["featureId"]
316
371
  ) {
317
372
  const evidenceURLs = [];
318
373
  this.evidence.forEach((evidence) => {
@@ -330,11 +385,11 @@ export default {
330
385
  }
331
386
  });
332
387
  const userAnnotation = {
333
- resource: this.annotationEntry["resourceId"],
388
+ resource: this.entry["resourceId"],
334
389
  item: Object.assign(
335
- { id: this.annotationEntry["featureId"] },
390
+ { id: this.entry["featureId"] },
336
391
  Object.fromEntries(
337
- Object.entries(this.annotationEntry).filter(([key]) =>
392
+ Object.entries(this.entry).filter(([key]) =>
338
393
  ["label", "models"].includes(key)
339
394
  )
340
395
  )
@@ -343,10 +398,10 @@ export default {
343
398
  evidence: evidenceURLs,
344
399
  comment: this.comment,
345
400
  },
346
- feature: this.annotationEntry["feature"],
401
+ feature: this.entry["feature"],
347
402
  };
348
- Object.assign(userAnnotation.body, this.annotationEntry["body"]);
349
- if (this.annotationEntry["type"] === "deleted") {
403
+ Object.assign(userAnnotation.body, this.entry["body"]);
404
+ if (this.entry["type"] === "deleted") {
350
405
  userAnnotation.feature = undefined;
351
406
  }
352
407
  if (this.creator) userAnnotation.creator = this.creator;
@@ -375,33 +430,33 @@ export default {
375
430
  this.comment = "";
376
431
  },
377
432
  getUpdateCopyContent: function () {
378
- if (!this.annotationEntry) {
433
+ if (!this.entry) {
379
434
  return '';
380
435
  }
381
436
 
382
437
  const contentArray = [];
383
438
 
384
439
  // featureId
385
- if (this.annotationEntry.featureId) {
386
- contentArray.push(`<div><strong>Feature ID:</strong>${this.annotationEntry.featureId}</div>`);
440
+ if (this.entry.featureId) {
441
+ contentArray.push(`<div><strong>Feature ID:</strong>${this.entry.featureId}</div>`);
387
442
  }
388
443
 
389
444
  // label
390
- if (this.annotationEntry.label) {
391
- contentArray.push(`<div><strong>Label:</strong>${this.annotationEntry.label}</div>`);
445
+ if (this.entry.label) {
446
+ contentArray.push(`<div><strong>Label:</strong>${this.entry.label}</div>`);
392
447
  }
393
448
 
394
449
  // models
395
- if (this.annotationEntry.models) {
396
- contentArray.push(`<div><strong>Ontology:</strong>${this.annotationEntry.models}</div>`);
450
+ if (this.entry.models) {
451
+ contentArray.push(`<div><strong>Ontology:</strong>${this.entry.models}</div>`);
397
452
  if (this.ontologyLink) {
398
453
  contentArray.push(`<div><strong>Ontology Link:</strong>${this.ontologyLink}</div>`);
399
454
  }
400
455
  }
401
456
 
402
457
  // resourceId
403
- if (this.annotationEntry.resourceId) {
404
- contentArray.push(`<div><strong>Resource:</strong>${this.annotationEntry.resourceId}</div>`);
458
+ if (this.entry.resourceId) {
459
+ contentArray.push(`<div><strong>Resource:</strong>${this.entry.resourceId}</div>`);
405
460
  }
406
461
 
407
462
  if (this.prevSubs.length) {
@@ -430,14 +485,23 @@ export default {
430
485
  },
431
486
  watch: {
432
487
  annotationEntry: {
488
+ deep: true,
489
+ immediate: true,
433
490
  handler: function (newVal, oldVal) {
434
491
  if (newVal !== oldVal) {
492
+ this.entryIndex = 0;
493
+ }
494
+ },
495
+ },
496
+ entry: {
497
+ deep: true,
498
+ immediate: true,
499
+ handler: function (newVal, oldVal) {
500
+ if (newVal && newVal !== oldVal) {
435
501
  this.resetSubmission();
436
502
  this.updatePrevSubmissions();
437
503
  }
438
504
  },
439
- immediate: false,
440
- deep: false,
441
505
  },
442
506
  },
443
507
  mounted: function () {
@@ -456,6 +520,35 @@ export default {
456
520
  </script>
457
521
 
458
522
  <style lang="scss" scoped>
523
+ .toggle-button {
524
+ display: flex;
525
+ justify-content: space-between;
526
+
527
+ .is-disabled {
528
+ color: #fff !important;
529
+ background-color: #ac76c5 !important;
530
+ border: 1px solid #ac76c5 !important;
531
+ }
532
+
533
+ .button {
534
+ margin-left: 0px !important;
535
+ margin-top: 0px !important;
536
+ font-size: 14px !important;
537
+ background-color: $app-primary-color;
538
+ color: #fff;
539
+
540
+ & + .button {
541
+ margin-top: 10px !important;
542
+ }
543
+
544
+ &:hover {
545
+ color: #fff !important;
546
+ background: #ac76c5 !important;
547
+ border: 1px solid #ac76c5 !important;
548
+ }
549
+ }
550
+ }
551
+
459
552
  .info-field {
460
553
  padding: 0;
461
554
  display: flex;