@7365admin1/layer-common 1.8.5 → 1.9.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 1.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b7d47c7: update layer common package new changes
8
+
9
+ ## 1.8.6
10
+
11
+ ### Patch Changes
12
+
13
+ - 21990e5: Update Version for new changes
14
+
3
15
  ## 1.8.5
4
16
 
5
17
  ### Patch Changes
@@ -24,7 +24,24 @@
24
24
  type="text"
25
25
  ></v-select>
26
26
  </v-col>
27
- <v-col cols="12" class="px-1 pb-5">
27
+ <v-col cols="12" class="px-1" v-if="isNonPhysicalCard">
28
+ <InputLabel
29
+ class="text-capitalize font-weight-bold"
30
+ title="Quantity"
31
+ required
32
+ />
33
+ <v-text-field
34
+ v-model.number="card.quantity"
35
+ density="compact"
36
+ hide-details
37
+ :rules="[requiredRule]"
38
+ type="number"
39
+ :min="1"
40
+ hide-spin-buttons
41
+ @input="enforceMinQuantity"
42
+ />
43
+ </v-col>
44
+ <v-col cols="12" class="px-1 pb-5" v-if="!isNonPhysicalCard">
28
45
  <InputLabel
29
46
  class="text-capitalize font-weight-bold"
30
47
  :title="`Card No (${cardNoMaxLength} digits)`"
@@ -35,36 +52,38 @@
35
52
  density="compact"
36
53
  hide-details
37
54
  :rules="[requiredRule]"
38
- maxlength="10"
55
+ :maxlength="cardNoMaxLength"
39
56
  type="number"
40
57
  hide-spin-buttons
58
+ :suffix="`${card.cardNumber?.toString().length || 0}/${cardNoMaxLength}`"
59
+ @input="limitCardNumber"
41
60
  >
42
61
  </v-text-field>
43
62
  </v-col>
44
- <v-col cols="12" class="px-1">
63
+ <v-col cols="12" class="px-1" v-if="!isNonPhysicalCard">
45
64
  <InputLabel
46
65
  class="text-capitalize font-weight-bold"
47
66
  title="Start Date"
48
67
  required
49
68
  />
50
- <InputDateTimePicker
51
- ref="startDateRef"
69
+ <InputDatePicker
52
70
  v-model="card.startDate"
53
71
  placeholder="Start Date"
54
72
  :rules="[requiredRule]"
73
+ @update:model-value="updateEndDate"
55
74
  />
56
75
  </v-col>
57
- <v-col cols="12" class="px-1 pb-4">
76
+ <v-col cols="12" class="px-1 pb-4" v-if="!isNonPhysicalCard">
58
77
  <InputLabel
59
78
  class="text-capitalize font-weight-bold"
60
79
  title="End Date"
61
80
  required
62
81
  />
63
- <InputDateTimePicker
64
- ref="endDateRef"
82
+ <InputDatePicker
65
83
  v-model="card.endDate"
66
84
  placeholder="End Date"
67
85
  :rules="[requiredRule]"
86
+ readonly
68
87
  />
69
88
  </v-col>
70
89
  <v-divider />
@@ -102,7 +121,7 @@
102
121
  >
103
122
  </v-select>
104
123
  </v-col>
105
- <v-col cols="12">
124
+ <v-col cols="12" v-if="!isNonPhysicalCard">
106
125
  <InputLabel
107
126
  class="text-capitalize font-weight-bold"
108
127
  title="Card Type"
@@ -119,7 +138,7 @@
119
138
  >
120
139
  </v-select>
121
140
  </v-col>
122
- <v-col cols="12">
141
+ <v-col cols="12" v-if="!isNonPhysicalCard">
123
142
  <InputLabel
124
143
  class="text-capitalize font-weight-bold"
125
144
  :title="`Pin No (${cardPinMaxLength} digits)`"
@@ -130,26 +149,27 @@
130
149
  density="compact"
131
150
  hide-details
132
151
  :rules="[requiredRule]"
133
- maxlength="10"
152
+ :maxlength="cardPinMaxLength"
134
153
  type="number"
135
154
  hide-spin-buttons
155
+ :suffix="`${card.pinNo?.toString().length || 0}/${cardPinMaxLength}`"
156
+ @input="limitPinNo"
136
157
  >
137
158
  </v-text-field>
138
159
  </v-col>
139
160
  <v-col cols="12" class="pt-5">
140
- <v-btn
141
- block
161
+ <v-switch
162
+ v-model="card.useAsLiftCard"
163
+ label="Use as Lift Card"
142
164
  color="primary"
143
- variant="text"
144
- class="text-none font-weight-bold"
145
- text="Use as lift Card"
146
- @click="card.useAsLiftCard = !card.useAsLiftCard"
147
- ></v-btn>
165
+ hide-details
166
+ density="compact"
167
+ />
148
168
  </v-col>
149
169
  <v-col cols="12" v-if="card.useAsLiftCard">
150
170
  <InputLabel
151
171
  class="text-capitalize font-weight-bold"
152
- title="Lift Access Label"
172
+ title="Lift Access Level"
153
173
  :required="card.useAsLiftCard"
154
174
  />
155
175
  <v-select
@@ -187,6 +207,67 @@
187
207
  </span>
188
208
  </div>
189
209
  </v-col>
210
+ <v-col cols="12">
211
+ <v-divider class="my-4" />
212
+ </v-col>
213
+ <v-col cols="12">
214
+ <v-switch
215
+ v-model="card.showAssign"
216
+ label="Assign (Optional)"
217
+ color="primary"
218
+ hide-details
219
+ density="compact"
220
+ />
221
+ </v-col>
222
+ <template v-if="card.showAssign">
223
+ <v-col cols="12">
224
+ <InputLabel
225
+ class="text-capitalize font-weight-bold"
226
+ title="Building"
227
+ />
228
+ <v-autocomplete
229
+ v-model="card.assignBuilding"
230
+ density="compact"
231
+ :items="buildingItems"
232
+ hide-details
233
+ item-title="name"
234
+ item-value="value"
235
+ placeholder="Search building..."
236
+ />
237
+ </v-col>
238
+ <v-col cols="12">
239
+ <InputLabel
240
+ class="text-capitalize font-weight-bold"
241
+ title="Level"
242
+ />
243
+ <v-autocomplete
244
+ v-model="card.assignLevel"
245
+ density="compact"
246
+ :items="levelItems"
247
+ hide-details
248
+ item-title="name"
249
+ item-value="value"
250
+ placeholder="Search level..."
251
+ :disabled="!card.assignBuilding"
252
+ />
253
+ </v-col>
254
+ <v-col cols="12">
255
+ <InputLabel
256
+ class="text-capitalize font-weight-bold"
257
+ title="Unit"
258
+ />
259
+ <v-autocomplete
260
+ v-model="card.assignUnit"
261
+ density="compact"
262
+ :items="unitItems"
263
+ hide-details
264
+ item-title="name"
265
+ item-value="value"
266
+ placeholder="Search unit..."
267
+ :disabled="!card.assignLevel"
268
+ />
269
+ </v-col>
270
+ </template>
190
271
  </v-row>
191
272
  </v-row>
192
273
  </v-form>
@@ -244,6 +325,8 @@ const prop = defineProps({
244
325
  });
245
326
 
246
327
  const { add: _addCard, updateById: _updateCardById } = useCard();
328
+ const { getAll: _getBuildings } = useBuilding();
329
+ const { getAllUnits: _getUnits } = useBuildingUnit();
247
330
  const emit = defineEmits(["cancel", "success"]);
248
331
 
249
332
  const validForm = ref(false);
@@ -252,27 +335,43 @@ const message = ref("");
252
335
 
253
336
  const { requiredRule } = useUtils();
254
337
 
338
+ function formatDate(date: Date): string {
339
+ return date.toISOString().split("T")[0];
340
+ }
341
+
342
+ const today = new Date();
343
+ const tenYearsLater = new Date(today);
344
+ tenYearsLater.setFullYear(today.getFullYear() + 10);
345
+
255
346
  const card = ref<Record<string, any>>({
256
- accessCardType: "",
347
+ accessCardType: "Physical Access Card",
257
348
  type: "door-setup",
258
349
  cardNumber: "",
259
- startDate: "",
260
- endDate: "",
350
+ startDate: formatDate(today),
351
+ endDate: formatDate(tenYearsLater),
261
352
  door: "",
262
353
  accessGroup: [],
263
- cardType: "",
354
+ cardType: "Normal",
264
355
  pinNo: "",
265
356
  isActivate: true,
266
357
  isAntiPassBack: false,
267
358
  useAsLiftCard: false,
359
+ isWinsland: false,
268
360
  status: "active",
269
361
  liftAccessLevel: "",
270
362
  org: "",
271
363
  site: "",
272
364
  unit: "",
273
365
  assign: "",
366
+ quantity: 1,
367
+ showAssign: false,
368
+ assignBuilding: "",
369
+ assignLevel: "",
370
+ assignUnit: "",
274
371
  });
275
372
 
373
+ const isNonPhysicalCard = computed(() => card.value.accessCardType === "Non Physical Access Card");
374
+
276
375
  if (prop.mode === "edit") {
277
376
  card.value.accessCardType = prop.card.accessCardType;
278
377
  card.value.type = prop.card.type;
@@ -292,15 +391,19 @@ if (prop.mode === "edit") {
292
391
  card.value.site = prop.card.site;
293
392
  card.value.unit = prop.card.unit;
294
393
  card.value.assign = prop.card.assign;
394
+ card.value.quantity = prop.card.quantity;
395
+ card.value.showAssign = prop.card.showAssign;
396
+ card.value.assignBuilding = prop.card.assignBuilding;
397
+ card.value.assignLevel = prop.card.assignLevel;
398
+ card.value.assignUnit = prop.card.assignUnit;
295
399
  }
296
400
 
297
401
  const accessCardTypes = ["Physical Access Card", "Non Physical Access Card"];
298
402
  const typeOfVisitors = ["Contractor", "Visitor"];
299
403
 
300
404
  const accessLevelItems = ref<{ name: string; no: string }[]>([
301
- { name: "All access", no: "1" },
302
405
  ]);
303
- const accessGroupItems = ref(["All Access", "Glass Door 1"]);
406
+ const accessGroupItems = ref([]);
304
407
  const cardTypeItems = ref([
305
408
  {
306
409
  name: "Normal - Access Card",
@@ -321,14 +424,119 @@ const cardTypeItems = ref([
321
424
  ]);
322
425
  const cardNoMaxLength = ref(10);
323
426
  const cardPinMaxLength = ref(6);
324
- const startDateRef = ref<HTMLInputElement | null>(null);
325
- const endDateRef = ref<HTMLInputElement | null>(null);
326
427
  const liftAccessLevelItems = ref<{ name: string; no: string }[]>([]);
428
+ const buildingItems = ref<{ name: string; value: string }[]>([]);
429
+ const levelItems = ref<{ name: string; value: string }[]>([]);
430
+ const unitItems = ref<{ name: string; value: string }[]>([]);
431
+ const buildingsData = ref<Record<string, any>[]>([]);
327
432
 
328
433
  const route = useRoute();
329
434
  const siteId = route.params.site as string;
330
435
  const orgId = route.params.org as string;
331
436
 
437
+ function limitCardNumber() {
438
+ if (card.value.cardNumber && card.value.cardNumber.toString().length > cardNoMaxLength.value) {
439
+ card.value.cardNumber = card.value.cardNumber.toString().slice(0, cardNoMaxLength.value);
440
+ }
441
+ }
442
+
443
+ function limitPinNo() {
444
+ if (card.value.pinNo && card.value.pinNo.toString().length > cardPinMaxLength.value) {
445
+ card.value.pinNo = card.value.pinNo.toString().slice(0, cardPinMaxLength.value);
446
+ }
447
+ }
448
+
449
+ function enforceMinQuantity() {
450
+ if (card.value.quantity < 1 || !card.value.quantity) {
451
+ card.value.quantity = 1;
452
+ }
453
+ }
454
+
455
+ function updateEndDate(startDate: string | null) {
456
+ if (startDate) {
457
+ const date = new Date(startDate);
458
+ date.setFullYear(date.getFullYear() + 10);
459
+ card.value.endDate = formatDate(date);
460
+ }
461
+ }
462
+
463
+ // Watch for Assign toggle to fetch buildings
464
+ watch(() => card.value.showAssign, async (newVal) => {
465
+ if (newVal) {
466
+ try {
467
+ const response = await _getBuildings({
468
+ page: 1,
469
+ status: "active",
470
+ site: siteId,
471
+ });
472
+ buildingsData.value = response.items || [];
473
+ buildingItems.value = buildingsData.value.map((building: any) => ({
474
+ name: building.name,
475
+ value: building._id,
476
+ }));
477
+ } catch (error) {
478
+ console.error("Failed to fetch buildings:", error);
479
+ }
480
+ } else {
481
+ // Reset selections when toggled off
482
+ card.value.assignBuilding = "";
483
+ card.value.assignLevel = "";
484
+ card.value.assignUnit = "";
485
+ buildingItems.value = [];
486
+ levelItems.value = [];
487
+ unitItems.value = [];
488
+ }
489
+ });
490
+
491
+ // Watch for building selection to populate levels
492
+ watch(() => card.value.assignBuilding, async (newVal) => {
493
+ if (newVal) {
494
+ const selectedBuilding = buildingsData.value.find((b: any) => b._id === newVal);
495
+ if (selectedBuilding && selectedBuilding.levels) {
496
+ levelItems.value = selectedBuilding.levels.map((level: string) => ({
497
+ name: level,
498
+ value: level,
499
+ }));
500
+ }
501
+ // Reset level and unit when building changes
502
+ card.value.assignLevel = "";
503
+ card.value.assignUnit = "";
504
+ unitItems.value = [];
505
+ } else {
506
+ levelItems.value = [];
507
+ card.value.assignLevel = "";
508
+ card.value.assignUnit = "";
509
+ unitItems.value = [];
510
+ }
511
+ });
512
+
513
+ // Watch for level selection to fetch units
514
+ watch(() => card.value.assignLevel, async (newVal) => {
515
+ if (newVal && card.value.assignBuilding) {
516
+ try {
517
+ const response = await _getUnits({
518
+ page: 1,
519
+ status: "active",
520
+ site: siteId,
521
+ building: card.value.assignBuilding,
522
+ });
523
+ const units = response.items || [];
524
+ // Filter units by selected level
525
+ const filteredUnits = units.filter((unit: any) => unit.level === newVal);
526
+ unitItems.value = filteredUnits.map((unit: any) => ({
527
+ name: unit.name,
528
+ value: unit._id,
529
+ }));
530
+ } catch (error) {
531
+ console.error("Failed to fetch units:", error);
532
+ }
533
+ card.value.assignUnit = "";
534
+ } else {
535
+ unitItems.value = [];
536
+ card.value.assignUnit = "";
537
+ }
538
+ });
539
+
332
540
  function cancel() {
333
541
  // createMore.value = false;
334
542
  message.value = "";
@@ -28,7 +28,7 @@
28
28
  </v-toolbar>
29
29
 
30
30
  <v-data-table :headers="headers" :items="items" item-value="_id" items-per-page="20" fixed-header
31
- hide-default-footer hide-default-header @click:row="tableRowClickHandler"
31
+ hide-default-footer @click:row="tableRowClickHandler"
32
32
  style="max-height: calc(100vh - (200px))">
33
33
  <template #item.createdAt="{ value }">
34
34
  {{ new Date(value).toLocaleDateString() }}
@@ -333,3 +333,8 @@ function setBuilding({
333
333
  }
334
334
  }
335
335
  </script>
336
+ <style scoped>
337
+ .v-data-table :deep(thead th) {
338
+ font-weight: bold !important;
339
+ }
340
+ </style>
@@ -28,7 +28,7 @@
28
28
  </v-toolbar>
29
29
 
30
30
  <v-data-table :headers="props.headers" :items="items" item-value="_id" items-per-page="20" fixed-header
31
- hide-default-footer hide-default-header @click:row="tableRowClickHandler"
31
+ hide-default-footer @click:row="tableRowClickHandler"
32
32
  style="max-height: calc(100vh - (200px))">
33
33
  <template #item.block="{ value }">
34
34
  {{ value ? `blk ${value}` : "" }}
@@ -348,3 +348,9 @@ function setBuilding({
348
348
  }
349
349
  }
350
350
  </script>
351
+
352
+ <style scoped>
353
+ .v-data-table :deep(thead th) {
354
+ font-weight: bold !important;
355
+ }
356
+ </style>
@@ -8,7 +8,7 @@
8
8
  <v-card-text style="max-height: 100vh; overflow-y: auto">
9
9
  <v-form v-model="validForm" :disabled="disable">
10
10
  <v-row no-gutters>
11
- <v-col cols="12" class="mt-2">
11
+ <!-- <v-col cols="12" class="mt-2">
12
12
  <v-row no-gutters>
13
13
  <InputLabel class="text-capitalize" title="Name" required />
14
14
  <v-col cols="12">
@@ -19,7 +19,7 @@
19
19
  ></v-text-field>
20
20
  </v-col>
21
21
  </v-row>
22
- </v-col>
22
+ </v-col> -->
23
23
 
24
24
  <v-col cols="12">
25
25
  <v-row>
@@ -48,7 +48,7 @@
48
48
  </v-row>
49
49
  </v-col>
50
50
 
51
- <v-col cols="12">
51
+ <!-- <v-col cols="12">
52
52
  <v-row>
53
53
  <v-col cols="12" class="mt-2">
54
54
  <v-row no-gutters>
@@ -67,9 +67,9 @@
67
67
  </v-row>
68
68
  </v-col>
69
69
  </v-row>
70
- </v-col>
70
+ </v-col> -->
71
71
 
72
- <v-col cols="12">
72
+ <!-- <v-col cols="12">
73
73
  <v-row>
74
74
  <v-col cols="12" class="mt-2">
75
75
  <v-row no-gutters>
@@ -87,9 +87,9 @@
87
87
  </v-row>
88
88
  </v-col>
89
89
  </v-row>
90
- </v-col>
90
+ </v-col> -->
91
91
 
92
- <v-col cols="12">
92
+ <!-- <v-col cols="12">
93
93
  <v-row>
94
94
  <v-col cols="12" class="mt-2">
95
95
  <v-row no-gutters>
@@ -129,7 +129,7 @@
129
129
  </v-row>
130
130
  </v-col>
131
131
  </v-row>
132
- </v-col>
132
+ </v-col> -->
133
133
 
134
134
  <v-col cols="12" class="mt-2">
135
135
  <v-row no-gutters>
@@ -221,7 +221,7 @@
221
221
  </v-row>
222
222
  </v-expand-transition>
223
223
 
224
- <v-col cols="12" class="mt-5">
224
+ <!-- <v-col cols="12" class="mt-5">
225
225
  <InputLabel
226
226
  class="text-capitalize"
227
227
  title="Upload Files (Lease of Contract, Cert. of Occupancy)"
@@ -233,7 +233,7 @@
233
233
  title="Upload PDF Files"
234
234
  accept="application/pdf"
235
235
  />
236
- </v-col>
236
+ </v-col> -->
237
237
 
238
238
  <v-col cols="12" class="mt-2">
239
239
  <v-checkbox v-model="createMore" density="comfortable" hide-details>
@@ -343,6 +343,7 @@ const buildingUnit = ref<TBuildingUnit>({
343
343
  leaseEnd: "",
344
344
  });
345
345
 
346
+
346
347
  const startDateRef = ref<HTMLInputElement | null>(null);
347
348
  const expiryDateRef = ref<HTMLInputElement | null>(null);
348
349
 
@@ -408,10 +409,11 @@ function setBuildingUnit() {
408
409
 
409
410
  async function submit() {
410
411
  disable.value = true;
412
+ const {buildingUnitFiles, companyName, companyRegistrationNumber, leaseStart, leaseEnd, ...rest} = buildingUnit.value;
411
413
  try {
412
414
  await add({
413
415
  labels: unitLabels.value,
414
- unit: buildingUnit.value,
416
+ unit: rest,
415
417
  qty: buildingUnitQty.value,
416
418
  });
417
419
 
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <v-btn text="Close" class="bg-grey-lighten-2 text-capitalize" :height="prop.height" @click="emit('click')" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ const prop = defineProps<{
7
+ height?: string | number;
8
+ }>();
9
+
10
+ const emit = defineEmits<{
11
+ (e: 'click'): void;
12
+ }>();
13
+
14
+ </script>
15
+
16
+ <style scoped></style>
@@ -11,6 +11,7 @@
11
11
 
12
12
  <template #append>
13
13
  <v-btn
14
+ v-if="!prop.readOnly"
14
15
  variant="flat"
15
16
  color="primary"
16
17
  class="text-none"
@@ -144,7 +145,7 @@
144
145
 
145
146
  <v-toolbar class="pa-0" density="compact">
146
147
  <v-row no-gutters>
147
- <v-col cols="6" class="pa-0">
148
+ <v-col :cols="prop.readOnly ? 12 : 6" class="pa-0">
148
149
  <v-btn
149
150
  block
150
151
  variant="text"
@@ -157,7 +158,7 @@
157
158
  </v-btn>
158
159
  </v-col>
159
160
 
160
- <v-col cols="6" class="pa-0">
161
+ <v-col v-if="!prop.readOnly" cols="6" class="pa-0">
161
162
  <v-menu>
162
163
  <template #activator="{ props }">
163
164
  <v-btn
@@ -176,13 +177,13 @@
176
177
  <v-list class="pa-0">
177
178
  <v-list-item @click="openDialogEdit()">
178
179
  <v-list-item-title class="text-subtitle-2">
179
- Edit Building
180
+ Edit
180
181
  </v-list-item-title>
181
182
  </v-list-item>
182
183
 
183
184
  <v-list-item @click="openDialogDelete()" class="text-red">
184
185
  <v-list-item-title class="text-subtitle-2">
185
- Delete Building
186
+ Delete
186
187
  </v-list-item-title>
187
188
  </v-list-item>
188
189
  </v-list>
@@ -268,6 +269,10 @@ const prop = defineProps({
268
269
  { text: "Actions", value: "action", sortable: false },
269
270
  ],
270
271
  },
272
+ readOnly: {
273
+ type: Boolean,
274
+ default: false,
275
+ },
271
276
  });
272
277
 
273
278
  const items = ref<Array<TCamera>>([]);
@@ -41,6 +41,7 @@
41
41
  color="black"
42
42
  class="text-none"
43
43
  height="48"
44
+ :disabled="disabled"
44
45
  v-bind="props"
45
46
  tile
46
47
  >
@@ -78,6 +79,10 @@ const prop = defineProps({
78
79
  type: Boolean,
79
80
  default: true,
80
81
  },
82
+ disabled: {
83
+ type: Boolean,
84
+ default: false,
85
+ },
81
86
  editButtonLabel: {
82
87
  type: String,
83
88
  default: "Edit",
@@ -97,7 +102,7 @@ const prop = defineProps({
97
102
  });
98
103
 
99
104
  const emit = defineEmits(["close", "edit", "delete"]);
100
- const { canUpdate, editButtonLabel, deleteButtonLabel, title } = prop;
105
+ const { canUpdate, editButtonLabel, deleteButtonLabel, title, disabled } = prop;
101
106
  </script>
102
107
 
103
108
  <style scoped></style>
@@ -305,21 +305,32 @@ async function handleCompletionFileAdded(file: File) {
305
305
 
306
306
  const res = await addFile(file);
307
307
 
308
- if (res?.id && res?.name) {
309
- const url = `https://seven365-storage.sgp1.cdn.digitaloceanspaces.com/dev/${res.id}`;
308
+ const uploadedId = res?.id;
310
309
 
311
- if (!completionAttachments.value) {
312
- completionAttachments.value = [];
313
- }
310
+ if (uploadedId) {
311
+ const url = `${uploadedId}`;
314
312
 
313
+ completionAttachments.value = completionAttachments.value ?? [];
315
314
  completionAttachments.value.push(url);
315
+ }
316
316
 
317
- completionFileNames.value[url] = res.name;
317
+ // if (res?.id && res?.name) {
318
+ // const url = `https://seven365-storage.sgp1.cdn.digitaloceanspaces.com/dev/${res.id}`;
318
319
 
319
- if (completionFileInput.value) {
320
- completionFileInput.value.updateFileName(url, res.name);
321
- }
322
- }
320
+ // if (!completionAttachments.value) {
321
+ // completionAttachments.value = [];
322
+ // }
323
+
324
+ // completionAttachments.value.push(url);
325
+
326
+ // completionFileNames.value[url] = res.name;
327
+
328
+ // if (completionFileInput.value) {
329
+ // completionFileInput.value.updateFileName(url, res.name);
330
+ // }
331
+ // }
332
+
333
+ console.log("completionAttachments.value", completionAttachments.value);
323
334
  } catch (error) {
324
335
  console.error("Error uploading completion file:", error);
325
336
  showMessage("Failed to upload file", "error");