@7365admin1/layer-common 4.90.2-staging.491 → 4.90.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +16 -4
  2. package/assets/css/primitives.css +0 -57
  3. package/assets/css/screens.css +4 -8
  4. package/components/AccessCardDetailsDialog.vue +6 -59
  5. package/components/AccessCardPreviewDialog.vue +53 -371
  6. package/components/AppSelect.vue +4 -143
  7. package/components/BuildingUnitFormEdit.vue +0 -6
  8. package/components/Dialog/UpdateMoreAction.vue +1 -11
  9. package/components/DocumentForm.vue +112 -407
  10. package/components/DocumentManagement.vue +12 -213
  11. package/components/Facility/BookingSetup.vue +0 -63
  12. package/components/HidAccessLogDashboard.vue +17 -74
  13. package/components/HidIntercomManagement.vue +14 -183
  14. package/components/HidQrCodeConfiguration.vue +195 -17
  15. package/components/HidReaderManagement.vue +0 -398
  16. package/components/HidReaderUserRoster.vue +3 -44
  17. package/components/HidUserEnrollment.vue +292 -2255
  18. package/components/InventoryItemDetail.vue +1 -2
  19. package/components/InventoryLinesDialog.vue +13 -91
  20. package/components/InventoryPhotoInput.vue +6 -44
  21. package/components/InventoryReportsTab.vue +3 -23
  22. package/components/InventoryRequestsTab.vue +4 -27
  23. package/components/InventoryStockTab.vue +0 -3
  24. package/components/InvitationClientForm.vue +1 -19
  25. package/components/InvitationForm.vue +4 -31
  26. package/components/InvitationMain.vue +22 -124
  27. package/components/SiteSettings.vue +0 -48
  28. package/components/TableMain.vue +7 -22
  29. package/components/VehicleManagement.vue +5 -80
  30. package/components/VisitorForm.vue +0 -12
  31. package/components/VisitorManagement.vue +5 -267
  32. package/composables/useAccessManagement.ts +1 -17
  33. package/composables/useDocument.ts +0 -7
  34. package/composables/useFacility.ts +0 -11
  35. package/composables/useHidAmico.ts +0 -165
  36. package/composables/useHidNavigation.ts +1 -25
  37. package/composables/useInventory.ts +1 -4
  38. package/composables/useMember.ts +0 -12
  39. package/composables/useNFCPatrolReportFilters.ts +3 -21
  40. package/composables/useNFCPatrolRoute.ts +1 -8
  41. package/composables/usePeople.ts +0 -19
  42. package/composables/useServiceProvider.ts +2 -45
  43. package/composables/useSettingsPermission.ts +0 -14
  44. package/composables/useUser.ts +2 -6
  45. package/composables/useVehicle.ts +1 -40
  46. package/composables/useVerification.ts +0 -3
  47. package/middleware/01.auth.ts +7 -3
  48. package/package.json +1 -1
  49. package/pages/[org]/[site]/access-mgmt/administrator/index.vue +1 -1
  50. package/pages/[org]/[site]/access-mgmt/hid-cards/index.vue +1 -1
  51. package/pages/[org]/[site]/access-mgmt/hid-readers/index.vue +1 -1
  52. package/types/document.d.ts +0 -14
  53. package/types/facility.d.ts +0 -4
  54. package/types/inventory.d.ts +0 -27
  55. package/types/member.d.ts +0 -4
  56. package/types/people.d.ts +1 -28
  57. package/types/service-provider.d.ts +0 -5
  58. package/types/site.d.ts +1 -7
  59. package/components/BuildingUnitManagement.vue +0 -298
  60. package/components/HidAccessPermissions.vue +0 -424
  61. package/components/HidProfileQrCode.vue +0 -332
  62. package/components/InventoryPoDialog.vue +0 -111
  63. package/components/VehicleQrStickerDialog.vue +0 -249
  64. package/composables/useHidReaderSelection.ts +0 -50
  65. package/composables/useSiteCategory.ts +0 -45
  66. package/pages/[org]/[site]/access-mgmt/hid-qr-code/index.vue +0 -23
  67. package/utils/hid-enrolment-subject.ts +0 -344
  68. package/utils/hid-permission-assignments.ts +0 -198
  69. package/utils/hid-reader-selection.ts +0 -52
  70. package/utils/inventory-receiving.ts +0 -90
  71. package/utils/invite-group.ts +0 -61
  72. package/utils/invite-sites.ts +0 -25
  73. package/utils/occupancy-role.ts +0 -109
  74. package/utils/service-type.ts +0 -30
  75. package/utils/vehicle-qr-sticker.ts +0 -184
@@ -18,8 +18,7 @@
18
18
  <template>
19
19
  <v-menu
20
20
  v-if="!multiple"
21
- v-model="singleOpen"
22
- :close-on-content-click="!searchable"
21
+ :close-on-content-click="true"
23
22
  :disabled="disabled"
24
23
  location="bottom start"
25
24
  offset="4"
@@ -53,27 +52,9 @@
53
52
  </div>
54
53
  </template>
55
54
 
56
- <div
57
- ref="singleMenu"
58
- class="app-select__menu"
59
- role="listbox"
60
- @scroll.passive="onMenuScroll"
61
- >
62
- <div v-if="searchable" class="app-select__search">
63
- <v-icon icon="mdi-magnify" size="16" />
64
- <input
65
- ref="singleSearchInput"
66
- v-model="search"
67
- type="text"
68
- class="app-select__search-input"
69
- :placeholder="searchPlaceholder"
70
- aria-label="Search options"
71
- @keydown.enter.prevent="selectFirstMatch"
72
- @keydown.esc.stop="singleOpen = false"
73
- >
74
- </div>
55
+ <div class="app-select__menu" role="listbox">
75
56
  <button
76
- v-for="opt in visibleOptions"
57
+ v-for="opt in normalized"
77
58
  :key="String(opt.value)"
78
59
  type="button"
79
60
  class="app-select__option"
@@ -85,14 +66,6 @@
85
66
  <span class="app-select__option-text">{{ opt.title }}</span>
86
67
  <v-icon v-if="isSingleOn(opt)" icon="mdi-check" size="17" />
87
68
  </button>
88
- <p v-if="searchable && !visibleOptions.length" class="app-select__empty">
89
- {{ normalized.length ? "No matches" : "Nothing to choose from" }}
90
- </p>
91
- <!-- In the list, not under the field: the wait belongs where the reader's
92
- eye already is, at the end of what they just scrolled through. -->
93
- <p v-if="loadingMore" class="app-select__loading" role="status">
94
- Loading more...
95
- </p>
96
69
  </div>
97
70
  </v-menu>
98
71
 
@@ -149,18 +122,8 @@
149
122
  </template>
150
123
 
151
124
  <div class="app-select__menu">
152
- <div v-if="searchable" class="app-select__search">
153
- <v-icon icon="mdi-magnify" size="16" />
154
- <input
155
- v-model="search"
156
- type="text"
157
- class="app-select__search-input"
158
- :placeholder="searchPlaceholder"
159
- aria-label="Search options"
160
- >
161
- </div>
162
125
  <button
163
- v-for="opt in visibleOptions"
126
+ v-for="opt in normalized"
164
127
  :key="String(opt.value)"
165
128
  type="button"
166
129
  class="app-select__option"
@@ -175,9 +138,6 @@
175
138
  />
176
139
  <span class="app-select__option-text">{{ opt.title }}</span>
177
140
  </button>
178
- <p v-if="searchable && !visibleOptions.length" class="app-select__empty">
179
- {{ normalized.length ? "No matches" : "Nothing to choose from" }}
180
- </p>
181
141
  </div>
182
142
  </v-menu>
183
143
  </template>
@@ -194,34 +154,6 @@ defineOptions({ inheritAttrs: false });
194
154
  */
195
155
  const model = defineModel<any>({ default: "" });
196
156
 
197
- /**
198
- * ASKING FOR THE NEXT PAGE, FROM INSIDE THE LIST.
199
- *
200
- * A dropdown that pages should load as it is scrolled - a button under the
201
- * field asks the reader to leave the list they are reading to fetch more of it.
202
- * The menu is already the scroll container (`max-height: 280px; overflow-y:
203
- * auto` in `primitives.css`), so the end of the list is the natural trigger.
204
- */
205
- const emit = defineEmits<{ (e: "load-more"): void }>();
206
-
207
- /** How close to the end counts as the end. About one row and a half. */
208
- const LOAD_MORE_SLACK_PX = 48;
209
-
210
- const singleMenu = ref<HTMLElement | null>(null);
211
- /* Scroll fires per pixel. This makes the ask happen once per ARRIVAL at the
212
- end, not once per event, and rearms when the list grows under the reader. */
213
- const askedAtBottom = ref(false);
214
-
215
- function onMenuScroll(event: Event) {
216
- const el = event.target as HTMLElement | null;
217
- if (!el || !props.hasMore || props.loadingMore) return;
218
- const near = el.scrollHeight - el.scrollTop - el.clientHeight <= LOAD_MORE_SLACK_PX;
219
- if (near && !askedAtBottom.value) emit("load-more");
220
- askedAtBottom.value = near;
221
- }
222
-
223
-
224
-
225
157
  const props = defineProps({
226
158
  label: { type: String, default: "" },
227
159
  /** Strings, or the `{ title, value }` shape `v-select` already takes. */
@@ -236,22 +168,6 @@ const props = defineProps({
236
168
  returnObject: { type: Boolean, default: false },
237
169
  clearable: { type: Boolean, default: false },
238
170
  placeholder: { type: String, default: "" },
239
- /**
240
- * A filter box at the top of the popover. Opt-in, so the 44 consumers that
241
- * do not ask for it render exactly the DOM they render today - a list short
242
- * enough to read does not want a search field in front of it.
243
- */
244
- searchable: { type: Boolean, default: false },
245
- /**
246
- * MORE OPTIONS EXIST THAN ARE LOADED - see the `load-more` emit.
247
- *
248
- * Opt-in, and single-select only for now. A caller that leaves these alone
249
- * behaves exactly as it did: no footer, no listener, no emit.
250
- */
251
- hasMore: { type: Boolean, default: false },
252
- /** A page is on its way; shows the footer and stops further asking. */
253
- loadingMore: { type: Boolean, default: false },
254
- searchPlaceholder: { type: String, default: "Search" },
255
171
  });
256
172
 
257
173
  const normalized = computed(() =>
@@ -262,56 +178,6 @@ const normalized = computed(() =>
262
178
  )
263
179
  );
264
180
 
265
- /* ---- search ---------------------------------------------------------- */
266
-
267
- const search = ref("");
268
- const singleOpen = ref(false);
269
- const singleSearchInput = ref<HTMLInputElement | null>(null);
270
-
271
- /* Case-insensitive substring over what the option READS AS, not its value:
272
- the title is the only part the user can see to type. */
273
- const visibleOptions = computed(() => {
274
- const term = search.value.trim().toLowerCase();
275
- if (!props.searchable || !term) return normalized.value;
276
- return normalized.value.filter((opt) =>
277
- String(opt.title ?? "").toLowerCase().includes(term)
278
- );
279
- });
280
-
281
- /*
282
- * A page that does not fill the menu leaves nothing to scroll, and the reader
283
- * would be stranded with no way to reach the rest. That is not hypothetical
284
- * here: a page of ten whose rows are mostly filtered out by the caller can draw
285
- * four options in a box built for eight. So whenever the list settles short of
286
- * its own container, the next page is asked for straight away.
287
- */
288
- watch(
289
- () => [visibleOptions.value.length, props.hasMore, props.loadingMore, singleOpen.value],
290
- async () => {
291
- if (!props.hasMore || props.loadingMore || !singleOpen.value) return;
292
- await nextTick();
293
- const el = singleMenu.value;
294
- if (el && el.scrollHeight <= el.clientHeight) emit("load-more");
295
- },
296
- { flush: "post" },
297
- );
298
-
299
- /* A stale term would hide the list the next time the popover opens, so it is
300
- dropped on every open - and the caret goes into the box, since opening a
301
- searchable select is almost always a prelude to typing. */
302
- watch(singleOpen, async (open) => {
303
- if (!props.searchable) return;
304
- search.value = "";
305
- if (!open) return;
306
- await nextTick();
307
- singleSearchInput.value?.focus();
308
- });
309
-
310
- function selectFirstMatch() {
311
- const [first] = visibleOptions.value;
312
- if (first) selectSingle(first);
313
- }
314
-
315
181
  /* A model entry is either the plain value or - under `return-object` - the
316
182
  source item, so everything compares on this one key. */
317
183
  const keyOf = (v: any) =>
@@ -339,11 +205,6 @@ const isSingleOn = (opt: any) =>
339
205
  function selectSingle(opt: any) {
340
206
  if (props.disabled) return;
341
207
  model.value = props.returnObject ? opt.raw : String(opt.value);
342
- // `close-on-content-click` has to be OFF while searching - it fires on the
343
- // click that puts the caret in the search box, so the popover would shut the
344
- // moment it was typed into. With it off, picking an option has to close the
345
- // popover by hand.
346
- if (props.searchable) singleOpen.value = false;
347
208
  }
348
209
 
349
210
  function clearSingle() {
@@ -10,7 +10,6 @@
10
10
  <v-tab value="general">General</v-tab>
11
11
  <v-tab value="residents">Residents/Tenants</v-tab>
12
12
  <v-tab value="vehicles">Vehicles</v-tab>
13
- <v-tab value="management">Management</v-tab>
14
13
  <v-tab value="others">Others</v-tab>
15
14
  </v-tabs>
16
15
  </v-toolbar>
@@ -171,11 +170,6 @@
171
170
  </TableMain>
172
171
  </template>
173
172
 
174
- <template v-else-if="tab === 'management'">
175
- <BuildingUnitManagement :unit-id="buildingUnit._id" :site-id="buildingUnit?.site?._id"
176
- :can-update="canUpdateUnit" />
177
- </template>
178
-
179
173
  <template v-else-if="tab === 'others'">
180
174
  <v-row>
181
175
  <!-- <v-col cols="12" md="6" class="mt-2">
@@ -23,7 +23,7 @@
23
23
  Close
24
24
  </v-btn>
25
25
 
26
- <v-menu v-if="canUpdate || canDelete || $slots.actions" contained>
26
+ <v-menu v-if="canUpdate || canDelete" contained>
27
27
  <template #activator="{ props }">
28
28
  <v-btn
29
29
  variant="flat"
@@ -42,16 +42,6 @@
42
42
  render-verified either. Only the row type and the destructive ink
43
43
  change. -->
44
44
  <v-list class="pa-0 update-more__list">
45
- <!--
46
- Screen-specific rows, above Edit and the destructive one.
47
-
48
- Additive: a screen that passes nothing gets the menu it always
49
- had, and `$slots.actions` is undefined unless a caller actually
50
- defines the slot - so the button does not appear over an empty
51
- list when a screen has neither permission nor extra rows.
52
- -->
53
- <slot name="actions" />
54
-
55
45
  <v-list-item v-if="canUpdate" @click="emit('edit')">
56
46
  <v-list-item-title>
57
47
  {{ editButtonLabel }}