@isi-ui7/bos7-shared 0.2.4 → 0.2.7
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/crud-components.d.ts +2 -0
- package/dist/crud-hooks.d.ts +1 -1
- package/dist/form-numeric.d.ts +12 -0
- package/dist/form-renderer.d.ts +4 -2
- package/dist/form-types.d.ts +75 -3
- package/dist/form-value-schema.d.ts +118 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4768 -4534
- package/dist/shell/app-shell-layout.d.ts +21 -6
- package/dist/style-contract.d.ts +20 -5
- package/dist/workflow/starter.d.ts +13 -0
- package/package.json +10 -7
- package/src/crud-components.tsx +27 -2
- package/src/crud-hooks.ts +5 -2
- package/src/form-contract.css +64 -2
- package/src/form-numeric.ts +16 -0
- package/src/form-renderer.tsx +381 -18
- package/src/form-types.ts +83 -5
- package/src/form-value-schema.test.ts +263 -0
- package/src/form-value-schema.ts +500 -0
- package/src/index.ts +1 -0
- package/src/shell/app-shell-layout.tsx +22 -46
- package/src/style-contract.test.ts +1 -0
- package/src/style-contract.ts +38 -5
- package/src/workflow/starter.ts +48 -11
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { ElementType, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface AppShellAuthState {
|
|
4
4
|
isAuthenticated: boolean;
|
|
@@ -12,7 +12,22 @@ export interface AppShellAuthState {
|
|
|
12
12
|
login: () => void;
|
|
13
13
|
logout: () => Promise<void> | void;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Structural shape of a side-nav item, mirroring ui-shell's `ShellNavItem`.
|
|
17
|
+
* `label`/`href` are required to stay mutually assignable with `ShellNavItem`:
|
|
18
|
+
* this type is used both covariantly (`navItems`) and contravariantly
|
|
19
|
+
* (`markActive`'s parameter), so consumers passing `ShellNavItem`-typed values
|
|
20
|
+
* would otherwise fail under `strict`. The index signature keeps it permissive
|
|
21
|
+
* for extra metadata (e.g. `requiredPermission`).
|
|
22
|
+
*/
|
|
23
|
+
export interface ShellNavItemLike {
|
|
24
|
+
label: string;
|
|
25
|
+
href: string;
|
|
26
|
+
isActive?: boolean;
|
|
27
|
+
icon?: string;
|
|
28
|
+
children?: ShellNavItemLike[];
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
16
31
|
export interface ShellNotificationLike {
|
|
17
32
|
id?: string;
|
|
18
33
|
read?: boolean;
|
|
@@ -43,9 +58,9 @@ export interface AppShellLayoutDeps {
|
|
|
43
58
|
theme: ThemeLike;
|
|
44
59
|
};
|
|
45
60
|
useNotificationBell: (opts: NotificationBellOptionsLike) => NotificationBellLike;
|
|
46
|
-
GlobalTheme:
|
|
47
|
-
ModalProvider:
|
|
48
|
-
UiShell:
|
|
61
|
+
GlobalTheme: ElementType;
|
|
62
|
+
ModalProvider: ElementType;
|
|
63
|
+
UiShell: ElementType;
|
|
49
64
|
useAuth?: () => AppShellAuthState;
|
|
50
65
|
}
|
|
51
66
|
export interface AppShellLayoutProps {
|
|
@@ -63,7 +78,7 @@ export interface AppShellLayoutProps {
|
|
|
63
78
|
notificationsViewAllTarget?: string;
|
|
64
79
|
hideMenuButton?: boolean;
|
|
65
80
|
disableAppsMenu?: boolean;
|
|
66
|
-
sideNavMode?: "drilldown" | "overlay";
|
|
81
|
+
sideNavMode?: "drilldown" | "overlay" | "expand";
|
|
67
82
|
sideNavItems?: ShellNavItemLike[];
|
|
68
83
|
}
|
|
69
84
|
export declare function AppShellLayout({ children, deps, navItems, markActive, appNameFallback, auth7UiUrlFallback, portalUrlFallback, roleFallback, appSwitchMode, resolveNotificationHref, notificationsViewAllHref, notificationsViewAllTarget, hideMenuButton, disableAppsMenu, sideNavMode, sideNavItems, }: AppShellLayoutProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/style-contract.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
export type Ui7FormDensity = "compact" | "comfortable";
|
|
2
2
|
export type Ui7ThemeDensity = Ui7FormDensity | "normal";
|
|
3
|
+
/**
|
|
4
|
+
* Desktop form-panel width. Mobile + tablet (<1056px) always release the
|
|
5
|
+
* cap and stretch to 100% — the modifier only matters at ≥1056px.
|
|
6
|
+
*
|
|
7
|
+
* - "half" → 50% of page body
|
|
8
|
+
* - "two-thirds" → 66.6667% (default — readable column width on wide
|
|
9
|
+
* monitors, what the contract shipped with originally)
|
|
10
|
+
* - "full" → 100% (forms with many columns or wide tables inside)
|
|
11
|
+
*/
|
|
12
|
+
export type Ui7FormWidth = "half" | "two-thirds" | "full";
|
|
3
13
|
export interface Ui7FormVisualTokens {
|
|
4
14
|
labelSpacing: "6px";
|
|
5
15
|
labelFontSize: "12px";
|
|
@@ -38,6 +48,9 @@ export declare const UI7_FORM_VISUAL_CLASSNAMES: {
|
|
|
38
48
|
readonly scope: "ui7-form-contract";
|
|
39
49
|
readonly densityCompact: "ui7-form-contract--density-compact";
|
|
40
50
|
readonly densityComfortable: "ui7-form-contract--density-comfortable";
|
|
51
|
+
readonly widthHalf: "ui7-form-contract--width-half";
|
|
52
|
+
readonly widthTwoThirds: "ui7-form-contract--width-two-thirds";
|
|
53
|
+
readonly widthFull: "ui7-form-contract--width-full";
|
|
41
54
|
readonly readonly: "ui7-form-contract--readonly";
|
|
42
55
|
readonly row: "ui7-form-row";
|
|
43
56
|
readonly section: "ui7-form-section";
|
|
@@ -52,21 +65,23 @@ export declare const UI7_FORM_VISUAL_CLASSNAMES: {
|
|
|
52
65
|
export declare const UI7_FORM_DENSITY_TOKENS: {
|
|
53
66
|
readonly compact: {
|
|
54
67
|
readonly controlHeight: "2rem";
|
|
55
|
-
readonly rowGap: "
|
|
56
|
-
readonly sectionGap: "
|
|
57
|
-
readonly columnGap: "
|
|
68
|
+
readonly rowGap: "1rem";
|
|
69
|
+
readonly sectionGap: "1.25rem";
|
|
70
|
+
readonly columnGap: "1rem";
|
|
58
71
|
};
|
|
59
72
|
readonly comfortable: {
|
|
60
73
|
readonly controlHeight: "2.5rem";
|
|
61
|
-
readonly rowGap: "
|
|
74
|
+
readonly rowGap: "1.25rem";
|
|
62
75
|
readonly sectionGap: "1.5rem";
|
|
63
|
-
readonly columnGap: "
|
|
76
|
+
readonly columnGap: "1.25rem";
|
|
64
77
|
};
|
|
65
78
|
};
|
|
66
79
|
export declare function normalizeUi7FormDensity(density?: Ui7ThemeDensity | null, fallback?: Ui7FormDensity): Ui7FormDensity;
|
|
67
80
|
export declare function getUi7FormDensityClassName(density?: Ui7ThemeDensity | null, fallback?: Ui7FormDensity): string;
|
|
81
|
+
export declare function getUi7FormWidthClassName(width?: Ui7FormWidth | null): string;
|
|
68
82
|
export declare function getUi7FormContractClassName(options?: {
|
|
69
83
|
density?: Ui7ThemeDensity | null;
|
|
84
|
+
width?: Ui7FormWidth | null;
|
|
70
85
|
readonly?: boolean;
|
|
71
86
|
className?: string | null;
|
|
72
87
|
}): string;
|
|
@@ -13,9 +13,22 @@ export type StartWorkflowInput = {
|
|
|
13
13
|
flowId: string;
|
|
14
14
|
payload: Record<string, unknown>;
|
|
15
15
|
externalRef?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional override for initiator identity. By default the helper decodes
|
|
18
|
+
* the full tenant identity (user_id, username, org_id, branch_id, branch_code)
|
|
19
|
+
* from the access token and uses that. Any field explicitly set here wins.
|
|
20
|
+
*
|
|
21
|
+
* Set ONLY when the caller has a verified reason to override (rare). For
|
|
22
|
+
* normal flow-start paths leave this undefined — letting the helper read
|
|
23
|
+
* the JWT keeps initiator_context aligned with the auth7 signature.
|
|
24
|
+
*/
|
|
16
25
|
initiatorContext?: {
|
|
17
26
|
user_id?: string;
|
|
27
|
+
username?: string;
|
|
28
|
+
org_id?: string;
|
|
18
29
|
branch_id?: string;
|
|
30
|
+
branch_code?: string;
|
|
31
|
+
ip?: string;
|
|
19
32
|
};
|
|
20
33
|
/** User access token dari auth7 — diforward ke workflow7 sebagai Bearer. */
|
|
21
34
|
userAccessToken: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isi-ui7/bos7-shared",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Shared auth7 and layout primitives for bos7 applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -72,7 +72,8 @@
|
|
|
72
72
|
"@carbon/react": "^1.97.0",
|
|
73
73
|
"@carbon/icons-react": "^11.71.0",
|
|
74
74
|
"@isi-ui7/data-table": ">=0.2.0",
|
|
75
|
-
"@isi-ui7/lookup-input": ">=0.2.0"
|
|
75
|
+
"@isi-ui7/lookup-input": ">=0.2.0",
|
|
76
|
+
"@isi-ui7/editable-table": ">=0.2.0"
|
|
76
77
|
},
|
|
77
78
|
"devDependencies": {
|
|
78
79
|
"@eslint/eslintrc": "^3.3.1",
|
|
@@ -98,13 +99,14 @@
|
|
|
98
99
|
"next": "16.1.1",
|
|
99
100
|
"@carbon/react": "^1.97.0",
|
|
100
101
|
"@carbon/icons-react": "^11.71.0",
|
|
101
|
-
"@isi-ui7/ui-shell": "0.2.3",
|
|
102
102
|
"@isi-ui7/i18n": "0.2.0",
|
|
103
|
+
"@isi-ui7/corporate-themes": "0.2.4",
|
|
104
|
+
"@isi-ui7/ui-shell": "0.2.4",
|
|
103
105
|
"@isi-ui7/modal-manager": "0.2.1",
|
|
104
|
-
"@isi-ui7/lookup-input": "0.2.2",
|
|
105
106
|
"@isi-ui7/realtime": "0.2.2",
|
|
106
|
-
"@isi-ui7/
|
|
107
|
-
"@isi-ui7/data-table": "0.2.2"
|
|
107
|
+
"@isi-ui7/lookup-input": "0.2.2",
|
|
108
|
+
"@isi-ui7/data-table": "0.2.2",
|
|
109
|
+
"@isi-ui7/editable-table": "0.2.2"
|
|
108
110
|
},
|
|
109
111
|
"dependencies": {
|
|
110
112
|
"@carbon/icons-react": "^11.71.0",
|
|
@@ -117,8 +119,9 @@
|
|
|
117
119
|
"@opentelemetry/sdk-node": "^0.57.0",
|
|
118
120
|
"@opentelemetry/exporter-trace-otlp-http": "^0.57.0",
|
|
119
121
|
"@opentelemetry/auto-instrumentations-node": "^0.57.0",
|
|
122
|
+
"@isi-ui7/lookup-input": "0.2.2",
|
|
120
123
|
"@isi-ui7/data-table": "0.2.2",
|
|
121
|
-
"@isi-ui7/
|
|
124
|
+
"@isi-ui7/editable-table": "0.2.2"
|
|
122
125
|
},
|
|
123
126
|
"scripts": {
|
|
124
127
|
"build": "vite build",
|
package/src/crud-components.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
ToastNotification,
|
|
16
16
|
} from "@carbon/react";
|
|
17
17
|
import { ServerDataTable } from "@isi-ui7/data-table";
|
|
18
|
+
import type { I_DataTblColumn } from "@isi-ui7/data-table";
|
|
18
19
|
import type { CrudCustomActionSchema, CrudDeleteSchema, CrudListSchema } from "./crud-types";
|
|
19
20
|
import type { CrudForm, FormMode } from "./form-types";
|
|
20
21
|
import type { Ui7FormDensity } from "./style-contract";
|
|
@@ -25,6 +26,24 @@ import { useCrudForm } from "./workflow/use-crud-form";
|
|
|
25
26
|
import { useWorkflowTracker } from "./workflow/use-workflow-tracker";
|
|
26
27
|
import { useBosSharedI18n } from "./i18n";
|
|
27
28
|
|
|
29
|
+
// Re-export the value_schema → form adapter so category pages (bos7-enterprise)
|
|
30
|
+
// can compose: [scopeSection(t), ...buildValueSections(schema, t).sections].
|
|
31
|
+
export {
|
|
32
|
+
buildValueSections,
|
|
33
|
+
buildXRulesValidator,
|
|
34
|
+
} from "./form-value-schema";
|
|
35
|
+
export type {
|
|
36
|
+
JSONSchema,
|
|
37
|
+
XUi,
|
|
38
|
+
XUiRoot,
|
|
39
|
+
XUiNumeric,
|
|
40
|
+
XUiOption,
|
|
41
|
+
XUiWidget,
|
|
42
|
+
XRule,
|
|
43
|
+
XRuleOp,
|
|
44
|
+
ValueValidatorFn,
|
|
45
|
+
} from "./form-value-schema";
|
|
46
|
+
|
|
28
47
|
// ── List page (bare) ──────────────────────────────────────────────────────────
|
|
29
48
|
|
|
30
49
|
export function SharedCrudListPage({
|
|
@@ -46,10 +65,10 @@ export function SharedCrudListPage({
|
|
|
46
65
|
<ServerDataTable
|
|
47
66
|
key={tableKey}
|
|
48
67
|
apiPath={schema.apiPath}
|
|
49
|
-
columns={schema.columns as
|
|
68
|
+
columns={schema.columns as Record<string, I_DataTblColumn>}
|
|
50
69
|
showSearch={schema.showSearch ?? true}
|
|
51
70
|
showSort={schema.showSort ?? true}
|
|
52
|
-
popupMenu={{ src: "local", items: schema.popupMenuItems
|
|
71
|
+
popupMenu={{ src: "local", items: schema.popupMenuItems, onClick: onPopupClick }}
|
|
53
72
|
toolbarActions={
|
|
54
73
|
<Button renderIcon={Add} size="sm" onClick={onAdd}>
|
|
55
74
|
{schema.addButtonLabel || labels.next}
|
|
@@ -307,6 +326,9 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
|
|
|
307
326
|
}) {
|
|
308
327
|
const labels = useBosSharedI18n();
|
|
309
328
|
const density = densityProp ?? schema.density ?? "compact";
|
|
329
|
+
// Width default lives in the renderer — passing undefined here keeps
|
|
330
|
+
// the contract function's "two-thirds" fallback as the single source.
|
|
331
|
+
const width = schema.width;
|
|
310
332
|
const {
|
|
311
333
|
form,
|
|
312
334
|
setForm,
|
|
@@ -379,6 +401,7 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
|
|
|
379
401
|
disabled={saving}
|
|
380
402
|
onChange={setForm}
|
|
381
403
|
density={density}
|
|
404
|
+
width={width}
|
|
382
405
|
/>
|
|
383
406
|
</PageBody>
|
|
384
407
|
);
|
|
@@ -437,6 +460,7 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
|
|
|
437
460
|
disabled={saving}
|
|
438
461
|
onChange={setForm}
|
|
439
462
|
density={density}
|
|
463
|
+
width={width}
|
|
440
464
|
/>
|
|
441
465
|
</div>
|
|
442
466
|
))}
|
|
@@ -463,6 +487,7 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
|
|
|
463
487
|
disabled={saving}
|
|
464
488
|
onChange={setForm}
|
|
465
489
|
density={density}
|
|
490
|
+
width={width}
|
|
466
491
|
/>
|
|
467
492
|
) : null}
|
|
468
493
|
</PageBody>
|
package/src/crud-hooks.ts
CHANGED
|
@@ -9,9 +9,12 @@ export async function runCrudHook<TData extends Record<string, unknown>, TResult
|
|
|
9
9
|
return hook(data, context);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export function applyCrudFieldOverrides<
|
|
12
|
+
export function applyCrudFieldOverrides<
|
|
13
|
+
TField extends { key: string; readonly?: boolean; required?: boolean; helperText?: unknown },
|
|
14
|
+
TData extends Record<string, unknown> = Record<string, unknown>,
|
|
15
|
+
>(
|
|
13
16
|
fields: TField[],
|
|
14
|
-
hooks?: CrudActionOverrideHooks<
|
|
17
|
+
hooks?: CrudActionOverrideHooks<TData>,
|
|
15
18
|
): TField[] {
|
|
16
19
|
if (!hooks?.fieldOverrides) return fields;
|
|
17
20
|
|
package/src/form-contract.css
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
/* Form contract — Carbon overrides scoped to .ui7-form-contract
|
|
2
2
|
Token source of truth: UI7_FORM_VISUAL_TOKENS in style-contract.ts */
|
|
3
3
|
|
|
4
|
+
/* Panel width — desktop-first (matches the rest of this file).
|
|
5
|
+
The width modifier (one of --width-half / --width-two-thirds / --width-full)
|
|
6
|
+
is always present on the root — `getUi7FormContractClassName` emits one,
|
|
7
|
+
defaulting to two-thirds when the consumer omits the option. Base scope
|
|
8
|
+
sets only the hard ceiling + alignment; modifier sets the width. The
|
|
9
|
+
breakpoint override at the bottom of the file releases the cap on tablet
|
|
10
|
+
+ mobile (<1056px) so fields can use full width on narrow screens. */
|
|
11
|
+
.ui7-form-contract {
|
|
12
|
+
max-width: 1200px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.ui7-form-contract--width-half {
|
|
16
|
+
width: 50%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.ui7-form-contract--width-two-thirds {
|
|
20
|
+
width: 66.6667%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.ui7-form-contract--width-full {
|
|
24
|
+
width: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
4
27
|
/* Label: 12px / 500 / 16px */
|
|
5
28
|
.ui7-form-contract .cds--label {
|
|
6
29
|
margin-block-end: 0;
|
|
@@ -21,15 +44,54 @@
|
|
|
21
44
|
line-height: 1.25rem;
|
|
22
45
|
}
|
|
23
46
|
|
|
47
|
+
/* Control height — keep Select aligned with TextInput / DatePicker per density.
|
|
48
|
+
Carbon uses logical `block-size` (not `height`) on every input element and
|
|
49
|
+
resolves it through --cds-layout-size-height-* tokens that the React `size`
|
|
50
|
+
prop sets on the wrapper. A `height` rule alone loses the cascade because
|
|
51
|
+
`block-size` is a separate physical→logical property in horizontal writing
|
|
52
|
+
mode. We do TWO things to win cleanly:
|
|
53
|
+
1. Redirect Carbon's height tokens at the density-modifier class
|
|
54
|
+
(see @isi-ui7/corporate-themes globals.scss).
|
|
55
|
+
2. Set both `block-size` AND `height` here as a safety net, anchored to
|
|
56
|
+
the same var so density swaps stay in sync across all input flavours.
|
|
57
|
+
--ui7-form-control-height resolves to 1.75rem (compact) / 2.5rem (comfortable). */
|
|
58
|
+
.ui7-form-contract .cds--text-input,
|
|
59
|
+
.ui7-form-contract .cds--select-input,
|
|
60
|
+
.ui7-form-contract .cds--date-picker__input,
|
|
61
|
+
.ui7-form-contract .cds--number input,
|
|
62
|
+
.ui7-form-contract .cds--combo-box__input,
|
|
63
|
+
.ui7-form-contract .cds--dropdown {
|
|
64
|
+
block-size: var(--ui7-form-control-height);
|
|
65
|
+
min-block-size: var(--ui7-form-control-height);
|
|
66
|
+
max-block-size: var(--ui7-form-control-height);
|
|
67
|
+
height: var(--ui7-form-control-height);
|
|
68
|
+
min-height: var(--ui7-form-control-height);
|
|
69
|
+
}
|
|
70
|
+
|
|
24
71
|
/* Full-width date picker */
|
|
25
72
|
.ui7-form-contract .cds--date-picker,
|
|
26
73
|
.ui7-form-contract .cds--date-picker-container {
|
|
27
74
|
width: 100%;
|
|
28
75
|
}
|
|
29
76
|
|
|
77
|
+
/* ── Tablet + mobile: release the desktop width cap ─────────────────────── */
|
|
78
|
+
/* Below Carbon's lg breakpoint (1056px), narrow viewports need every
|
|
79
|
+
available pixel — any desktop width modifier (half / two-thirds / full)
|
|
80
|
+
would leave fields cramped. Release back to full width here, beating
|
|
81
|
+
the modifier selectors via specificity (compound) + later declaration. */
|
|
82
|
+
@media (max-width: 1055px) {
|
|
83
|
+
.ui7-form-contract,
|
|
84
|
+
.ui7-form-contract.ui7-form-contract--width-half,
|
|
85
|
+
.ui7-form-contract.ui7-form-contract--width-two-thirds,
|
|
86
|
+
.ui7-form-contract.ui7-form-contract--width-full {
|
|
87
|
+
width: 100%;
|
|
88
|
+
max-width: 100%;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
30
92
|
/* ── Mobile: collapse all form panels to single column ───────────────────── */
|
|
31
|
-
/*
|
|
32
|
-
|
|
93
|
+
/* Multi-column span values set via inline style are overridden below Carbon's
|
|
94
|
+
md breakpoint (671px). !important required to beat inline style. */
|
|
33
95
|
@media (max-width: 671px) {
|
|
34
96
|
.ui7-form-contract .ui7-form-row > .ui7-form-column {
|
|
35
97
|
grid-column: 1 / -1 !important;
|
package/src/form-numeric.ts
CHANGED
|
@@ -171,3 +171,19 @@ export const INDONESIA_CURRENCY_CONFIG: CurrencyPrecisionConfig = {
|
|
|
171
171
|
precisionByCurrency: { IDR: 2, USD: 4 },
|
|
172
172
|
defaultPrecision: 2,
|
|
173
173
|
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Whole-rupiah currency config — used for ledger-style fields like plafond,
|
|
177
|
+
* subsidi, agent limit, where the convention in Indonesian retail banking is
|
|
178
|
+
* to round to whole IDR (no sen). USD/USD-denominated fields still keep 2
|
|
179
|
+
* decimals (standard cents). Default precision is 0 so any other currency
|
|
180
|
+
* defaults to whole units in these contexts.
|
|
181
|
+
*
|
|
182
|
+
* Use this for "agent plafond / saldo / subsidi" style fields. For amounts
|
|
183
|
+
* that genuinely need sub-rupiah precision (e.g. percentage-derived fees,
|
|
184
|
+
* accrued interest), prefer `INDONESIA_CURRENCY_CONFIG` instead.
|
|
185
|
+
*/
|
|
186
|
+
export const INDONESIA_RUPIAH_WHOLE_CONFIG: CurrencyPrecisionConfig = {
|
|
187
|
+
precisionByCurrency: { IDR: 0, USD: 2 },
|
|
188
|
+
defaultPrecision: 0,
|
|
189
|
+
};
|