@isi-ui7/bos7-shared 0.3.8 → 0.3.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isi-ui7/bos7-shared",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "Shared auth7 and layout primitives for bos7 applications.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,11 +9,11 @@
9
9
  "directory": "packages/bos7-shared"
10
10
  },
11
11
  "type": "module",
12
- "main": "src/index.ts",
13
- "module": "src/index.ts",
14
- "types": "src/index.ts",
12
+ "main": "dist/index.js",
13
+ "module": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
15
  "exports": {
16
- ".": "./src/index.ts",
16
+ ".": "./dist/index.js",
17
17
  "./auth7": "./src/auth7/index.ts",
18
18
  "./page-layout": "./src/page-layout.tsx",
19
19
  "./modal-layout": "./src/modal-layout.tsx",
@@ -50,85 +50,28 @@
50
50
  "./bff/health": "./src/bff/health.ts",
51
51
  "./observability/otel-init": "./src/observability/otel-init.ts",
52
52
  "./form-types": "./src/form-types.ts",
53
- "./form-value-schema": "./src/form-value-schema.ts",
54
53
  "./form-numeric": "./src/form-numeric.ts",
55
54
  "./form-renderer": "./src/form-renderer.tsx",
56
55
  "./form-renderer-utils": "./src/form-renderer-utils.ts",
57
56
  "./form-rules": "./src/form-rules.ts",
58
57
  "./i18n": "./src/i18n.tsx",
59
58
  "./workflow/use-crud-form": "./src/workflow/use-crud-form.ts",
60
- "./styles": "./src/form-contract.css"
59
+ "./styles": "./src/form-contract.css",
60
+ "./form-value-schema": "./src/form-value-schema.ts"
61
61
  },
62
62
  "publishConfig": {
63
63
  "registry": "https://registry.npmjs.org",
64
- "access": "public",
65
- "main": "dist/index.js",
66
- "module": "dist/index.js",
67
- "types": "dist/index.d.ts",
68
- "exports": {
69
- ".": "./dist/index.js",
70
- "./auth7": "./src/auth7/index.ts",
71
- "./page-layout": "./src/page-layout.tsx",
72
- "./modal-layout": "./src/modal-layout.tsx",
73
- "./form-layout": "./src/form-layout.tsx",
74
- "./backend": "./src/backend.ts",
75
- "./export": "./src/export.ts",
76
- "./types/notification": "./src/types/notification.ts",
77
- "./nats/client": "./src/nats/client.ts",
78
- "./event-bus": "./src/event-bus/index.ts",
79
- "./event-bus/useEventBus": "./src/event-bus/useEventBus.ts",
80
- "./api": "./src/api.ts",
81
- "./types/core": "./src/types/core.ts",
82
- "./style-contract": "./src/style-contract.ts",
83
- "./crud-components": "./src/crud-components.tsx",
84
- "./workflow/backend": "./src/workflow/backend.ts",
85
- "./workflow/notif7": "./src/workflow/notif7.ts",
86
- "./workflow/api-client": "./src/workflow/api-client.ts",
87
- "./workflow/starter": "./src/workflow/starter.ts",
88
- "./workflow/use-workflow-tracker": "./src/workflow/use-workflow-tracker.ts",
89
- "./workflow/crud-client": "./src/workflow/crud-client.ts",
90
- "./data-table/cursor-adapter": "./src/data-table/cursor-adapter.ts",
91
- "./data-table/proxy": "./src/data-table/proxy.ts",
92
- "./notification/routing": "./src/notification/routing.ts",
93
- "./shell/interaction": "./src/shell/interaction.ts",
94
- "./shell/branch": "./src/shell/branch.ts",
95
- "./notif7": "./src/notif7.ts",
96
- "./shell/provider": "./src/shell/provider.tsx",
97
- "./shell/app-shell-layout": "./src/shell/app-shell-layout.tsx",
98
- "./notifications-bff": "./src/notifications-bff.ts",
99
- "./bff/auth-me": "./src/bff/auth-me.ts",
100
- "./bff/auth-refresh": "./src/bff/auth-refresh.ts",
101
- "./bff/auth-logout": "./src/bff/auth-logout.ts",
102
- "./bff/auth-preferences": "./src/bff/auth-preferences.ts",
103
- "./bff/health": "./src/bff/health.ts",
104
- "./observability/otel-init": "./src/observability/otel-init.ts",
105
- "./form-types": "./src/form-types.ts",
106
- "./form-numeric": "./src/form-numeric.ts",
107
- "./form-renderer": "./src/form-renderer.tsx",
108
- "./form-renderer-utils": "./src/form-renderer-utils.ts",
109
- "./form-rules": "./src/form-rules.ts",
110
- "./i18n": "./src/i18n.tsx",
111
- "./workflow/use-crud-form": "./src/workflow/use-crud-form.ts",
112
- "./styles": "./src/form-contract.css",
113
- "./form-value-schema": "./src/form-value-schema.ts"
114
- }
64
+ "access": "public"
115
65
  },
116
66
  "files": [
117
67
  "dist",
118
68
  "src"
119
69
  ],
120
- "scripts": {
121
- "build": "vite build",
122
- "prepublishOnly": "pnpm run build",
123
- "lint": "eslint \"src/**/*.{ts,tsx}\"",
124
- "test": "vitest run --passWithNoTests",
125
- "typecheck": "tsc --noEmit"
126
- },
127
70
  "peerDependencies": {
128
71
  "@carbon/icons-react": "^11.71.0",
129
72
  "@carbon/react": "^1.97.0",
130
- "@isi-ui7/corporate-themes": ">=0.2.6",
131
- "@isi-ui7/data-table": ">=0.2.4",
73
+ "@isi-ui7/corporate-themes": ">=0.2.7",
74
+ "@isi-ui7/data-table": ">=0.2.5",
132
75
  "@isi-ui7/editable-table": ">=0.2.3",
133
76
  "@isi-ui7/i18n": ">=0.2.3",
134
77
  "@isi-ui7/lookup-input": ">=0.2.4",
@@ -144,14 +87,6 @@
144
87
  "@carbon/react": "^1.97.0",
145
88
  "@eslint/eslintrc": "^3.3.1",
146
89
  "@eslint/js": "^9.39.0",
147
- "@isi-ui7/corporate-themes": "workspace:*",
148
- "@isi-ui7/data-table": "workspace:*",
149
- "@isi-ui7/editable-table": "workspace:*",
150
- "@isi-ui7/i18n": "workspace:*",
151
- "@isi-ui7/lookup-input": "workspace:*",
152
- "@isi-ui7/modal-manager": "workspace:*",
153
- "@isi-ui7/realtime": "workspace:*",
154
- "@isi-ui7/ui-shell": "workspace:*",
155
90
  "@testing-library/dom": "^10.0.0",
156
91
  "@testing-library/react": "^16.0.0",
157
92
  "@testing-library/user-event": "^14.5.0",
@@ -170,14 +105,19 @@
170
105
  "typescript": "^5.3.3",
171
106
  "vite": "^5.0.0",
172
107
  "vite-plugin-dts": "^3.6.0",
173
- "vitest": "^1.0.0"
108
+ "vitest": "^1.0.0",
109
+ "@isi-ui7/corporate-themes": "0.2.7",
110
+ "@isi-ui7/data-table": "0.2.5",
111
+ "@isi-ui7/editable-table": "0.2.3",
112
+ "@isi-ui7/i18n": "0.2.3",
113
+ "@isi-ui7/lookup-input": "0.2.4",
114
+ "@isi-ui7/modal-manager": "0.2.2",
115
+ "@isi-ui7/ui-shell": "0.2.8",
116
+ "@isi-ui7/realtime": "0.2.3"
174
117
  },
175
118
  "dependencies": {
176
119
  "@carbon/icons-react": "^11.71.0",
177
120
  "@carbon/react": "^1.97.0",
178
- "@isi-ui7/data-table": "workspace:*",
179
- "@isi-ui7/editable-table": "workspace:*",
180
- "@isi-ui7/lookup-input": "workspace:*",
181
121
  "@opentelemetry/auto-instrumentations-node": "^0.57.0",
182
122
  "@opentelemetry/exporter-trace-otlp-http": "^0.57.0",
183
123
  "@opentelemetry/sdk-node": "^0.57.0",
@@ -185,6 +125,15 @@
185
125
  "exceljs": "^4.4.0",
186
126
  "jose": "^5.9.6",
187
127
  "jspdf": "^4.2.1",
188
- "jspdf-autotable": "^5.0.7"
128
+ "jspdf-autotable": "^5.0.7",
129
+ "@isi-ui7/data-table": "0.2.5",
130
+ "@isi-ui7/editable-table": "0.2.3",
131
+ "@isi-ui7/lookup-input": "0.2.4"
132
+ },
133
+ "scripts": {
134
+ "build": "vite build",
135
+ "lint": "eslint \"src/**/*.{ts,tsx}\"",
136
+ "test": "vitest run --passWithNoTests",
137
+ "typecheck": "tsc --noEmit"
189
138
  }
190
- }
139
+ }
@@ -10,8 +10,6 @@ import {
10
10
  ModalBody,
11
11
  ModalFooter,
12
12
  ModalHeader,
13
- ProgressIndicator,
14
- ProgressStep,
15
13
  Select,
16
14
  SelectItem,
17
15
  TextArea,
@@ -489,6 +487,34 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
489
487
 
490
488
  const layout = schema.layout;
491
489
 
490
+ /**
491
+ * Wizard adalah alat bantu PENGISIAN, bukan cara menyusun halaman.
492
+ *
493
+ * Ia ada untuk memandu petugas melalui formulir panjang yang belum pernah
494
+ * diisi, dan — pada registrasi nasabah — untuk MENAHAN langkah berikutnya
495
+ * sampai gerbang `canLeavePage` terpenuhi. Kedua alasan itu hanya berlaku
496
+ * saat data DIBUAT.
497
+ *
498
+ * Pada `edit` dan `view` datanya sudah ada dan sudah lolos gerbangnya.
499
+ * Memaksa operator melangkah lima kali untuk membaca satu field di langkah
500
+ * 5 bukan panduan, ia penghalang — dan pada `view` bahkan tidak bisa
501
+ * dilewati: footer mode-view sengaja nol tombol Lanjut, jadi satu-satunya
502
+ * jalan maju adalah menebak bahwa stepper-nya bisa diklik.
503
+ *
504
+ * Karena itu di luar `create` wizard dirender DATAR: seluruh halaman
505
+ * berurutan dalam satu aliran, tanpa stepper dan tanpa Lanjut/Kembali.
506
+ * Yang HILANG hanya navigasinya; isinya tidak ada yang dibuang.
507
+ *
508
+ * Aman terhadap validasi: `handleSave` memakai `validateAll()`, yang sudah
509
+ * mengumpulkan field dari SELURUH halaman tanpa peduli halaman aktif —
510
+ * jadi menyimpan dari bentuk datar memeriksa hal yang sama persis.
511
+ *
512
+ * Keputusan PM 2026-08-19. Sengaja dipasang di sini, BUKAN di skema tiap
513
+ * app: ini keputusan tentang cara me-render sebuah layout, dan menaruhnya
514
+ * di skema berarti tiap app harus mengingat untuk mengulanginya.
515
+ */
516
+ const wizardNav = layout.type === "wizard" && mode === "create";
517
+
492
518
  const renderBody = () => {
493
519
  if (layout.type === "single-page") {
494
520
  return (
@@ -570,6 +596,76 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
570
596
  );
571
597
  }
572
598
 
599
+ // Wizard di luar `create` — datar, tanpa stepper. Lihat `wizardNav`.
600
+ //
601
+ // Syaratnya ditulis LENGKAP (`layout.type === "wizard" && !wizardNav`),
602
+ // bukan `!wizardNav` saja. Keduanya setara hari ini, tapi bentuk pendek
603
+ // benar hanya karena `single-page` dan `tabs` sudah return di atas — ia
604
+ // cabang *sisa*, bukan cabang *wizard*. Varian layout ke-5 yang lupa
605
+ // ditaruh di atas sini akan ikut dirender datar tanpa galat, tanpa lint,
606
+ // tanpa uji yang menahan. Dengan bentuk lengkap, kelalaian yang sama
607
+ // menjadi galat `tsc` di `layout.pages` beberapa baris di bawah.
608
+ if (layout.type === "wizard" && !wizardNav) {
609
+ return (
610
+ <PageBody>
611
+ {errBanner}
612
+ {layout.pages.map((pg, i) => (
613
+ <div key={i} style={{ marginBottom: "2.5rem" }}>
614
+ {/* Label halaman tetap dirender — sebagai JUDUL KELOMPOK, bukan
615
+ navigasi. Membuang steppernya tidak boleh ikut membuang satu-
616
+ satunya tempat `pg.label`/`pg.sublabel` pernah tampil: pada
617
+ form 5 langkah, hasilnya 13 panel beruntun tanpa satu pun
618
+ pemisah tingkat-halaman. Yang dilarang PM adalah navigasinya,
619
+ bukan judulnya. */}
620
+ <div
621
+ style={{
622
+ marginBottom: "1rem",
623
+ paddingBottom: "0.5rem",
624
+ borderBottom: "1px solid var(--cds-border-subtle-01, #e0e0e0)",
625
+ }}
626
+ >
627
+ <div
628
+ style={{
629
+ fontSize: "1rem",
630
+ fontWeight: 600,
631
+ color: "var(--cds-text-primary, #161616)",
632
+ }}
633
+ >
634
+ {pg.label}
635
+ </div>
636
+ {pg.sublabel ? (
637
+ <div
638
+ style={{
639
+ fontSize: "0.75rem",
640
+ color: "var(--cds-text-secondary, #525252)",
641
+ marginTop: "0.125rem",
642
+ }}
643
+ >
644
+ {pg.sublabel}
645
+ </div>
646
+ ) : null}
647
+ </div>
648
+ <SchemaFormRenderer
649
+ mode={mode}
650
+ value={form}
651
+ sections={pg.sections}
652
+ errors={fieldErrors}
653
+ disabled={saving}
654
+ onChange={setForm}
655
+ density={density}
656
+ // `width` apa adanya, BUKAN `width ?? "full"` seperti cabang
657
+ // wizard. `full` di sana berarti "penuhi kolom KIRI", jalan
658
+ // keluar untuk ruang yang dipersempit stepper. Di sini nol
659
+ // stepper, jadi alasannya hilang dan default kontrak
660
+ // ("two-thirds") kembali berlaku.
661
+ width={width}
662
+ />
663
+ </div>
664
+ ))}
665
+ </PageBody>
666
+ );
667
+ }
668
+
573
669
  const currentPage = layout.pages[page];
574
670
  return (
575
671
  <PageBody>
@@ -640,7 +736,9 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
640
736
  );
641
737
  }
642
738
 
643
- if (layout.type === "wizard") {
739
+ // Lanjut/Kembali hanya saat wizard benar-benar memandu — lihat `wizardNav`.
740
+ // Di `edit`, footer jatuh ke bentuk baku: satu tombol Simpan.
741
+ if (wizardNav) {
644
742
  return (
645
743
  <PageFooter spread>
646
744
  <Button kind="secondary" size="sm" onClick={onBack} disabled={saving}>
@@ -657,7 +755,13 @@ export function CrudSchemaPage<TData extends Record<string, unknown>>({
657
755
  kind="primary"
658
756
  size="sm"
659
757
  onClick={handleSave}
660
- disabled={saving || (mode === "edit" && !isDirty)}
758
+ // Nol penjaga `isDirty` di sini: blok ini kini hanya terjangkau
759
+ // saat `create` (lihat `wizardNav`), dan form baru yang belum
760
+ // disentuh memang belum "kotor" — memakai penjaga edit di sini
761
+ // akan mematikan tombol Simpan pada satu-satunya mode yang
762
+ // masih memakainya. tsc menandainya sebagai perbandingan yang
763
+ // tak mungkin benar; ia benar.
764
+ disabled={saving}
661
765
  >
662
766
  {saving ? labels.saving : submitLabel}
663
767
  </Button>