@feedmepos/mf-hrm-portal 2.1.1-dev.3 → 2.1.1-dev.4
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/dist/ApprovalCodeList-B0PLZwav.js +758 -0
- package/dist/AuditLogList-CRXwPImZ.js +1611 -0
- package/dist/ConditionFormHost.vue_vue_type_script_setup_true_lang-zJwkM_Xb.js +387 -0
- package/dist/EmployeeList-DN2pnXcS.js +884 -0
- package/dist/GrantUserList-DoyxknJZ.js +464 -0
- package/dist/{Main-cskEZ3k_.js → Main-B5BKGpLg.js} +1033 -1029
- package/dist/Main-BGONIxo8.js +122 -0
- package/dist/{Main-DLlpEU3j.js → Main-DQj4xtkB.js} +7 -7
- package/dist/PermissionSetList-4uIU9FvN.js +393 -0
- package/dist/PortalPermissionEditor.vue_vue_type_script_setup_true_lang-D0luaKDb.js +4122 -0
- package/dist/{PortalUserSearcher.vue_vue_type_style_index_0_scoped_a439fdd8_lang-BJp9hEfv.js → PortalUserSearcher.vue_vue_type_style_index_0_scoped_827dfd60_lang-DVVSBIx2.js} +1 -0
- package/dist/ResponsiveFabButton.vue_vue_type_script_setup_true_lang-QrqYEy8i.js +42 -0
- package/dist/RoleList-Bj5Y5jd_.js +685 -0
- package/dist/Skeleton.vue_vue_type_script_setup_true_lang-B4PxNMwq.js +16 -0
- package/dist/TableEmptyState.vue_vue_type_script_setup_true_lang-IfAZmWr0.js +37 -0
- package/dist/TeamMemberList-Byjlca2Y.js +1216 -0
- package/dist/{TimesheetList-B1H_6zfP.js → TimesheetList-DwIcsOM-.js} +118 -112
- package/dist/{TimesheetList.vue_vue_type_style_index_0_scoped_91afda4e_lang-DeTpbaRk.js → TimesheetList.vue_vue_type_style_index_0_scoped_2c7a177a_lang-B9qlQ6KG.js} +2 -2
- package/dist/{app-DX-PG6wx.js → app-BZwE2coe.js} +5407 -2374
- package/dist/app.js +1 -1
- package/dist/{dayjs.min-BJrHE7oz.js → dayjs.min-BXBPls4m.js} +1 -1
- package/dist/{employee-BJcqtqLM.js → employee-CJTbs1f7.js} +3 -3
- package/dist/{iteration-Cfaqt-0s.js → iteration-BCbIbdHR.js} +1 -1
- package/dist/{lodash-ClKqCmlZ.js → lodash-CUIS1iIz.js} +1 -1
- package/dist/{role-CR_-nBDY.js → role-CzXchcSS.js} +1 -1
- package/dist/rule-BO6xj2Xa.js +1058 -0
- package/dist/src/api/audit-log/index.d.ts +6 -0
- package/dist/src/components/CheckboxInput.vue.d.ts +1 -1
- package/dist/src/components/button/ResponsiveFabButton.vue.d.ts +7 -1
- package/dist/src/components/table/TableEmptyState.vue.d.ts +7 -15
- package/dist/src/composables/useBasePermission.d.ts +2 -1
- package/dist/src/composables/useConditionDraft.d.ts +40 -0
- package/dist/src/composables/useCoverConditionOverride.d.ts +61 -0
- package/dist/src/helpers/business-timezone.d.ts +22 -0
- package/dist/src/helpers/filter.d.ts +15 -0
- package/dist/src/helpers/permission-reconcile.d.ts +15 -0
- package/dist/src/helpers/permission-reconcile.test.d.ts +1 -0
- package/dist/src/helpers/permission-set.d.ts +8 -4
- package/dist/src/helpers/rule.d.ts +2 -1
- package/dist/src/stores/permission-set.d.ts +12 -3
- package/dist/src/types/approval-code.d.ts +22 -7
- package/dist/src/types/audit-log.d.ts +1 -1
- package/dist/src/views/approval-code/components/ApprovalCodeCreatedDialog.vue.d.ts +9 -0
- package/dist/src/views/approval-code/components/ApprovalCodeForm.vue.d.ts +6 -1
- package/dist/src/views/approval-code/locales/index.d.ts +40 -0
- package/dist/src/views/audit-log/event-line.d.ts +13 -0
- package/dist/src/views/audit-log/locales/index.d.ts +296 -0
- package/dist/src/views/audit-log/snapshot-diff.d.ts +11 -0
- package/dist/src/views/hr/employee/EmployeeList.vue.d.ts +1 -0
- package/dist/src/views/team/components/BasePermission.vue.d.ts +13 -0
- package/dist/src/views/team/condition-builders/ConditionFormHost.vue.d.ts +22 -0
- package/dist/src/views/team/condition-builders/ConditionFormRenderer.vue.d.ts +23 -0
- package/dist/src/views/team/condition-builders/component-map.d.ts +4 -0
- package/dist/src/views/team/condition-builders/condition-form-dedupe.d.ts +23 -0
- package/dist/src/views/team/locales/index.d.ts +80 -0
- package/dist/style.css +1 -1
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/useDebounce-B8ZPVS5C.js +15 -0
- package/dist/{useReportPermissions-ybHA26cJ.js → useReportPermissions-Q-xLwz5N.js} +3 -3
- package/package.json +2 -2
- package/dist/ApprovalCodeList-BH5sgVMU.js +0 -638
- package/dist/AuditLogList-Q4L5Te8O.js +0 -1145
- package/dist/CollapsibleWrapper.vue_vue_type_script_setup_true_lang-BLJlmPVa.js +0 -58
- package/dist/EmployeeList-GtKmJZbf.js +0 -899
- package/dist/GrantUserList-CnLjOi5_.js +0 -468
- package/dist/Main-Cn7Dawg4.js +0 -120
- package/dist/PermissionSetList-C2fK2pTz.js +0 -357
- package/dist/PortalPermissionEditor.vue_vue_type_script_setup_true_lang-CMh0DL1_.js +0 -3458
- package/dist/ResponsiveFabButton.vue_vue_type_script_setup_true_lang-Cn-3MRBO.js +0 -38
- package/dist/RoleList-CcuT1ERb.js +0 -567
- package/dist/TeamMemberList-Dfs2iNdC.js +0 -1131
- package/dist/rule-BB-3S-2R.js +0 -996
- package/dist/useDebounce-CWb5QR9G.js +0 -28
|
@@ -9,6 +9,9 @@ declare const AuditLogAPI: {
|
|
|
9
9
|
actions?: string[];
|
|
10
10
|
outcomes?: string[];
|
|
11
11
|
feedmeAdminActors?: boolean;
|
|
12
|
+
search?: string;
|
|
13
|
+
searchUserIds?: string[];
|
|
14
|
+
searchSubjects?: string[];
|
|
12
15
|
}): Promise<number>;
|
|
13
16
|
read(params?: {
|
|
14
17
|
limit?: number;
|
|
@@ -21,6 +24,9 @@ declare const AuditLogAPI: {
|
|
|
21
24
|
actions?: string[];
|
|
22
25
|
outcomes?: string[];
|
|
23
26
|
feedmeAdminActors?: boolean;
|
|
27
|
+
search?: string;
|
|
28
|
+
searchUserIds?: string[];
|
|
29
|
+
searchSubjects?: string[];
|
|
24
30
|
}): Promise<AuditLogEntry[]>;
|
|
25
31
|
/**
|
|
26
32
|
* 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
|
-
max: number;
|
|
145
144
|
min: number;
|
|
145
|
+
max: number;
|
|
146
146
|
disable: boolean;
|
|
147
147
|
showAllToggle: string | boolean;
|
|
148
148
|
includeDisabledOptionsWhenSelectAll: boolean;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { type FmButtonProps } from '@feedmepos/ui-library';
|
|
2
|
-
|
|
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>;
|
|
3
9
|
export default _default;
|
|
@@ -5,30 +5,22 @@ interface Props {
|
|
|
5
5
|
isEmpty: boolean;
|
|
6
6
|
isLoading?: boolean;
|
|
7
7
|
/**
|
|
8
|
-
* At what width do the column titles disappear?
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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.
|
|
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;
|
|
21
14
|
}
|
|
22
|
-
declare var
|
|
23
|
-
|
|
15
|
+
declare var __VLS_1: {
|
|
16
|
+
isEmpty: boolean;
|
|
24
17
|
};
|
|
25
18
|
type __VLS_Slots = {} & {
|
|
26
|
-
default?: (props: typeof
|
|
19
|
+
default?: (props: typeof __VLS_1) => any;
|
|
27
20
|
};
|
|
28
21
|
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
|
|
29
22
|
isLoading: boolean;
|
|
30
23
|
collapseAt: Breakpoints | false;
|
|
31
|
-
hideTableBelow: Breakpoints | false;
|
|
32
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
25
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
34
26
|
export default _default;
|
|
@@ -7,6 +7,7 @@ export type CategoryGroup = {
|
|
|
7
7
|
options: {
|
|
8
8
|
label: string;
|
|
9
9
|
value: string;
|
|
10
|
+
optionKey: string;
|
|
10
11
|
}[];
|
|
11
12
|
selectedSubjects: string[];
|
|
12
13
|
isMultiAction: boolean;
|
|
@@ -25,7 +26,7 @@ export declare function useBasePermission(modelValue: Readonly<Ref<FdoPermission
|
|
|
25
26
|
toggleAllManage: (group: CategoryGroup) => void;
|
|
26
27
|
isManageChecked: (group: CategoryGroup, subject: string) => boolean;
|
|
27
28
|
isManageIndeterminate: (group: CategoryGroup, subject: string) => boolean;
|
|
28
|
-
toggleManage: (
|
|
29
|
+
toggleManage: (group: CategoryGroup, subject: string, checked: boolean) => void;
|
|
29
30
|
hasNonManageActions: (group: CategoryGroup, subject: string) => boolean;
|
|
30
31
|
isActionChecked: (group: CategoryGroup, subject: string, action: string) => boolean;
|
|
31
32
|
isRowFullyCoveredByCover: (group: CategoryGroup, subject: string) => boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Local draft state for condition editing — tracks form field edits and
|
|
4
|
+
* inherit/custom mode changes for each builder, keyed by `${subject}::${builderKey}`.
|
|
5
|
+
*
|
|
6
|
+
* Drafts remain local until explicitly committed via `applyDrafts`. Closing
|
|
7
|
+
* a popover/menu without applying discards uncommitted changes.
|
|
8
|
+
*/
|
|
9
|
+
export interface DraftKey {
|
|
10
|
+
subject: string;
|
|
11
|
+
builderKey: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ConditionDraft {
|
|
14
|
+
/** The local draft form value for this builder. */
|
|
15
|
+
formValue: unknown;
|
|
16
|
+
/** Local draft inherit/custom mode for builders under a cover subject. */
|
|
17
|
+
inheritMode?: 'inherit' | 'custom';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a composable to manage local draft state for condition editing.
|
|
21
|
+
*
|
|
22
|
+
* @param committedSource - Ref to the committed state (e.g., modelValue, reportExtraConditions)
|
|
23
|
+
* used to detect external changes and reset drafts accordingly
|
|
24
|
+
*/
|
|
25
|
+
export declare function useConditionDraft<T>(committedSource?: Ref<T>): {
|
|
26
|
+
drafts: Ref<Map<string, {
|
|
27
|
+
formValue: unknown;
|
|
28
|
+
inheritMode?: "inherit" | "custom" | undefined;
|
|
29
|
+
}> & Omit<Map<string, ConditionDraft>, keyof Map<any, any>>, Map<string, ConditionDraft> | (Map<string, {
|
|
30
|
+
formValue: unknown;
|
|
31
|
+
inheritMode?: "inherit" | "custom" | undefined;
|
|
32
|
+
}> & Omit<Map<string, ConditionDraft>, keyof Map<any, any>>)>;
|
|
33
|
+
setDraft: (key: DraftKey, draft: ConditionDraft) => void;
|
|
34
|
+
getDraft: (key: DraftKey) => ConditionDraft | undefined;
|
|
35
|
+
hasDraftsForSubject: (subject: string) => boolean;
|
|
36
|
+
getDraftsForSubject: (subject: string) => Map<string, ConditionDraft>;
|
|
37
|
+
clearDraftsForSubject: (subject: string) => void;
|
|
38
|
+
clearAllDrafts: () => void;
|
|
39
|
+
clearDraft: (key: DraftKey) => void;
|
|
40
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type Ref, type ComputedRef } from 'vue';
|
|
2
|
+
import type { FdoPermissionRule } from '@feedmepos/core/entity';
|
|
3
|
+
import { type IFdtoPortalPermissionsWithVisibilityCondition } from '@feedmepos/hrm-permission';
|
|
4
|
+
import { type ConditionBuilder, type ConditionSummary } from '@feedmepos/hrm-permission/condition-builder';
|
|
5
|
+
/**
|
|
6
|
+
* Generic "category cover" machinery for the portal permission editor: any
|
|
7
|
+
* subject whose permission-definition category declares a cover (see
|
|
8
|
+
* `getCoverSubjectFor`) can have its condition-builder settings either
|
|
9
|
+
* inherit the cover subject's condition or hold a custom override — and the
|
|
10
|
+
* cover subject itself can push its condition down onto every individual
|
|
11
|
+
* override in the category.
|
|
12
|
+
*
|
|
13
|
+
* Zero knowledge of any specific subject, category, or builder lives here —
|
|
14
|
+
* everything is driven by the `defs` list (permission definitions carrying
|
|
15
|
+
* `category`/`isCategoryCover`) and the `ConditionBuilder` contract
|
|
16
|
+
* (`ownedFields`, `appliesToActions`, `summarizeForm`).
|
|
17
|
+
*/
|
|
18
|
+
/** The minimum shape the editor's per-row entry needs to expose for cover/inherit resolution. */
|
|
19
|
+
export interface CoverConditionEntry {
|
|
20
|
+
/** Index of this subject's raw rule in the model, or null when no direct rule exists yet. */
|
|
21
|
+
index: number | null;
|
|
22
|
+
subject: string;
|
|
23
|
+
label: string;
|
|
24
|
+
actions: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/** Resolution handles passed to `onOverridesConflict` — the caller (UI) decides which to invoke. */
|
|
27
|
+
export interface CoverOverrideResolution {
|
|
28
|
+
/** Strip this builder's fragment from every covered override rule (dropping a rule once it carries no more conditions and its actions are covered). */
|
|
29
|
+
override: () => void;
|
|
30
|
+
/** Leave every covered override rule untouched. */
|
|
31
|
+
keep: () => void;
|
|
32
|
+
}
|
|
33
|
+
export interface UpdateBuilderConditionOptions {
|
|
34
|
+
/** Create a direct rule even if the resulting condition is empty (used when explicitly switching to "custom"). */
|
|
35
|
+
forceCreateRule?: boolean;
|
|
36
|
+
afterCommit?: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Invoked instead of auto-resolving when this write touches a cover
|
|
39
|
+
* subject's row and other subjects in the same category hold a
|
|
40
|
+
* conditioned override on this builder. Omit only for callers that don't
|
|
41
|
+
* need a confirmation step — the write then defaults to keeping the
|
|
42
|
+
* overrides untouched (the non-destructive choice).
|
|
43
|
+
*/
|
|
44
|
+
onOverridesConflict?: (resolution: CoverOverrideResolution) => void;
|
|
45
|
+
}
|
|
46
|
+
export interface BuilderConditionDraft {
|
|
47
|
+
builder: ConditionBuilder;
|
|
48
|
+
form: unknown;
|
|
49
|
+
mode: 'inherit' | 'custom';
|
|
50
|
+
}
|
|
51
|
+
export declare function useCoverConditionOverride(rules: Ref<FdoPermissionRule[]>, defs: ComputedRef<IFdtoPortalPermissionsWithVisibilityCondition[]>, updateRules: (next: FdoPermissionRule[]) => void): {
|
|
52
|
+
getCoverSubject: (subject: string) => string | undefined;
|
|
53
|
+
coverLabel: (subject: string) => string | undefined;
|
|
54
|
+
shouldShowInheritToggle: (entry: CoverConditionEntry, builder: ConditionBuilder) => boolean;
|
|
55
|
+
inheritMode: (entry: CoverConditionEntry, builder: ConditionBuilder) => "inherit" | "custom";
|
|
56
|
+
setInheritMode: (entry: CoverConditionEntry, builder: ConditionBuilder, mode: "inherit" | "custom") => void;
|
|
57
|
+
inheritedSummary: (entry: CoverConditionEntry, builder: ConditionBuilder, timeZone: string) => ConditionSummary | undefined;
|
|
58
|
+
getEffectiveActions: (subject: string) => readonly string[];
|
|
59
|
+
updateBuilderCondition: (entry: CoverConditionEntry, builder: ConditionBuilder, form: unknown, options?: UpdateBuilderConditionOptions) => void;
|
|
60
|
+
applyConditionDrafts: (entry: CoverConditionEntry, updates: BuilderConditionDraft[], options?: UpdateBuilderConditionOptions) => void;
|
|
61
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Business timezone resolution — a pure mapping from country code to IANA
|
|
3
|
+
* timezone, used as a fallback when a business has no explicit timezone
|
|
4
|
+
* configured. Kept independent of any store so it's testable in isolation;
|
|
5
|
+
* callers resolve the business/country from their own store and pass the
|
|
6
|
+
* plain values in.
|
|
7
|
+
*/
|
|
8
|
+
/** IANA timezone for a country code; falls back to the runtime's local zone for unknown/missing codes. */
|
|
9
|
+
export declare function getCountryTimezone(country?: string): string;
|
|
10
|
+
/** Minimal shape a business needs for timezone resolution. */
|
|
11
|
+
export interface BusinessTimezoneSource {
|
|
12
|
+
timezone?: string;
|
|
13
|
+
timeZone?: string;
|
|
14
|
+
country?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the effective IANA timezone for a business: an explicit business
|
|
18
|
+
* timezone field wins (`timezone`, then legacy `timeZone`), otherwise falls
|
|
19
|
+
* back to the country's default timezone (business's own country first, then
|
|
20
|
+
* `fallbackCountry`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveBusinessTimezone(business: BusinessTimezoneSource | undefined, fallbackCountry?: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentinel value used in multi-select list filters (assigned role, restaurant, etc.) to
|
|
3
|
+
* represent "this field is empty/unassigned for the record". Must match the backend's
|
|
4
|
+
* `UNASSIGNED_FILTER_VALUE` in src/common/helpers/filter.ts.
|
|
5
|
+
*
|
|
6
|
+
* When sending a filter that includes this value to the backend, it must be the first element
|
|
7
|
+
* of the array -- the backend only checks index 0 to detect it (cheap even for filters with
|
|
8
|
+
* large option sets), it does not scan the whole list.
|
|
9
|
+
*/
|
|
10
|
+
export declare const UNASSIGNED_FILTER_VALUE = "__unassigned__";
|
|
11
|
+
/**
|
|
12
|
+
* Reorders a multi-select filter's selected values so the "unassigned" sentinel (if present)
|
|
13
|
+
* is always first, matching what the backend's `splitUnassignedFilter` expects.
|
|
14
|
+
*/
|
|
15
|
+
export declare function withUnassignedFirst(values?: string[]): string[] | undefined;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FdoPermissionRule } from '@feedmepos/core/entity';
|
|
2
|
+
import type { IFdtoPortalPermissionsWithVisibilityCondition } from '@feedmepos/hrm-permission';
|
|
3
|
+
/**
|
|
4
|
+
* Reconcile a BasePermission update (which works with the expanded view) back to the raw modelValue.
|
|
5
|
+
*
|
|
6
|
+
* - Subject removed that was directly in raw → remove it
|
|
7
|
+
* - Subject removed that was system-expanded (not in raw) → add inverted rule to block re-expansion
|
|
8
|
+
* - Subject removed that was stored directly AND still reachable via expansion from remaining
|
|
9
|
+
* rules (e.g. previously materialized by an earlier save) → remove direct rule AND add inverted,
|
|
10
|
+
* otherwise materializeSystemPermissionSetOverrides re-injects it during save
|
|
11
|
+
* - Subject added that had an inverted rule → remove the inverted rule (expansion re-enables it)
|
|
12
|
+
* - Subject added that is genuinely new → add it to raw
|
|
13
|
+
* - Subject unchanged but actions changed → update actions in raw (multi-action permissions)
|
|
14
|
+
*/
|
|
15
|
+
export declare function reconcileBasePermissionUpdate(prevExpandedRules: FdoPermissionRule[], newExpandedRules: FdoPermissionRule[], rawRules: FdoPermissionRule[], findPermissionDef: (subject: string) => IFdtoPortalPermissionsWithVisibilityCondition | undefined): FdoPermissionRule[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -71,10 +71,14 @@ 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
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
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.
|
|
78
82
|
* Rules that end up with no remaining actions are dropped.
|
|
79
83
|
*
|
|
80
84
|
* Inverted rules and the cover subjects themselves pass through untouched.
|
|
@@ -20,7 +20,8 @@ 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
|
|
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>>): {
|
|
24
25
|
subject: string;
|
|
25
26
|
actions: ("delete" | "create" | "update" | "read" | "manage")[];
|
|
26
27
|
conditions: object;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IFdtoPermissionSet, IFdtoCreatePermissionSetReq, IFdtoUpdatePermissionSetReq } from '@/types/permission-set';
|
|
2
2
|
export declare const usePermissionSetStore: () => {
|
|
3
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
3
4
|
permissionSets: import("vue").Ref<{
|
|
4
5
|
id: string;
|
|
5
6
|
permissions: {
|
|
@@ -30,6 +31,7 @@ export declare const usePermissionSetStore: () => {
|
|
|
30
31
|
name: string;
|
|
31
32
|
}[]>;
|
|
32
33
|
$state: {
|
|
34
|
+
isLoading: boolean;
|
|
33
35
|
permissionSets: {
|
|
34
36
|
id: string;
|
|
35
37
|
permissions: {
|
|
@@ -75,12 +77,14 @@ export declare const usePermissionSetStore: () => {
|
|
|
75
77
|
businessId: string;
|
|
76
78
|
name: string;
|
|
77
79
|
}[]>;
|
|
80
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
78
81
|
readPermissionSets: () => Promise<void>;
|
|
79
82
|
createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
|
|
80
83
|
updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
|
|
81
84
|
deletePermissionSet: (id: string) => Promise<void>;
|
|
82
|
-
}, "permissionSets">>;
|
|
85
|
+
}, "isLoading" | "permissionSets">>;
|
|
83
86
|
$patch(partialState: import("pinia")._DeepPartial<{
|
|
87
|
+
isLoading: boolean;
|
|
84
88
|
permissionSets: {
|
|
85
89
|
id: string;
|
|
86
90
|
permissions: {
|
|
@@ -98,6 +102,7 @@ export declare const usePermissionSetStore: () => {
|
|
|
98
102
|
}[];
|
|
99
103
|
}>): void;
|
|
100
104
|
$patch<F extends (state: {
|
|
105
|
+
isLoading: boolean;
|
|
101
106
|
permissionSets: {
|
|
102
107
|
id: string;
|
|
103
108
|
permissions: {
|
|
@@ -145,11 +150,12 @@ export declare const usePermissionSetStore: () => {
|
|
|
145
150
|
businessId: string;
|
|
146
151
|
name: string;
|
|
147
152
|
}[]>;
|
|
153
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
148
154
|
readPermissionSets: () => Promise<void>;
|
|
149
155
|
createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
|
|
150
156
|
updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
|
|
151
157
|
deletePermissionSet: (id: string) => Promise<void>;
|
|
152
|
-
}, "permissionSets">>, options?: {
|
|
158
|
+
}, "isLoading" | "permissionSets">>, options?: {
|
|
153
159
|
detached?: boolean;
|
|
154
160
|
} & import("vue").WatchOptions): () => void;
|
|
155
161
|
$onAction(callback: import("pinia").StoreOnActionListener<"permissionSet", Pick<{
|
|
@@ -182,11 +188,12 @@ export declare const usePermissionSetStore: () => {
|
|
|
182
188
|
businessId: string;
|
|
183
189
|
name: string;
|
|
184
190
|
}[]>;
|
|
191
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
185
192
|
readPermissionSets: () => Promise<void>;
|
|
186
193
|
createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
|
|
187
194
|
updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
|
|
188
195
|
deletePermissionSet: (id: string) => Promise<void>;
|
|
189
|
-
}, "permissionSets">, Pick<{
|
|
196
|
+
}, "isLoading" | "permissionSets">, Pick<{
|
|
190
197
|
permissionSets: import("vue").Ref<{
|
|
191
198
|
id: string;
|
|
192
199
|
permissions: {
|
|
@@ -216,6 +223,7 @@ export declare const usePermissionSetStore: () => {
|
|
|
216
223
|
businessId: string;
|
|
217
224
|
name: string;
|
|
218
225
|
}[]>;
|
|
226
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
219
227
|
readPermissionSets: () => Promise<void>;
|
|
220
228
|
createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
|
|
221
229
|
updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
|
|
@@ -250,6 +258,7 @@ export declare const usePermissionSetStore: () => {
|
|
|
250
258
|
businessId: string;
|
|
251
259
|
name: string;
|
|
252
260
|
}[]>;
|
|
261
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
253
262
|
readPermissionSets: () => Promise<void>;
|
|
254
263
|
createPermissionSet: (dto: IFdtoCreatePermissionSetReq) => Promise<void>;
|
|
255
264
|
updatePermissionSet: (id: string, dto: IFdtoUpdatePermissionSetReq) => Promise<void>;
|
|
@@ -64,6 +64,19 @@ export interface IFdtoCreateApprovalCodeReq {
|
|
|
64
64
|
* rule has no adjustment ceiling.
|
|
65
65
|
*/
|
|
66
66
|
export declare function getRuleAdjustmentCeilingPercentage(rule: IFdtoApprovalCodeRule): number | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Human-readable labels for a code's permission rules, e.g. `["Refund",
|
|
69
|
+
* "Apply discount ≤20%"]`. `translate` is the caller's i18n `t` — labels
|
|
70
|
+
* live under `approvalCode.permissions.<key>`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function formatPermissionLabels(permissions: IFdtoApprovalCodeRule[], translate: (key: string) => string): string[];
|
|
73
|
+
/**
|
|
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.
|
|
77
|
+
* Missing parts are skipped rather than leaving dangling separators.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildCodeClipboardText(code: Pick<IFdtoApprovalCode, 'passcode' | 'permissions'>, restaurantName: string | undefined, translate: (key: string) => string): string;
|
|
67
80
|
/**
|
|
68
81
|
* Validate the optional discount max-percentage input. Undefined, empty, or
|
|
69
82
|
* whitespace-only means "no ceiling" and is valid; otherwise the value must
|
|
@@ -78,15 +91,17 @@ export declare function validateMaxPercentage(value: number | string | undefined
|
|
|
78
91
|
export declare function resolveMaxPercentage(value: number | string | undefined): number | undefined;
|
|
79
92
|
/**
|
|
80
93
|
* A selectable action option in the create form / list filter (KDI-4982 UI
|
|
81
|
-
* redesign). The
|
|
82
|
-
* `
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
94
|
+
* redesign). The 9 options mirror the POS v7 passcode prompts exactly:
|
|
95
|
+
* `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.
|
|
87
102
|
*/
|
|
88
103
|
export interface AccessCodeActionOption {
|
|
89
|
-
key: 'printReceipt' | 'resend' | 'openDrawer' | 'counter' | 'discount' | 'void' | 'changePaymentType' | 'refund';
|
|
104
|
+
key: 'printReceipt' | 'resend' | 'openDrawer' | 'counter' | 'discount' | 'changePrice' | 'void' | 'changePaymentType' | 'refund';
|
|
90
105
|
ruleKeys: ApprovalCodePermission[];
|
|
91
106
|
}
|
|
92
107
|
export type AccessCodeActionOptionKey = AccessCodeActionOption['key'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { AuditLogEntry, AuditLogMetadata, AuditLogOutcome, AuditLogResolvedFrom } from '@feedmepos/hrm-permission';
|
|
1
|
+
export type { AuditLogEntry, AuditLogMetadata, AuditLogOperation, AuditLogOutcome, AuditLogResolvedFrom, } from '@feedmepos/hrm-permission';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type IFdtoApprovalCode } from '@/types/approval-code';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<{}, {
|
|
3
|
+
open: (created: IFdtoApprovalCode[]) => void;
|
|
4
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
createAnother: () => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
7
|
+
onCreateAnother?: (() => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
9
|
+
export default _default;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type IFdtoApprovalCode } from '@/types/approval-code';
|
|
1
2
|
declare var __VLS_1: {
|
|
2
3
|
trigger: () => void;
|
|
3
4
|
};
|
|
@@ -7,7 +8,11 @@ type __VLS_Slots = {} & {
|
|
|
7
8
|
declare const __VLS_component: import("vue").DefineComponent<{}, {
|
|
8
9
|
show: import("vue").Ref<boolean, boolean>;
|
|
9
10
|
trigger: () => void;
|
|
10
|
-
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
+
created: (codes: IFdtoApprovalCode[]) => any;
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
14
|
+
onCreated?: ((codes: IFdtoApprovalCode[]) => any) | undefined;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
11
16
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
12
17
|
export default _default;
|
|
13
18
|
type __VLS_WithSlots<T, S> = T & {
|
|
@@ -57,6 +57,16 @@ export declare const i18nMessages: {
|
|
|
57
57
|
successMessage: string;
|
|
58
58
|
successMessageBulk: string;
|
|
59
59
|
};
|
|
60
|
+
created: {
|
|
61
|
+
title: string;
|
|
62
|
+
titleBulk: string;
|
|
63
|
+
subtitle: string;
|
|
64
|
+
subtitleBulk: string;
|
|
65
|
+
copy: string;
|
|
66
|
+
copyAll: string;
|
|
67
|
+
createAnother: string;
|
|
68
|
+
done: string;
|
|
69
|
+
};
|
|
60
70
|
revoke: {
|
|
61
71
|
title: string;
|
|
62
72
|
message: string;
|
|
@@ -136,6 +146,16 @@ export declare const i18nMessages: {
|
|
|
136
146
|
successMessage: string;
|
|
137
147
|
successMessageBulk: string;
|
|
138
148
|
};
|
|
149
|
+
created: {
|
|
150
|
+
title: string;
|
|
151
|
+
titleBulk: string;
|
|
152
|
+
subtitle: string;
|
|
153
|
+
subtitleBulk: string;
|
|
154
|
+
copy: string;
|
|
155
|
+
copyAll: string;
|
|
156
|
+
createAnother: string;
|
|
157
|
+
done: string;
|
|
158
|
+
};
|
|
139
159
|
revoke: {
|
|
140
160
|
title: string;
|
|
141
161
|
message: string;
|
|
@@ -215,6 +235,16 @@ export declare const i18nMessages: {
|
|
|
215
235
|
successMessage: string;
|
|
216
236
|
successMessageBulk: string;
|
|
217
237
|
};
|
|
238
|
+
created: {
|
|
239
|
+
title: string;
|
|
240
|
+
titleBulk: string;
|
|
241
|
+
subtitle: string;
|
|
242
|
+
subtitleBulk: string;
|
|
243
|
+
copy: string;
|
|
244
|
+
copyAll: string;
|
|
245
|
+
createAnother: string;
|
|
246
|
+
done: string;
|
|
247
|
+
};
|
|
218
248
|
revoke: {
|
|
219
249
|
title: string;
|
|
220
250
|
message: string;
|
|
@@ -294,6 +324,16 @@ export declare const i18nMessages: {
|
|
|
294
324
|
successMessage: string;
|
|
295
325
|
successMessageBulk: string;
|
|
296
326
|
};
|
|
327
|
+
created: {
|
|
328
|
+
title: string;
|
|
329
|
+
titleBulk: string;
|
|
330
|
+
subtitle: string;
|
|
331
|
+
subtitleBulk: string;
|
|
332
|
+
copy: string;
|
|
333
|
+
copyAll: string;
|
|
334
|
+
createAnother: string;
|
|
335
|
+
done: string;
|
|
336
|
+
};
|
|
297
337
|
revoke: {
|
|
298
338
|
title: string;
|
|
299
339
|
message: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface EventLineSource {
|
|
2
|
+
eventKey?: string;
|
|
3
|
+
params?: Record<string, string | number>;
|
|
4
|
+
operationLabel?: string;
|
|
5
|
+
}
|
|
6
|
+
type Translate = (key: string, params?: Record<string, unknown>) => string;
|
|
7
|
+
export declare function splitEventKey(key: string): {
|
|
8
|
+
entity: string;
|
|
9
|
+
verb: string;
|
|
10
|
+
} | null;
|
|
11
|
+
export declare function humanizeSegment(segment: string): string;
|
|
12
|
+
export declare function renderEventLine(t: Translate, source: EventLineSource): string;
|
|
13
|
+
export {};
|