@isi-ui7/bos7-shared 0.5.2 → 0.5.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/form-types.d.ts +17 -0
- package/package.json +6 -6
- package/src/detail-rows-hide-buttons.test.tsx +109 -0
- package/src/form-renderer.tsx +2 -0
- package/src/form-types.ts +18 -0
package/dist/form-types.d.ts
CHANGED
|
@@ -105,6 +105,23 @@ export type DetailRowsConfig = {
|
|
|
105
105
|
* Forwarded to `<EditableTable lockExistingRows>`.
|
|
106
106
|
*/
|
|
107
107
|
lockExistingRows?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Menyembunyikan tombol "Tambah Baris" / aksi "Hapus" per baris.
|
|
110
|
+
*
|
|
111
|
+
* 🔴 Ada karena `maxRows` dan `lockExistingRows` KEDUANYA salah untuk tabel
|
|
112
|
+
* yang barisnya ditentukan master tapi NILAINYA diisi petugas (limit
|
|
113
|
+
* transaksi CDD): `maxRows` men-DISABLE tombolnya (ia tetap ada, dan
|
|
114
|
+
* kontrol yang ada-tapi-nol-pernah-bekerja mengajari petugas bahwa fiturnya
|
|
115
|
+
* rusak), `lockExistingRows` membuat baris termuat READ-ONLY seluruhnya.
|
|
116
|
+
*
|
|
117
|
+
* ⚠️ Keduanya diteruskan APA ADANYA ke `<EditableTable>` (0.2.4+). Prop yang
|
|
118
|
+
* dideklarasikan di sini tapi NOL diteruskan akan lolos tsc, lolos uji tipe,
|
|
119
|
+
* dan mencapai NOL — itu persis keadaan yang berkas ini perbaiki, dan
|
|
120
|
+
* `detail-rows-hide-buttons.test.tsx` menguji SAMPAI (tombol hilang di DOM),
|
|
121
|
+
* bukan ADA (prop hadir di objek config).
|
|
122
|
+
*/
|
|
123
|
+
hideAddButton?: boolean;
|
|
124
|
+
hideDeleteAction?: boolean;
|
|
108
125
|
};
|
|
109
126
|
/**
|
|
110
127
|
* Satu kolom pada tabel RINGKAS `detail-modal`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isi-ui7/bos7-shared",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Shared auth7 and layout primitives for bos7 applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@carbon/icons-react": "^11.71.0",
|
|
72
72
|
"@carbon/react": "^1.97.0",
|
|
73
|
-
"@isi-ui7/corporate-themes": ">=0.2.
|
|
73
|
+
"@isi-ui7/corporate-themes": ">=0.2.22",
|
|
74
74
|
"@isi-ui7/data-table": ">=0.2.5",
|
|
75
|
-
"@isi-ui7/editable-table": ">=0.2.
|
|
75
|
+
"@isi-ui7/editable-table": ">=0.2.5",
|
|
76
76
|
"@isi-ui7/i18n": ">=0.2.4",
|
|
77
77
|
"@isi-ui7/lookup-input": ">=0.2.4",
|
|
78
78
|
"@isi-ui7/modal-manager": ">=0.2.0",
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"vite": "^5.0.0",
|
|
107
107
|
"vite-plugin-dts": "^3.6.0",
|
|
108
108
|
"vitest": "^1.0.0",
|
|
109
|
-
"@isi-ui7/corporate-themes": "0.2.
|
|
109
|
+
"@isi-ui7/corporate-themes": "0.2.22",
|
|
110
110
|
"@isi-ui7/data-table": "0.2.5",
|
|
111
|
-
"@isi-ui7/editable-table": "0.2.
|
|
111
|
+
"@isi-ui7/editable-table": "0.2.5",
|
|
112
112
|
"@isi-ui7/i18n": "0.2.4",
|
|
113
113
|
"@isi-ui7/lookup-input": "0.2.4",
|
|
114
114
|
"@isi-ui7/modal-manager": "0.2.2",
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"jspdf": "^4.2.1",
|
|
128
128
|
"jspdf-autotable": "^5.0.7",
|
|
129
129
|
"@isi-ui7/data-table": "0.2.5",
|
|
130
|
-
"@isi-ui7/editable-table": "0.2.
|
|
130
|
+
"@isi-ui7/editable-table": "0.2.5",
|
|
131
131
|
"@isi-ui7/lookup-input": "0.2.4"
|
|
132
132
|
},
|
|
133
133
|
"scripts": {
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { cleanup, render, screen } from "@testing-library/react";
|
|
3
|
+
import { SchemaFormRenderer } from "./form-renderer";
|
|
4
|
+
import type { FormSection } from "./form-types";
|
|
5
|
+
|
|
6
|
+
afterEach(cleanup);
|
|
7
|
+
|
|
8
|
+
type D = Record<string, unknown>;
|
|
9
|
+
|
|
10
|
+
// `hideAddButton` / `hideDeleteAction` menembus `detail-rows` sampai ke
|
|
11
|
+
// `<EditableTable>`.
|
|
12
|
+
//
|
|
13
|
+
// 🔴 Kenapa berkas ini menguji DOM dan bukan objek config.
|
|
14
|
+
//
|
|
15
|
+
// Kedua prop mendarat di `@isi-ui7/editable-table` 0.2.4 dengan ujinya sendiri
|
|
16
|
+
// (28 hijau, sabotase dua arah). Lalu NOL SEORANG PUN dapat memakainya: layar
|
|
17
|
+
// nol merender `<EditableTable>` langsung — ia lewat `detail-rows` di paket
|
|
18
|
+
// ini, dan paket ini nol mengenal kedua prop itu. Menyetelnya di skema
|
|
19
|
+
// konsumen mencapai NOL, dan ia terlihat seperti berhasil: tsc hijau, uji
|
|
20
|
+
// hijau, tombolnya tetap ada.
|
|
21
|
+
//
|
|
22
|
+
// ⚠️ Prop yang dideklarasikan di `DetailRowsConfig` tapi nol diteruskan di
|
|
23
|
+
// `form-renderer.tsx` menghasilkan keadaan yang SAMA, satu lapis lebih tinggi
|
|
24
|
+
// — dan uji yang mengasersi "propnya ada di config" akan HIJAU sepanjang
|
|
25
|
+
// waktu. Karena itu asersinya: tombolnya HILANG DI DOM.
|
|
26
|
+
//
|
|
27
|
+
// ⚠️ Dan lengan SEBALIKNYA wajib: prop yang SELALU menyembunyikan lolos uji
|
|
28
|
+
// yang cuma memeriksa `true`.
|
|
29
|
+
|
|
30
|
+
const BARIS = [{ jenis: "Tarik Tunai", nominal: "1000000" }];
|
|
31
|
+
|
|
32
|
+
function sectionDgn(detail: Record<string, unknown>): FormSection<D> {
|
|
33
|
+
return {
|
|
34
|
+
title: "Limit",
|
|
35
|
+
fields: [
|
|
36
|
+
{
|
|
37
|
+
key: "limits",
|
|
38
|
+
label: "Limit Transaksi",
|
|
39
|
+
type: "detail-rows",
|
|
40
|
+
span: 12,
|
|
41
|
+
detailRows: {
|
|
42
|
+
columns: [
|
|
43
|
+
{ field: "jenis", header: "Jenis", columnType: { type: "text" } },
|
|
44
|
+
{ field: "nominal", header: "Nominal", columnType: { type: "text" } },
|
|
45
|
+
],
|
|
46
|
+
newRowFactory: () => ({ jenis: "", nominal: "" }),
|
|
47
|
+
...detail,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function renderDgn(detail: Record<string, unknown> = {}) {
|
|
55
|
+
return render(
|
|
56
|
+
<SchemaFormRenderer<D>
|
|
57
|
+
mode="edit"
|
|
58
|
+
value={{ limits: BARIS }}
|
|
59
|
+
sections={[sectionDgn(detail)]}
|
|
60
|
+
onChange={() => {}}
|
|
61
|
+
/>,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
describe("detail-rows meneruskan hideAddButton / hideDeleteAction ke EditableTable", () => {
|
|
66
|
+
it("BAWAAN (nol diberikan): KEDUA kontrol tampil", () => {
|
|
67
|
+
// 🔴 Kontrol positif untuk kedua uji di bawah. Tanpa lengan ini, sebuah
|
|
68
|
+
// perender yang menyembunyikan SEGALANYA lulus keduanya — dan begitu juga
|
|
69
|
+
// perender yang kebetulan nol merender tabelnya sama sekali.
|
|
70
|
+
renderDgn();
|
|
71
|
+
expect(screen.getByText("Tambah Baris")).toBeTruthy();
|
|
72
|
+
expect(screen.getAllByLabelText("Hapus").length).toBe(1);
|
|
73
|
+
// Dan barisnya memang ADA: kalau tabelnya kosong, "1 tombol Hapus" nol
|
|
74
|
+
// dapat terjadi, jadi asersi ini juga menjaga penyebutnya.
|
|
75
|
+
expect(screen.getByText("Tarik Tunai")).toBeTruthy();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("hideAddButton: Tambah HILANG di DOM, Hapus TETAP", () => {
|
|
79
|
+
renderDgn({ hideAddButton: true });
|
|
80
|
+
expect(screen.queryByText("Tambah Baris")).toBeNull();
|
|
81
|
+
// Lengan yang membuktikan keduanya TERPISAH saat menyeberangi lapis ini —
|
|
82
|
+
// satu flag yang menyembunyikan dua hal lolos tanpa ini.
|
|
83
|
+
expect(screen.getAllByLabelText("Hapus").length).toBe(1);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("hideDeleteAction: Hapus HILANG di DOM, Tambah TETAP", () => {
|
|
87
|
+
renderDgn({ hideDeleteAction: true });
|
|
88
|
+
expect(screen.queryAllByLabelText("Hapus").length).toBe(0);
|
|
89
|
+
expect(screen.getByText("Tambah Baris")).toBeTruthy();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("false eksplisit ⇒ KEDUANYA tetap tampil", () => {
|
|
93
|
+
// Membedakan "diteruskan apa adanya" dari "diteruskan sebagai truthy".
|
|
94
|
+
// `hideAddButton={detail.hideAddButton ?? true}` lolos ketiga uji di atas.
|
|
95
|
+
renderDgn({ hideAddButton: false, hideDeleteAction: false });
|
|
96
|
+
expect(screen.getByText("Tambah Baris")).toBeTruthy();
|
|
97
|
+
expect(screen.getAllByLabelText("Hapus").length).toBe(1);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("keduanya menyala: nol ada kontrol baris, TAPI selnya tetap tersunting", () => {
|
|
101
|
+
// Pembedaan yang paling mudah hilang: `readOnly` juga menyembunyikan
|
|
102
|
+
// kedua tombol — tapi ia MEMBEKUKAN selnya, dan itu cacat yang persis
|
|
103
|
+
// baru diperbaiki di layar limit transaksi.
|
|
104
|
+
renderDgn({ hideAddButton: true, hideDeleteAction: true });
|
|
105
|
+
expect(screen.queryByText("Tambah Baris")).toBeNull();
|
|
106
|
+
expect(screen.queryAllByLabelText("Hapus").length).toBe(0);
|
|
107
|
+
expect(screen.getByText("Tarik Tunai")).toBeTruthy();
|
|
108
|
+
});
|
|
109
|
+
});
|
package/src/form-renderer.tsx
CHANGED
|
@@ -661,6 +661,8 @@ export function SchemaFormRenderer<TData extends Record<string, unknown>>({
|
|
|
661
661
|
maxRows={detail.maxRows}
|
|
662
662
|
readOnly={effectiveReadonly}
|
|
663
663
|
lockExistingRows={detail.lockExistingRows}
|
|
664
|
+
hideAddButton={detail.hideAddButton}
|
|
665
|
+
hideDeleteAction={detail.hideDeleteAction}
|
|
664
666
|
validateRow={detail.validateRow}
|
|
665
667
|
lookupCellRenderer={(args) => {
|
|
666
668
|
const ct = args.column.columnType;
|
package/src/form-types.ts
CHANGED
|
@@ -112,6 +112,24 @@ export type DetailRowsConfig = {
|
|
|
112
112
|
* Forwarded to `<EditableTable lockExistingRows>`.
|
|
113
113
|
*/
|
|
114
114
|
lockExistingRows?: boolean;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Menyembunyikan tombol "Tambah Baris" / aksi "Hapus" per baris.
|
|
118
|
+
*
|
|
119
|
+
* 🔴 Ada karena `maxRows` dan `lockExistingRows` KEDUANYA salah untuk tabel
|
|
120
|
+
* yang barisnya ditentukan master tapi NILAINYA diisi petugas (limit
|
|
121
|
+
* transaksi CDD): `maxRows` men-DISABLE tombolnya (ia tetap ada, dan
|
|
122
|
+
* kontrol yang ada-tapi-nol-pernah-bekerja mengajari petugas bahwa fiturnya
|
|
123
|
+
* rusak), `lockExistingRows` membuat baris termuat READ-ONLY seluruhnya.
|
|
124
|
+
*
|
|
125
|
+
* ⚠️ Keduanya diteruskan APA ADANYA ke `<EditableTable>` (0.2.4+). Prop yang
|
|
126
|
+
* dideklarasikan di sini tapi NOL diteruskan akan lolos tsc, lolos uji tipe,
|
|
127
|
+
* dan mencapai NOL — itu persis keadaan yang berkas ini perbaiki, dan
|
|
128
|
+
* `detail-rows-hide-buttons.test.tsx` menguji SAMPAI (tombol hilang di DOM),
|
|
129
|
+
* bukan ADA (prop hadir di objek config).
|
|
130
|
+
*/
|
|
131
|
+
hideAddButton?: boolean;
|
|
132
|
+
hideDeleteAction?: boolean;
|
|
115
133
|
};
|
|
116
134
|
|
|
117
135
|
/**
|