@vcmap/module-selector 2.0.1 → 2.0.3

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.
@@ -16,7 +16,7 @@
16
16
  <v-col>
17
17
  <VcsTextField
18
18
  id="moduleselector-window-title"
19
- :placeholder="$t('moduleSelector.title')"
19
+ :placeholder="$st('moduleSelector.title')"
20
20
  v-model="localConfig.windowTitle"
21
21
  />
22
22
  </v-col>
@@ -39,24 +39,6 @@
39
39
  </v-row>
40
40
  </v-container>
41
41
  </VcsFormSection>
42
- <VcsFormSection
43
- heading="moduleSelector.configEditor.windowPosition"
44
- :expandable="true"
45
- >
46
- <WindowPositionSettings
47
- v-model="localConfig.position!"
48
- :position-keys="[
49
- 'top',
50
- 'right',
51
- 'bottom',
52
- 'left',
53
- 'width',
54
- 'maxWidth',
55
- 'height',
56
- 'maxHeight',
57
- ]"
58
- />
59
- </VcsFormSection>
60
42
  <VcsFormSection heading="moduleSelector.configEditor.baseModule">
61
43
  <v-container class="py-0 px-1">
62
44
  <v-row no-gutters>
@@ -163,7 +145,7 @@
163
145
  heading="moduleSelector.configEditor.heading"
164
146
  :start-open="true"
165
147
  :header-actions="headerActions"
166
- ><!--V-if currentItem group > cards || wenn url oder empty listItems-->
148
+ >
167
149
  <VcsList
168
150
  v-if="currentGroup === undefined"
169
151
  :items="listItemArray"
@@ -177,17 +159,45 @@
177
159
  @item-moved="move"
178
160
  />
179
161
  <v-dialog
180
- v-if="editingItem"
181
- :model-value="true"
162
+ v-model="editingItemDialogVisible"
182
163
  width="400"
183
164
  :persistent="true"
184
165
  >
185
166
  <ModuleEditor
186
167
  :model-value="editingItem"
187
- @close="editingItem = undefined"
168
+ @close="editingItemDialogVisible = false"
188
169
  @submit="updateItem()"
189
170
  />
190
171
  </v-dialog>
172
+ <v-dialog
173
+ v-model="selectCloudItemDialogVisible"
174
+ width="1000"
175
+ :persistent="true"
176
+ >
177
+ <VcsModuleTable
178
+ :model-value="selectCloudItem"
179
+ @close="selectCloudItemDialogVisible = false"
180
+ @submit="updateCloudItem()"
181
+ />
182
+ </v-dialog>
183
+ </VcsFormSection>
184
+ <VcsFormSection
185
+ heading="moduleSelector.configEditor.windowPosition"
186
+ :expandable="true"
187
+ >
188
+ <WindowPositionSettings
189
+ v-model="localConfig.position!"
190
+ :position-keys="[
191
+ 'top',
192
+ 'right',
193
+ 'bottom',
194
+ 'left',
195
+ 'width',
196
+ 'maxWidth',
197
+ 'height',
198
+ 'maxHeight',
199
+ ]"
200
+ />
191
201
  </VcsFormSection>
192
202
  </AbstractConfigEditor>
193
203
  </template>
@@ -212,6 +222,7 @@
212
222
  reactive,
213
223
  Ref,
214
224
  ref,
225
+ toRaw,
215
226
  watch,
216
227
  } from 'vue';
217
228
  import {
@@ -226,6 +237,7 @@
226
237
  import { Module, ModuleSelectorConfig, ModuleType } from '../index';
227
238
  import getDefaultOptions from '../defaultOptions.js';
228
239
  import WindowPositionSettings from './WindowPositionSettings.vue';
240
+ import CloudModuleSelector from './CloudModuleSelector.vue';
229
241
 
230
242
  interface VcsListItemWithLabel extends VcsListItem {
231
243
  id: string;
@@ -236,6 +248,7 @@
236
248
  cards?: VcsListItemWithLabel[];
237
249
  }
238
250
 
251
+ export const windowIdConfigEditor = 'configEditor_window_id';
239
252
  export default defineComponent({
240
253
  name: 'ModuleSelectorConfigEditor',
241
254
  components: {
@@ -253,6 +266,7 @@
253
266
  VBreadcrumbs,
254
267
  VBreadcrumbsItem,
255
268
  WindowPositionSettings,
269
+ VcsModuleTable: CloudModuleSelector,
256
270
  },
257
271
  props: {
258
272
  getConfig: {
@@ -271,13 +285,27 @@
271
285
  const listItemArray: Ref<VcsListItemWithLabel[]> = ref([]);
272
286
  const currentGroup: Ref<VcsListItemWithLabel | undefined> =
273
287
  ref(undefined);
274
- const editingItem: Ref<
275
- | { id: string; title: string; icon: string; moduleUrl: string }
276
- | undefined
277
- > = ref(undefined);
288
+ const editingItem: Ref<{
289
+ id: string;
290
+ title: string;
291
+ icon: string;
292
+ moduleUrl: string;
293
+ }> = ref({ id: '', title: '', icon: '', moduleUrl: '' });
294
+ const selectCloudItem: Ref<{
295
+ id: string;
296
+ title: string;
297
+ icon: string;
298
+ moduleUrl: string;
299
+ }> = ref({ id: '', title: '', icon: '', moduleUrl: '' });
300
+ const selectCloudItemDialogVisible: Ref<boolean> = ref(false);
301
+ const editingItemDialogVisible: Ref<boolean> = ref(false);
302
+ const groupItemDialogVisible: Ref<boolean> = ref(false);
278
303
  const listItems: Ref<VcsListItemWithLabel[] | undefined> = ref(undefined);
279
304
 
280
- localConfig.value = { ...getDefaultOptions(), ...props.getConfig() };
305
+ localConfig.value = {
306
+ ...getDefaultOptions(),
307
+ ...props.getConfig(),
308
+ } as ModuleSelectorConfig;
281
309
 
282
310
  const basisModule = ref();
283
311
 
@@ -299,75 +327,12 @@
299
327
  });
300
328
  const headerActions = reactive<VcsAction[]>([]);
301
329
 
302
- function removeIdAndActions(
303
- item: VcsListItemWithLabel,
304
- ): Module<ModuleType> {
305
- if (item.type === 'url') {
306
- return {
307
- title: item.title,
308
- type: item.type,
309
- icon: item.icon,
310
- moduleUrl: item.moduleUrl || '',
311
- } as Module<'url'>;
312
- } else {
313
- const updatedCards =
314
- item.cards?.map((card) => {
315
- return {
316
- title: card.title,
317
- icon: card.icon,
318
- moduleUrl: card.moduleUrl,
319
- type: card.type,
320
- };
321
- }) || [];
322
- return {
323
- title: item.title,
324
- type: item.type,
325
- icon: item.icon,
326
- ...(updatedCards.length ? { cards: updatedCards } : {}),
327
- } as Module<'group'>;
328
- }
329
- }
330
-
331
- const headerGroupAction = {
332
- name: 'moduleSelector.configEditor.addGroup',
333
- callback(): void {
334
- const newGroup = {
335
- type: 'group',
336
- name: '',
337
- id: '',
338
- title: 'title',
339
- icon: 'icon',
340
- cards: [],
341
- };
342
-
343
- listItemArray.value?.push(newGroup);
344
- currentGroup.value = newGroup;
345
-
346
- const newIndex = listItemArray.value.indexOf(newGroup);
347
-
348
- newGroup.id = `${newGroup.title}-${newIndex}`;
349
-
350
- headerActions.splice(1, 1);
351
- if (headerActions.length > 0) {
352
- headerActions[0].icon = '$vcsPlus';
353
- headerActions[0].title =
354
- 'moduleSelector.configEditor.TooltipAddModule';
355
- }
356
- },
357
- };
358
-
359
- function removeIdAndActionsFromArray(
360
- items: VcsListItemWithLabel[],
361
- ): Module<ModuleType>[] {
362
- return items.map(removeIdAndActions);
363
- }
364
-
365
330
  function createListItem(
366
331
  moduleInfo: Module<ModuleType>,
367
332
  index: number,
368
333
  ): VcsListItemWithLabel {
369
334
  const listItemObject: VcsListItemWithLabel = {
370
- id: `${moduleInfo.title}-${index}`,
335
+ id: `${moduleInfo.title || 'undefined'}-${index}`,
371
336
  name: moduleInfo.title,
372
337
  title: moduleInfo.title,
373
338
  icon: moduleInfo.icon,
@@ -411,6 +376,7 @@
411
376
  };
412
377
  }
413
378
  }
379
+ editingItemDialogVisible.value = true;
414
380
  },
415
381
  });
416
382
  }
@@ -426,10 +392,10 @@
426
392
  );
427
393
  if (item) {
428
394
  currentGroup.value = item;
429
- headerActions.splice(1, 1);
430
- if (headerActions.length > 0) {
431
- headerActions[0].icon = '$vcsPlus';
432
- headerActions[0].title =
395
+ headerActions.splice(2, 1);
396
+ if (headerActions.length > 1) {
397
+ headerActions[1].icon = '$vcsPlus';
398
+ headerActions[1].title =
433
399
  'moduleSelector.configEditor.TooltipAddModule';
434
400
  }
435
401
  }
@@ -459,6 +425,80 @@
459
425
  return listItemObject;
460
426
  }
461
427
 
428
+ headerActions.push({
429
+ name: 'moduleSelector.configEditor.addFromCloud',
430
+ icon: '$vcsImport',
431
+ callback(): void {
432
+ selectCloudItem.value = {
433
+ id: '',
434
+ title: '',
435
+ icon: '',
436
+ moduleUrl: '',
437
+ };
438
+ selectCloudItemDialogVisible.value = true;
439
+ },
440
+ });
441
+
442
+ function removeIdAndActions(
443
+ item: VcsListItemWithLabel,
444
+ ): Module<ModuleType> {
445
+ if (item.type === 'url') {
446
+ const { actions, id, name, ...configItem } = item;
447
+ return {
448
+ ...configItem,
449
+ moduleUrl: item.moduleUrl || '',
450
+ } as Module<'url'>;
451
+ } else {
452
+ const updatedCards =
453
+ item.cards?.map((card) => {
454
+ const { actions, id, name, ...configItem } = card;
455
+ return {
456
+ ...configItem,
457
+ } as Module<'url'>;
458
+ }) || [];
459
+ const { actions, id, name, ...configItem } = item;
460
+ return {
461
+ ...configItem,
462
+ ...(updatedCards.length ? { cards: updatedCards } : {}),
463
+ } as Module<'group'>;
464
+ }
465
+ }
466
+
467
+ const headerGroupAction = {
468
+ name: 'moduleSelector.configEditor.addGroup',
469
+ callback(): void {
470
+ const newGroup = {
471
+ type: 'group',
472
+ title: '',
473
+ icon: '',
474
+ cards: [],
475
+ };
476
+
477
+ groupItemDialogVisible.value = true;
478
+ const indexItem = listItemArray.value?.push(
479
+ createListItem(
480
+ newGroup as Module<'group'>,
481
+ listItemArray.value.length,
482
+ ),
483
+ );
484
+
485
+ currentGroup.value = listItemArray.value[indexItem - 1];
486
+
487
+ headerActions.splice(2, 1);
488
+ if (headerActions.length > 1) {
489
+ headerActions[1].icon = '$vcsPlus';
490
+ headerActions[1].title =
491
+ 'moduleSelector.configEditor.TooltipAddModule';
492
+ }
493
+ },
494
+ };
495
+
496
+ function removeIdAndActionsFromArray(
497
+ items: VcsListItemWithLabel[],
498
+ ): Module<ModuleType>[] {
499
+ return items.map(removeIdAndActions);
500
+ }
501
+
462
502
  if (localConfig.value?.modules) {
463
503
  listItemArray.value = localConfig.value.modules.map(createListItem);
464
504
  }
@@ -469,10 +509,11 @@
469
509
  callback(): void {
470
510
  editingItem.value = {
471
511
  id: '',
472
- title: 'title',
473
- icon: 'icon',
474
- moduleUrl: 'url',
512
+ title: '',
513
+ icon: '',
514
+ moduleUrl: '',
475
515
  };
516
+ editingItemDialogVisible.value = true;
476
517
  },
477
518
  },
478
519
  headerGroupAction,
@@ -488,11 +529,27 @@
488
529
  });
489
530
 
490
531
  const apply = (): void => {
491
- props.setConfig({
492
- ...localConfig.value,
532
+ const position = toRaw(localConfig.value?.position) as Record<
533
+ string,
534
+ unknown
535
+ >;
536
+ const isPositionDefined = Object.values(position).some(
537
+ (value) => value !== undefined,
538
+ );
539
+
540
+ const config = {
541
+ ...toRaw(localConfig.value),
493
542
  modules: removeIdAndActionsFromArray(listItemArray.value),
494
- basisModule: basisModule.value,
495
- });
543
+ basisModule: toRaw(basisModule.value),
544
+ };
545
+
546
+ if (isPositionDefined) {
547
+ config.position = position;
548
+ } else {
549
+ delete config.position;
550
+ }
551
+
552
+ props.setConfig(config);
496
553
  };
497
554
 
498
555
  const updateItem = (): void => {
@@ -503,35 +560,30 @@
503
560
  (i) => i.id === editingItem.value?.id,
504
561
  );
505
562
  if (item) {
506
- item.title = editingItem.value.title;
507
- item.icon = editingItem.value.icon;
508
- item.moduleUrl = editingItem.value.moduleUrl;
563
+ Object.assign(item, {
564
+ ...editingItem.value,
565
+ });
509
566
  }
510
567
  } else {
511
- listItemArray.value.push({
512
- id: `${editingItem.value.title}-${listItemArray.value.length}`,
513
- title: editingItem.value.title,
514
- name: editingItem.value.title,
515
- icon: editingItem.value.icon,
516
- moduleUrl: editingItem.value.moduleUrl,
517
- type: 'url',
518
- });
519
-
520
- const filteredItems = removeIdAndActionsFromArray(
521
- listItemArray.value,
568
+ listItemArray.value.push(
569
+ createListItem(
570
+ {
571
+ ...editingItem.value,
572
+ type: 'url',
573
+ },
574
+ listItemArray.value.length,
575
+ ),
522
576
  );
523
-
524
- listItemArray.value = filteredItems.map(createListItem);
525
577
  }
526
578
  }
527
579
  } else if (editingItem.value && editingItem.value?.id !== '') {
528
580
  const item = currentGroup.value.cards!.find(
529
- (i) => i.id === editingItem.value!.id,
581
+ (i) => i.id === editingItem.value.id,
530
582
  );
531
583
  if (item) {
532
- item.title = editingItem.value.title;
533
- item.icon = editingItem.value.icon;
534
- item.moduleUrl = editingItem.value.moduleUrl;
584
+ Object.assign(item, {
585
+ ...editingItem.value,
586
+ });
535
587
  }
536
588
 
537
589
  let groupId;
@@ -544,19 +596,61 @@
544
596
  (i) => i.id === groupId,
545
597
  );
546
598
  } else {
547
- currentGroup.value.cards!.push({
548
- id: `${editingItem.value!.title}-${currentGroup.value?.cards?.length}`,
549
- title: editingItem.value!.title,
550
- name: editingItem.value!.title,
551
- icon: editingItem.value!.icon,
552
- moduleUrl: editingItem.value!.moduleUrl,
553
- type: 'url',
554
- });
555
- const filteredItems = removeIdAndActionsFromArray(
556
- listItemArray.value,
599
+ currentGroup.value.cards!.push(
600
+ createListItem(
601
+ {
602
+ ...editingItem.value,
603
+ type: 'url',
604
+ },
605
+ currentGroup.value.cards!.length,
606
+ ),
607
+ );
608
+
609
+ let groupId;
610
+ if (currentGroup.value?.id || currentGroup.value?.id !== '') {
611
+ groupId = currentGroup.value.id;
612
+ } else {
613
+ groupId = `${currentGroup.value?.title}-${listItemArray.value.length - 1}`;
614
+ }
615
+ currentGroup.value = listItemArray.value?.find(
616
+ (item) => item.id === groupId,
557
617
  );
618
+ }
619
+
620
+ editingItem.value = {
621
+ id: '',
622
+ title: '',
623
+ icon: '',
624
+ moduleUrl: '',
625
+ };
626
+ editingItemDialogVisible.value = false;
627
+ };
558
628
 
559
- listItemArray.value = filteredItems.map(createListItem);
629
+ const updateCloudItem = (): void => {
630
+ if (currentGroup.value === undefined) {
631
+ if (selectCloudItem.value) {
632
+ listItemArray.value.push(
633
+ createListItem(
634
+ {
635
+ title: selectCloudItem.value.title,
636
+ icon: selectCloudItem.value.icon,
637
+ moduleUrl: selectCloudItem.value.moduleUrl,
638
+ type: 'url',
639
+ },
640
+ listItemArray.value.length,
641
+ ),
642
+ );
643
+ }
644
+ } else {
645
+ currentGroup.value.cards!.push(
646
+ createListItem(
647
+ {
648
+ ...selectCloudItem.value,
649
+ type: 'url',
650
+ },
651
+ currentGroup.value.cards!.length,
652
+ ),
653
+ );
560
654
 
561
655
  let groupId;
562
656
  if (currentGroup.value?.id || currentGroup.value?.id !== '') {
@@ -569,14 +663,20 @@
569
663
  );
570
664
  }
571
665
 
572
- editingItem.value = undefined;
666
+ selectCloudItem.value = {
667
+ id: '',
668
+ title: '',
669
+ icon: '',
670
+ moduleUrl: '',
671
+ };
672
+ selectCloudItemDialogVisible.value = false;
573
673
  };
574
674
 
575
675
  const returnLevel = (): void => {
576
676
  currentGroup.value = undefined;
577
- if (headerActions.length > 0) {
578
- delete headerActions[0].icon;
579
- delete headerActions[0].title;
677
+ if (headerActions.length > 1) {
678
+ delete headerActions[1].icon;
679
+ delete headerActions[1].title;
580
680
  }
581
681
  headerActions.push(headerGroupAction);
582
682
  };
@@ -603,6 +703,9 @@
603
703
  });
604
704
  return {
605
705
  editingItem,
706
+ selectCloudItem,
707
+ editingItemDialogVisible,
708
+ selectCloudItemDialogVisible,
606
709
  localConfig,
607
710
  listItemArray,
608
711
  breadcrumbItems,
@@ -610,6 +713,7 @@
610
713
  apply,
611
714
  returnLevel,
612
715
  updateItem,
716
+ updateCloudItem,
613
717
  level,
614
718
  listItems: listItems as unknown as unknown[],
615
719
  basisModule,
@@ -0,0 +1,25 @@
1
+ import { authorize, setServerUrl } from '@vcsuite/publisher-sdk';
2
+ import { getLogger } from '@vcsuite/logger';
3
+ import { name } from '../../package.json';
4
+ import { ModuleSelectorConfig } from '../index';
5
+
6
+ // eslint-disable-next-line import/prefer-default-export
7
+ export function setupPublisherSDK(options: ModuleSelectorConfig): void {
8
+ try {
9
+ if (options.serverUrl) {
10
+ const serverUrl = new URL(
11
+ options.serverUrl,
12
+ window.location.href,
13
+ ).toString();
14
+ setServerUrl(serverUrl);
15
+
16
+ const token = options.token || localStorage.getItem('Meteor.loginToken');
17
+ if (token) {
18
+ authorize(token);
19
+ getLogger(name).info('Publisher connection successful');
20
+ }
21
+ }
22
+ } catch (err) {
23
+ getLogger(name).error('Failed to connect to publisher', err);
24
+ }
25
+ }
@@ -11,4 +11,8 @@ export default (): ModuleSelectorConfig => ({
11
11
  },
12
12
  basisModule: undefined,
13
13
  modules: [],
14
+ serverUrl: '',
15
+ projectId: '',
16
+ appId: '',
17
+ token: '',
14
18
  });
package/src/index.ts CHANGED
@@ -33,6 +33,10 @@ export type ModuleSelectorConfig = {
33
33
  windowTitle?: string;
34
34
  isActiveOnStart?: boolean;
35
35
  requireModuleSelection?: boolean;
36
+ serverUrl?: string;
37
+ projectId?: string;
38
+ appId?: string;
39
+ token?: string;
36
40
  position?: WindowPositionOptions;
37
41
  basisModule?: BasisModule;
38
42
  modules?: Array<Module<ModuleType>>;
@@ -43,7 +47,7 @@ export type PluginState = {
43
47
  smi?: number | undefined | null;
44
48
  // selectedNestedModuleIndex
45
49
  snmi?: number | undefined | null;
46
- // module elector window open
50
+ // module selector window open
47
51
  w?: boolean;
48
52
  modules?: Array<Module<ModuleType>>;
49
53
  };
@@ -120,8 +124,8 @@ export default function plugin(
120
124
  this.selectedMainModuleIndex.value,
121
125
  this.selectedNestedModuleIndex.value,
122
126
  app,
123
- configInput.modules!,
124
- configInput.basisModule,
127
+ this.config.modules,
128
+ this.config.basisModule,
125
129
  );
126
130
  }
127
131
  }
@@ -146,7 +150,7 @@ export default function plugin(
146
150
  ButtonLocation.PROJECT,
147
151
  );
148
152
 
149
- if ((state && state.w) || (!state && configInput.isActiveOnStart)) {
153
+ if ((state && state.w) || (!state && this.config.isActiveOnStart)) {
150
154
  app.windowManager.add(moduleSelectorComponent, name);
151
155
  }
152
156
 
@@ -205,6 +209,22 @@ export default function plugin(
205
209
  serial.basisModule = this.config.basisModule;
206
210
  }
207
211
 
212
+ if (configInput.serverUrl != null) {
213
+ serial.serverUrl = configInput.serverUrl;
214
+ }
215
+
216
+ if (configInput.projectId != null) {
217
+ serial.projectId = configInput.projectId;
218
+ }
219
+
220
+ if (configInput.appId != null) {
221
+ serial.appId = configInput.appId;
222
+ }
223
+
224
+ if (configInput.token != null) {
225
+ serial.token = configInput.token;
226
+ }
227
+
208
228
  return serial;
209
229
  },
210
230
  i18n: {
@@ -215,6 +235,20 @@ export default function plugin(
215
235
  startButton: 'Anwendung starten',
216
236
  cardBack: 'Zurück',
217
237
  configEditor: {
238
+ moduleCloudPicker: {
239
+ searchName: 'Suche nach Name...',
240
+ continue: 'Weiter',
241
+ back: 'Zurück',
242
+ headers: {
243
+ name: 'Modul Name',
244
+ type: 'Typ',
245
+ description: 'Beschreibung',
246
+ createdAt: 'Erzeugt am',
247
+ updatedAt: 'Aktualisiert am',
248
+ createdBy: 'Erzeugt von',
249
+ updatedBy: 'Aktualisiert von',
250
+ },
251
+ },
218
252
  TooltipAddModule: 'Modul hinzufügen',
219
253
  TooltipEditModule: 'Modul bearbeiten',
220
254
  TooltipEditGroup: 'Modul-Gruppe bearbeiten',
@@ -248,6 +282,20 @@ export default function plugin(
248
282
  startButton: 'Start application',
249
283
  cardBack: 'Back',
250
284
  configEditor: {
285
+ moduleCloudPicker: {
286
+ searchName: 'Search for name...',
287
+ continue: 'Continue',
288
+ back: 'Back',
289
+ headers: {
290
+ name: 'Module name',
291
+ type: 'Type',
292
+ description: 'Description',
293
+ createdAt: 'Created at',
294
+ updatedAt: 'Updated at',
295
+ createdBy: 'Created by',
296
+ updatedBy: 'Updated by',
297
+ },
298
+ },
251
299
  TooltipAddModule: 'Add module',
252
300
  TooltipEditModule: 'Edit module',
253
301
  TooltipEditGroup: 'Edit module group',