@7365admin1/layer-common 4.0.3-staging.231 → 4.0.3-staging.233

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.
@@ -181,15 +181,20 @@
181
181
  </v-data-table>
182
182
  </AppCard>
183
183
 
184
- <!-- Create / Edit Dialog -->
184
+ <!--
185
+ Create / Edit Dialog. The form component renders its OWN `.screen-modal`
186
+ card, so it has to be the dialog's DIRECT child: Vuetify only makes
187
+ `.v-overlay__content > .v-card` a capped flex column. Wrapping it in a
188
+ second `v-card` handed that treatment to the wrapper and left the real
189
+ card a plain `overflow: hidden` block - it grew past the viewport and
190
+ clipped its own Cancel/Save footer, with no scrollbar to reach it.
191
+ -->
185
192
  <v-dialog v-model="showModal" max-width="600px" persistent>
186
- <v-card class="pa-4">
187
- <CreateSubscriptionPlan
188
- :initial-plan="editingPlan"
189
- @cancel="closeModal"
190
- @submit="handleSubmit"
191
- />
192
- </v-card>
193
+ <CreateSubscriptionPlan
194
+ :initial-plan="editingPlan"
195
+ @cancel="closeModal"
196
+ @submit="handleSubmit"
197
+ />
193
198
  </v-dialog>
194
199
 
195
200
  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
@@ -922,7 +922,7 @@ const hidQrValidityMinutes = computed(() => {
922
922
  return Number.isFinite(value) && value > 0 ? value : 60;
923
923
  });
924
924
 
925
- const hidQrReaderId = computed(() => String(hidQrCodePassConfig.value?.readerId || ""));
925
+ const hidQrConfiguredReaderId = computed(() => String(hidQrCodePassConfig.value?.readerId || ""));
926
926
  type HidQrReaderSummary = {
927
927
  _id: string;
928
928
  name?: string;
@@ -930,6 +930,9 @@ type HidQrReaderSummary = {
930
930
  portalName?: string;
931
931
  };
932
932
  const hidQrReader = ref<HidQrReaderSummary | null>(null);
933
+ const hidQrReaderId = computed(() => (
934
+ hidQrConfiguredReaderId.value || String(hidQrReader.value?._id || "")
935
+ ));
933
936
 
934
937
  const hidQrCodePassAllowed = computed(() => {
935
938
  return (
@@ -1541,26 +1544,38 @@ const {
1541
1544
  getSiteById(prop.site)
1542
1545
  );
1543
1546
 
1544
- // Has to sit BELOW `siteData`, not beside `hidQrReaderId` up at the HID block.
1545
- // `hidQrReaderId` reads `hidQrCodePassConfig`, which reads `siteData`, and Vue
1547
+ // Has to sit BELOW `siteData`, not beside `hidQrConfiguredReaderId` up at the HID block.
1548
+ // `hidQrConfiguredReaderId` reads `hidQrCodePassConfig`, which reads `siteData`, and Vue
1546
1549
  // runs a watcher's source getter the moment `watch()` is called - so declared
1547
1550
  // any earlier this throws `Cannot access 'siteData' before initialization` and
1548
1551
  // the whole form fails to mount.
1549
1552
  watch(
1550
- [hidQrReaderId, () => prop.site],
1551
- async ([readerId, site]) => {
1553
+ [hidQrConfiguredReaderId, () => prop.site],
1554
+ async ([configuredReaderId, site]) => {
1552
1555
  hidQrReader.value = null;
1553
- if (!readerId || !site) return;
1556
+ if (!site) return;
1554
1557
  try {
1555
1558
  const response = await getReaders({ site, page: 1, limit: 100 });
1556
1559
  const readers: unknown = response?.items ?? response?.data?.items ?? response?.data?.readers ?? [];
1557
- hidQrReader.value = Array.isArray(readers)
1558
- ? readers.find((reader: unknown): reader is HidQrReaderSummary => (
1560
+ const availableReaders = Array.isArray(readers)
1561
+ ? readers.filter((reader: unknown): reader is HidQrReaderSummary => (
1559
1562
  typeof reader === "object"
1560
1563
  && reader !== null
1561
- && String((reader as Record<string, unknown>)._id || "") === readerId
1562
- )) || null
1564
+ && Boolean(String((reader as Record<string, unknown>)._id || ""))
1565
+ ))
1566
+ : [];
1567
+ const configuredReader = configuredReaderId
1568
+ ? availableReaders.find((reader) => reader._id === configuredReaderId) || null
1563
1569
  : null;
1570
+ const portalReadyReaders = availableReaders.filter((reader) => (
1571
+ Boolean(reader.portalId && reader.portalName)
1572
+ ));
1573
+ hidQrReader.value = configuredReader
1574
+ // Preserve an explicit choice. Only infer a reader for existing sites
1575
+ // when exactly one reader with a portal is available.
1576
+ || (!configuredReaderId && portalReadyReaders.length === 1
1577
+ ? portalReadyReaders[0]
1578
+ : null);
1564
1579
  } catch {
1565
1580
  hidQrReader.value = null;
1566
1581
  }
@@ -270,6 +270,7 @@ export default function useHidAmico() {
270
270
  search?: string;
271
271
  status?: "mapped" | "unmapped" | "";
272
272
  includeVisitors?: boolean;
273
+ userType?: "all" | "user" | "visitor";
273
274
  } = {}) {
274
275
  return useNuxtApp().$api<HidCollectionResponse>(`${basePath}/readers/${readerId}/users`, {
275
276
  method: "GET",
@@ -29,13 +29,6 @@ export default function useHidNavigation() {
29
29
  params: { org, site },
30
30
  },
31
31
  },
32
- {
33
- title: "HID User Mapping",
34
- route: {
35
- name: "org-site-access-mgmt-hid-user-mapping",
36
- params: { org, site },
37
- },
38
- },
39
32
  {
40
33
  title: "HID Cards",
41
34
  route: {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "4.0.3-staging.231",
5
+ "version": "4.0.3-staging.233",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",