@feedmepos/mf-hrm-portal 2.1.1-dev.4 → 2.1.1-dev.5

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 (71) hide show
  1. package/dist/ApprovalCodeList-CXJyMKEg.js +757 -0
  2. package/dist/AuditLogList-CXUkbDyT.js +1145 -0
  3. package/dist/CollapsibleWrapper.vue_vue_type_script_setup_true_lang-BLJlmPVa.js +58 -0
  4. package/dist/EmployeeList-BSfUFTcN.js +899 -0
  5. package/dist/{GrantUserList-DoyxknJZ.js → GrantUserList-DKP4MBQM.js} +137 -140
  6. package/dist/{Main-BGONIxo8.js → Main-CblWfQk_.js} +3 -3
  7. package/dist/{Main-B5BKGpLg.js → Main-CyCfz4ka.js} +1029 -1033
  8. package/dist/{Main-DQj4xtkB.js → Main-Cz1pfe2k.js} +7 -7
  9. package/dist/PermissionSetList-BwyblSeE.js +357 -0
  10. package/dist/PortalPermissionEditor.vue_vue_type_script_setup_true_lang-BJ-PZ2Nv.js +3458 -0
  11. package/dist/{PortalUserSearcher.vue_vue_type_style_index_0_scoped_827dfd60_lang-DVVSBIx2.js → PortalUserSearcher.vue_vue_type_style_index_0_scoped_a439fdd8_lang-BJp9hEfv.js} +0 -1
  12. package/dist/ResponsiveFabButton.vue_vue_type_script_setup_true_lang-Cn-3MRBO.js +38 -0
  13. package/dist/RoleList-CXYgCmHp.js +567 -0
  14. package/dist/TeamMemberList-CnLbqaPS.js +1131 -0
  15. package/dist/{TimesheetList-DwIcsOM-.js → TimesheetList-s_bP5OGA.js} +112 -118
  16. package/dist/{TimesheetList.vue_vue_type_style_index_0_scoped_2c7a177a_lang-B9qlQ6KG.js → TimesheetList.vue_vue_type_style_index_0_scoped_91afda4e_lang-BCLv-2Re.js} +2 -2
  17. package/dist/{app-BZwE2coe.js → app-BP0oihBR.js} +2359 -5361
  18. package/dist/app.js +1 -1
  19. package/dist/{dayjs.min-BXBPls4m.js → dayjs.min-BTSZLci9.js} +1 -1
  20. package/dist/{employee-CJTbs1f7.js → employee-BPv1j6T4.js} +3 -3
  21. package/dist/{iteration-BCbIbdHR.js → iteration-BNA1cEos.js} +1 -1
  22. package/dist/{lodash-CUIS1iIz.js → lodash-DKG9IyB-.js} +1 -1
  23. package/dist/{role-CzXchcSS.js → role-BS3LFO8u.js} +1 -1
  24. package/dist/rule-DaSLVZWm.js +996 -0
  25. package/dist/src/api/audit-log/index.d.ts +0 -6
  26. package/dist/src/components/CheckboxInput.vue.d.ts +1 -1
  27. package/dist/src/components/button/ResponsiveFabButton.vue.d.ts +1 -7
  28. package/dist/src/components/table/TableEmptyState.vue.d.ts +15 -7
  29. package/dist/src/composables/useBasePermission.d.ts +1 -2
  30. package/dist/src/helpers/permission-set.d.ts +4 -8
  31. package/dist/src/helpers/rule.d.ts +1 -2
  32. package/dist/src/stores/approval-code.d.ts +6 -6
  33. package/dist/src/stores/permission-set.d.ts +3 -12
  34. package/dist/src/types/approval-code.d.ts +51 -26
  35. package/dist/src/types/audit-log.d.ts +1 -1
  36. package/dist/src/views/approval-code/ApprovalCodeList.vue.d.ts +1 -1
  37. package/dist/src/views/approval-code/locales/index.d.ts +4 -12
  38. package/dist/src/views/audit-log/locales/index.d.ts +0 -296
  39. package/dist/src/views/hr/employee/EmployeeList.vue.d.ts +0 -1
  40. package/dist/src/views/team/components/BasePermission.vue.d.ts +0 -13
  41. package/dist/src/views/team/locales/index.d.ts +0 -80
  42. package/dist/style.css +1 -1
  43. package/dist/tsconfig.app.tsbuildinfo +1 -1
  44. package/dist/useDebounce-CWb5QR9G.js +28 -0
  45. package/dist/{useReportPermissions-Q-xLwz5N.js → useReportPermissions-J3-DjopO.js} +3 -3
  46. package/package.json +2 -2
  47. package/dist/ApprovalCodeList-B0PLZwav.js +0 -758
  48. package/dist/AuditLogList-CRXwPImZ.js +0 -1611
  49. package/dist/ConditionFormHost.vue_vue_type_script_setup_true_lang-zJwkM_Xb.js +0 -387
  50. package/dist/EmployeeList-DN2pnXcS.js +0 -884
  51. package/dist/PermissionSetList-4uIU9FvN.js +0 -393
  52. package/dist/PortalPermissionEditor.vue_vue_type_script_setup_true_lang-D0luaKDb.js +0 -4122
  53. package/dist/ResponsiveFabButton.vue_vue_type_script_setup_true_lang-QrqYEy8i.js +0 -42
  54. package/dist/RoleList-Bj5Y5jd_.js +0 -685
  55. package/dist/Skeleton.vue_vue_type_script_setup_true_lang-B4PxNMwq.js +0 -16
  56. package/dist/TableEmptyState.vue_vue_type_script_setup_true_lang-IfAZmWr0.js +0 -37
  57. package/dist/TeamMemberList-Byjlca2Y.js +0 -1216
  58. package/dist/rule-BO6xj2Xa.js +0 -1058
  59. package/dist/src/composables/useConditionDraft.d.ts +0 -40
  60. package/dist/src/composables/useCoverConditionOverride.d.ts +0 -61
  61. package/dist/src/helpers/business-timezone.d.ts +0 -22
  62. package/dist/src/helpers/filter.d.ts +0 -15
  63. package/dist/src/helpers/permission-reconcile.d.ts +0 -15
  64. package/dist/src/helpers/permission-reconcile.test.d.ts +0 -1
  65. package/dist/src/views/audit-log/event-line.d.ts +0 -13
  66. package/dist/src/views/audit-log/snapshot-diff.d.ts +0 -11
  67. package/dist/src/views/team/condition-builders/ConditionFormHost.vue.d.ts +0 -22
  68. package/dist/src/views/team/condition-builders/ConditionFormRenderer.vue.d.ts +0 -23
  69. package/dist/src/views/team/condition-builders/component-map.d.ts +0 -4
  70. package/dist/src/views/team/condition-builders/condition-form-dedupe.d.ts +0 -23
  71. package/dist/useDebounce-B8ZPVS5C.js +0 -15
@@ -9,9 +9,6 @@ declare const AuditLogAPI: {
9
9
  actions?: string[];
10
10
  outcomes?: string[];
11
11
  feedmeAdminActors?: boolean;
12
- search?: string;
13
- searchUserIds?: string[];
14
- searchSubjects?: string[];
15
12
  }): Promise<number>;
16
13
  read(params?: {
17
14
  limit?: number;
@@ -24,9 +21,6 @@ declare const AuditLogAPI: {
24
21
  actions?: string[];
25
22
  outcomes?: string[];
26
23
  feedmeAdminActors?: boolean;
27
- search?: string;
28
- searchUserIds?: string[];
29
- searchSubjects?: string[];
30
24
  }): Promise<AuditLogEntry[]>;
31
25
  /**
32
26
  * FeedMe-admin options for the User filter. `actors` is the named admin list (internal
@@ -141,8 +141,8 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
141
141
  }>> & Readonly<{
142
142
  "onUpdate:model-value"?: ((...args: any[]) => any) | undefined;
143
143
  }>, {
144
- min: number;
145
144
  max: number;
145
+ min: number;
146
146
  disable: boolean;
147
147
  showAllToggle: string | boolean;
148
148
  includeDisabledOptionsWhenSelectAll: boolean;
@@ -1,9 +1,3 @@
1
1
  import { type FmButtonProps } from '@feedmepos/ui-library';
2
- interface Props extends FmButtonProps {
3
- /** Whether the page has a fixed bottom footer (e.g. a pagination bar) the mobile FAB should raise above. */
4
- hasFooterBelow?: boolean;
5
- }
6
- declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
7
- hasFooterBelow: boolean;
8
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
2
+ declare const _default: import("vue").DefineComponent<FmButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FmButtonProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
3
  export default _default;
@@ -5,22 +5,30 @@ interface Props {
5
5
  isEmpty: boolean;
6
6
  isLoading?: boolean;
7
7
  /**
8
- * At what width do the column titles disappear? Below/at this breakpoint the message is
9
- * styled as a standalone bordered card instead of blending flat under the table header. Must
10
- * mirror the wrapped FmTable's own `shrink-at` prop (both default to "sm"); pass `false` if
11
- * the table never collapses.
8
+ * At what width do the column titles disappear? The table's column labels are gone at/below
9
+ * this breakpoint, so the empty state should move outside instead of overlaying the table
10
+ * body. Must mirror the wrapped FmTable's own `shrink-at` prop (both default to "sm"); pass
11
+ * `false` if the table never collapses.
12
12
  */
13
13
  collapseAt?: Breakpoints | false;
14
+ /**
15
+ * At what width do we hide the table completely because there's a separate mobile view taking
16
+ * over? For callers that render their own alternate view (e.g. a mobile FmList) at/below this
17
+ * breakpoint. Pass `false` if the table has no alternate view and should stay visible at every
18
+ * breakpoint.
19
+ */
20
+ hideTableBelow?: Breakpoints | false;
14
21
  }
15
- declare var __VLS_1: {
16
- isEmpty: boolean;
22
+ declare var __VLS_5: {
23
+ isTableCollapsed: boolean;
17
24
  };
18
25
  type __VLS_Slots = {} & {
19
- default?: (props: typeof __VLS_1) => any;
26
+ default?: (props: typeof __VLS_5) => any;
20
27
  };
21
28
  declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
22
29
  isLoading: boolean;
23
30
  collapseAt: Breakpoints | false;
31
+ hideTableBelow: Breakpoints | false;
24
32
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
33
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
26
34
  export default _default;
@@ -7,7 +7,6 @@ export type CategoryGroup = {
7
7
  options: {
8
8
  label: string;
9
9
  value: string;
10
- optionKey: string;
11
10
  }[];
12
11
  selectedSubjects: string[];
13
12
  isMultiAction: boolean;
@@ -26,7 +25,7 @@ export declare function useBasePermission(modelValue: Readonly<Ref<FdoPermission
26
25
  toggleAllManage: (group: CategoryGroup) => void;
27
26
  isManageChecked: (group: CategoryGroup, subject: string) => boolean;
28
27
  isManageIndeterminate: (group: CategoryGroup, subject: string) => boolean;
29
- toggleManage: (group: CategoryGroup, subject: string, checked: boolean) => void;
28
+ toggleManage: (_group: CategoryGroup, subject: string, checked: boolean) => void;
30
29
  hasNonManageActions: (group: CategoryGroup, subject: string) => boolean;
31
30
  isActionChecked: (group: CategoryGroup, subject: string, action: string) => boolean;
32
31
  isRowFullyCoveredByCover: (group: CategoryGroup, subject: string) => boolean;
@@ -71,14 +71,10 @@ export declare function filterStalePermissions(permissions: FdoPermissionRule[],
71
71
  * `allCustomReports` positive grant, preventing redundant data from being saved.
72
72
  *
73
73
  * - If the cover rule has `manage` selected → every individual rule in that bucket is
74
- * fully covered and dropped entirely only when the cover condition also covers the
75
- * individual rule.
76
- * - Otherwise, only covered non-manage actions are stripped from individual rules when
77
- * the cover condition also covers the individual rule.
78
- * `manage` is a real CASL wildcard grant that implies every action, not merely a
79
- * shorthand for "all non-manage actions selected" — a rule carrying `manage` is
80
- * pushed through UNCHANGED (a cover lacking `manage` cannot cover it). Stripping its
81
- * constituent actions and then dropping `manage` would destroy the user's grant.
74
+ * fully covered and dropped entirely.
75
+ * - Otherwise, only covered non-manage actions are stripped from individual rules.
76
+ * If `manage` was present and any non-manage action is stripped (breaking the
77
+ * "manage = all non-manage selected" invariant), `manage` is also stripped.
82
78
  * Rules that end up with no remaining actions are dropped.
83
79
  *
84
80
  * Inverted rules and the cover subjects themselves pass through untouched.
@@ -20,8 +20,7 @@ export declare function getMaxDiscount(rules: FdoPermissionRule[]): number;
20
20
  export declare function getManagableRestaurantIds(rules: (FdoPermissionRule | RawRule)[]): string[] | null;
21
21
  export declare function hasAdminRule(rules: FdoPermissionRule[]): boolean;
22
22
  export declare function usableRoleIds(rules: (FdoPermissionRule | RawRule)[]): string[] | null;
23
- export declare function extractReportExtraCondition(rule: FdoPermissionRule): Record<string, unknown> | undefined;
24
- export declare function fromValue(values: string[], maxDiscountPercentage: number, periodConditions?: Map<string, Record<string, unknown>>): {
23
+ export declare function fromValue(values: string[], maxDiscountPercentage: number): {
25
24
  subject: string;
26
25
  actions: ("delete" | "create" | "update" | "read" | "manage")[];
27
26
  conditions: object;
@@ -11,7 +11,7 @@ export declare const useApprovalCodeStore: import("pinia").StoreDefinition<"appr
11
11
  key: import("@/types/approval-code").ApprovalCodePermission;
12
12
  subject: string;
13
13
  actions: string[];
14
- conditions?: Record<string, unknown> | undefined;
14
+ conditions?: (Record<string, unknown> | null) | undefined;
15
15
  }[];
16
16
  status: "active" | "used" | "revoked";
17
17
  usedAt?: string | undefined;
@@ -31,7 +31,7 @@ export declare const useApprovalCodeStore: import("pinia").StoreDefinition<"appr
31
31
  key: import("@/types/approval-code").ApprovalCodePermission;
32
32
  subject: string;
33
33
  actions: string[];
34
- conditions?: Record<string, unknown> | undefined;
34
+ conditions?: (Record<string, unknown> | null) | undefined;
35
35
  }[];
36
36
  status: "active" | "used" | "revoked";
37
37
  usedAt?: string | undefined;
@@ -57,7 +57,7 @@ export declare const useApprovalCodeStore: import("pinia").StoreDefinition<"appr
57
57
  key: import("@/types/approval-code").ApprovalCodePermission;
58
58
  subject: string;
59
59
  actions: string[];
60
- conditions?: Record<string, unknown> | undefined;
60
+ conditions?: (Record<string, unknown> | null) | undefined;
61
61
  }[];
62
62
  status: "active" | "used" | "revoked";
63
63
  usedAt?: string | undefined;
@@ -77,7 +77,7 @@ export declare const useApprovalCodeStore: import("pinia").StoreDefinition<"appr
77
77
  key: import("@/types/approval-code").ApprovalCodePermission;
78
78
  subject: string;
79
79
  actions: string[];
80
- conditions?: Record<string, unknown> | undefined;
80
+ conditions?: (Record<string, unknown> | null) | undefined;
81
81
  }[];
82
82
  status: "active" | "used" | "revoked";
83
83
  usedAt?: string | undefined;
@@ -103,7 +103,7 @@ export declare const useApprovalCodeStore: import("pinia").StoreDefinition<"appr
103
103
  key: import("@/types/approval-code").ApprovalCodePermission;
104
104
  subject: string;
105
105
  actions: string[];
106
- conditions?: Record<string, unknown> | undefined;
106
+ conditions?: (Record<string, unknown> | null) | undefined;
107
107
  }[];
108
108
  status: "active" | "used" | "revoked";
109
109
  usedAt?: string | undefined;
@@ -123,7 +123,7 @@ export declare const useApprovalCodeStore: import("pinia").StoreDefinition<"appr
123
123
  key: import("@/types/approval-code").ApprovalCodePermission;
124
124
  subject: string;
125
125
  actions: string[];
126
- conditions?: Record<string, unknown> | undefined;
126
+ conditions?: (Record<string, unknown> | null) | undefined;
127
127
  }[];
128
128
  status: "active" | "used" | "revoked";
129
129
  usedAt?: string | undefined;
@@ -1,6 +1,5 @@
1
1
  import type { IFdtoPermissionSet, IFdtoCreatePermissionSetReq, IFdtoUpdatePermissionSetReq } from '@/types/permission-set';
2
2
  export declare const usePermissionSetStore: () => {
3
- isLoading: import("vue").Ref<boolean, boolean>;
4
3
  permissionSets: import("vue").Ref<{
5
4
  id: string;
6
5
  permissions: {
@@ -31,7 +30,6 @@ export declare const usePermissionSetStore: () => {
31
30
  name: string;
32
31
  }[]>;
33
32
  $state: {
34
- isLoading: boolean;
35
33
  permissionSets: {
36
34
  id: string;
37
35
  permissions: {
@@ -77,14 +75,12 @@ export declare const usePermissionSetStore: () => {
77
75
  businessId: string;
78
76
  name: string;
79
77
  }[]>;
80
- isLoading: import("vue").Ref<boolean, boolean>;
81
78
  readPermissionSets: () => Promise<void>;
82
79
  createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
83
80
  updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
84
81
  deletePermissionSet: (id: string) => Promise<void>;
85
- }, "isLoading" | "permissionSets">>;
82
+ }, "permissionSets">>;
86
83
  $patch(partialState: import("pinia")._DeepPartial<{
87
- isLoading: boolean;
88
84
  permissionSets: {
89
85
  id: string;
90
86
  permissions: {
@@ -102,7 +98,6 @@ export declare const usePermissionSetStore: () => {
102
98
  }[];
103
99
  }>): void;
104
100
  $patch<F extends (state: {
105
- isLoading: boolean;
106
101
  permissionSets: {
107
102
  id: string;
108
103
  permissions: {
@@ -150,12 +145,11 @@ export declare const usePermissionSetStore: () => {
150
145
  businessId: string;
151
146
  name: string;
152
147
  }[]>;
153
- isLoading: import("vue").Ref<boolean, boolean>;
154
148
  readPermissionSets: () => Promise<void>;
155
149
  createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
156
150
  updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
157
151
  deletePermissionSet: (id: string) => Promise<void>;
158
- }, "isLoading" | "permissionSets">>, options?: {
152
+ }, "permissionSets">>, options?: {
159
153
  detached?: boolean;
160
154
  } & import("vue").WatchOptions): () => void;
161
155
  $onAction(callback: import("pinia").StoreOnActionListener<"permissionSet", Pick<{
@@ -188,12 +182,11 @@ export declare const usePermissionSetStore: () => {
188
182
  businessId: string;
189
183
  name: string;
190
184
  }[]>;
191
- isLoading: import("vue").Ref<boolean, boolean>;
192
185
  readPermissionSets: () => Promise<void>;
193
186
  createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
194
187
  updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
195
188
  deletePermissionSet: (id: string) => Promise<void>;
196
- }, "isLoading" | "permissionSets">, Pick<{
189
+ }, "permissionSets">, Pick<{
197
190
  permissionSets: import("vue").Ref<{
198
191
  id: string;
199
192
  permissions: {
@@ -223,7 +216,6 @@ export declare const usePermissionSetStore: () => {
223
216
  businessId: string;
224
217
  name: string;
225
218
  }[]>;
226
- isLoading: import("vue").Ref<boolean, boolean>;
227
219
  readPermissionSets: () => Promise<void>;
228
220
  createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
229
221
  updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
@@ -258,7 +250,6 @@ export declare const usePermissionSetStore: () => {
258
250
  businessId: string;
259
251
  name: string;
260
252
  }[]>;
261
- isLoading: import("vue").Ref<boolean, boolean>;
262
253
  readPermissionSets: () => Promise<void>;
263
254
  createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
264
255
  updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
@@ -1,37 +1,49 @@
1
- export declare const APPROVAL_CODE_PERMISSIONS: readonly ["void", "refund", "discount", "changePrice", "claimDeposit", "payment", "resend", "changePaymentType", "openDrawer", "openCounter", "closeCounter", "printReceipt"];
1
+ export declare const APPROVAL_CODE_PERMISSIONS: readonly ["void", "refund", "discount", "changePrice", "claimDeposit", "payment", "resend", "changePaymentType", "openDrawer", "counter"];
2
2
  export type ApprovalCodePermission = (typeof APPROVAL_CODE_PERMISSIONS)[number];
3
3
  /**
4
4
  * A single CASL-shaped rule keyed by the approval-code action it grants, as
5
5
  * stored/returned by the backend. Mirrors `FdoApprovalCodeRule` from
6
- * `apps/hrm-backend/src/grant-user/grant-user.entity.ts`.
6
+ * `apps/hrm-backend/src/grant-user/grant-user.entity.ts`. `conditions` is
7
+ * `null` (not just absent) for keys whose full-POS counterpart carries no
8
+ * conditions at all (see `APPROVAL_CODE_RULE_TEMPLATES`).
7
9
  */
8
10
  export interface IFdtoApprovalCodeRule {
9
11
  key: ApprovalCodePermission;
10
12
  subject: string;
11
13
  actions: string[];
12
- conditions?: Record<string, unknown>;
14
+ conditions?: Record<string, unknown> | null;
13
15
  }
14
16
  /**
15
17
  * The rule template (subject/actions/conditions, minus `key`) for every
16
18
  * approval-code permission the portal can grant. The portal is now the
17
19
  * owner of these shapes (KDI-4982 Task A2) — the backend only validates the
18
20
  * shape of whatever rule it receives, it no longer composes rules itself.
19
- * These values were copied verbatim from the backend's server-side
20
- * key-to-rule manifest before it was deleted; they must keep matching
21
- * `FdoApprovalCodeRule`'s shape validation in
22
- * `apps/hrm-backend/src/grant-user/grant-user.entity.ts`.
21
+ * These shapes are not arbitrary: they mirror `FullPosPermissions`
22
+ * (`packages/permission/src/common/full-pos-permissions.ts`) exactly, entry
23
+ * for entry, so a code granting one of these keys evaluates identically to
24
+ * the corresponding rule a full-POS-permission staff member already has.
25
+ * That's why `refund`/`openDrawer`/`counter` carry `conditions: null` — full
26
+ * POS has no `operation` condition on those subjects — and why `discount`
27
+ * always carries an `adjustment` condition (full POS's unbounded discount
28
+ * rule is `adjustment: { $lte: 1 }`, i.e. "up to 100%", not "no adjustment
29
+ * condition at all"). `counter` is a single key (not separate open/close
30
+ * keys) because POS guards both opening and closing a counter with the same
31
+ * `counterRecord`/`manage` permission — two identical rules would just be
32
+ * redundant.
23
33
  */
24
34
  export declare const APPROVAL_CODE_RULE_TEMPLATES: Record<ApprovalCodePermission, {
25
35
  subject: string;
26
36
  actions: string[];
27
- conditions: Record<string, unknown>;
37
+ conditions: Record<string, unknown> | null;
28
38
  }>;
29
39
  /**
30
40
  * Compose the full CASL-shaped rule for `key`, ready to send to the backend
31
- * as-is. Only `discount` honors `params.maxPercentage`, appending it as an
32
- * `adjustment: { $lte: maxPercentage / 100 } }` condition — every other key
33
- * ignores `params` if passed, matching the deleted backend manifest's
34
- * `buildRule` behavior.
41
+ * as-is, saved shape-identical to the corresponding `FullPosPermissions`
42
+ * entry. Keys whose template has `conditions: null` always return `null` —
43
+ * there's nothing to clone. Only `discount` honors `params.maxPercentage`,
44
+ * setting the `adjustment.$lte` fraction (defaulting to `1`, i.e. no
45
+ * effective ceiling, matching full POS's unbounded discount rule) — every
46
+ * other object-conditions key ignores `params` if passed.
35
47
  */
36
48
  export declare function buildApprovalCodeRule(key: ApprovalCodePermission, params?: {
37
49
  maxPercentage?: number;
@@ -61,7 +73,11 @@ export interface IFdtoCreateApprovalCodeReq {
61
73
  /**
62
74
  * Read the discount ceiling back out of a rule's `conditions.adjustment.$lte`
63
75
  * fraction (0-1) as a whole percentage (1-100). Returns `undefined` when the
64
- * rule has no adjustment ceiling.
76
+ * rule has no adjustment ceiling, when `conditions` is `null` (full-POS-style
77
+ * null-condition rules never carry an adjustment), or when the ceiling is
78
+ * 100% — `$lte: 1` is the unbounded/default form (see
79
+ * `APPROVAL_CODE_RULE_TEMPLATES.discount`), so showing "≤100%" would be
80
+ * meaningless noise on every plain discount grant.
65
81
  */
66
82
  export declare function getRuleAdjustmentCeilingPercentage(rule: IFdtoApprovalCodeRule): number | undefined;
67
83
  /**
@@ -71,12 +87,17 @@ export declare function getRuleAdjustmentCeilingPercentage(rule: IFdtoApprovalCo
71
87
  */
72
88
  export declare function formatPermissionLabels(permissions: IFdtoApprovalCodeRule[], translate: (key: string) => string): string[];
73
89
  /**
74
- * Clipboard text for sharing a code — passcode plus its actions and
75
- * restaurant (e.g. "Code 3843 · Refund · Gulu-gulu Main") so the recipient
76
- * can tell what the code unlocks and where without opening the portal.
90
+ * The shared context of a code (or batch of codes): who it's named for, what
91
+ * it unlocks, and where — e.g. "Cashier 1 · Refund · Gulu-gulu Main".
77
92
  * Missing parts are skipped rather than leaving dangling separators.
78
93
  */
79
- export declare function buildCodeClipboardText(code: Pick<IFdtoApprovalCode, 'passcode' | 'permissions'>, restaurantName: string | undefined, translate: (key: string) => string): string;
94
+ export declare function buildCodeContextLine(code: Pick<IFdtoApprovalCode, 'name' | 'permissions'>, restaurantName: string | undefined, translate: (key: string) => string): string;
95
+ /**
96
+ * Clipboard text for sharing a single code — the context line with the
97
+ * passcode appended (e.g. "Cashier 1 · Refund · Gulu-gulu Main · Code 3843"),
98
+ * matching the batch format's context-first ordering.
99
+ */
100
+ export declare function buildCodeClipboardText(code: Pick<IFdtoApprovalCode, 'name' | 'passcode' | 'permissions'>, restaurantName: string | undefined, translate: (key: string) => string): string;
80
101
  /**
81
102
  * Validate the optional discount max-percentage input. Undefined, empty, or
82
103
  * whitespace-only means "no ceiling" and is valid; otherwise the value must
@@ -91,18 +112,22 @@ export declare function validateMaxPercentage(value: number | string | undefined
91
112
  export declare function resolveMaxPercentage(value: number | string | undefined): number | undefined;
92
113
  /**
93
114
  * A selectable action option in the create form / list filter (KDI-4982 UI
94
- * redesign). The 9 options mirror the POS v7 passcode prompts exactly:
115
+ * redesign). The 8 options mirror the POS v7 passcode prompts exactly:
95
116
  * `claimDeposit` and `payment` are not offered (neither has a passcode prompt
96
- * on POS v7), and open/close counter share one option because POS guards both
97
- * with the same `counterRecord` permission. `changePrice` is offered as
98
- * "Input Custom Price" — POS prompts for a passcode when a custom price is
99
- * keyed in. The 12-key `APPROVAL_CODE_PERMISSIONS` enum is untouched — stored
100
- * rules and the wire format still use the full key set, so legacy codes keep
101
- * rendering.
117
+ * on POS v7) even though both have `APPROVAL_CODE_RULE_TEMPLATES` entries
118
+ * matching full POS. `changePrice` is offered as "Input Custom Price" — POS
119
+ * prompts for a passcode when a custom price is keyed in. `counter` covers
120
+ * both opening and closing a counter (one `counterRecord`/`manage` rule, see
121
+ * `APPROVAL_CODE_RULE_TEMPLATES.counter`). `printReceipt` was dropped
122
+ * entirely (no full-POS counterpart, and this feature has no pre-existing
123
+ * stored data to keep rendering) — there is a 1:1 mapping between every
124
+ * option and its single `ApprovalCodePermission` rule key, so each option
125
+ * carries `ruleKey` directly rather than an array (there is no longer any
126
+ * option backed by more than one rule).
102
127
  */
103
128
  export interface AccessCodeActionOption {
104
- key: 'printReceipt' | 'resend' | 'openDrawer' | 'counter' | 'discount' | 'changePrice' | 'void' | 'changePaymentType' | 'refund';
105
- ruleKeys: ApprovalCodePermission[];
129
+ key: 'resend' | 'openDrawer' | 'counter' | 'discount' | 'changePrice' | 'void' | 'changePaymentType' | 'refund';
130
+ ruleKey: ApprovalCodePermission;
106
131
  }
107
132
  export type AccessCodeActionOptionKey = AccessCodeActionOption['key'];
108
133
  export declare const ACCESS_CODE_ACTION_OPTIONS: AccessCodeActionOption[];
@@ -1 +1 @@
1
- export type { AuditLogEntry, AuditLogMetadata, AuditLogOperation, AuditLogOutcome, AuditLogResolvedFrom, } from '@feedmepos/hrm-permission';
1
+ export type { AuditLogEntry, AuditLogMetadata, AuditLogOutcome, AuditLogResolvedFrom } from '@feedmepos/hrm-permission';
@@ -12,7 +12,7 @@ declare const _default: import("vue").DefineComponent<{}, {
12
12
  key: import("@/types/approval-code").ApprovalCodePermission;
13
13
  subject: string;
14
14
  actions: string[];
15
- conditions?: Record<string, unknown> | undefined;
15
+ conditions?: (Record<string, unknown> | null) | undefined;
16
16
  }[];
17
17
  status: "active" | "used" | "revoked";
18
18
  usedAt?: string | undefined;
@@ -12,6 +12,7 @@ export declare const i18nMessages: {
12
12
  title: string;
13
13
  section: string;
14
14
  name: string;
15
+ namePlaceholder: string;
15
16
  nameRequired: string;
16
17
  restaurant: string;
17
18
  selectRestaurant: string;
@@ -48,9 +49,6 @@ export declare const i18nMessages: {
48
49
  resend: string;
49
50
  changePaymentType: string;
50
51
  openDrawer: string;
51
- openCounter: string;
52
- closeCounter: string;
53
- printReceipt: string;
54
52
  counter: string;
55
53
  };
56
54
  create: {
@@ -101,6 +99,7 @@ export declare const i18nMessages: {
101
99
  title: string;
102
100
  section: string;
103
101
  name: string;
102
+ namePlaceholder: string;
104
103
  nameRequired: string;
105
104
  restaurant: string;
106
105
  selectRestaurant: string;
@@ -137,9 +136,6 @@ export declare const i18nMessages: {
137
136
  resend: string;
138
137
  changePaymentType: string;
139
138
  openDrawer: string;
140
- openCounter: string;
141
- closeCounter: string;
142
- printReceipt: string;
143
139
  counter: string;
144
140
  };
145
141
  create: {
@@ -190,6 +186,7 @@ export declare const i18nMessages: {
190
186
  title: string;
191
187
  section: string;
192
188
  name: string;
189
+ namePlaceholder: string;
193
190
  nameRequired: string;
194
191
  restaurant: string;
195
192
  selectRestaurant: string;
@@ -226,9 +223,6 @@ export declare const i18nMessages: {
226
223
  resend: string;
227
224
  changePaymentType: string;
228
225
  openDrawer: string;
229
- openCounter: string;
230
- closeCounter: string;
231
- printReceipt: string;
232
226
  counter: string;
233
227
  };
234
228
  create: {
@@ -279,6 +273,7 @@ export declare const i18nMessages: {
279
273
  title: string;
280
274
  section: string;
281
275
  name: string;
276
+ namePlaceholder: string;
282
277
  nameRequired: string;
283
278
  restaurant: string;
284
279
  selectRestaurant: string;
@@ -315,9 +310,6 @@ export declare const i18nMessages: {
315
310
  resend: string;
316
311
  changePaymentType: string;
317
312
  openDrawer: string;
318
- openCounter: string;
319
- closeCounter: string;
320
- printReceipt: string;
321
313
  counter: string;
322
314
  };
323
315
  create: {