@thefreshop/tb 1.1.2 → 1.1.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/README.md +273 -0
- package/dist/cjs/index.js +48 -13
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tbframe/layout/main.d.ts +3 -1
- package/dist/cjs/tbframe/provider/provider.d.ts +2 -1
- package/dist/cjs/tbpage/component/modules/antBaseTable/btn_widget.d.ts +3 -1
- package/dist/cjs/types/antBaseTable.types.d.ts +1 -0
- package/dist/cjs/types/provider.types.d.ts +1 -0
- package/dist/cjs/types/tbframe.types.d.ts +1 -0
- package/dist/esm/index.js +48 -13
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tbframe/layout/main.d.ts +3 -1
- package/dist/esm/tbframe/provider/provider.d.ts +2 -1
- package/dist/esm/tbpage/component/modules/antBaseTable/btn_widget.d.ts +3 -1
- package/dist/esm/types/antBaseTable.types.d.ts +1 -0
- package/dist/esm/types/provider.types.d.ts +1 -0
- package/dist/esm/types/tbframe.types.d.ts +1 -0
- package/dist/index.d.ts +3 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# @thefreshop/tb — tb framework
|
|
2
|
+
|
|
3
|
+
## 1) 패키지 이름 + 한 줄 소개
|
|
4
|
+
Ant Design 기반의 React UI 프레임워크로, 탭형 어드민 프레임과 CRUD 테이블/검색/페이지 스캐폴드를 제공합니다.
|
|
5
|
+
|
|
6
|
+
## 2) Why / What it solves
|
|
7
|
+
- 탭 기반 어드민 프레임(Top/Nav/Bottom)과 라우팅을 빠르게 구성.
|
|
8
|
+
- 검색/테이블/모달 CRUD 흐름을 재사용 가능한 컴포넌트로 표준화.
|
|
9
|
+
- Ant Design을 기반으로 일관된 관리자 UI 구축.
|
|
10
|
+
|
|
11
|
+
## 3) Features
|
|
12
|
+
- [x] 탭 기반 프레임 레이아웃 + 동적 라우팅
|
|
13
|
+
- [x] 세션 기반 탭 상태 저장(`sessionStorage`)
|
|
14
|
+
- [x] 검색 박스 + 테이블 + 로딩 레이아웃 스캐폴드
|
|
15
|
+
- [x] Ant Design Table 기반 CRUD 래퍼 + 모달 생성/수정
|
|
16
|
+
- [x] 한국어 로케일 기본 제공(dayjs/moment/antd)
|
|
17
|
+
|
|
18
|
+
## 4) Installation
|
|
19
|
+
```bash
|
|
20
|
+
npm i @thefreshop/tb
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn add @thefreshop/tb
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @thefreshop/tb
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Peer Dependencies
|
|
32
|
+
이 패키지는 아래 피어 의존성을 필요로 합니다:
|
|
33
|
+
```bash
|
|
34
|
+
npm i react react-dom react-router antd @ant-design/icons dayjs moment react-error-boundary @monaco-editor/react
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 5) Quick Start
|
|
38
|
+
```tsx
|
|
39
|
+
import React from "react";
|
|
40
|
+
import { TbProvider, TbpProvider, TbFrame } from "@thefreshop/tb";
|
|
41
|
+
import type { navType, topType, tbframeType } from "@thefreshop/tb";
|
|
42
|
+
|
|
43
|
+
const setting: tbframeType = { islogin: false, startTabKey: "dashboard" };
|
|
44
|
+
const top: topType = { title: "TB Admin", topMenuSetting: [{ key: "main", title: "Main" }] };
|
|
45
|
+
const nav: navType = {
|
|
46
|
+
menuSet: [
|
|
47
|
+
{
|
|
48
|
+
parentkey: "main",
|
|
49
|
+
menuSetting: [
|
|
50
|
+
{ tab: { key: "dashboard", title: "Dashboard", page: <div>Home</div> }, hasPage: true },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default function App() {
|
|
57
|
+
return (
|
|
58
|
+
<TbProvider basename="/">
|
|
59
|
+
<TbpProvider>
|
|
60
|
+
<TbFrame setting={setting} top={top} nav={nav} />
|
|
61
|
+
</TbpProvider>
|
|
62
|
+
</TbProvider>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 6) Usage
|
|
68
|
+
### 기본 사용
|
|
69
|
+
```tsx
|
|
70
|
+
import { Tbpage } from "@thefreshop/tb";
|
|
71
|
+
|
|
72
|
+
const columns = [
|
|
73
|
+
{
|
|
74
|
+
tableProps: { dataIndex: "name", title: "Name" },
|
|
75
|
+
search: true,
|
|
76
|
+
create: true,
|
|
77
|
+
modify: true,
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
export default function Users() {
|
|
82
|
+
return (
|
|
83
|
+
<Tbpage
|
|
84
|
+
title="Users"
|
|
85
|
+
decs="User list"
|
|
86
|
+
searchOption={[{ key: "base", items: [{ type: "input", key: "name", title: "Name" }] }]}
|
|
87
|
+
tableProps={{ rowKey: "id", columns, dataSource: [] }}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 옵션/설정(핵심 props 요약)
|
|
94
|
+
#### TbFrame
|
|
95
|
+
| 이름 | 타입 | 기본값 | 설명 |
|
|
96
|
+
| --- | --- | --- | --- |
|
|
97
|
+
| `setting` | `tbframeType` | - | 로그인/시작 탭 등 기본 프레임 설정 |
|
|
98
|
+
| `top` | `topType` | - | 상단 영역 설정 |
|
|
99
|
+
| `nav` | `navType` | - | 네비게이션/탭 정의 |
|
|
100
|
+
| `bottom` | `bottomType` | `undefined` | 하단 영역 |
|
|
101
|
+
| `top_banner` | `React.ReactNode` | `undefined` | 상단 배너 영역 |
|
|
102
|
+
| `hashmode` | `boolean` | `false` | 해시 라우팅 사용 여부 |
|
|
103
|
+
| `frameStyle` | `FrameStyleType` | `undefined` | 스타일 오버라이드 |
|
|
104
|
+
|
|
105
|
+
#### Tbpage
|
|
106
|
+
| 이름 | 타입 | 기본값 | 설명 |
|
|
107
|
+
| --- | --- | --- | --- |
|
|
108
|
+
| `tableProps` | `any` | - | AntBaseTable에 전달되는 props |
|
|
109
|
+
| `searchOption` | `any` | `undefined` | SearchBox 옵션 |
|
|
110
|
+
| `searchDisabled` | `boolean` | `false` | 검색 비활성화 |
|
|
111
|
+
| `onSubmit` | `(searchdata?, rowdata?, isReset?) => void` | `undefined` | 검색 제출/리셋 콜백 |
|
|
112
|
+
| `isLoading` | `boolean` | `undefined` | 로딩 오버레이 |
|
|
113
|
+
| `title`/`decs` | `string` | `undefined` | 타이틀/설명 |
|
|
114
|
+
| `PageStyle` | `PageStyleType` | `undefined` | 스타일 오버라이드 |
|
|
115
|
+
|
|
116
|
+
> 더 많은 props 및 타입은 `docs/API.md`를 참고하세요.
|
|
117
|
+
|
|
118
|
+
### 반환값/에러
|
|
119
|
+
| 항목 | 반환 | 에러/주의사항 |
|
|
120
|
+
| --- | --- | --- |
|
|
121
|
+
| `useTbState()` | `ProviderType` | `TbProvider` 밖에서 호출 시 Error throw |
|
|
122
|
+
|
|
123
|
+
## 7) API Reference
|
|
124
|
+
API가 많은 관계로 `docs/API.md`로 분리했습니다.
|
|
125
|
+
- 핵심 export: `TbProvider`, `useTbState`, `tbContext`, `TbFrame`, `TbpProvider`, `ContentLayout`, `Tbpage`, `TbpageSm`, `Tblist`, `TbpageMulti`, `AntBaseTable`, `AntBaseModalCreate`, `AuthTable` 및 타입들
|
|
126
|
+
|
|
127
|
+
## 8) TypeScript
|
|
128
|
+
- 타입 엔트리: `package.json`의 `types: ./dist/cjs/index.d.ts`
|
|
129
|
+
- 공개 타입: `export type * from "./types"`로 노출
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import type { tbframeType, navType, antBasePropsType } from "@thefreshop/tb";
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 9) Compatibility
|
|
136
|
+
- **Runtime**: 브라우저 기반 React 앱 (DOM lib 사용)
|
|
137
|
+
- **React**: `react@^19.1.1` (peer)
|
|
138
|
+
- **Router**: `react-router@^7.10.0` (peer)
|
|
139
|
+
- **UI**: `antd@^6.0.0` (peer)
|
|
140
|
+
- **CJS/ESM**: `main`(CJS), `module`(ESM) 빌드 제공
|
|
141
|
+
- **Node 엔진**: Not found in repository
|
|
142
|
+
|
|
143
|
+
## 10) Bundling / Tree-shaking
|
|
144
|
+
- `exports`/`sideEffects` 필드가 없어 트리 셰이킹 동작은 번들러 설정에 의존합니다.
|
|
145
|
+
- Rollup 빌드에서 CSS Modules를 런타임 inject 하므로 일부 부수효과(side effects)가 있을 수 있습니다.
|
|
146
|
+
|
|
147
|
+
## 11) Examples
|
|
148
|
+
### Basic (프레임 구성)
|
|
149
|
+
```tsx
|
|
150
|
+
import { TbProvider, TbpProvider, TbFrame } from "@thefreshop/tb";
|
|
151
|
+
import type { navType, topType, tbframeType } from "@thefreshop/tb";
|
|
152
|
+
|
|
153
|
+
const setting: tbframeType = { islogin: false };
|
|
154
|
+
const top: topType = { title: "Admin", topMenuSetting: [{ key: "main", title: "Main" }] };
|
|
155
|
+
const nav: navType = {
|
|
156
|
+
menuSet: [
|
|
157
|
+
{
|
|
158
|
+
parentkey: "main",
|
|
159
|
+
menuSetting: [{ tab: { key: "home", title: "Home", page: <div>Home</div> }, hasPage: true }],
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export default function App() {
|
|
165
|
+
return (
|
|
166
|
+
<TbProvider>
|
|
167
|
+
<TbpProvider>
|
|
168
|
+
<TbFrame setting={setting} top={top} nav={nav} />
|
|
169
|
+
</TbpProvider>
|
|
170
|
+
</TbProvider>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Advanced (검색 + 테이블)
|
|
176
|
+
```tsx
|
|
177
|
+
import { Tbpage } from "@thefreshop/tb";
|
|
178
|
+
|
|
179
|
+
const columns = [
|
|
180
|
+
{ tableProps: { dataIndex: "name", title: "Name" }, search: true, create: true, modify: true },
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
export default function Users() {
|
|
184
|
+
return (
|
|
185
|
+
<Tbpage
|
|
186
|
+
title="Users"
|
|
187
|
+
searchOption={[{ key: "base", items: [{ type: "input", key: "name", title: "Name" }] }]}
|
|
188
|
+
tableProps={{ rowKey: "id", columns, dataSource: [] }}
|
|
189
|
+
onSubmit={(query, data) => {
|
|
190
|
+
console.log(query, data);
|
|
191
|
+
}}
|
|
192
|
+
/>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Real-world (멀티 패널)
|
|
198
|
+
```tsx
|
|
199
|
+
import { TbpageMulti } from "@thefreshop/tb";
|
|
200
|
+
|
|
201
|
+
export default function Dashboard() {
|
|
202
|
+
return (
|
|
203
|
+
<TbpageMulti
|
|
204
|
+
title="Dashboard"
|
|
205
|
+
arrtableProps={[
|
|
206
|
+
{ type: "table", title: "Left", tableprops: { rowKey: "id", columns: [], dataSource: [] } },
|
|
207
|
+
{ type: "module", title: "Right", module: <div>Custom Module</div> },
|
|
208
|
+
]}
|
|
209
|
+
arrflex={[2, 1]}
|
|
210
|
+
direction="row"
|
|
211
|
+
/>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## 12) Troubleshooting
|
|
217
|
+
1. **peerDependencies 충돌**: React/antd/react-router 버전이 맞지 않으면 런타임 오류가 발생합니다.
|
|
218
|
+
2. **CSS Modules 미적용**: 소비 앱 번들러에서 CSS Modules가 비활성화되면 레이아웃이 깨집니다.
|
|
219
|
+
3. **SSR 환경 오류**: `sessionStorage` 사용으로 SSR 시 `window` 관련 에러가 날 수 있습니다.
|
|
220
|
+
4. **CJS/ESM 혼용 오류**: 번들러가 `module`/`main` 선택을 잘못하면 중복 React 경고가 발생할 수 있습니다.
|
|
221
|
+
5. **타입 인식 실패**: `types` 경로(`dist/cjs/index.d.ts`)가 올바르게 배포되었는지 확인하세요.
|
|
222
|
+
6. **Ant Design 스타일 누락**: 소비 앱에서 antd 스타일을 로드하지 않으면 컴포넌트가 깨집니다.
|
|
223
|
+
7. **모달 폼 초기값 미반영**: `AntBaseModalCreate`에서 `initialValues` 사용 시 `open` 타이밍을 확인하세요.
|
|
224
|
+
|
|
225
|
+
## 13) FAQ
|
|
226
|
+
1. **React 18에서도 동작하나요?** Not found in repository (peerDependencies는 React 19 기준입니다).
|
|
227
|
+
2. **React Router v6 사용 가능?** Not found in repository (peerDependencies는 v7 기준입니다).
|
|
228
|
+
3. **라우팅 구조는 어떻게 만들나요?** `nav.menuSet`과 `nav.globalTabs` 기반으로 라우트가 자동 생성됩니다.
|
|
229
|
+
4. **해시 라우팅을 지원하나요?** `TbFrame`의 `hashmode`로 지원합니다.
|
|
230
|
+
5. **탭 상태는 어디에 저장되나요?** `sessionStorage`의 `tbFrameState` 키에 저장됩니다.
|
|
231
|
+
6. **로케일 설정은 어디서 하나요?** `TbpProvider`가 `antd` `ConfigProvider`와 `ko_KR` 로케일을 설정합니다.
|
|
232
|
+
7. **테스트 예제나 Storybook이 있나요?** Not found in repository.
|
|
233
|
+
8. **변경 이력(Changelog)이 있나요?** No changelog found.
|
|
234
|
+
|
|
235
|
+
## 14) Contributing
|
|
236
|
+
### 로컬 개발
|
|
237
|
+
```bash
|
|
238
|
+
yarn install
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
yarn dev
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
yarn build
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
- 테스트/린트 스크립트: Not found in repository
|
|
250
|
+
- 배포 스크립트: Not found in repository
|
|
251
|
+
|
|
252
|
+
## 15) Security
|
|
253
|
+
- 공급망 보안: peerDependencies 버전을 고정/검증하세요.
|
|
254
|
+
- 토큰/시크릿 관리: 레포에 환경변수 파일이 없으므로 소비 앱에서 안전하게 관리하세요.
|
|
255
|
+
- 취약점 신고: `package.json`의 `bugs.url` 참고.
|
|
256
|
+
|
|
257
|
+
## 16) License
|
|
258
|
+
- `package.json`: MIT
|
|
259
|
+
- LICENSE 파일: No license file found
|
|
260
|
+
|
|
261
|
+
## 17) Quick Commands
|
|
262
|
+
| 목적 | 명령 | 비고 |
|
|
263
|
+
| --- | --- | --- |
|
|
264
|
+
| 개발(와치) | ```bash
|
|
265
|
+
yarn dev
|
|
266
|
+
``` | Rollup watch 빌드 |
|
|
267
|
+
| 빌드 | ```bash
|
|
268
|
+
yarn build
|
|
269
|
+
``` | `dist/` 출력 |
|
|
270
|
+
| 테스트 | Not found in repository | - |
|
|
271
|
+
| 린트 | Not found in repository | - |
|
|
272
|
+
| 타입체크 | Not found in repository | - |
|
|
273
|
+
| 퍼블리시 | Not found in repository | - |
|
package/dist/cjs/index.js
CHANGED
|
@@ -40,7 +40,7 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
|
40
40
|
const tbContext = React.createContext(undefined);
|
|
41
41
|
|
|
42
42
|
const SESSION_STORAGE_KEY = "tbFrameState";
|
|
43
|
-
const TbProvider = ({ children }) => {
|
|
43
|
+
const TbProvider = ({ basename, children }) => {
|
|
44
44
|
const [topkey, setTopkey] = React.useState("");
|
|
45
45
|
const [tabList, setTabList] = React.useState([]);
|
|
46
46
|
const [currentTabKey, setCurrentTabKey] = React.useState();
|
|
@@ -142,6 +142,7 @@ const TbProvider = ({ children }) => {
|
|
|
142
142
|
errMsg,
|
|
143
143
|
tabList,
|
|
144
144
|
setTabList,
|
|
145
|
+
basename,
|
|
145
146
|
} }, children));
|
|
146
147
|
};
|
|
147
148
|
const useTbState = () => {
|
|
@@ -402,11 +403,11 @@ var css_248z$7 = ".main-module_mainFrame__Etjvl{height:100%;width:100%}.main-mod
|
|
|
402
403
|
var styles$5 = {"mainFrame":"main-module_mainFrame__Etjvl","mainFrameFullscreen":"main-module_mainFrameFullscreen__oEwV8"};
|
|
403
404
|
styleInject(css_248z$7);
|
|
404
405
|
|
|
405
|
-
const Main = () => {
|
|
406
|
+
const Main = ({ style }) => {
|
|
406
407
|
const [sp] = reactRouter.useSearchParams();
|
|
407
408
|
const isFs = sp.get("fs") === "1" || sp.get("fullscreen") === "1";
|
|
408
409
|
// console.log("Main render, isFs:", isFs);
|
|
409
|
-
return (React.createElement("div", { className: isFs ? styles$5.mainFrameFullscreen : styles$5.mainFrame },
|
|
410
|
+
return (React.createElement("div", { className: isFs ? styles$5.mainFrameFullscreen : styles$5.mainFrame, style: style },
|
|
410
411
|
React.createElement(reactRouter.Outlet, null)));
|
|
411
412
|
};
|
|
412
413
|
|
|
@@ -501,7 +502,7 @@ const NullPage = () => {
|
|
|
501
502
|
};
|
|
502
503
|
|
|
503
504
|
const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, frameStyle, }) => {
|
|
504
|
-
const { user, errMsg, tabList, setTabList, startTabKey, setStartTabKey, loginUser } = useTbState();
|
|
505
|
+
const { basename, user, errMsg, tabList, setTabList, startTabKey, setStartTabKey, loginUser } = useTbState();
|
|
505
506
|
React.useEffect(() => {
|
|
506
507
|
let p_tabList = [];
|
|
507
508
|
nav.menuSet.forEach((item) => {
|
|
@@ -574,7 +575,9 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, fram
|
|
|
574
575
|
children: route(),
|
|
575
576
|
errorElement: React.createElement(NullPage, null),
|
|
576
577
|
},
|
|
577
|
-
]
|
|
578
|
+
], {
|
|
579
|
+
basename: basename ?? "/",
|
|
580
|
+
});
|
|
578
581
|
}
|
|
579
582
|
else {
|
|
580
583
|
return reactRouter.createBrowserRouter([
|
|
@@ -584,9 +587,11 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, fram
|
|
|
584
587
|
children: route(),
|
|
585
588
|
errorElement: React.createElement(NullPage, null),
|
|
586
589
|
},
|
|
587
|
-
]
|
|
590
|
+
], {
|
|
591
|
+
basename: basename ?? "/",
|
|
592
|
+
});
|
|
588
593
|
}
|
|
589
|
-
}, [hashmode, user, top, nav, setting, top_banner, bottom, frameStyle]);
|
|
594
|
+
}, [hashmode, user, top, nav, setting, top_banner, bottom, frameStyle, basename]);
|
|
590
595
|
return React.createElement(reactRouter.RouterProvider, { router: router });
|
|
591
596
|
};
|
|
592
597
|
const MainLayout = ({ errMsg, setting, top_banner, nav, user, top, bottom, frameStyle, }) => {
|
|
@@ -631,7 +636,7 @@ const MainLayout = ({ errMsg, setting, top_banner, nav, user, top, bottom, frame
|
|
|
631
636
|
React.createElement(Nav, { nav: nav, islogin: setting.islogin ?? false, frameStyle: frameStyle }),
|
|
632
637
|
React.createElement("div", { className: styles$9.contentsFrame, style: frameStyle?.contentsFrame },
|
|
633
638
|
React.createElement(Tabs, { nav: nav, frameStyle: frameStyle }),
|
|
634
|
-
React.createElement(Main,
|
|
639
|
+
React.createElement(Main, { style: frameStyle?.contentsMainFrame }))),
|
|
635
640
|
React.createElement("div", { className: styles$9.bottomFrame, style: frameStyle?.bottomFrame }, bottom && React.createElement(Bottom, { bottom: bottom, frameStyle: frameStyle }))))));
|
|
636
641
|
};
|
|
637
642
|
|
|
@@ -700,7 +705,7 @@ const FORM_CREATE = "등록";
|
|
|
700
705
|
|
|
701
706
|
* @todo
|
|
702
707
|
*/
|
|
703
|
-
const TableTopButtonGroup = ({ isSelect, onRefresh, isCounter, autoRefreshTime, addProps, modifyProps, deleteProps, removeProps, resetProps, customProps, }) => {
|
|
708
|
+
const TableTopButtonGroup = ({ isSelect, onRefresh, isCounter, autoRefreshTime, addProps, modifyProps, deleteProps, removeProps, resetProps, customProps, isInSearch = false, onInSearch, }) => {
|
|
704
709
|
if (!addProps && !modifyProps && !deleteProps && !removeProps && !resetProps && !customProps && !onRefresh) {
|
|
705
710
|
return null;
|
|
706
711
|
}
|
|
@@ -747,7 +752,8 @@ const TableTopButtonGroup = ({ isSelect, onRefresh, isCounter, autoRefreshTime,
|
|
|
747
752
|
deleteProps ? (React.createElement(antd.Button, { danger: true, disabled: !isSelect || deleteProps.disable, onClick: deleteProps.onFun }, deleteProps.title ? deleteProps.title : TABLE_DELETE)) : null,
|
|
748
753
|
resetProps ? (React.createElement(antd.Button, { disabled: !isSelect || resetProps.disable, onClick: resetProps.onFun }, resetProps.title ? resetProps.title : TABLE_RESET)) : null,
|
|
749
754
|
removeProps ? (React.createElement(antd.Button, { danger: true, type: "primary", disabled: !isSelect || removeProps.disable, onClick: removeProps.onFun }, removeProps.title ? removeProps.title : TABLE_REMOVE)) : null,
|
|
750
|
-
customProps?.rightRender && customProps?.rightRender()
|
|
755
|
+
customProps?.rightRender && customProps?.rightRender(),
|
|
756
|
+
isInSearch && onInSearch ? React.createElement(InSearchForm, { onInSearch: onInSearch }) : null))));
|
|
751
757
|
};
|
|
752
758
|
const TableBottomButtonGroup = ({ isSelect, topProps, bottomProps, upProps, downProps, }) => {
|
|
753
759
|
return (React.createElement(antd.Row, { justify: "space-between" },
|
|
@@ -761,6 +767,22 @@ const TableBottomButtonGroup = ({ isSelect, topProps, bottomProps, upProps, down
|
|
|
761
767
|
downProps ? (React.createElement(antd.Button, { disabled: !isSelect || downProps.disable, onClick: downProps.onFun }, TABLE_DOWN)) : null,
|
|
762
768
|
bottomProps ? (React.createElement(antd.Button, { disabled: !isSelect || bottomProps.disable, onClick: bottomProps.onFun }, TABLE_BOTTOM)) : null))));
|
|
763
769
|
};
|
|
770
|
+
const InSearchForm = ({ onInSearch }) => {
|
|
771
|
+
const [inputSearch, setInputSearch] = React.useState("");
|
|
772
|
+
const SearchClick = () => {
|
|
773
|
+
onInSearch(inputSearch);
|
|
774
|
+
};
|
|
775
|
+
const activeEnter = (e) => {
|
|
776
|
+
if (e.key === "Enter") {
|
|
777
|
+
SearchClick();
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
return (React.createElement(antd.Space.Compact, null,
|
|
781
|
+
React.createElement(antd.Input, { style: { width: "150px" }, onChange: (e) => {
|
|
782
|
+
setInputSearch(e.target.value);
|
|
783
|
+
}, value: inputSearch, onKeyDown: (e) => activeEnter(e) }),
|
|
784
|
+
React.createElement(antd.Button, { onClick: SearchClick }, "\uAC80\uC0C9")));
|
|
785
|
+
};
|
|
764
786
|
|
|
765
787
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
766
788
|
|
|
@@ -23338,11 +23360,24 @@ const AntBaseModalCreate = ({ modalProps, formProps, props }) => {
|
|
|
23338
23360
|
|
|
23339
23361
|
const { Title: Title$1 } = antd.Typography;
|
|
23340
23362
|
const { confirm: confirm$1 } = antd.Modal;
|
|
23341
|
-
const AntBaseTable = ({ bordered, className, rowKey, rowName, dataSource, initData, customColumn, customValue, columns, expandable, size, onDoubleClick, onClick, selectProps, addProps, modifyProps, deleteProps, removeProps, resetProps, customProps, topProps, bottomProps, upProps, downProps, pageProps, scroll, onRefresh, isCounter, autoRefreshTime, createModalWidth = 1000, onCreateClose, }, ref) => {
|
|
23363
|
+
const AntBaseTable = ({ bordered, className, rowKey, rowName, dataSource, initData, customColumn, customValue, columns, expandable, size, onDoubleClick, onClick, selectProps, addProps, modifyProps, deleteProps, removeProps, resetProps, customProps, topProps, bottomProps, upProps, downProps, pageProps, scroll, onRefresh, isCounter, autoRefreshTime, createModalWidth = 1000, onCreateClose, isInSearch = false, }, ref) => {
|
|
23342
23364
|
const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
|
|
23343
23365
|
const [selectedRow, setSelectedRow] = React.useState();
|
|
23344
23366
|
const [popupCreate, setPopupCreate] = React.useState(false);
|
|
23345
23367
|
const [popupModify, setPopupModify] = React.useState(false);
|
|
23368
|
+
const [viewData, setViewData] = React.useState(dataSource);
|
|
23369
|
+
const onInSearch = (value) => {
|
|
23370
|
+
const search = value.trim().toLowerCase();
|
|
23371
|
+
if (!search) {
|
|
23372
|
+
setViewData(dataSource);
|
|
23373
|
+
return;
|
|
23374
|
+
}
|
|
23375
|
+
setViewData(dataSource.filter((item) => Object.values(item).some((itemValue) => {
|
|
23376
|
+
if (itemValue == null)
|
|
23377
|
+
return false;
|
|
23378
|
+
return String(itemValue).toLowerCase().includes(search);
|
|
23379
|
+
})));
|
|
23380
|
+
};
|
|
23346
23381
|
React.useEffect(() => {
|
|
23347
23382
|
setSelectedRow(dataSource?.find((m) => {
|
|
23348
23383
|
if (m) {
|
|
@@ -23435,7 +23470,7 @@ const AntBaseTable = ({ bordered, className, rowKey, rowName, dataSource, initDa
|
|
|
23435
23470
|
height: "100%",
|
|
23436
23471
|
padding: "20px",
|
|
23437
23472
|
} },
|
|
23438
|
-
React.createElement(TableTopButtonGroup, { isSelect: isSelect, isCounter: isCounter, onRefresh: onRefresh, autoRefreshTime: autoRefreshTime, addProps: addProps && {
|
|
23473
|
+
React.createElement(TableTopButtonGroup, { isInSearch: isInSearch, onInSearch: onInSearch, isSelect: isSelect, isCounter: isCounter, onRefresh: onRefresh, autoRefreshTime: autoRefreshTime, addProps: addProps && {
|
|
23439
23474
|
...addProps,
|
|
23440
23475
|
onFun: () => {
|
|
23441
23476
|
if (addProps.customModal) {
|
|
@@ -23616,7 +23651,7 @@ const AntBaseTable = ({ bordered, className, rowKey, rowName, dataSource, initDa
|
|
|
23616
23651
|
return {
|
|
23617
23652
|
onClick: () => { }, // click header row
|
|
23618
23653
|
};
|
|
23619
|
-
}, dataSource:
|
|
23654
|
+
}, dataSource: viewData?.map((i) => i),
|
|
23620
23655
|
// columns={tableColumns(
|
|
23621
23656
|
// columns.concat(
|
|
23622
23657
|
// deleteCol({
|