@abi-software/scaffoldvuer 1.6.2 → 1.7.0

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": "@abi-software/scaffoldvuer",
3
- "version": "1.6.2",
3
+ "version": "1.7.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  "*.js"
42
42
  ],
43
43
  "dependencies": {
44
- "@abi-software/map-utilities": "^1.2.0",
44
+ "@abi-software/map-utilities": "^1.3.0",
45
45
  "@abi-software/sparc-annotation": "^0.3.1",
46
46
  "@abi-software/svg-sprite": "^1.0.1",
47
47
  "@element-plus/icons-vue": "^2.3.1",
@@ -54,7 +54,7 @@
54
54
  "vue": "^3.4.21",
55
55
  "vue-router": "^4.2.5",
56
56
  "vue3-component-svg-sprite": "^0.0.1",
57
- "zincjs": "^1.11.4"
57
+ "zincjs": "^1.11.5"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@vitejs/plugin-vue": "^4.6.2",
package/src/App.vue CHANGED
@@ -29,6 +29,7 @@
29
29
  :marker-labels="markerLabels"
30
30
  :enableLocalAnnotations="false"
31
31
  @open-map="openMap"
32
+ @on-error="onError"
32
33
  @on-ready="onReady"
33
34
  @scaffold-selected="onSelected"
34
35
  @scaffold-navigated="onNavigated"
@@ -184,6 +185,9 @@
184
185
  <el-col :span="auto">
185
186
  <el-switch v-model="renderInfoOn" active-text="Renderer Info" active-color="#8300bf" />
186
187
  </el-col>
188
+ <el-button size="small" @click="PrintViewport()">
189
+ Print Viewport
190
+ </el-button>
187
191
  </el-row>
188
192
 
189
193
  <template v-if="renderInfoOn && rendererInfo">
@@ -597,6 +601,10 @@ export default {
597
601
  this.$refs.scaffold.getDynamicSelectedCoordinates();
598
602
  this.rendererInfo = this.$refs.scaffold.getRendererInfo();
599
603
  },
604
+ PrintViewport: function() {
605
+ const scene = this.$refs.scaffold.$module.scene;
606
+ console.log(scene.getZincCameraControls().getCurrentViewport());
607
+ },
600
608
  fetchSuggestions: function (term, cb) {
601
609
  if (term === "" || !this.$refs.scaffold) {
602
610
  cb([]);
@@ -640,6 +648,17 @@ export default {
640
648
  }
641
649
  });
642
650
  },
651
+ onError: function(payload) {
652
+ if (payload?.type === "download-error") {
653
+ const dropZone = this.$refs.dropzone;
654
+ if (dropZone) {
655
+ const realFilename = dropZone.findRealFilename(payload.xhr.responseURL);
656
+ if (realFilename) {
657
+ console.error(`External Resource ${realFilename}`);
658
+ }
659
+ }
660
+ }
661
+ },
643
662
  onReady: function () {
644
663
  if (this.consoleOn) console.log(this.$refs.scaffold)
645
664
  if (this.readyCallback) {
@@ -13,6 +13,7 @@
13
13
 
14
14
  <script>
15
15
  /* eslint-disable no-alert, no-console */
16
+ import { markRaw } from 'vue';
16
17
  import { SimpleDropzone } from "simple-dropzone";
17
18
  import path from "path";
18
19
 
@@ -26,7 +27,8 @@ export default {
26
27
  name: "DropZone",
27
28
  data: function () {
28
29
  return {
29
- objectURLs: [],
30
+ objectURLs: markRaw([]),
31
+ filesMapping: markRaw({}),
30
32
  };
31
33
  },
32
34
  mounted: function () {
@@ -39,6 +41,9 @@ export default {
39
41
  });
40
42
  },
41
43
  methods: {
44
+ findRealFilename: function(objectURL) {
45
+ return this.filesMapping[objectURL]
46
+ },
42
47
  processTextureFile: function(textureData, flatarray) {
43
48
  if (textureData && textureData.images && textureData.images.source) {
44
49
  const images = textureData.images.source;
@@ -50,6 +55,7 @@ export default {
50
55
  const objectURL = URL.createObjectURL(flatarray[index][1]);
51
56
  this.objectURLs.push(objectURL);
52
57
  textureData.images.source[i] = objectURL;
58
+ this.filesMapping[objectURL] = images[i];
53
59
  }
54
60
  }
55
61
  const content = JSON.stringify(textureData);
@@ -65,6 +71,7 @@ export default {
65
71
  const re = new RegExp(key, "g");
66
72
  content = content.replace(re, objectURL);
67
73
  this.objectURLs.push(objectURL);
74
+ this.filesMapping[objectURL] = key;
68
75
  }
69
76
  }
70
77
  const data = JSON.parse(content);
@@ -93,7 +100,8 @@ export default {
93
100
  },
94
101
  revokeURLs: function () {
95
102
  this.objectURLs.forEach(objectURL => URL.revokeObjectURL(objectURL));
96
- this.objectURLs = [];
103
+ this.objectURLs.length = 0;
104
+ this.filesMapping = markRaw({});
97
105
  },
98
106
  localDrop: function (fileMap) {
99
107
  this.revokeURLs();
@@ -308,7 +308,7 @@
308
308
  </template>
309
309
  </div>
310
310
  <el-row class="viewing-mode-description">
311
- {{ viewingModes[viewingMode] }}
311
+ {{ modeDescription }}
312
312
  </el-row>
313
313
  </el-row>
314
314
  <el-row class="backgroundSpacer"></el-row>
@@ -805,7 +805,7 @@ export default {
805
805
  viewingMode: "Exploration",
806
806
  viewingModes: {
807
807
  "Exploration": "View and explore detailed visualization of 3D scaffolds",
808
- "Annotation": "View internal identifiers of features",
808
+ "Annotation": ['View feature annotations', 'Add, comment on and view feature annotations'],
809
809
  },
810
810
  openMapRef: undefined,
811
811
  backgroundIconRef: undefined,
@@ -918,24 +918,6 @@ export default {
918
918
  }
919
919
  this.previousMarkerLabels = markRaw({...labels});
920
920
  },
921
- annotationDisplay: function(value) {
922
- if (this.annotationSidebar) {
923
- if (value) {
924
- const region = this.tData.region ? this.tData.region +"/" : "";
925
- const annotationEntry = {
926
- "featureId": region + this.tData.label,
927
- "resourceId": this.url,
928
- "resource": this.url,
929
- };
930
- this.$emit('annotation-open', {annotationEntry: annotationEntry,
931
- commitCallback: this.commitAnnotationEvent});
932
- } else {
933
- if (!this.createData.toBeConfirmed || !this.createData.toBeDeleted) {
934
- this.$emit("annotation-close");
935
- }
936
- }
937
- }
938
- }
939
921
  },
940
922
  beforeCreate: function () {
941
923
  this.$module = new OrgansViewer();
@@ -977,7 +959,17 @@ export default {
977
959
  annotationDisplay: function() {
978
960
  return this.viewingMode === 'Annotation' && this.tData.active === true &&
979
961
  (this.activeDrawMode !== "Point" && this.activeDrawMode !== 'LineString');
980
- }
962
+ },
963
+ modeDescription: function () {
964
+ let description = this.viewingModes[this.viewingMode];
965
+ if (this.viewingMode === 'Annotation') {
966
+ if (this.userInformation) {
967
+ return description[1]
968
+ }
969
+ return description[0]
970
+ };
971
+ return description;
972
+ },
981
973
  },
982
974
  methods: {
983
975
  /**
@@ -1337,6 +1329,7 @@ export default {
1337
1329
  this.createData.shape = '';
1338
1330
  this.$module.selectObjectOnPick = true;
1339
1331
  } else if (type === 'tool') {
1332
+ if (this.annotationDisplay) return;
1340
1333
  this.activeDrawTool = icon;
1341
1334
  this.createData.shape = this.activeDrawTool ? this.activeDrawTool : '';
1342
1335
  this.$module.selectObjectOnPick = false;
@@ -2209,6 +2202,11 @@ export default {
2209
2202
  }
2210
2203
  }
2211
2204
  },
2205
+ downloadErrorCallback: function() {
2206
+ return (error) => {
2207
+ this.$emit('on-error', error);
2208
+ }
2209
+ },
2212
2210
  setURLFinishCallback: function (options) {
2213
2211
  return () => {
2214
2212
  this.localAnnotationsList.length = 0;
@@ -2368,6 +2366,9 @@ export default {
2368
2366
  this.isReady = false;
2369
2367
  this.$_searchIndex.removeAll();
2370
2368
  this.hideRegionTooltip();
2369
+ this.$module.setDownloadErrorCallback(
2370
+ this.downloadErrorCallback()
2371
+ );
2371
2372
  this.$module.setFinishDownloadCallback(
2372
2373
  this.setURLFinishCallback({
2373
2374
  background: state?.background,
@@ -40,6 +40,7 @@ const OrgansSceneData = function() {
40
40
  const organPartAddedCallbacks = new Array();
41
41
  const organPartRemovedCallbacks = new Array();
42
42
  let finishDownloadCallback = undefined;
43
+ let downloadErrorCallback = undefined;
43
44
  const modelsLoader = ModelsLoaderIn;
44
45
  this.NDCCameraControl = undefined;
45
46
  _this.typeName = "Organ Viewer";
@@ -187,6 +188,16 @@ const OrgansSceneData = function() {
187
188
  finishDownloadCallback = undefined;
188
189
  }
189
190
 
191
+
192
+ this.setDownloadErrorCallback = function(callback) {
193
+ if (typeof(callback === "function"))
194
+ downloadErrorCallback = callback;
195
+ }
196
+
197
+ this.unsetDownloadErrorCallback = function() {
198
+ downloadErrorCallback = undefined;
199
+ }
200
+
190
201
  this.getNamedObjectsToScreenCoordinates = function(name, camera) {
191
202
  const vector = new THREE.Vector3();
192
203
  vector.setFromMatrixPosition( obj.matrixWorld );
@@ -435,11 +446,22 @@ const OrgansSceneData = function() {
435
446
  finishDownloadCallback();
436
447
  }
437
448
  }
438
-
439
- const singleItemDownloadCompletedCallback = function(systemName, partName, useDefautColour) {
440
- return function(geometry) {
441
- addOrganPart(systemName, partName, useDefautColour, geometry);
442
- _this.settingsChanged();
449
+
450
+ //The payload can either be a zinc object when the loading is successful or
451
+ //an object containg the details of error message on failure.
452
+ //We only use it to handle an error
453
+ const singleItemFinishCallback = function() {
454
+ return function(payload) {
455
+
456
+ if (payload?.type === "Error") {
457
+ if (downloadErrorCallback) {
458
+ const error = {
459
+ xhr: payload.xhr,
460
+ type: "download-error",
461
+ };
462
+ downloadErrorCallback(error);
463
+ }
464
+ }
443
465
  }
444
466
  }
445
467
 
@@ -549,7 +571,7 @@ const OrgansSceneData = function() {
549
571
  _this.sceneData.metaURL = url;
550
572
  organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(systemName, partName, false));
551
573
  organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
552
- organScene.loadMetadataURL(url, undefined, downloadCompletedCallback());
574
+ organScene.loadMetadataURL(url, singleItemFinishCallback(), downloadCompletedCallback());
553
575
  _this.scene = organScene;
554
576
  _this.zincRenderer.setCurrentScene(organScene);
555
577
  _this.graphicsHighlight.reset();
@@ -0,0 +1,36 @@
1
+ import { defineConfig } from 'vite'
2
+ import rootConfig from './vite.config.js'
3
+ import { nodePolyfills } from 'vite-plugin-node-polyfills'
4
+ import vue from '@vitejs/plugin-vue'
5
+
6
+ // defineWorkspace provides a nice type hinting DX
7
+ export default defineConfig((configEnv) => {
8
+ const config = rootConfig(configEnv);
9
+ config.css.extract = false
10
+ config.plugins.push(
11
+ nodePolyfills({
12
+ // To add only specific polyfills, add them here. If no option is passed, adds all polyfills
13
+ include: ['path']
14
+ })
15
+ );
16
+ // config.plugins.push(
17
+ // cssInjectedByJsPlugin()
18
+ // );
19
+ config.plugins[0] = vue({
20
+ template: {
21
+ compilerOptions: {
22
+ isCustomElement: (tag) => tag.includes('scaffoldvuer-wc')
23
+ }
24
+ }
25
+ }),
26
+ config.build = {
27
+ lib: {
28
+ entry: './src/ScaffoldVuer-wc.js',
29
+ name: 'scaffoldvuer-wc',
30
+ // the proper extensions will be added
31
+ fileName: 'scaffoldvuer-wc'
32
+ },
33
+ }
34
+
35
+ return config;
36
+ })