@axboot-mcp/mcp-server 1.0.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/CLAUDE.md +119 -0
- package/MCP_TOOL_PLAN.md +710 -0
- package/MCP_USAGE.md +914 -0
- package/README.md +168 -0
- package/REPOSITORY_CONVENTIONS.md +250 -0
- package/SEARCH_PARAMS_MCP_TOOL_COMPLETE_PLAN.md +646 -0
- package/SEARCH_PARAMS_PLAN.md +2570 -0
- package/STORE_PATTERNS.md +1178 -0
- package/debug-dto.js +72 -0
- package/generate-banner-store.js +62 -0
- package/generation-plan.json +2176 -0
- package/generation-results.json +1817 -0
- package/package.json +45 -0
- package/scripts/batch-generate-all.js +159 -0
- package/scripts/batch-generate-mcp.js +329 -0
- package/scripts/batch-generate-stores-v2.js +272 -0
- package/scripts/batch-generate-stores.js +179 -0
- package/scripts/batch-plan.json +3810 -0
- package/scripts/batch-process.py +90 -0
- package/scripts/batch-regenerate.js +356 -0
- package/scripts/direct-generate.js +227 -0
- package/scripts/execute-batches.js +1911 -0
- package/scripts/generate-all-stores.js +144 -0
- package/scripts/generate-stores-mcp.js +161 -0
- package/scripts/generate-stores-v2.js +450 -0
- package/scripts/generate-stores-v3.js +412 -0
- package/scripts/generate-stores-v4.js +521 -0
- package/scripts/generate-stores.js +382 -0
- package/scripts/repos-to-process.json +1899 -0
- package/src/config/nh-layout-patterns.ts +166 -0
- package/src/docs/HOOK_GENERATION_PLAN.md +2226 -0
- package/src/docs/NH_STORE_PATTERNS.md +297 -0
- package/src/docs/README.md +216 -0
- package/src/docs/index.ts +28 -0
- package/src/docs/loader.ts +568 -0
- package/src/docs/patterns.json +419 -0
- package/src/docs/practical-examples.md +732 -0
- package/src/docs/quick-start.md +257 -0
- package/src/docs/requirements-analysis-guide.md +364 -0
- package/src/docs/rules.json +321 -0
- package/src/docs/store-pattern-analysis.md +664 -0
- package/src/docs/store-patterns-rules.md +1168 -0
- package/src/docs/store-patterns-usage-guide.md +1835 -0
- package/src/docs/troubleshooting.md +544 -0
- package/src/docs/type-selection-guide.md +572 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/AntD-/354/273/264/355/217/254/353/204/214/355/212/270-/354/202/254/354/232/251/353/262/225.md +1515 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/DataGrid-/354/202/254/354/232/251/353/262/225.md +866 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/FormItem-/354/202/254/354/232/251/353/262/225.md +903 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/FormModal-/354/202/254/354/232/251/353/262/225.md +1155 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/MCP-/353/260/224/354/235/264/353/270/214/354/275/224/353/224/251-/352/260/200/354/235/264/353/223/234.md +1133 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/MSW-Mock-/353/215/260/354/235/264/355/204/260-/354/202/254/354/232/251/353/262/225.md +579 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/Search-/354/273/264/355/217/254/353/204/214/355/212/270-/354/202/254/354/232/251/353/262/225.md +738 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/Store-/355/214/250/355/204/264-/354/202/254/354/232/251/353/262/225.md +1135 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/224/353/251/264/352/265/254/354/204/261-/355/203/200/354/236/205/353/263/204-/352/260/234/353/260/234/354/210/234/354/204/234.md +1805 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/224/353/251/264/355/203/200/354/236/205/353/263/204-/352/260/234/353/260/234-/355/224/204/353/241/254/355/224/204/355/212/270-/352/260/200/354/235/264/353/223/234.md +946 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/225/354/236/245/355/231/224/353/251/264/355/203/200/354/236/205/353/263/204-/354/203/201/354/204/270-/355/224/204/353/241/254/355/224/204/355/212/270/352/260/200/354/235/264/353/223/234.md +2422 -0
- package/src/features/store-features.ts +232 -0
- package/src/handlers/analyze-requirements.ts +403 -0
- package/src/handlers/analyze.ts +1373 -0
- package/src/handlers/generate-from-requirements.ts +250 -0
- package/src/handlers/generate-hook.ts +950 -0
- package/src/handlers/generate-interactive.ts +840 -0
- package/src/handlers/generate-listdatagrid.ts +521 -0
- package/src/handlers/generate-multi-stores.ts +577 -0
- package/src/handlers/generate-requirements-from-layout.ts +160 -0
- package/src/handlers/generate-search-params.ts +717 -0
- package/src/handlers/generate.ts +911 -0
- package/src/handlers/list-templates.ts +104 -0
- package/src/handlers/scan-metadata.ts +485 -0
- package/src/handlers/suggest-layout.ts +326 -0
- package/src/index.ts +959 -0
- package/src/prompts/search-params.md +793 -0
- package/src/templates/index.ts +107 -0
- package/src/templates/unified.ts +462 -0
- package/store-generation-error-patterns.md +225 -0
- package/test/useAgentStore.ts +136 -0
- package/test-server.js +78 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,793 @@
|
|
|
1
|
+
# SearchParams 생성 가이드
|
|
2
|
+
|
|
3
|
+
이 프롬프트는 NH-FE-B 패턴의 SearchParams 컴포넌트를 자동 생성하는 방법을 안내합니다.
|
|
4
|
+
|
|
5
|
+
## 사용자 요청 인식
|
|
6
|
+
|
|
7
|
+
사용자가 다음과 같은 요청을 하면 이 가이드를 따르세요:
|
|
8
|
+
- "search params를 만들어줘"
|
|
9
|
+
- "검색 조건 추가해줘"
|
|
10
|
+
- "SearchParams 생성"
|
|
11
|
+
- "dateRange code:XXX search 추가"
|
|
12
|
+
|
|
13
|
+
## 처리 단계
|
|
14
|
+
|
|
15
|
+
### 1. 파라미터 파싱
|
|
16
|
+
|
|
17
|
+
사용자 입력에서 다음 패턴을 추출:
|
|
18
|
+
- `dateRange` 또는 `dateRange:withPeriod` - 날짜 범위
|
|
19
|
+
- `code:CODE_NAME` 또는 `code:CODE_NAME:multi` - 코드 선택
|
|
20
|
+
- `search` 또는 `search:withType` - 검색어
|
|
21
|
+
- `finder:라벨:필드명:모달함수:너비` - VALUES_FINDER
|
|
22
|
+
- `cascade:라벨:필드명:옵션변수:너비` - CASCADE
|
|
23
|
+
- `numberRange:라벨:필드명` - 숫자 범위
|
|
24
|
+
- `radio:라벨:필드명[:옵션들]` - 라디오 버튼
|
|
25
|
+
- `checkbox:라벨:필드명:CODE_VAR` - 체크박스
|
|
26
|
+
|
|
27
|
+
**예시:**
|
|
28
|
+
```
|
|
29
|
+
사용자: "search params 만들어줘: dateRange code:STATUS_CODE search"
|
|
30
|
+
|
|
31
|
+
파싱 결과:
|
|
32
|
+
- dateRange: { withPeriodType: false }
|
|
33
|
+
- code:STATUS_CODE: { name: "statusCd", codeVar: "STATUS_CODE", multi: false }
|
|
34
|
+
- search: { withSearchType: false }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. 파일 경로 확인
|
|
38
|
+
|
|
39
|
+
**현재 열린 App.tsx 찾기:**
|
|
40
|
+
```typescript
|
|
41
|
+
// mcp__jetbrains__get_all_open_file_paths 호출
|
|
42
|
+
// 또는 사용자가 지정한 경로 사용
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
파일이 없으면 사용자에게 경로 요청.
|
|
46
|
+
|
|
47
|
+
### 3. Store 자동 감지 (중요!)
|
|
48
|
+
|
|
49
|
+
App.tsx와 동일한 경로(`src/pages/resources/xxx/`)에서 Store 파일을 찾습니다.
|
|
50
|
+
|
|
51
|
+
**Store 파일 찾기:**
|
|
52
|
+
1. `use*.ts` 패턴으로 파일 검색 (예: `useSystemSeoStore.ts`, `useMemberStore.ts`)
|
|
53
|
+
2. 또는 `*.Store.ts` 패턴으로 검색
|
|
54
|
+
3. 찾은 Store 파일명으로 import 문 생성
|
|
55
|
+
|
|
56
|
+
**Store import 예시:**
|
|
57
|
+
```typescript
|
|
58
|
+
// App.tsx 경로: /src/pages/resources/test/App.tsx
|
|
59
|
+
// Store 파일: /src/pages/resources/test/useSystemSeoStore.ts
|
|
60
|
+
|
|
61
|
+
import { useSystemSeoStore } from "./useSystemSeoStore";
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**필요한 Store 상태 선언:**
|
|
65
|
+
```typescript
|
|
66
|
+
const callListApi = useSystemSeoStore((s) => s.callListApi);
|
|
67
|
+
const listRequestValue = useSystemSeoStore((s) => s.listRequestValue);
|
|
68
|
+
const setListRequestValue = useSystemSeoStore((s) => s.setListRequestValue);
|
|
69
|
+
const listSpinning = useSystemSeoStore((s) => s.listSpinning);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Store 파일을 찾지 못한 경우:**
|
|
73
|
+
- 사용자에게 Store 파일 경로를 요청
|
|
74
|
+
- 또는 `useXxxStore` 형태로 가정하고 진행 후 나중에 수정 요청
|
|
75
|
+
|
|
76
|
+
### 4. 코드 자동 추가 (중요!)
|
|
77
|
+
|
|
78
|
+
**모든 코드 사용 패턴에서 자동으로 CodeModel에 추가**
|
|
79
|
+
|
|
80
|
+
다음 경우에 `CodeModel` 인터페이스에 코드를 자동으로 추가합니다:
|
|
81
|
+
1. `code:XXX` 파라미터 발견 시
|
|
82
|
+
2. `const XXX = useCodeStore((s) => s.XXX);` 패턴 사용 시
|
|
83
|
+
3. `options: XXX?.options ?? []` 사용 시
|
|
84
|
+
|
|
85
|
+
**자동 추가 절차 (실제 파일 수정):**
|
|
86
|
+
|
|
87
|
+
1. `/Users/kyle/Desktop/nh-fe-bo/src/stores/useCodeStore.ts` 파일 읽기
|
|
88
|
+
2. `CodeModel` 인터페이스에서 해당 코드 존재 확인
|
|
89
|
+
3. **없으면 실제로 파일을 수정하여 추가** (알파벳순 정렬)
|
|
90
|
+
|
|
91
|
+
**⚠️ 반드시 실제 파일을 수정해야 합니다!**
|
|
92
|
+
- 단순히 설명만 하지 말고 **실제로 파일을 편집하세요**
|
|
93
|
+
- `Read` 도구로 파일을 읽고 `Edit` 도구로 수정하세요
|
|
94
|
+
- 알파벳순으로 올바른 위치에 삽입하세요
|
|
95
|
+
|
|
96
|
+
**코드 추출 규칙:**
|
|
97
|
+
```typescript
|
|
98
|
+
// code:STATUS_CODE → 추출: STATUS_CODE
|
|
99
|
+
// const STATUS_CODE = useCodeStore((s) => s.STATUS_CODE); → 추출: STATUS_CODE
|
|
100
|
+
// options: STATUS_CODE?.options → 추출: STATUS_CODE
|
|
101
|
+
// const CHANNEL_TYPE = useCodeStore((s) => s.CHANNEL_TYPE); → 추출: CHANNEL_TYPE
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**실제 파일 수정 예시:**
|
|
105
|
+
```typescript
|
|
106
|
+
// 1. 파일 읽기
|
|
107
|
+
// /Users/kyle/Desktop/nh-fe-bo/src/stores/useCodeStore.ts
|
|
108
|
+
|
|
109
|
+
// 2. CodeModel 인터페이스 확인
|
|
110
|
+
export interface CodeModel {
|
|
111
|
+
// ... 기존 코드들 ...
|
|
112
|
+
// CHANNEL_TYPE이 있는지 확인
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 3. 없으면 실제로 수정 (Edit 도구 사용)
|
|
116
|
+
// 알파벳순으로 C... 영역에 추가:
|
|
117
|
+
export interface CodeModel {
|
|
118
|
+
// ... 기존 코드들 ...
|
|
119
|
+
CHANNEL_TYPE?: Code; // ← 실제로 파일에 추가 (알파벳순 C 위치)
|
|
120
|
+
// ... 이후 코드들 ...
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**⚠️ 중요: 모든 코드 사용 전에 CodeModel 확인 및 자동 추가**
|
|
125
|
+
```typescript
|
|
126
|
+
// 1단계: 코드명 추출 (예: CHANNEL_TYPE)
|
|
127
|
+
// 2단계: CodeModel 확인 (Read 도구로 파일 읽기)
|
|
128
|
+
// 3단계: 없으면 실제로 파일 수정 (Edit 도구로 추가)
|
|
129
|
+
// 4단계: 그 후에야 코드 사용 가능
|
|
130
|
+
const CHANNEL_TYPE = useCodeStore((s) => s.CHANNEL_TYPE);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**파일 수정 시 주의사항:**
|
|
134
|
+
- 파일 경로: `/Users/kyle/Desktop/nh-fe-bo/src/stores/useCodeStore.ts`
|
|
135
|
+
- 반드시 `Edit` 도구를 사용하여 실제 파일을 수정
|
|
136
|
+
- 알파벳순 정렬 준수 (A→Z 순서)
|
|
137
|
+
- 주석 포함: `// 코드 설명`
|
|
138
|
+
|
|
139
|
+
### 5. Import 문 추가
|
|
140
|
+
|
|
141
|
+
App.tsx 상단에 필요한 import 추가:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { IParam, SearchParams, SearchParamType } from "@core/components/search";
|
|
145
|
+
import { DT_FORMAT } from "@types";
|
|
146
|
+
import { DtPickerPresetRender } from "components/presetRender/DtPickerPresetRender";
|
|
147
|
+
import { useCodeStore } from "stores"; // ⚠️ "hooks"가 아닌 "stores"에서 import
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**⚠️ 중요: useCodeStore는 반드시 "stores"에서 import하세요**
|
|
151
|
+
```typescript
|
|
152
|
+
// ❌ 잘못된 예
|
|
153
|
+
import { useCodeStore } from "hooks";
|
|
154
|
+
|
|
155
|
+
// ✅ 올바른 예
|
|
156
|
+
import { useCodeStore } from "stores";
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**⚠️ 중요: SearchBarFormInstance는 import하지 말고, Form.useForm()에 제네릭 타입을 지정하지 마세요**
|
|
160
|
+
```typescript
|
|
161
|
+
// ❌ 잘못된 예
|
|
162
|
+
import { SearchBarFormInstance } from "@core/components/search";
|
|
163
|
+
const [searchForm] = Form.useForm<SearchBarFormInstance>();
|
|
164
|
+
|
|
165
|
+
// ✅ 올바른 예
|
|
166
|
+
const [searchForm] = Form.useForm();
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**finder 사용 시 추가:**
|
|
170
|
+
```typescript
|
|
171
|
+
import { open모달함수 } from "modals/...";
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**cascade 사용 시 추가:**
|
|
175
|
+
```typescript
|
|
176
|
+
import { useOrganizationCascadeData } from "hooks/useOrganizationCascadeData";
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 6. Code Store 선언
|
|
180
|
+
|
|
181
|
+
컴포넌트 내부에 필요한 코드 선언:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const STATUS_CODE = useCodeStore((s) => s.STATUS_CODE);
|
|
185
|
+
const CUPON_KN_TPCD = useCodeStore((s) => s.CUPON_KN_TPCD);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**⚠️ 중요: 4단계 "코드 자동 추가"를 먼저 수행하세요**
|
|
189
|
+
- `const XXX = useCodeStore((s) => s.XXX);`를 선언하기 전에
|
|
190
|
+
- `XXX`가 `CodeModel` 인터페이스에 있는지 확인
|
|
191
|
+
- 없으면 4단계 절차에 따라 자동으로 추가
|
|
192
|
+
|
|
193
|
+
**cascade 사용 시:**
|
|
194
|
+
```typescript
|
|
195
|
+
const { list: organizationOption } = useOrganizationCascadeData();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 7. params 배열 생성
|
|
199
|
+
|
|
200
|
+
파싱된 파라미터를 TypeScript 코드로 변환:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const params: IParam[] = [
|
|
204
|
+
// dateRange 파라미터
|
|
205
|
+
{
|
|
206
|
+
label: t("기간"),
|
|
207
|
+
placeholder: [t("년월일"), t("년월일")],
|
|
208
|
+
name: "dateRange",
|
|
209
|
+
type: SearchParamType.DTPICKER_DATE_RANGE,
|
|
210
|
+
format: DT_FORMAT.DATE,
|
|
211
|
+
isTimeSelector: false,
|
|
212
|
+
presetRender: DtPickerPresetRender({ type: "all" }),
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
// code:STATUS_CODE 파라미터
|
|
216
|
+
{
|
|
217
|
+
label: t("상태"),
|
|
218
|
+
name: "statusCd",
|
|
219
|
+
type: SearchParamType.SELECT,
|
|
220
|
+
width: 150,
|
|
221
|
+
options: STATUS_CODE?.options ?? [],
|
|
222
|
+
showSearch: false,
|
|
223
|
+
allowClear: true,
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
// search 파라미터
|
|
227
|
+
{
|
|
228
|
+
label: t("검색어"),
|
|
229
|
+
placeholder: t("검색어"),
|
|
230
|
+
name: "searchText",
|
|
231
|
+
type: SearchParamType.INPUT,
|
|
232
|
+
},
|
|
233
|
+
];
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 8. PageSearchBar 추가
|
|
237
|
+
|
|
238
|
+
return 문 내부에 SearchParams 컴포넌트 추가:
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
<PageSearchBar>
|
|
242
|
+
<SearchParams
|
|
243
|
+
form={searchForm}
|
|
244
|
+
params={params}
|
|
245
|
+
paramsValue={listRequestValue}
|
|
246
|
+
onChangeParamsValue={(value, changedValues) => setListRequestValue(value, changedValues)}
|
|
247
|
+
onSearch={handleSearch}
|
|
248
|
+
spinning={listSpinning}
|
|
249
|
+
/>
|
|
250
|
+
</PageSearchBar>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 9. PageSearchBar 스타일 확인/추가
|
|
254
|
+
|
|
255
|
+
App.tsx 하단의 styled 컴포넌트 영역에 `PageSearchBar` 스타일이 있는지 확인합니다.
|
|
256
|
+
|
|
257
|
+
**있으면 패스:**
|
|
258
|
+
```typescript
|
|
259
|
+
const PageSearchBar = styled(PageLayout.PageSearchBar)``;
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**없으면 추가:**
|
|
263
|
+
```typescript
|
|
264
|
+
const PageSearchBar = styled(PageLayout.PageSearchBar)``;
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
위치는 `const Header = styled(PageLayout.Header)``;` 다음, `const Body = styled(PageLayout.FrameRow)``;` 전에 추가합니다.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const Container = styled(PageLayout)``;
|
|
271
|
+
const Header = styled(PageLayout.Header)``;
|
|
272
|
+
const PageSearchBar = styled(PageLayout.PageSearchBar)``; // ← 추가
|
|
273
|
+
const Body = styled(PageLayout.FrameRow)``;
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 10. Form.useForm() 선언 확인
|
|
277
|
+
|
|
278
|
+
App.tsx 컴포넌트 내부에 `searchForm` 선언이 있는지 확인합니다.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const [searchForm] = Form.useForm();
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**⚠️ 중요: 제네릭 타입을 지정하지 마세요**
|
|
285
|
+
```typescript
|
|
286
|
+
// ❌ 잘못된 예
|
|
287
|
+
import { SearchBarFormInstance } from "@core/components/search";
|
|
288
|
+
const [searchForm] = Form.useForm<SearchBarFormInstance>();
|
|
289
|
+
|
|
290
|
+
// ✅ 올바른 예
|
|
291
|
+
const [searchForm] = Form.useForm();
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
없으면 `const resizerContainerRef = React.useRef<HTMLDivElement>(null);` 근처에 추가합니다.
|
|
295
|
+
|
|
296
|
+
## 파라미터 타입별 변환 규칙
|
|
297
|
+
|
|
298
|
+
### dateRange
|
|
299
|
+
```typescript
|
|
300
|
+
{
|
|
301
|
+
label: t("기간"),
|
|
302
|
+
placeholder: [t("년월일"), t("년월일")],
|
|
303
|
+
name: "dateRange",
|
|
304
|
+
type: SearchParamType.DTPICKER_DATE_RANGE,
|
|
305
|
+
format: DT_FORMAT.DATE,
|
|
306
|
+
isTimeSelector: false,
|
|
307
|
+
presetRender: DtPickerPresetRender({ type: "all" }),
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**dateRange:withPeriod 인 경우:**
|
|
312
|
+
```typescript
|
|
313
|
+
{
|
|
314
|
+
type: SearchParamType.GROUP,
|
|
315
|
+
children: [
|
|
316
|
+
{
|
|
317
|
+
label: t("기간구분"),
|
|
318
|
+
name: "periodType",
|
|
319
|
+
type: SearchParamType.SELECT,
|
|
320
|
+
width: 140,
|
|
321
|
+
options: [
|
|
322
|
+
{ label: t("전체"), value: "" },
|
|
323
|
+
{ label: t("등록일"), value: "01" },
|
|
324
|
+
{ label: t("수정일"), value: "02" },
|
|
325
|
+
],
|
|
326
|
+
showSearch: false,
|
|
327
|
+
allowClear: false,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
label: t("기간"),
|
|
331
|
+
placeholder: [t("년월일"), t("년월일")],
|
|
332
|
+
name: "dateRange",
|
|
333
|
+
type: SearchParamType.DTPICKER_DATE_RANGE,
|
|
334
|
+
format: DT_FORMAT.DATE,
|
|
335
|
+
isTimeSelector: false,
|
|
336
|
+
presetRender: DtPickerPresetRender({ type: "all" }),
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### code:CODE_NAME
|
|
343
|
+
|
|
344
|
+
**단일 선택 (기본):**
|
|
345
|
+
```typescript
|
|
346
|
+
{
|
|
347
|
+
label: t("상태"),
|
|
348
|
+
name: "statusCd",
|
|
349
|
+
type: SearchParamType.SELECT,
|
|
350
|
+
width: 150,
|
|
351
|
+
options: STATUS_CODE?.options ?? [],
|
|
352
|
+
showSearch: false,
|
|
353
|
+
allowClear: true,
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**다중 선택 (code:CODE_NAME:multi):**
|
|
358
|
+
```typescript
|
|
359
|
+
{
|
|
360
|
+
label: t("쿠폰종류"),
|
|
361
|
+
name: "cuponKnTpcds",
|
|
362
|
+
type: SearchParamType.SELECT_MULTI,
|
|
363
|
+
width: 200,
|
|
364
|
+
options: CUPON_KN_TPCD?.options ?? [],
|
|
365
|
+
checkAllItem: true,
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### search
|
|
370
|
+
|
|
371
|
+
**기본:**
|
|
372
|
+
```typescript
|
|
373
|
+
{
|
|
374
|
+
label: t("검색어"),
|
|
375
|
+
placeholder: t("검색어"),
|
|
376
|
+
name: "searchText",
|
|
377
|
+
type: SearchParamType.INPUT,
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**search:withType:**
|
|
382
|
+
```typescript
|
|
383
|
+
{
|
|
384
|
+
type: SearchParamType.GROUP,
|
|
385
|
+
children: [
|
|
386
|
+
{
|
|
387
|
+
label: t("검색어구분"),
|
|
388
|
+
name: "searchType",
|
|
389
|
+
type: SearchParamType.SELECT,
|
|
390
|
+
width: 120,
|
|
391
|
+
options: [
|
|
392
|
+
{ label: t("전체"), value: "" },
|
|
393
|
+
{ label: t("제목"), value: "01" },
|
|
394
|
+
{ label: t("내용"), value: "02" },
|
|
395
|
+
],
|
|
396
|
+
showSearch: false,
|
|
397
|
+
allowClear: false,
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
label: t("검색어"),
|
|
401
|
+
placeholder: t("검색어"),
|
|
402
|
+
name: "searchText",
|
|
403
|
+
type: SearchParamType.INPUT,
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### finder:라벨:필드명:모달함수:너비
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
{
|
|
413
|
+
label: t("고객사"),
|
|
414
|
+
name: "custId",
|
|
415
|
+
type: SearchParamType.VALUES_FINDER,
|
|
416
|
+
width: 200,
|
|
417
|
+
onSearch: async () => {
|
|
418
|
+
const data = await openCustomerModal();
|
|
419
|
+
return [{
|
|
420
|
+
label: data.customer?.custNm,
|
|
421
|
+
value: JSON.stringify({
|
|
422
|
+
custId: data.customer?.id,
|
|
423
|
+
custNm: data.customer?.custNm,
|
|
424
|
+
}),
|
|
425
|
+
}];
|
|
426
|
+
},
|
|
427
|
+
config: { single: true },
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### cascade:라벨:필드명:옵션변수:너비
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
{
|
|
435
|
+
label: t("조직"),
|
|
436
|
+
name: "_orgCd",
|
|
437
|
+
type: SearchParamType.CASCADE,
|
|
438
|
+
width: 200,
|
|
439
|
+
options: organizationOption,
|
|
440
|
+
displayRender: (labels: string[]) => labels[labels.length - 1],
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### numberRange:라벨:필드명
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
{
|
|
448
|
+
label: t("방문회수"),
|
|
449
|
+
placeholder: [t("MIN"), t("MAX")],
|
|
450
|
+
name: "visitCount",
|
|
451
|
+
type: SearchParamType.NUMBER_RANGE,
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### radio:라벨:필드명
|
|
456
|
+
|
|
457
|
+
**필드명이 *Yn으로 끝나는 경우 (자동):**
|
|
458
|
+
```typescript
|
|
459
|
+
{
|
|
460
|
+
label: t("이메일수신동의"),
|
|
461
|
+
name: "emailRecptnYn",
|
|
462
|
+
type: SearchParamType.RADIO,
|
|
463
|
+
options: [
|
|
464
|
+
{ label: t("전체"), value: "" },
|
|
465
|
+
{ label: t("사용"), value: "Y" },
|
|
466
|
+
{ label: t("미사용"), value: "N" },
|
|
467
|
+
],
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
**직접 옵션 지정 (radio:라벨:필드명:옵션1,옵션2):**
|
|
472
|
+
```typescript
|
|
473
|
+
{
|
|
474
|
+
label: t("성별"),
|
|
475
|
+
name: "gender",
|
|
476
|
+
type: SearchParamType.RADIO,
|
|
477
|
+
options: [
|
|
478
|
+
{ label: t("전체"), value: "" },
|
|
479
|
+
{ label: t("남성"), value: "M" },
|
|
480
|
+
{ label: t("여성"), value: "F" },
|
|
481
|
+
],
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### checkbox:라벨:필드명:CODE_VAR
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
{
|
|
489
|
+
label: t("회원가입채널"),
|
|
490
|
+
name: "sbscrbPathClcdArr",
|
|
491
|
+
type: SearchParamType.CHECKBOX,
|
|
492
|
+
options: SBSCRB_PATH_CLCD?.options ?? [],
|
|
493
|
+
checkAllItem: true,
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## 필수 확인 사항
|
|
498
|
+
|
|
499
|
+
1. **Form 선언 확인:**
|
|
500
|
+
```typescript
|
|
501
|
+
const [searchForm] = Form.useForm();
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
2. **Store 상태 확인:**
|
|
505
|
+
- `listRequestValue`
|
|
506
|
+
- `setListRequestValue`
|
|
507
|
+
- `listSpinning`
|
|
508
|
+
- `handleSearch` 또는 `callListApi`
|
|
509
|
+
|
|
510
|
+
3. **PageSearchBar 스타일 확인:**
|
|
511
|
+
```typescript
|
|
512
|
+
const PageSearchBar = styled(PageLayout.PageSearchBar)``;
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
## 에러 처리
|
|
516
|
+
|
|
517
|
+
- Code가 useCodeStore에 없으면 자동 추가
|
|
518
|
+
- 모달 함수가 없으면 사용자에게 알림
|
|
519
|
+
- App.tsx가 열려있지 않으면 경로 요청
|
|
520
|
+
|
|
521
|
+
## 예시 응답
|
|
522
|
+
|
|
523
|
+
### 케이스 1: 기본 검색 (dateRange + code + search)
|
|
524
|
+
|
|
525
|
+
**사용자:** "search params 만들어줘: dateRange code:STATUS_CODE search"
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
529
|
+
|
|
530
|
+
1. Store 감지 중...
|
|
531
|
+
- Store 파일: useSystemSeoStore.ts
|
|
532
|
+
|
|
533
|
+
2. useCodeStore.ts 확인 중...
|
|
534
|
+
- STATUS_CODE가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
535
|
+
- 추가된 코드: `STATUS_CODE?: Code;`
|
|
536
|
+
|
|
537
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
538
|
+
- import 문 (IParam, SearchParams, SearchParamType, DT_FORMAT, DtPickerPresetRender)
|
|
539
|
+
- Store import: useSystemSeoStore
|
|
540
|
+
- Store 상태 선언: callListApi, listRequestValue, setListRequestValue, listSpinning
|
|
541
|
+
- Code 선언: const STATUS_CODE = useCodeStore((s) => s.STATUS_CODE);
|
|
542
|
+
- params 배열 (dateRange + statusCd + searchText)
|
|
543
|
+
- PageSearchBar 스타일 추가
|
|
544
|
+
- Form.useForm() 선언
|
|
545
|
+
- PageSearchBar 컴포넌트
|
|
546
|
+
|
|
547
|
+
완료되었습니다!
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### 케이스 2: 검색구분 포함 (search:withType)
|
|
551
|
+
|
|
552
|
+
**사용자:** "search params 만들어줘: dateRange search:withType"
|
|
553
|
+
|
|
554
|
+
```
|
|
555
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
556
|
+
|
|
557
|
+
1. Store 감지 중...
|
|
558
|
+
- Store 파일: useMemberStore.ts
|
|
559
|
+
|
|
560
|
+
2. App.tsx에 다음을 추가했습니다:
|
|
561
|
+
- import 문
|
|
562
|
+
- Store import: useMemberStore
|
|
563
|
+
- Store 상태 선언
|
|
564
|
+
- params 배열 (dateRange + 검색구분 GROUP)
|
|
565
|
+
- PageSearchBar 스타일
|
|
566
|
+
- Form.useForm() 선언
|
|
567
|
+
- PageSearchBar 컴포넌트
|
|
568
|
+
|
|
569
|
+
검색구분 옵션:
|
|
570
|
+
- 전체: ""
|
|
571
|
+
- 제목: "TITLE"
|
|
572
|
+
- 내용: "CONTENT"
|
|
573
|
+
- 작성자: "WRITER"
|
|
574
|
+
|
|
575
|
+
완료되었습니다!
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### 케이스 3: 기간구분 포함 (dateRange:withPeriod)
|
|
579
|
+
|
|
580
|
+
**사용자:** "search params 만들어줘: dateRange:withPeriod code:USER_TYPE"
|
|
581
|
+
|
|
582
|
+
```
|
|
583
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
584
|
+
|
|
585
|
+
1. Store 감지 중...
|
|
586
|
+
- Store 파일: useOrderStore.ts
|
|
587
|
+
|
|
588
|
+
2. useCodeStore.ts 확인 중...
|
|
589
|
+
- USER_TYPE가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
590
|
+
- 추가된 코드: `USER_TYPE?: Code;`
|
|
591
|
+
|
|
592
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
593
|
+
- import 문
|
|
594
|
+
- Store import: useOrderStore
|
|
595
|
+
- Store 상태 선언
|
|
596
|
+
- Code 선언: const USER_TYPE = useCodeStore((s) => s.USER_TYPE);
|
|
597
|
+
- params 배열 (기간구분 GROUP + dateRange + userCd)
|
|
598
|
+
- PageSearchBar 스타일
|
|
599
|
+
- Form.useForm() 선언
|
|
600
|
+
- PageSearchBar 컴포넌트
|
|
601
|
+
|
|
602
|
+
기간구분 옵션:
|
|
603
|
+
- 전체: ""
|
|
604
|
+
- 등록일: "REG_DATE"
|
|
605
|
+
- 수정일: "MOD_DATE"
|
|
606
|
+
|
|
607
|
+
완료되었습니다!
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### 케이스 4: 간단한 검색어만
|
|
611
|
+
|
|
612
|
+
**사용자:** "search params 만들어줘: search"
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
616
|
+
|
|
617
|
+
1. Store 감지 중...
|
|
618
|
+
- Store 파일: useNoticeStore.ts
|
|
619
|
+
|
|
620
|
+
2. App.tsx에 다음을 추가했습니다:
|
|
621
|
+
- import 문
|
|
622
|
+
- Store import: useNoticeStore
|
|
623
|
+
- Store 상태 선언
|
|
624
|
+
- params 배열 (searchText만)
|
|
625
|
+
- PageSearchBar 스타일
|
|
626
|
+
- Form.useForm() 선언
|
|
627
|
+
- PageSearchBar 컴포넌트
|
|
628
|
+
|
|
629
|
+
완료되었습니다!
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### 케이스 5: 코드 다중 선택 포함
|
|
633
|
+
|
|
634
|
+
**사용자:** "search params 만들어줘: code:CATEGORY:multi code:STATUS_CODE search"
|
|
635
|
+
|
|
636
|
+
```
|
|
637
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
638
|
+
|
|
639
|
+
1. Store 감지 중...
|
|
640
|
+
- Store 파일: useProductStore.ts
|
|
641
|
+
|
|
642
|
+
2. useCodeStore.ts 확인 중...
|
|
643
|
+
- CATEGORY가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
644
|
+
- STATUS_CODE가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
645
|
+
- 추가된 코드: `CATEGORY?: Code;`, `STATUS_CODE?: Code;`
|
|
646
|
+
|
|
647
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
648
|
+
- import 문
|
|
649
|
+
- Store import: useProductStore
|
|
650
|
+
- Store 상태 선언
|
|
651
|
+
- Code 선언: const CATEGORY = useCodeStore((s) => s.CATEGORY); const STATUS_CODE = useCodeStore((s) => s.STATUS_CODE);
|
|
652
|
+
- params 배열 (CATEGORY 다중 + statusCd 단일 + searchText)
|
|
653
|
+
- PageSearchBar 스타일
|
|
654
|
+
- Form.useForm() 선언
|
|
655
|
+
- PageSearchBar 컴포넌트
|
|
656
|
+
|
|
657
|
+
완료되었습니다!
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### 케이스 6: 복합 케이스 (dateRange:withPeriod + code + search:withType)
|
|
661
|
+
|
|
662
|
+
**사용자:** "search params 만들어줘: dateRange:withPeriod code:ORDER_STATUS search:withType"
|
|
663
|
+
|
|
664
|
+
```
|
|
665
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
666
|
+
|
|
667
|
+
1. Store 감지 중...
|
|
668
|
+
- Store 파일: useOrderListStore.ts
|
|
669
|
+
|
|
670
|
+
2. useCodeStore.ts 확인 중...
|
|
671
|
+
- ORDER_STATUS가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
672
|
+
- 추가된 코드: `ORDER_STATUS?: Code;`
|
|
673
|
+
|
|
674
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
675
|
+
- import 문
|
|
676
|
+
- Store import: useOrderListStore
|
|
677
|
+
- Store 상태 선언
|
|
678
|
+
- Code 선언: const ORDER_STATUS = useCodeStore((s) => s.ORDER_STATUS);
|
|
679
|
+
- params 배열 (기간구분 GROUP + dateRange + orderStatusCd + 검색구분 GROUP)
|
|
680
|
+
- PageSearchBar 스타일
|
|
681
|
+
- Form.useForm() 선언
|
|
682
|
+
- PageSearchBar 컴포넌트
|
|
683
|
+
|
|
684
|
+
완료되었습니다!
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### 케이스 7: 날짜 범위 없음 (code + search)
|
|
688
|
+
|
|
689
|
+
**사용자:** "search params 만들어줘: code:BOARD_TYPE search"
|
|
690
|
+
|
|
691
|
+
```
|
|
692
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
693
|
+
|
|
694
|
+
1. Store 감지 중...
|
|
695
|
+
- Store 파일: useBoardStore.ts
|
|
696
|
+
|
|
697
|
+
2. useCodeStore.ts 확인 중...
|
|
698
|
+
- BOARD_TYPE가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
699
|
+
- 추가된 코드: `BOARD_TYPE?: Code;`
|
|
700
|
+
|
|
701
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
702
|
+
- import 문 (DT_FORMAT, DtPickerPresetRender 제외)
|
|
703
|
+
- Store import: useBoardStore
|
|
704
|
+
- Store 상태 선언
|
|
705
|
+
- Code 선언: const BOARD_TYPE = useCodeStore((s) => s.BOARD_TYPE);
|
|
706
|
+
- params 배열 (boardTypeCd + searchText)
|
|
707
|
+
- PageSearchBar 스타일
|
|
708
|
+
- Form.useForm() 선언
|
|
709
|
+
- PageSearchBar 컴포넌트
|
|
710
|
+
|
|
711
|
+
완료되었습니다!
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### 케이스 8: 숫자 범위 포함
|
|
715
|
+
|
|
716
|
+
**사용자:** "search params 만들어줘: numberRange:방문회수:visitCount code:MEMBER_LEVEL"
|
|
717
|
+
|
|
718
|
+
```
|
|
719
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
720
|
+
|
|
721
|
+
1. Store 감지 중...
|
|
722
|
+
- Store 파일: useMemberStore.ts
|
|
723
|
+
|
|
724
|
+
2. useCodeStore.ts 확인 중...
|
|
725
|
+
- MEMBER_LEVEL가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
726
|
+
- 추가된 코드: `MEMBER_LEVEL?: Code;`
|
|
727
|
+
|
|
728
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
729
|
+
- import 문
|
|
730
|
+
- Store import: useMemberStore
|
|
731
|
+
- Store 상태 선언
|
|
732
|
+
- Code 선언: const MEMBER_LEVEL = useCodeStore((s) => s.MEMBER_LEVEL);
|
|
733
|
+
- params 배열 (visitCount NUMBER_RANGE + memberLevelCd)
|
|
734
|
+
- PageSearchBar 스타일
|
|
735
|
+
- Form.useForm() 선언
|
|
736
|
+
- PageSearchBar 컴포넌트
|
|
737
|
+
|
|
738
|
+
완료되었습니다!
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### 케이스 9: Y/N 필드 포함
|
|
742
|
+
|
|
743
|
+
**사용자:** "search params 만들어줘: radio:이메일수신동의:emailRecptnYn code:STATUS_CODE"
|
|
744
|
+
|
|
745
|
+
```
|
|
746
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
747
|
+
|
|
748
|
+
1. Store 감지 중...
|
|
749
|
+
- Store 파일: useMemberStore.ts
|
|
750
|
+
|
|
751
|
+
2. useCodeStore.ts 확인 중...
|
|
752
|
+
- STATUS_CODE가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
753
|
+
- 추가된 코드: `STATUS_CODE?: Code;`
|
|
754
|
+
|
|
755
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
756
|
+
- import 문
|
|
757
|
+
- Store import: useMemberStore
|
|
758
|
+
- Store 상태 선언
|
|
759
|
+
- Code 선언: const STATUS_CODE = useCodeStore((s) => s.STATUS_CODE);
|
|
760
|
+
- params 배열 (emailRecptnYn RADIO + statusCd)
|
|
761
|
+
- PageSearchBar 스타일
|
|
762
|
+
- Form.useForm() 선언
|
|
763
|
+
- PageSearchBar 컴포넌트
|
|
764
|
+
|
|
765
|
+
완료되었습니다!
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
### 케이스 10: 체크박스 포함
|
|
769
|
+
|
|
770
|
+
**사용자:** "search params 만들어줘: checkbox:가입채널:joinChannelArr:CHANNEL_TYPE dateRange"
|
|
771
|
+
|
|
772
|
+
```
|
|
773
|
+
SearchParams 컴포넌트를 생성하겠습니다.
|
|
774
|
+
|
|
775
|
+
1. Store 감지 중...
|
|
776
|
+
- Store 파일: useMemberStore.ts
|
|
777
|
+
|
|
778
|
+
2. useCodeStore.ts 확인 중...
|
|
779
|
+
- CHANNEL_TYPE가 CodeModel 인터페이스에 없어서 자동 추가했습니다.
|
|
780
|
+
- 추가된 코드: `CHANNEL_TYPE?: Code;`
|
|
781
|
+
|
|
782
|
+
3. App.tsx에 다음을 추가했습니다:
|
|
783
|
+
- import 문
|
|
784
|
+
- Store import: useMemberStore
|
|
785
|
+
- Store 상태 선언
|
|
786
|
+
- Code 선언: const CHANNEL_TYPE = useCodeStore((s) => s.CHANNEL_TYPE);
|
|
787
|
+
- params 배열 (joinChannelArr CHECKBOX + dateRange)
|
|
788
|
+
- PageSearchBar 스타일
|
|
789
|
+
- Form.useForm() 선언
|
|
790
|
+
- PageSearchBar 컴포넌트
|
|
791
|
+
|
|
792
|
+
완료되었습니다!
|
|
793
|
+
```
|