@7365admin1/layer-common 4.97.1-staging.585 → 4.97.1-staging.586

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.
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <!-- Seven365 Super Admin only: everyone else never sees Manpower set-up. -->
3
+ <v-expansion-panel v-if="isStaff" data-test="manpower-site-switch">
4
+ <v-expansion-panel-title>
5
+ <v-icon class="mr-2">mdi-chart-bar</v-icon>
6
+ Manpower
7
+ </v-expansion-panel-title>
8
+ <v-expansion-panel-text>
9
+ <v-switch v-model="enabled" label="Show Manpower at this site" color="primary" hide-details
10
+ data-test="manpower-site-switch-toggle" />
11
+ <p class="text-caption text-medium-emphasis mt-1 mb-3">
12
+ Manpower (HRMLabs staff attendance) is for security agencies only. When on, the agency's managers see
13
+ Manpower in the menu and the guard app at this site. Only Seven365 can switch this on or off.
14
+ Now: <strong>{{ savedOn ? "On" : "Off" }}</strong>{{ saved ? "" : " (not set - default)" }}.
15
+ </p>
16
+ <v-btn class="screen-btn-primary" color="primary-button" variant="flat" text="Save"
17
+ :loading="saving" :disabled="!loaded" data-test="manpower-site-switch-save" @click="save" />
18
+ <Snackbar v-model="toast.show" :text="toast.message" :color="toast.color" />
19
+ </v-expansion-panel-text>
20
+ </v-expansion-panel>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ import useSiteFeatureSettings from "../composables/useSiteFeatureSettings";
25
+ import useConsoleTier from "../composables/useConsoleTier";
26
+
27
+ /**
28
+ * Site setting `metadata.manpower` (core site-feature-settings, owner
29
+ * 2026-10-21). Not set = as before: on only at the one site Manpower was
30
+ * pinned to (core `MANPOWER_LEGACY_SITE_ID`), off everywhere else. The server
31
+ * refuses a change by anyone but the Seven365 Super Admin (403) and enforces
32
+ * the switch on every Manpower route; this only draws the switch.
33
+ */
34
+ const LEGACY_SITE_ID = "6a4496f47521150c58977c68";
35
+
36
+ const props = defineProps({
37
+ siteId: { type: String, required: true },
38
+ saved: { type: Object as PropType<{ enabled?: boolean } | null>, default: null },
39
+ /** The site has been read; Save stays off until then. */
40
+ loaded: { type: Boolean, default: false },
41
+ });
42
+ const emit = defineEmits(["saved"]);
43
+
44
+ const { isStaff, load: loadTier } = useConsoleTier();
45
+ onMounted(() => loadTier());
46
+
47
+ const savedOn = computed(() =>
48
+ typeof props.saved?.enabled === "boolean" ? props.saved.enabled : props.siteId === LEGACY_SITE_ID,
49
+ );
50
+ const enabled = ref(false);
51
+ watch(savedOn, (v) => (enabled.value = v), { immediate: true });
52
+
53
+ const { saveSiteFeature } = useSiteFeatureSettings();
54
+ const saving = ref(false);
55
+ const toast = reactive({ show: false, message: "", color: "" });
56
+
57
+ async function save() {
58
+ if (!props.loaded || !isStaff.value) return;
59
+ saving.value = true;
60
+ try {
61
+ await saveSiteFeature(props.siteId, "manpower", { enabled: enabled.value });
62
+ Object.assign(toast, { show: true, message: "Saved.", color: "success" });
63
+ emit("saved");
64
+ } catch (e: any) {
65
+ Object.assign(toast, { show: true, message: e?.data?.message || "Could not save.", color: "error" });
66
+ } finally {
67
+ saving.value = false;
68
+ }
69
+ }
70
+ </script>
@@ -269,6 +269,9 @@
269
269
  </v-expansion-panel-text>
270
270
  </v-expansion-panel>
271
271
 
272
+ <ManpowerSiteSwitch v-if="showManpowerSwitch" :site-id="siteId"
273
+ :saved="(siteData as any)?.metadata?.manpower" :loaded="!!siteData" @saved="refreshSiteData" />
274
+
272
275
  <slot
273
276
  name="panels"
274
277
  :can-manage="canManageSiteSettings"
@@ -298,6 +301,8 @@ const props = defineProps({
298
301
  showResidentVisitors: { type: Boolean, default: false },
299
302
  /** Visitor registration, Passes & keys and Incident report emails: PM and Security only. */
300
303
  showSiteSwitches: { type: Boolean, default: false },
304
+ /** Manpower per-site switch (Seven365 Super Admin only): the Security host only. */
305
+ showManpowerSwitch: { type: Boolean, default: false },
301
306
  });
302
307
 
303
308
  const openPanels = ref([]); // default open first
@@ -17,6 +17,7 @@ export const SITE_FEATURE_KEYS = [
17
17
  "maStaffRegistration",
18
18
  "visitorPassSms",
19
19
  "robotSharedSpace",
20
+ "manpower",
20
21
  ] as const;
21
22
 
22
23
  export type TSiteFeatureKey = (typeof SITE_FEATURE_KEYS)[number];
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.97.1-staging.585",
5
+ "version": "4.97.1-staging.586",
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.",