@starasia/admin 14.9.0 → 14.11.0
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/components/FilterBar/components/ColumnHeaderFilter.d.ts +34 -0
- package/dist/components/FilterBar/components/pills/DatePill.d.ts +14 -1
- package/dist/components/FilterBar/components/pills/TextPill.d.ts +19 -0
- package/dist/components/FilterBar/hooks/useFilterBarControls.d.ts +12 -0
- package/dist/components/FilterBar/index.d.ts +1 -0
- package/dist/components/FilterBar/types.d.ts +14 -2
- package/dist/components/TableLayout/ColumnMenu.d.ts +12 -1
- package/dist/components/TableLayout/types.d.ts +10 -0
- package/dist/index.cjs.js +5 -5
- package/dist/index.es.js +3058 -2726
- package/dist/index.umd.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { FilterFieldConfig } from '../types';
|
|
3
|
+
import { FilterBarControls } from '../hooks/useFilterBarControls';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kontrol filter untuk dipasang di HEADER kolom TableLayout (Excel-style),
|
|
7
|
+
* dirakit otomatis dari `field.type` — sama seperti FilterBar merender tipe,
|
|
8
|
+
* dan memakai komponen date design system yang SAMA (`StarasiaDate` + `OpMenu`
|
|
9
|
+
* + `CompactBody` yang dipakai FilterBar). Menulis ke sumber filter yang SAMA
|
|
10
|
+
* (`useFilterBarControls`), jadi pill FilterBar + query ikut sinkron;
|
|
11
|
+
* TableLayout tetap filter-agnostic.
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const filter = useFilterBarControls({ filterConfigs });
|
|
15
|
+
* const columns = baseColumns.map((col) => {
|
|
16
|
+
* const field = filterConfigs.find((f) => f.key === col.key);
|
|
17
|
+
* if (!field) return col;
|
|
18
|
+
* return {
|
|
19
|
+
* ...col,
|
|
20
|
+
* renderFilter: () => <ColumnHeaderFilter field={field} controls={filter} />,
|
|
21
|
+
* filterActive: isColumnFilterActive(field, filter),
|
|
22
|
+
* };
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export interface ColumnHeaderFilterProps {
|
|
27
|
+
/** Config filter — objek yang SAMA yang diberikan ke `<FilterBar>` via `filterConfigs`. */
|
|
28
|
+
field: FilterFieldConfig;
|
|
29
|
+
/** Controller dari `useFilterBarControls` (sumber filter yang sama dg FilterBar). */
|
|
30
|
+
controls: FilterBarControls;
|
|
31
|
+
}
|
|
32
|
+
/** Apakah field ini sedang punya filter aktif — untuk menyalakan funnel header. */
|
|
33
|
+
export declare const isColumnFilterActive: (field: FilterFieldConfig, controls: FilterBarControls) => boolean;
|
|
34
|
+
export declare const ColumnHeaderFilter: ({ field, controls }: ColumnHeaderFilterProps) => React.JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { DateCompactFilterField, DateCompactValue, DateFilterField } from '../../types';
|
|
2
|
+
import { DateCompactFilterField, DateCompactOp, DateCompactValue, DateFilterField } from '../../types';
|
|
3
3
|
|
|
4
4
|
interface DatePillProps {
|
|
5
5
|
field: DateFilterField | DateCompactFilterField;
|
|
@@ -9,5 +9,18 @@ interface DatePillProps {
|
|
|
9
9
|
/** Removes the whole pill. Omit for locked fields. */
|
|
10
10
|
onRemove?: () => void;
|
|
11
11
|
}
|
|
12
|
+
type DateMode = 'days' | 'months' | 'years';
|
|
13
|
+
export declare const ALL_OPS: DateCompactOp[];
|
|
12
14
|
export declare const DatePill: React.FC<DatePillProps>;
|
|
15
|
+
export declare const OpMenu: React.FC<{
|
|
16
|
+
op: DateCompactOp;
|
|
17
|
+
ops: DateCompactOp[];
|
|
18
|
+
onChange: (next: DateCompactOp) => void;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const CompactBody: React.FC<{
|
|
21
|
+
value: DateCompactValue | undefined;
|
|
22
|
+
op: DateCompactOp;
|
|
23
|
+
mode?: DateMode;
|
|
24
|
+
onChange: (v: unknown) => void;
|
|
25
|
+
}>;
|
|
13
26
|
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { TextFilterField } from '../../types';
|
|
3
|
+
|
|
4
|
+
interface TextPillProps {
|
|
5
|
+
field: TextFilterField;
|
|
6
|
+
value: string;
|
|
7
|
+
/** Tulis nilai baru (string kosong = hapus nilai). */
|
|
8
|
+
onChange: (v: string) => void;
|
|
9
|
+
/** Kosongkan nilai tanpa menghapus pill. */
|
|
10
|
+
onClear: () => void;
|
|
11
|
+
/** Hapus pill sepenuhnya. Kosong untuk field `locked`. */
|
|
12
|
+
onRemove?: () => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Text pill — filter teks bebas ("contains"). Debounced (default 300ms) supaya
|
|
16
|
+
* tak refetch tiap ketikan; nilai kosong menghapus filter.
|
|
17
|
+
*/
|
|
18
|
+
export declare const TextPill: React.FC<TextPillProps>;
|
|
19
|
+
export {};
|
|
@@ -22,6 +22,18 @@ export interface FilterBarControls {
|
|
|
22
22
|
isActive: (key: string, value: string) => boolean;
|
|
23
23
|
/** Nilai-nilai aktif sekarang pada filter `key`. */
|
|
24
24
|
values: (key: string) => string[];
|
|
25
|
+
/**
|
|
26
|
+
* Baca nilai MENTAH filter apa pun — termasuk non-select. `date` → `Date`,
|
|
27
|
+
* `date-compact` → `DateCompactValue`, select-type → array `{ value, label }`.
|
|
28
|
+
* Untuk memfilter dari luar FilterBar pada tipe yang tak muat di `values`.
|
|
29
|
+
*/
|
|
30
|
+
getRaw: (key: string) => unknown;
|
|
31
|
+
/**
|
|
32
|
+
* Tulis nilai MENTAH lewat jalur yang SAMA dengan FilterBar — mendukung
|
|
33
|
+
* `date` (kirim `Date`) & `date-compact` (kirim `DateCompactValue`) yang TIDAK
|
|
34
|
+
* didukung `set`. `null`/`undefined` → hapus filter. Pill + query ikut sinkron.
|
|
35
|
+
*/
|
|
36
|
+
setRaw: (key: string, value: unknown) => void;
|
|
25
37
|
/** Ada filter aktif (apa pun). */
|
|
26
38
|
hasActiveFilter: boolean;
|
|
27
39
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { FilterBar } from './FilterBar';
|
|
2
2
|
export { useFilterBarApiParams, type UseFilterBarApiParamsOptions, type FilterBarApiParams } from './hooks/useFilterBarApiParams';
|
|
3
3
|
export { useFilterBarControls, type UseFilterBarControlsOptions, type FilterBarControls } from './hooks/useFilterBarControls';
|
|
4
|
+
export { ColumnHeaderFilter, isColumnFilterActive, type ColumnHeaderFilterProps } from './components/ColumnHeaderFilter';
|
|
4
5
|
export { expandDateCompact, type ExpandDateCompactOptions } from './utils/expand-date-compact';
|
|
5
6
|
export { localStorageAdapter, storageKeys } from './utils/storage-adapter';
|
|
6
7
|
export type { FilterBarProps, FilterFieldConfig, FilterFieldType, SelectFilterField, CheckboxMultipleFilterField, DateFilterField, DateCompactFilterField, DateCompactOp, DateCompactValue, RelativeDirection, RelativePeriod, ColumnConfig, ColumnPrefState, SavedView, FilterStorageAdapter } from './types';
|
|
@@ -8,7 +8,7 @@ import { Pagination } from '../TableSection/types';
|
|
|
8
8
|
* (`handleChangeFilter`, `getValuesFilter`, …) so the JSON-blob URL encoding
|
|
9
9
|
* (`?filter={...}`) is reused as-is. `key` is the param name inside that blob.
|
|
10
10
|
*/
|
|
11
|
-
export type FilterFieldType = 'date' | 'date-compact' | 'dropdown' | 'dropdown-multiple' | 'checkbox-multiple' | 'radio';
|
|
11
|
+
export type FilterFieldType = 'date' | 'date-compact' | 'dropdown' | 'dropdown-multiple' | 'checkbox-multiple' | 'radio' | 'text';
|
|
12
12
|
interface BaseFilterField {
|
|
13
13
|
/** Stable key — used as the field name inside the `?filter` blob. */
|
|
14
14
|
key: string;
|
|
@@ -49,6 +49,18 @@ export interface CheckboxMultipleFilterField extends BaseFilterField {
|
|
|
49
49
|
value: string;
|
|
50
50
|
}[];
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Filter teks bebas ("contains") — untuk kolom high-cardinality/teks bebas
|
|
54
|
+
* (deskripsi, nama, no. seri) yang tak muat di select/date. Menghasilkan
|
|
55
|
+
* string; backend biasanya `LIKE %value%`. Nilai kosong = filter dihapus.
|
|
56
|
+
*/
|
|
57
|
+
export interface TextFilterField extends BaseFilterField {
|
|
58
|
+
type: 'text';
|
|
59
|
+
/** Placeholder input. Default "Cari…". */
|
|
60
|
+
placeholder?: string;
|
|
61
|
+
/** Debounce sebelum tulis ke URL (ms). Default 300. */
|
|
62
|
+
debounceMs?: number;
|
|
63
|
+
}
|
|
52
64
|
export interface DateFilterField extends BaseFilterField {
|
|
53
65
|
type: 'date';
|
|
54
66
|
mode?: 'days' | 'months' | 'years';
|
|
@@ -94,7 +106,7 @@ export interface DateCompactFilterField extends BaseFilterField {
|
|
|
94
106
|
*/
|
|
95
107
|
mode?: 'days' | 'months' | 'years';
|
|
96
108
|
}
|
|
97
|
-
export type FilterFieldConfig = SelectFilterField | CheckboxMultipleFilterField | DateFilterField | DateCompactFilterField;
|
|
109
|
+
export type FilterFieldConfig = SelectFilterField | CheckboxMultipleFilterField | TextFilterField | DateFilterField | DateCompactFilterField;
|
|
98
110
|
/** A single column entry fed to the Customize Column panel. */
|
|
99
111
|
export interface ColumnConfig {
|
|
100
112
|
key: string;
|
|
@@ -11,5 +11,16 @@ export interface ColumnMenuProps {
|
|
|
11
11
|
onClearSort: () => void;
|
|
12
12
|
onToggleFreeze: () => void;
|
|
13
13
|
onHide: () => void;
|
|
14
|
+
/**
|
|
15
|
+
* Slot filter per-kolom (Excel-style). Di-render di ATAS menu (sebelum
|
|
16
|
+
* sort/freeze/hide) dalam section "Filter". Konten & state-nya milik consumer
|
|
17
|
+
* — ColumnMenu tak tahu tipe filter apa pun; teruskan kontrol yang menulis ke
|
|
18
|
+
* sumber filter yang sama dengan FilterBar (mis. `useFilterBarControls`),
|
|
19
|
+
* supaya pill FilterBar + query ikut sinkron. Klik di dalam slot TIDAK menutup
|
|
20
|
+
* menu (biar bisa pilih banyak nilai).
|
|
21
|
+
*/
|
|
22
|
+
filterSlot?: React.ReactNode;
|
|
23
|
+
/** Ada filter aktif di kolom ini → funnel trigger menyala + tetap terlihat. */
|
|
24
|
+
filterActive?: boolean;
|
|
14
25
|
}
|
|
15
|
-
export declare const ColumnMenu: ({ active, canSort, canHide, sortDir, frozen, onSort, onClearSort, onToggleFreeze, onHide }: ColumnMenuProps) => React.JSX.Element;
|
|
26
|
+
export declare const ColumnMenu: ({ active, canSort, canHide, sortDir, frozen, onSort, onClearSort, onToggleFreeze, onHide, filterSlot, filterActive }: ColumnMenuProps) => React.JSX.Element;
|
|
@@ -111,6 +111,16 @@ export interface TableLayoutColumn<T> {
|
|
|
111
111
|
sortKey?: keyof T;
|
|
112
112
|
/** sembunyikan menu kolom (Ascending/Descending/Freeze/Hide) di kolom ini */
|
|
113
113
|
disableMenu?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Filter per-kolom (Excel-style) — di-render di ATAS menu kolom. Kembalikan
|
|
116
|
+
* kontrol filter (checklist/dropdown/dst) yang menulis ke sumber filter yang
|
|
117
|
+
* SAMA dengan FilterBar (mis. `useFilterBarControls` di-key by kolom), supaya
|
|
118
|
+
* pill FilterBar + query ikut sinkron. TableLayout tak tahu tipe filter — ia
|
|
119
|
+
* hanya me-render node ini. Butuh `columnMenu` aktif & `disableMenu` tak diset.
|
|
120
|
+
*/
|
|
121
|
+
renderFilter?: () => ReactNode;
|
|
122
|
+
/** Ada filter aktif di kolom ini → funnel di header menyala + tetap terlihat. */
|
|
123
|
+
filterActive?: boolean;
|
|
114
124
|
/** kolom terkunci — tidak bisa di-hide (item "Hide column" disembunyikan) */
|
|
115
125
|
locked?: boolean;
|
|
116
126
|
/**
|