@7365admin1/layer-common 4.46.0 → 4.48.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
+ ## 4.48.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c9871b2: Members list: the role chip shows the member's real role name, and a clear warning ("No role assigned - assign one", "<name> (deleted) - assign a new role", "Invalid role - assign a new role") when the server's roleState says the role is missing, deleted or another organisation's. Rows from an older server render as before.
8
+
9
+ ## 4.47.0
10
+
11
+ ### Minor Changes
12
+
13
+ - cde8389: `getVerifications` takes `origin`; the console Client List's Pending tab lists only invitations Seven365 sent.
14
+
3
15
  ## 4.46.0
4
16
 
5
17
  ### Minor Changes
@@ -1515,11 +1527,11 @@
1515
1527
  `utils/console-tier.ts` + `composables/useConsoleTier.ts` mirror the server's
1516
1528
  own rule from two endpoints the console already calls, unprojected:
1517
1529
 
1518
- GET /api/members/user/:user/app/admin the Seven365 staff membership
1519
- GET /api/roles/id/:role that membership's role document
1530
+ GET /api/members/user/:user/app/admin the Seven365 staff membership
1531
+ GET /api/roles/id/:role that membership's role document
1520
1532
 
1521
- owner = member.type === "admin" && role.type === "admin" && role.default === true
1522
- staff = member.type === "admin" && role.type === "admin"
1533
+ owner = member.type === "admin" && role.type === "admin" && role.default === true
1534
+ staff = member.type === "admin" && role.type === "admin"
1523
1535
 
1524
1536
  `role.default` is the marker because it is the only property of a platform
1525
1537
  staff role no API caller can set - `role.controller.ts` validates create and
@@ -636,6 +636,8 @@ async function fetchPending() {
636
636
  const res = await getVerifications({
637
637
  status: 'pending',
638
638
  type: 'user-invite',
639
+ // Only what Seven365 sent - never a client's own invitations (owner, 2026-09-25).
640
+ origin: 'seven365',
639
641
  page: page.value,
640
642
  search: search.value,
641
643
  email: search.value,
@@ -73,11 +73,19 @@
73
73
  <template #item.nature="{ item }">
74
74
  {{ replaceMatch(item.nature, "_", " ") }}
75
75
  </template>
76
- <!-- The role is a soft pill in the design, not a plain word. Same
77
- text, same column, same source field. -->
76
+ <!-- The role is a soft pill in the design, not a plain word. The
77
+ member's REAL role name; a deleted / other-organisation / missing
78
+ role says so instead of reading as a working grant
79
+ (memberRoleChip in utils/role.ts, server roleState). -->
78
80
  <template #item.roleName="{ item }">
79
- <StatusChip v-if="item.roleName" :dot="false" pill tone="info">
80
- {{ item.roleName }}
81
+ <StatusChip
82
+ v-if="memberRoleChip(item)"
83
+ :dot="false"
84
+ pill
85
+ :tone="memberRoleChip(item)?.tone"
86
+ data-test="member-role-chip"
87
+ >
88
+ {{ memberRoleChip(item)?.text }}
81
89
  </StatusChip>
82
90
  </template>
83
91
  <template #item.dateInvited="{ item }">
@@ -258,7 +266,7 @@
258
266
  </template>
259
267
 
260
268
  <script setup lang="ts">
261
- import { withCurrentRole } from "../utils/role";
269
+ import { memberRoleChip, withCurrentRole } from "../utils/role";
262
270
 
263
271
  const props = defineProps({
264
272
  /** The design's page title. Every app that mounts this screen calls it
@@ -9,6 +9,8 @@ export default function useVerification() {
9
9
  siteId = "",
10
10
  orgId = "",
11
11
  limit = 20,
12
+ // "seven365": only the invitations Seven365 sent (the console's lists).
13
+ origin = "",
12
14
  } = {}): Promise<{
13
15
  items: TMiniVerification[];
14
16
  pages: number;
@@ -16,7 +18,11 @@ export default function useVerification() {
16
18
  }> {
17
19
  return useNuxtApp().$api("/api/verifications", {
18
20
  method: "GET",
19
- query: { status, search, page, type, email, app, siteId, orgId, limit },
21
+ query: {
22
+ status, search, page, type, email, app, siteId, orgId, limit,
23
+ // Sent only when asked for: an older API refuses a key it does not know.
24
+ ...(origin && { origin }),
25
+ },
20
26
  });
21
27
  }
22
28
 
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.46.0",
5
+ "version": "4.48.0",
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.",
package/utils/role.ts CHANGED
@@ -26,3 +26,29 @@ export function withCurrentRole<T extends { _id?: unknown; name?: unknown }>(
26
26
  if (!currentId || list.some((r) => String(r?._id) === currentId)) return list;
27
27
  return [...list, { _id: currentId, name: currentName || currentId }];
28
28
  }
29
+
30
+ /**
31
+ * What the Members list's "Roles and Permission" chip says for one row.
32
+ *
33
+ * The server's `roleState` (core 2026-09-25) says whether `roleName` is a role
34
+ * the member can really use. A bare name for a deleted role, another
35
+ * organisation's role, or no role at all read as a working grant (owner report:
36
+ * a member showed "Security" and Assign Role could not fix it). Rows from an
37
+ * older server carry no `roleState` and render exactly as before.
38
+ */
39
+ export function memberRoleChip(item: {
40
+ roleName?: unknown;
41
+ roleState?: unknown;
42
+ }): { text: string; tone: "info" | "warn" } | null {
43
+ const name = typeof item?.roleName === "string" ? item.roleName : "";
44
+ switch (item?.roleState) {
45
+ case "missing":
46
+ return { text: "No role assigned - assign one", tone: "warn" };
47
+ case "deleted":
48
+ return { text: `${name || "Role"} (deleted) - assign a new role`, tone: "warn" };
49
+ case "other-org":
50
+ return { text: "Invalid role - assign a new role", tone: "warn" };
51
+ default:
52
+ return name ? { text: name, tone: "info" } : null;
53
+ }
54
+ }