@7365admin1/layer-common 4.43.0 → 4.43.1

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,12 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 4.43.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 64e84bb: Service Providers screen: extracted the service-type code-to-label lookup (the one behind "security_agency" showing as "Security") into a tested pure function, with unit tests covering every known service type code.
8
+ - 238f9be: Service Providers screen: the TYPE column still showed the raw code (e.g. "security_agency" instead of "Security") for every row, because the API's `nature` field is not free text - it mirrors the same raw code as `type` - and the label lookup treated any truthy `nature` as an override. Only treat `nature` as free text when it is not itself a known service type code.
9
+
3
10
  ## 4.43.0
4
11
 
5
12
  ### Minor Changes
@@ -1489,11 +1496,11 @@
1489
1496
  `utils/console-tier.ts` + `composables/useConsoleTier.ts` mirror the server's
1490
1497
  own rule from two endpoints the console already calls, unprojected:
1491
1498
 
1492
- GET /api/members/user/:user/app/admin the Seven365 staff membership
1493
- GET /api/roles/id/:role that membership's role document
1499
+ GET /api/members/user/:user/app/admin the Seven365 staff membership
1500
+ GET /api/roles/id/:role that membership's role document
1494
1501
 
1495
- owner = member.type === "admin" && role.type === "admin" && role.default === true
1496
- staff = member.type === "admin" && role.type === "admin"
1502
+ owner = member.type === "admin" && role.type === "admin" && role.default === true
1503
+ staff = member.type === "admin" && role.type === "admin"
1497
1504
 
1498
1505
  `role.default` is the marker because it is the only property of a platform
1499
1506
  staff role no API caller can set - `role.controller.ts` validates create and
@@ -720,6 +720,7 @@ import {
720
720
  sentInvitedLine,
721
721
  sentStatusLine,
722
722
  spDay,
723
+ spTypeLabel,
723
724
  } from "../utils/sp-inviter-row";
724
725
 
725
726
  type ListTab = "active" | "pending" | "inactive";
@@ -1237,17 +1238,7 @@ function rowActionLabel(row: TableRow) {
1237
1238
  }
1238
1239
 
1239
1240
  function typeDisplay(type: string, nature?: string) {
1240
- if (nature && String(nature).trim()) return String(nature);
1241
- // useLocal returns a plain array; reading `.value` off it was always
1242
- // undefined, so every row fell through to the raw stored slug
1243
- // ("security_agency") instead of "Security".
1244
- const source = natureOfBusinessV3 as any;
1245
- const list = (Array.isArray(source) ? source : source?.value) as Array<{
1246
- title?: string;
1247
- value?: string;
1248
- }>;
1249
- const hit = list?.find((x) => x.value === type);
1250
- return hit?.title ?? type ?? "-";
1241
+ return spTypeLabel(type, nature, natureOfBusinessV3);
1251
1242
  }
1252
1243
 
1253
1244
  const providerDialog = ref(false);
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.43.0",
5
+ "version": "4.43.1",
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.",
@@ -29,6 +29,34 @@ const ANSWERED: Record<string, string> = {
29
29
  expired: "Expired",
30
30
  };
31
31
 
32
+ type TNatureOption = { title?: string; value?: string };
33
+
34
+ /**
35
+ * The service type in words: the org's free-text nature if it gave one,
36
+ * else the label from the nature-of-business list, else the raw stored code
37
+ * ("security_agency") as a last resort. `useLocal` can hand back a plain
38
+ * array or a ref-like `{ value }` wrapper - read whichever shape was passed.
39
+ *
40
+ * `nature` is NOT always free text: both `_getServiceProviders` and the
41
+ * `customer.sites`-derived `getServiceProvidersForSite` aggregations in
42
+ * @7365admin1/core set it to `organization.nature`, the SAME raw code `type`
43
+ * carries ("security_agency") - not a human-typed description. Treating it as
44
+ * free text made the raw code win over the label lookup for every row, since
45
+ * `nature` is truthy whenever it is set at all. Only trust it as an override
46
+ * when it is NOT itself one of the known codes.
47
+ */
48
+ export function spTypeLabel(type: string, nature: string | undefined, source: unknown): string {
49
+ const list = (Array.isArray(source) ? source : (source as any)?.value) as
50
+ | TNatureOption[]
51
+ | undefined;
52
+ const codeMatch = (value?: string) => list?.find((x) => x.value === value);
53
+
54
+ if (nature && String(nature).trim() && !codeMatch(nature)) return String(nature);
55
+
56
+ const hit = codeMatch(type) ?? codeMatch(nature);
57
+ return hit?.title ?? type ?? nature ?? "-";
58
+ }
59
+
32
60
  export function spDay(value?: string | null): string {
33
61
  if (!value) return "";
34
62
  const d = new Date(value);