@simplysm/sd-claude 14.0.89 → 14.0.91
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/references/sd-simplysm14/README.md +16 -17
- package/claude/references/sd-simplysm14/apis/angular/README.md +52 -30
- package/claude/references/sd-simplysm14/apis/angular/controls.md +200 -38
- package/claude/references/sd-simplysm14/apis/angular/crud.md +41 -53
- package/claude/references/sd-simplysm14/apis/angular/directives.md +66 -22
- package/claude/references/sd-simplysm14/apis/angular/features.md +127 -40
- package/claude/references/sd-simplysm14/apis/angular/infra.md +60 -43
- package/claude/references/sd-simplysm14/apis/angular/layout.md +56 -20
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +74 -74
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +50 -40
- package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +55 -15
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +59 -42
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +77 -62
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +8 -7
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +71 -43
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +22 -14
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +19 -19
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +17 -17
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +28 -28
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +37 -37
- package/claude/references/sd-simplysm14/apis/core-common/README.md +87 -219
- package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +54 -98
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +57 -99
- package/claude/references/sd-simplysm14/apis/core-common/datetime.md +60 -103
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +42 -47
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +42 -88
- package/claude/references/sd-simplysm14/apis/core-common/serialization.md +55 -0
- package/claude/references/sd-simplysm14/apis/core-node/README.md +6 -7
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +17 -12
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +14 -13
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +9 -8
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +14 -13
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +4 -8
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +14 -12
- package/claude/references/sd-simplysm14/apis/excel/README.md +22 -22
- package/claude/references/sd-simplysm14/apis/excel/cell.md +37 -29
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +29 -15
- package/claude/references/sd-simplysm14/apis/excel/style.md +33 -27
- package/claude/references/sd-simplysm14/apis/excel/utils.md +29 -19
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +78 -55
- package/claude/references/sd-simplysm14/apis/excel/wrapper.md +42 -45
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +6 -8
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +118 -67
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +83 -86
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +102 -93
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +138 -81
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +49 -44
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +42 -42
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +44 -33
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +11 -10
- package/claude/references/sd-simplysm14/apis/service-client/README.md +56 -52
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +33 -28
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +23 -21
- package/claude/references/sd-simplysm14/apis/service-common/README.md +83 -48
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +126 -34
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +109 -54
- package/claude/references/sd-simplysm14/apis/service-server/README.md +69 -81
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +46 -43
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +63 -37
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +40 -30
- package/claude/references/sd-simplysm14/apis/storage/README.md +17 -17
- package/claude/references/sd-simplysm14/manuals/client-app-structure.md +135 -140
- package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-service.md +19 -7
- package/claude/references/sd-simplysm14/manuals/client-shared-data.md +2 -2
- package/claude/references/sd-simplysm14/manuals/client-system-log.md +16 -4
- package/claude/references/sd-simplysm14/manuals/data-log.md +0 -1
- package/claude/references/sd-simplysm14/manuals/orm.md +16 -0
- package/claude/rules/sd-design-rules.md +10 -0
- package/claude/skills/sd-demo/SKILL.md +0 -6
- package/claude/skills/sd-docs/SKILL.md +60 -0
- package/claude/{workflows/sd-docs.rules.md → skills/sd-docs/references/subagent-prompt.md} +118 -103
- package/claude/skills/sd-impl/SKILL.md +7 -4
- package/claude/skills/sd-spec/SKILL.md +842 -15
- package/claude/skills/sd-spec/references/example-spec.md +26 -36
- package/package.json +1 -1
- package/claude/references/sd-simplysm14/apis/core-common/json-transfer.md +0 -53
- package/claude/skills/sd-spec/references/spec-authoring.md +0 -519
- package/claude/workflows/sd-docs.js +0 -84
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
# @simplysm/angular — 모달·토스트·Busy·인쇄 (
|
|
1
|
+
# @simplysm/angular — 모달·토스트·Busy·인쇄 (오버레이/전역 피드백)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
화면에서 프로그래밍 방식으로 모달을 띄우거나, 토스트로 알림·진행률을 표시하거나, busy 인디케이터·인쇄/PDF 출력을 호출할 때 함께 읽히는 군. provider 는 모두 `providedIn: "root"`, 컴포넌트는 provider 가 동적으로 body 에 attach 하므로 템플릿에 직접 둘 일은 거의 없음.
|
|
4
4
|
|
|
5
5
|
## SdModalProvider
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- showAsync<T>(modal: SdModalInfo<T>, options?: SdModalOptions): Promise<close결과 | undefined> — 모달 표시. 컨텐츠 컴포넌트의 `close.emit(result)` 시 result 로 resolve, 배경클릭/ESC/닫기버튼 시 undefined 로 resolve. 첫 탭 가능 컨트롤에 자동 포커스.
|
|
10
|
-
- modalCount: Signal<number> — 현재 열린 모달 수.
|
|
11
|
-
|
|
12
|
-
`SdModalInfo<T, X>` = `{ title: string; type: Type<T>; inputs: ... }`. inputs 는 컨텐츠 컴포넌트의 input 중 `initialized`/`close`/`actionTplRef`/`_optionalModalInputs` 와 X 로 지정한 키를 제외한 것. `_optionalModalInputs` 로 선언한 키는 optional.
|
|
13
|
-
|
|
14
|
-
`SdModalContentDef<O>` — 모달 컨텐츠 컴포넌트가 구현할 인터페이스:
|
|
15
|
-
- initialized: Signal<boolean> — 초기화 완료 신호(인쇄/대기 동기화에 사용).
|
|
16
|
-
- close: OutputEmitterRef<O | undefined> — 결과 emit. O 가 모달 반환 타입.
|
|
17
|
-
- actionTplRef?: TemplateRef — 헤더 우측 액션 영역에 투영할 템플릿(있으면 모달 헤더로 브릿지됨).
|
|
18
|
-
- _optionalModalInputs?: string — optional 로 둘 input 키들의 유니온 타입 표식(런타임 값 아님).
|
|
19
|
-
|
|
20
|
-
`SdModalOptions`:
|
|
21
|
-
- key?: string — 지정 시 크기·위치를 `SdSystemConfigProvider` 에 영속(`sd-modal.<key>`).
|
|
22
|
-
- hideHeader?: boolean — 헤더(제목·닫기버튼) 숨김.
|
|
23
|
-
- hideCloseButton?: boolean — 우상단 닫기 버튼만 숨김.
|
|
24
|
-
- headerStyle?: string — 헤더 인라인 스타일.
|
|
25
|
-
- useCloseByBackdrop?: boolean — 배경 클릭으로 닫기 허용(기본 true). 입력 확인 모달이면 false.
|
|
26
|
-
- useCloseByEscapeKey?: boolean — ESC 로 닫기 허용(기본 true).
|
|
27
|
-
- float?: boolean — 배경(backdrop) 없이 떠 있는 모달. 비차단 패널이면 true.
|
|
28
|
-
- fill?: boolean — 화면 가득 채움(전체화면 모달).
|
|
29
|
-
- resizable?: boolean — 8방향 리사이즈 핸들 표시.
|
|
30
|
-
- movable?: boolean — 헤더 드래그로 이동.
|
|
31
|
-
- position?: "bottom-right" | "top-right" — 고정 위치(알림형 모달).
|
|
32
|
-
- minHeightPx/minWidthPx/heightPx/widthPx?: number — 최소·초기 크기(px).
|
|
33
|
-
- noFirstControlFocusing?: boolean — 첫 컨트롤 자동 포커스 비활성(다이얼로그 자체에 포커스).
|
|
7
|
+
컴포넌트를 모달 셸(`SdModal`) 안에 동적 생성해 body 에 띄움. `close.emit(payload)` 또는 닫기(X/배경/ESC)로 종료.
|
|
34
8
|
|
|
35
9
|
```ts
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
);
|
|
10
|
+
showAsync<T extends SdModalContentDef<any>>(
|
|
11
|
+
modal: SdModalInfo<T>, options?: SdModalOptions,
|
|
12
|
+
): Promise<Parameters<T["close"]["emit"]>[0] | undefined>
|
|
40
13
|
```
|
|
41
14
|
|
|
42
|
-
|
|
15
|
+
- `modal.type: Type<T>` — `SdModalContentDef<O>` 를 구현한 컴포넌트 클래스(`SdModal` 자체가 아님). `O` 가 close 페이로드 타입.
|
|
16
|
+
- `modal.title: string` — 모달 헤더 제목.
|
|
17
|
+
- `modal.inputs` — 모달 컴포넌트가 받을 input 값. `initialized`/`close`/`actionTplRef` 와 `_optionalModalInputs` 로 표시된 키는 제외/optional 처리됨. 없으면 `{}`.
|
|
18
|
+
- 반환값 — 컴포넌트가 `close.emit` 한 페이로드. 닫기/취소로 닫히면 `undefined`. 매뉴얼 패턴: `const r = await this._sdModal.showAsync({...}); if (!r) return;`.
|
|
19
|
+
- `modalCount: WritableSignal<number>` — 현재 열린 모달 수.
|
|
43
20
|
|
|
44
|
-
|
|
21
|
+
### SdModalContentDef<O> (모달 컴포넌트가 구현)
|
|
45
22
|
|
|
46
|
-
|
|
23
|
+
- `initialized: Signal<boolean>` — 초기화 완료 여부. busy 표시 해제 기준.
|
|
24
|
+
- `close: OutputEmitterRef<O | undefined>` — 결과 emit. `O` 가 `showAsync` 반환 타입.
|
|
25
|
+
- `actionTplRef?: TemplateRef<any>` — 헤더 우측에 끼울 액션 영역 템플릿(있으면 모달 헤더로 브릿지됨).
|
|
26
|
+
- `_optionalModalInputs?: string` — (타입 전용 마커) 이 컴포넌트의 input 중 optional 로 둘 키 이름 리터럴. 런타임 값 아님.
|
|
47
27
|
|
|
48
|
-
|
|
49
|
-
- modalComponent: Signal<SdModal | undefined> / contentComponent: Signal<T | undefined>.
|
|
50
|
-
- canDeactivateFn: () => boolean — 닫기 차단 판정. `setupCanDeactivate` 가 설정. true 가 아니면 배경/ESC/버튼 닫기 무시.
|
|
28
|
+
### SdModalOptions (showAsync 2번째 인자)
|
|
51
29
|
|
|
52
|
-
|
|
30
|
+
- `key?: string` — 설정 저장 키. 지정 시 사용자가 조정한 width/height/위치를 `SdSystemConfigProvider` 에 영속·복원.
|
|
31
|
+
- `hideHeader?: boolean` — true 면 제목/닫기 헤더 숨김. 헤더 없는 풀커스텀 모달용.
|
|
32
|
+
- `hideCloseButton?: boolean` — true 면 헤더 X 버튼만 숨김.
|
|
33
|
+
- `headerStyle?: string` — 헤더 영역 인라인 스타일.
|
|
34
|
+
- `useCloseByBackdrop?: boolean` — 배경 클릭으로 닫기 허용(기본 동작상 컴포넌트 기본 true). false 면 배경 클릭 무시.
|
|
35
|
+
- `useCloseByEscapeKey?: boolean` — ESC 로 닫기 허용. false 면 ESC 무시.
|
|
36
|
+
- `float?: boolean` — true 면 배경(backdrop) 없는 떠있는 패널. 비모달 보조 패널용.
|
|
37
|
+
- `fill?: boolean` — true 면 화면 전체를 채움(풀스크린 모달).
|
|
38
|
+
- `resizable?: boolean` — true 면 8방향 리사이즈 핸들 표시.
|
|
39
|
+
- `movable?: boolean` — true 면 헤더 드래그로 이동.
|
|
40
|
+
- `position?: "bottom-right" | "top-right"` — 고정 위치. 토스트성 알림 모달에 사용.
|
|
41
|
+
- `minHeightPx?/minWidthPx?/heightPx?/widthPx?: number` — 최소/초기 크기.
|
|
42
|
+
- `noFirstControlFocusing?: boolean` — true 면 첫 입력 요소 자동 포커스를 끔(다이얼로그 자체에 포커스).
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
- SdPromptModal: `SdModalContentDef<string>`. `message = input.required<string>()`. 텍스트 입력(필수) 후 확인 시 입력값, 취소 시 undefined emit.
|
|
56
|
-
- SdConfirmModal: `SdModalContentDef<boolean>`. `message = input.required<string>()`. 확인 시 `true`, 취소 시 undefined emit.
|
|
44
|
+
### 내장 모달 컴포넌트
|
|
57
45
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
- `SdPromptModal` (`SdModalContentDef<string>`) — 메시지 + 텍스트 입력 후 확인/취소. `message: input.required<string>` (innerHTML). 확인 시 입력값, 취소/닫기 시 `undefined`. 입력은 required 라 빈 값이면 네이티브 검증으로 차단.
|
|
47
|
+
- `SdConfirmModal` (`SdModalContentDef<boolean>`) — 메시지 + 확인/취소. `message: input.required<string>`. 확인 시 `true`, 취소/닫기 시 `undefined`.
|
|
48
|
+
- 사용: `const ok = await this._sdModal.showAsync({ type: SdConfirmModal, title: "확인", inputs: { message: "삭제할까요?" } }); if (!ok) return;`.
|
|
61
49
|
|
|
62
|
-
|
|
50
|
+
### SdActivatedModalProvider
|
|
63
51
|
|
|
64
|
-
|
|
52
|
+
모달 컴포넌트 내부에서 inject. 자기 모달의 셸/콘텐츠 참조와 이탈 가드를 보유.
|
|
65
53
|
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- try<R>(fn, messageFn?): Promise<R | undefined> — fn 실행 중 Error 발생 시 danger 토스트 + 시스템로그 기록 후 undefined 반환(Error 아닌 throw 는 재throw). 화면 액션 핸들러를 감싸는 표준 패턴.
|
|
69
|
-
- alertThemes: WritableSignal<SdToastSeverity[]> — 이 심각도들은 토스트 대신 `window.alert`.
|
|
70
|
-
- overlap: WritableSignal<boolean> — true 면 새 토스트가 기존 토스트 모두 제거 후 표시(겹침 방지).
|
|
71
|
-
- beforeShowFn?: (theme) => void — 토스트 표시 직전 콜백(예: 사운드).
|
|
54
|
+
- `modalComponent: Signal<SdModal | undefined>` / `contentComponent: Signal<T | undefined>` — 셸/콘텐츠 컴포넌트 참조.
|
|
55
|
+
- `canDeactivateFn: () => boolean` — 닫기 시도 시 false 면 닫힘 차단. `setupCanDeactivate`(routing-appstructure.md) 가 모달 컨텍스트에서 이걸 설정.
|
|
72
56
|
|
|
73
|
-
|
|
57
|
+
### SdModal (모달 셸)
|
|
74
58
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
59
|
+
`SdModalProvider` 가 내부적으로 생성하는 셸 컴포넌트. 상속·직접 배치 대상 아님. `<ng-content>` 로 콘텐츠를 투영하고 위 `SdModalOptions` 와 동일한 input(`title`/`open`/`resizable`/... `closeRequest` output) 을 보유.
|
|
60
|
+
|
|
61
|
+
## SdToastProvider
|
|
62
|
+
|
|
63
|
+
화면 우상단(또는 overlap 모드)에 토스트를 띄움. 알림·비동기 에러 가드·진행률에 사용.
|
|
64
|
+
|
|
65
|
+
- `info/success/warning/danger(message: string): void` — 심각도별 토스트 1개 표시(3초 후 자동 해제, hover 중이면 지연). `info`/`success` 는 `aria-live=polite`, `warning`/`danger` 는 `assertive`. 심각도 의미는 `sd-design-rules` 의 분류를 따름(error=문제 발생).
|
|
66
|
+
- `info/...(message: string, useProgress: true): WritableSignal<number>` — progress 모드. 반환된 signal 에 0~100 을 set 하면 진행바 갱신, 100 도달 1초 후 자동 해제. 업로드/다운로드 진행률 표시에 사용.
|
|
67
|
+
- `try<R>(fn: () => Promise<R> | R, messageFn?: (err: Error) => string): Promise<R | undefined>` — `fn` 실행 중 `Error` 가 throw 되면 잡아서 `danger` 토스트 + 시스템로그 `error` 적재 후 `undefined` 반환(에러를 외부로 전파하지 않음). `Error` 가 아닌 throw 는 그대로 재전파. 매뉴얼의 비동기 작업 표준 가드: `await this._sdToast.try(async () => { ... })`.
|
|
68
|
+
- `notify<T extends SdToastContentDef<any>>(input: SdToastInput<T>): Promise<...>` — 커스텀 컴포넌트를 토스트로 띄우고 `close` 페이로드를 반환(5초 후 자동 `undefined`).
|
|
69
|
+
- `alertThemes: WritableSignal<SdToastSeverity[]>` — 여기 든 심각도는 토스트 대신 `window.alert` 로 표시(키오스크 등 강제 확인 필요 화면).
|
|
70
|
+
- `overlap: WritableSignal<boolean>` — true 면 새 토스트가 기존 토스트를 제거하고 단독 표시.
|
|
71
|
+
- `beforeShowFn?: (theme: SdToastSeverity) => void` — 토스트 표시 직전 콜백(사운드 등).
|
|
78
72
|
|
|
79
|
-
|
|
73
|
+
타입:
|
|
80
74
|
|
|
81
|
-
|
|
75
|
+
- `SdToastSeverity = "info"|"success"|"warning"|"danger"`.
|
|
76
|
+
- `SdToastTheme = "primary"|"secondary"|SdToastSeverity|"gray"|"blue-gray"` — `sd-toast` 컴포넌트 `theme` 입력 범위.
|
|
77
|
+
- `SdToastContentDef<O> = { close: OutputEmitterRef<O | undefined> }` — `notify` 커스텀 컴포넌트 규약.
|
|
78
|
+
- `SdToastInput<T> = { type: Type<T>; inputs: Omit<DirectiveInputSignals<T>, "close"> }`.
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
`SdToast`/`SdToastContainer` 는 provider 가 동적 생성하는 표시 컴포넌트(직접 배치 불필요).
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
- globalBusyCount: WritableSignal<number> — >0 이면 전역 busy 오버레이 표시(라우팅·인쇄가 자동 증감). 직접 작업 감쌀 때 update 로 증감.
|
|
87
|
-
- type: WritableSignal<SdBusyType> — 기본 표시 유형. `SdBusyType = "spinner"|"bar"|"cube"`.
|
|
82
|
+
## SdBusyProvider / SdBusyContainer
|
|
88
83
|
|
|
89
|
-
|
|
84
|
+
영역 단위 busy 오버레이.
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
86
|
+
- `SdBusyProvider.type: WritableSignal<SdBusyType>` — 전역 기본 인디케이터 종류. `SdBusyType = "spinner"|"bar"|"cube"`. `"bar"` = 상단 가는 진행바, `"spinner"` = 회전 원, `"cube"` = 큐브 애니메이션.
|
|
87
|
+
- `SdBusyProvider.globalBusyCount: WritableSignal<number>` — 전역 busy 카운트(>0 이면 화면 전체 busy). 라우팅·인쇄가 ±1. 직접 ±1 해 전역 차단 가능.
|
|
88
|
+
- `SdBusyContainer` (`sd-busy-container`) — 자식 영역에 busy 오버레이를 씌우는 컨테이너 컴포넌트.
|
|
89
|
+
- `busy: boolean` — true 면 오버레이 표시 + 영역 내 키입력 차단.
|
|
90
|
+
- `message: string` — 인디케이터 옆/아래 표시 메시지.
|
|
91
|
+
- `type: SdBusyType` — 이 영역만의 인디케이터 종류(미지정 시 provider 기본값).
|
|
92
|
+
- `progressPercent: number` — 지정 시 상단 진행바(0~100). 결정형 작업 진행률에 사용.
|
|
93
|
+
- 사용: `<sd-busy-container [busy]="busyCount() > 0">...</sd-busy-container>` (단, `sd-base-container` 가 이미 내장).
|
|
96
94
|
|
|
97
95
|
## SdPrintProvider
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
- printAsync<T>(template: SdPrintInput<T>, options?: { size?: string; margin?: string }): Promise<void> — 컴포넌트를 body 에 임시 렌더 후 `window.print()`. size 기본 `"A4 auto"`, margin 기본 `"0"`. 인쇄 동안 글로벌 busy.
|
|
101
|
-
- getPdfBufferAsync<T>(template, options?: { orientation?: "portrait"|"landscape"; pageSize?: string }): Promise<Uint8Array> — `.page` 엘리먼트별로 캔버스 변환(jsPDF) 후 PDF 버퍼 반환. pageSize 기본 `"a4"`, orientation 기본 portrait.
|
|
97
|
+
인쇄 템플릿 컴포넌트를 동적 생성해 `window.print()` 하거나 PDF 버퍼로 변환. 호출 동안 `globalBusyCount` ±1.
|
|
102
98
|
|
|
103
|
-
`
|
|
99
|
+
- `printAsync<T extends SdPrint>(template: SdPrintInput<T>, options?: { size?: string; margin?: string }): Promise<void>` — 템플릿을 숨겨 붙인 뒤 `@media print` CSS 로 그것만 출력. `size` 기본 `"A4 auto"`, `margin` 기본 `"0"`. 이미지 로드 완료를 기다린 후 인쇄.
|
|
100
|
+
- `getPdfBufferAsync<T extends SdPrint>(template: SdPrintInput<T>, options?: { orientation?: "portrait"|"landscape"; pageSize?: string }): Promise<Uint8Array>` — `.page` 요소들(없으면 루트)을 캔버스로 렌더해 jsPDF 로 PDF 바이트 생성. `orientation` 기본 portrait, `pageSize` 기본 `"a4"`. 첨부/저장용 PDF 가 필요할 때.
|
|
101
|
+
- `SdPrint = { initialized: Signal<boolean>; _optionalPrintInputs?: string }` — 인쇄 템플릿 컴포넌트 규약. `initialized` 가 true 가 되어야 인쇄 진행(데이터 로드 대기).
|
|
102
|
+
- `SdPrintInput<T> = { type: Type<T>; inputs: ... }` — 인쇄 컴포넌트 + input 값(`_optionalPrintInputs` 표시 키는 optional).
|
|
103
|
+
- 사용: `await this._sdPrint.printAsync({ type: OutboundPrintTemplate, inputs: { id } })`. 인쇄 템플릿 파일은 `<domain>.print-template.ts`(client-component.md).
|
|
@@ -1,69 +1,79 @@
|
|
|
1
1
|
# @simplysm/angular — 라우팅 / 앱 구조(메뉴·권한)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
라우터 링크·현재 페이지 식별·뷰 컨텍스트(page/control/modal)·이탈 가드, 그리고 앱 구조 트리에서 메뉴·권한을 파생하는 군. 화면 컴포넌트의 표준 시그널 `viewType`, 권한 가드 `injectPermsSignal`, 사이드바/탑바 메뉴가 이 군에 의존.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## injectViewTypeSignal / SdViewType
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
```ts
|
|
8
|
+
function injectViewTypeSignal(): Signal<SdViewType>
|
|
9
|
+
type SdViewType = "page" | "modal" | "control"
|
|
10
|
+
```
|
|
10
11
|
|
|
11
|
-
`
|
|
12
|
+
현재 컴포넌트가 어느 컨텍스트에서 동작 중인지 판정하는 signal. `"page"` = 라우팅 진입 화면, `"modal"` = 모달로 열림, `"control"` = 다른 화면 안에 임베드된 자식. 판정 기준: 모달 컨텍스트면 modal, 라우트 컴포넌트의 selector 가 현재 엘리먼트 태그와 일치하고 full/current 페이지 코드가 같으면 page, 그 외 control. 매뉴얼 표준 시그널 `viewType = injectViewTypeSignal()` 로 받아 `sd-base-container [viewType]` 에 전달.
|
|
12
13
|
|
|
13
14
|
## injectViewTitleSignal
|
|
14
15
|
|
|
15
|
-
`injectViewTitleSignal(): Signal<string>` —
|
|
16
|
+
- `function injectViewTitleSignal(): Signal<string>` — 현재 뷰의 표시 제목. 모달이면 모달 컴포넌트 `title`, 아니면 앱 구조에서 현재 페이지 코드로 찾은 제목(`[상위 > 경로] 현재`). 못 찾으면 `""`. `sd-base-container` 가 page 탑바 제목에 사용.
|
|
16
17
|
|
|
17
|
-
##
|
|
18
|
+
## injectFullPageCodeSignal / injectCurrentPageCodeSignal
|
|
18
19
|
|
|
19
|
-
`
|
|
20
|
+
- `function injectFullPageCodeSignal(): Signal<string>` — 라우터 URL 전체에서 파생한 페이지 코드(`/` → `.` 로 합침, 앞 2세그먼트 제외, `;`/`?` 이후 제거). 메뉴 선택 상태·뷰 타입 판정에 사용.
|
|
21
|
+
- `function injectCurrentPageCodeSignal(): Signal<string> | undefined` — 현재 `ActivatedRoute` 기준 상대 페이지 코드. 라우트 컨텍스트 없으면 `undefined`. 중첩 라우트에서 자기 위치 코드가 필요할 때.
|
|
20
22
|
|
|
21
23
|
## setupCanDeactivate
|
|
22
24
|
|
|
23
|
-
`setupCanDeactivate(fn: () => boolean): void` —
|
|
25
|
+
- `function setupCanDeactivate(fn: () => boolean): void` — 라우터 이탈/모달 닫기 시점에 `fn()` 이 false 면 이탈/닫기를 차단. 모달 컨텍스트면 `SdActivatedModalProvider.canDeactivateFn` 에, 라우트 컨텍스트면 해당 route 의 `canDeactivate` 에 등록(파괴 시 자동 해제). detail 화면의 변경 가드 표준: `setupCanDeactivate(() => this._checkIgnoreChanges())`(client-component.md).
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
setupCanDeactivate(() => !this.dirty() || confirm("저장하지 않고 나갈까요?"));
|
|
27
|
-
```
|
|
27
|
+
## SdRouterLink (`[sdRouterLink]`)
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
라우터 이동을 호스트 클릭에 붙이는 디렉티브. Ctrl/Shift 클릭·window 모드면 새 창/탭으로 분기.
|
|
30
30
|
|
|
31
|
-
`
|
|
32
|
-
-
|
|
31
|
+
- `sdRouterLink: { link: string; params?: Record<string,string>; window?: { width?; height? }; outletName?: string; queryParams?: Record<string,string> } | undefined` — 이동 옵션.
|
|
32
|
+
- `link` — 라우트 경로. `outletName` 있으면 named outlet 이동.
|
|
33
|
+
- `params` — 매트릭스 파라미터, `queryParams` — 쿼리 파라미터.
|
|
34
|
+
- `window` — Ctrl/Shift 클릭 또는 window 컨텍스트일 때 팝업 창 크기(기본 800x800).
|
|
35
|
+
- 미지정(`undefined`) 이면 클릭 무시 + 커서 기본. 메뉴 항목이 leaf 가 아닐 때 등.
|
|
36
|
+
- Alt+클릭은 무시. 사이드바/탑바 메뉴가 `getMenuRouterLinkOption(menu)` 결과를 이 입력에 바인딩.
|
|
33
37
|
|
|
34
38
|
## SdNavigateWindowProvider
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
- open(navigate: string, params?, features?): void — window 모드거나 features 지정 시 `window.open` 팝업(닫힐 때 부모와 함께 정리), 아니면 `_blank` 탭.
|
|
40
|
+
- `isWindow: boolean` — 현재 문서가 `window=true` 로 열린 팝업인지(해시 파라미터 검사).
|
|
41
|
+
- `open(navigate: string, params?: Record<string,string>, features?: string): void` — 새 창/탭으로 라우트 열기. window 컨텍스트이거나 `features` 가 있으면 `window=true` 팝업으로(부모 unload 시 자동 close), 아니면 `_blank` 탭으로. `SdRouterLink` 내부 + 화면에서 보조 창을 띄울 때.
|
|
39
42
|
|
|
40
|
-
##
|
|
43
|
+
## SdAppStructureProvider<TModule> / injectPermsSignal
|
|
44
|
+
|
|
45
|
+
앱 구조 트리(`AppStructureItem[]`, `@simplysm/service-common`)에서 메뉴·권한을 파생하는 root provider. 화면은 보통 `injectPermsSignal` 만 직접 씀.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
function injectPermsSignal<K extends string>(viewCodes: string[], keys: K[]): Signal<K[]>
|
|
49
|
+
```
|
|
41
50
|
|
|
42
|
-
- `
|
|
43
|
-
-
|
|
51
|
+
- `viewCodes` — 권한 path 목록(도메인 트리 좌표). `keys` — 확인할 action 목록. 반환 signal 은 사용자가 보유한 action 들의 배열. 매뉴얼 패턴: `perms = injectPermsSignal(["inventory.outbound"], ["use","edit"])` → `this.perms().includes("use")` 인라인 가드.
|
|
52
|
+
- provider 멤버:
|
|
53
|
+
- `usableModules: WritableSignal<TModule[] | undefined>` / `permRecord: WritableSignal<Record<string, boolean> | undefined>` — 인증 후 주입하는 활성 모듈·권한 레코드. 메뉴/권한 계산의 입력.
|
|
54
|
+
- `items: WritableSignal<AppStructureItem<TModule>[]>` / `initialize(items): void` — 앱 구조 트리 세팅.
|
|
55
|
+
- `usableMenus: Signal<SdMenu[]>` — 권한·모듈 필터를 적용한 트리형 메뉴(사이드바용).
|
|
56
|
+
- `usableFlatMenus: Signal<SdFlatMenu<TModule>[]>` — 평탄화된 메뉴 목록(검색/전체메뉴용).
|
|
57
|
+
- `getPermsByFullCode<K>(fullCodes, permKeys): K[]` — 코드 목록에 대해 보유 action 계산(`injectPermsSignal` 내부). 권한 정의 자체가 없는 항목은 모든 action 허용으로 간주.
|
|
58
|
+
- `getPermissionsByStructure(items, codeChain?)` — 권한표(`sd-permission-table`)용 `SdPermission` 트리 생성.
|
|
59
|
+
- `findTitleByFullCode(fullCode): string | undefined` / `getTitleByFullCode(fullCode): string`(못 찾으면 throw) / `getItemChainByFullCode(fullCode)` — 코드로 제목·항목 체인 조회.
|
|
44
60
|
|
|
45
|
-
##
|
|
61
|
+
## SdAppStructureUtils (static 유틸)
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
- usableModules: Signal<TModule[]|undefined> — 활성 모듈 목록. 메뉴/권한 필터에 사용(미설정 시 전체 허용 취급).
|
|
49
|
-
- permRecord: Signal<Record<string,boolean>|undefined> — `<코드>.<권한키>` → 허용 여부 맵.
|
|
50
|
-
- items: Signal<AppStructureItem<TModule>[]> — 구조 원본.
|
|
51
|
-
- initialize(items) — 구조 주입.
|
|
52
|
-
- usableMenus: Signal<SdMenu[]> — 모듈·권한 통과한 메뉴 트리(사이드바/탑바용).
|
|
53
|
-
- usableFlatMenus: Signal<SdFlatMenu<TModule>[]> — 평탄화된 메뉴 목록.
|
|
54
|
-
- getPermissionsByStructure(items, codeChain?) — 권한 편집표용 `SdPermission` 트리 생성.
|
|
55
|
-
- getTitleByFullCode(fullCode) / findTitleByFullCode(fullCode) — 전자는 못 찾으면 throw, 후자는 undefined(결측 보존).
|
|
56
|
-
- getItemChainByFullCode(fullCode) — 코드 체인에 해당하는 항목 배열(없으면 빈 배열).
|
|
57
|
-
- getPermsByFullCode(fullCodes, permKeys) — 해당 코드들에서 보유한 권한 키 목록.
|
|
63
|
+
`SdAppStructureProvider` 가 내부적으로 쓰는 순수 함수 모음(abstract 클래스의 static). 트리 → 메뉴/권한/제목 변환을 provider 밖에서 직접 할 때만 사용.
|
|
58
64
|
|
|
59
|
-
`
|
|
65
|
+
- `getMenus(items, codeChain, usableModules, permRecord): SdMenu[]` — 모듈·`use` 권한 필터 적용 트리 메뉴. `isNotMenu` 항목·빈 그룹 제외.
|
|
66
|
+
- `getFlatMenus(items, usableModules, permRecord): SdFlatMenu[]` — BFS 평탄화 메뉴.
|
|
67
|
+
- `getPermissions(items, codeChain, usableModules): SdPermission[]` — 권한표용 트리(leaf 의 `perms`/`subPerms` 포함).
|
|
68
|
+
- `getFlatPermissions(items, usableModules)` / `findTitleByFullCode` / `getTitleByFullCode` / `getItemChainByFullCode` / `getPermsByFullCode` — provider 동명 메서드의 구현.
|
|
60
69
|
|
|
61
|
-
##
|
|
70
|
+
## menu-utils
|
|
62
71
|
|
|
63
|
-
`
|
|
72
|
+
- `getMenuRouterLinkOption(menu: SdMenu): { link: string; queryParams: Record<string,string> | undefined } | undefined` — 메뉴를 `sdRouterLink` 옵션으로 변환. children 이 있거나 `url`(외부 링크) 이면 `undefined`(이동 불가 = leaf 아님). 그 외 `codeChain` 으로 `/home/<코드/...>` 링크 + 쿼리 분리.
|
|
73
|
+
- `getIsMenuSelected(menu: SdMenu, fullPageCode: string | undefined, customFn?: (menu) => boolean): boolean` — 메뉴 선택 여부. `customFn` 있으면 위임, 없으면 `fullPageCode === menu.codeChain.join(".")`.
|
|
64
74
|
|
|
65
75
|
## 타입
|
|
66
76
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
77
|
+
- `SdMenu = { title; codeChain: string[]; url?; icon?; children?: SdMenu[] }` — 트리 메뉴 항목. `url` 있으면 외부 링크, `children` 있으면 그룹.
|
|
78
|
+
- `SdFlatMenu<TModule> = { titleChain: string[]; codeChain: string[]; modulesChain: TModule[][] }` — 평탄 메뉴(경로 누적).
|
|
79
|
+
- `SdPermission<TModule> = { title; codeChain; modules; perms: ("use"|"edit")[] | undefined; children }` — 권한표 노드. `perms` 가 undefined 면 그룹(권한 없음). `sd-permission-table` 의 `items` 입력 타입.
|
|
@@ -1,28 +1,68 @@
|
|
|
1
|
-
# @simplysm/angular —
|
|
1
|
+
# @simplysm/angular — selection/sorting/expanding 매니저 (use* 컴포저블)
|
|
2
2
|
|
|
3
|
-
커스텀
|
|
3
|
+
커스텀 목록 컴포넌트에서 선택·정렬·트리펼침 상태 로직을 signal 기반으로 합성하는 함수 컴포저블 군. `sd-sheet` 가 이들을 조합해 만들어졌고, 직접 그리드/리스트를 만들 때 같은 로직을 재사용. 모두 함수 호출로 signal·메서드 묶음을 반환(컴포넌트 필드에 보관).
|
|
4
4
|
|
|
5
5
|
## useSelectionManager<TItem, TKey>
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
행 선택(single/multi)·전체선택·선택 가능 여부 로직.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
useSelectionManager<TItem, TKey>(options: {
|
|
11
|
+
displayItems: Signal<TItem[]>;
|
|
12
|
+
selectedKeys: WritableSignal<TKey[]>;
|
|
13
|
+
selectMode: Signal<"single" | "multi" | undefined>;
|
|
14
|
+
getItemSelectableFn: Signal<((item: TItem) => boolean | string) | undefined>;
|
|
15
|
+
trackByFn: Signal<(item: TItem, index: number) => TKey>;
|
|
16
|
+
}): { ... }
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- `options.displayItems` — 현재 표시 항목. `selectedKeys` — 선택 키(WritableSignal, 키는 `trackByFn` 반환값). `selectMode` — 모드(undefined 면 선택 비활성). `getItemSelectableFn` — 행별 선택 가능: `true`=가능, `false`=불가, 문자열=불가+사유. `trackByFn` — 항목→키.
|
|
20
|
+
- 반환:
|
|
21
|
+
- `hasSelectable: Signal<boolean>` — 선택 모드가 켜졌는지.
|
|
22
|
+
- `isAllSelected: Signal<boolean>` — 선택 가능한 항목이 모두 선택됐는지(전체선택 체크 상태).
|
|
23
|
+
- `getSelectable(item): true | string | undefined` — 항목 선택 가능 여부(문자열=사유 툴팁).
|
|
24
|
+
- `getCanChangeFn(item): () => boolean` — 체크박스 `canChangeFn` 에 넘길 가드.
|
|
25
|
+
- `select`/`deselect`/`toggle(item)` — 선택 조작(single 은 단일 키로 대체).
|
|
26
|
+
- `toggleAll()` — 선택 가능 항목 전체 토글.
|
|
27
|
+
- `isSelected(item): boolean`.
|
|
28
|
+
- 키 비교는 `===` 후 `obj.equal`(복합 키 지원).
|
|
10
29
|
|
|
11
30
|
## useSortingManager
|
|
12
31
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
정렬 상태(다중 컬럼) 토글·적용. `sd-sheet` 의 `sorts` 와 `SortingDef` 를 공유.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
useSortingManager(options: { sorts: WritableSignal<SortingDef[]> }): {
|
|
36
|
+
defMap: Signal<Map<string, { indexText?: string; desc: boolean }>>;
|
|
37
|
+
toggle(key: string, multiple: boolean): void;
|
|
38
|
+
sort<T>(items: T[]): T[];
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `SortingDef = { key: string; desc: boolean }` — 한 정렬 기준. `key`=컬럼 키, `desc`=내림차순 여부.
|
|
43
|
+
- `defMap` — 키별 정렬 상태(헤더 아이콘 표시용; `indexText` 는 다중 정렬 시 순번).
|
|
44
|
+
- `toggle(key, multiple)` — 정렬 토글. 한 키를 누를 때마다 없음→오름차순→내림차순→해제 순환. `multiple`(Shift) true 면 기존 정렬 유지하고 추가, false 면 단일 정렬로 대체.
|
|
45
|
+
- `sort<T>(items)` — 현재 정렬을 적용한 새 배열 반환. null 은 가장 앞, 문자열은 localeCompare, 숫자는 수치 비교. 클라이언트 정렬 시 사용.
|
|
17
46
|
|
|
18
47
|
## useExpandingManager<T>
|
|
19
48
|
|
|
20
|
-
트리
|
|
21
|
-
- binding: `{ items: Signal<T[]>; expandedItems: WritableSignal<T[]>; getChildrenFn: Signal<((item,index) => T[]|undefined)|undefined>; sort: (items) => T[] }` — getChildrenFn 으로 자식 조회, sort 로 각 레벨 정렬.
|
|
22
|
-
- 반환: `displayItems`/`hasExpandable`/`isAllExpanded`(Signal), `toggle(item)`/`toggleAll()`, `isVisible(item)`(조상이 모두 펼쳐졌는지), `def(item): ExpandItemDef<T>`(못 찾으면 throw).
|
|
23
|
-
- **ExpandItemDef<T>** — `{ item; parentDef: ExpandItemDef<T>|undefined; hasChildren; depth }`. 항목의 트리 위치 정의.
|
|
49
|
+
트리 항목 펼침/접힘 + 표시 항목 평탄화.
|
|
24
50
|
|
|
25
51
|
```ts
|
|
26
|
-
|
|
27
|
-
|
|
52
|
+
useExpandingManager<T>(binding: {
|
|
53
|
+
items: Signal<T[]>;
|
|
54
|
+
expandedItems: WritableSignal<T[]>;
|
|
55
|
+
getChildrenFn: Signal<((item: T, index: number) => T[] | undefined) | undefined>;
|
|
56
|
+
sort: (items: T[]) => T[];
|
|
57
|
+
}): { ... }
|
|
28
58
|
```
|
|
59
|
+
|
|
60
|
+
- `binding.items` — 루트 항목. `expandedItems` — 펼쳐진 항목(WritableSignal). `getChildrenFn` — 자식 조회(undefined 면 자식 없음). `sort` — 각 레벨 정렬 함수(보통 `useSortingManager.sort`).
|
|
61
|
+
- 반환:
|
|
62
|
+
- `displayItems: Signal<T[]>` — 펼침 상태를 반영해 평탄화·정렬된 표시 항목.
|
|
63
|
+
- `hasExpandable: Signal<boolean>` — 펼칠 수 있는 항목이 있는지(토글 컬럼 표시 기준).
|
|
64
|
+
- `isAllExpanded: Signal<boolean>` — 전체 펼침 상태.
|
|
65
|
+
- `toggle(item)` / `toggleAll()` — 펼침 토글.
|
|
66
|
+
- `isVisible(item): boolean` — 조상이 모두 펼쳐져 보이는지.
|
|
67
|
+
- `def(item): ExpandItemDef<T>` — 항목 메타(못 찾으면 throw).
|
|
68
|
+
- `ExpandItemDef<T> = { item: T; parentDef: ExpandItemDef<T> | undefined; hasChildren: boolean; depth: number }` — 항목의 부모·자식유무·깊이. 들여쓰기·토글 렌더에 사용.
|
|
@@ -1,57 +1,74 @@
|
|
|
1
|
-
# @simplysm/angular — 공유 데이터
|
|
1
|
+
# @simplysm/angular — 공유 마스터 데이터 + 선택 컨트롤
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
고객사·품목 등 자주 참조하는 마스터 데이터를 한 번 등록해 어느 화면에서든 공유 signal 로 쓰고, 그 데이터를 선택하는 드롭다운/버튼/리스트 컨트롤을 제공하는 군. 등록·항목 추가 절차는 `client-shared-data.md` 참조.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## SdSharedDataProvider<T> (abstract)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **SharedDataInfo<T>** — 등록 정보. `{ serviceKey: string; getter: (changeKeys?) => Promise<T[]>; filter?: unknown; orderBy?: (item) => 비교키 }`. getter 는 전체/부분(changeKeys) 로드, filter 는 이벤트 매칭, orderBy 는 정렬키.
|
|
9
|
-
- **SharedDataHandle<T>** — `{ items: Signal<T[]>; get(key): T | undefined }`. 화면에서 데이터 소비 핸들.
|
|
7
|
+
마스터 데이터를 이름별로 등록·로드·이벤트 동기화하는 root provider. 앱은 이걸 상속한 `AppSharedDataProvider` 를 만들고 `useSharedSignal` 헬퍼를 함께 export(client-shared-data.md).
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- `abstract initialize(): void` — 여기서 `register(name, info)` 로 항목 등록(앱이 구현).
|
|
10
|
+
- `register<K>(name: K, info: SharedDataInfo<T[K]>): void` — 항목 등록. 재호출 시 기존 리스너 정리 + generation 증가로 이전 결과 무시 후 재로드.
|
|
11
|
+
- `getHandle<K>(name: K): SharedDataHandle<T[K]>` — 항목 핸들 반환(첫 접근 시 lazy 로드 + 변경 이벤트 리스너 등록). 미등록 이름이면 throw. `useSharedSignal` 이 이걸 감쌈.
|
|
12
|
+
- `emitAsync<K>(name: K, changeKeys?: (string|number)[]): Promise<void>` — 변경 브로드캐스트. `changeKeys` 주면 해당 키만 부분 갱신, 없으면 전체 리로드(다른 클라이언트 포함).
|
|
13
|
+
- `wait(): Promise<void>` — 진행 중 로드가 끝날 때까지 대기. `sd-base-container` 가 ready 전에 호출.
|
|
14
|
+
- `loadingCount: WritableSignal<number>` — 진행 중 로드 수.
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
- loadingCount: WritableSignal<number> — 로딩 중 카운트.
|
|
15
|
-
- abstract initialize(): void — 앱 시작 시 각 데이터 register.
|
|
16
|
-
- register<K>(name, info: SharedDataInfo<T[K]>) — 데이터 등록(재호출 시 generation 증가로 이전 이벤트 무시·재로드).
|
|
17
|
-
- getHandle<K>(name): SharedDataHandle<T[K]> — 핸들 획득(첫 호출 시 lazy 로드 + 이벤트 리스너 등록). 미등록이면 throw.
|
|
18
|
-
- emitAsync<K>(name, changeKeys?) — 변경 이벤트 발행(같은 name·filter 구독자 갱신). changeKeys 지정 시 부분 갱신.
|
|
19
|
-
- wait(): Promise<void> — loadingCount 가 0 이 될 때까지 대기(화면 진입 전 데이터 준비).
|
|
16
|
+
### 타입
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
- `SharedDataBase<TKey extends string|number>` — 모든 공유 항목이 상속할 베이스. 매직 필드: `__valueKey: TKey`(항목 키), `__searchText: string`(검색용 텍스트), `__isHidden: boolean`(숨김), `__parentKey?: TKey`(트리 부모). getter 의 select 결과에 빠짐없이 포함.
|
|
19
|
+
- `SharedDataInfo<T>` — 등록 정보. `serviceKey: string`(이벤트 채널), `getter: (changeKeys?) => Promise<T[]>`(조회; changeKeys 주면 부분), `filter?: unknown`(이벤트 필터 매칭), `orderBy?: (item) => string|number|DateOnly|DateTime|Time|undefined`(정렬 키).
|
|
20
|
+
- `SharedDataHandle<T>` — `{ items: Signal<T[]>; get(key): T | undefined }`. 화면이 `useSharedSignal(name)` 으로 받아 `.items()`·`.get(id)` 사용.
|
|
21
|
+
- `SdSharedDataChangeEvent` — 변경 동기화에 쓰이는 `defineEvent`. payload `{ name; filter }`, data `(string|number)[] | undefined`.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
사용(화면): `sharedCustomers = useSharedSignal("고객사"); sharedCustomers.items(); sharedCustomers.get(id)`.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
- value = model<...>() — 선택값(single=키, multi=키 배열). 키는 `TItem["__valueKey"] | undefined`.
|
|
27
|
-
- items: input.required<TItem[]> — 후보(보통 handle.items()).
|
|
28
|
-
- selectMode: "single"|"multi"(기본 single).
|
|
29
|
-
- disabled/required/inset/inline/size — 컨트롤 공통.
|
|
30
|
-
- useUndefined: boolean — multi 에서도 "미지정" 항목 노출.
|
|
31
|
-
- filterFn?/filterFnParams? — 후보 필터(item,index,...params).
|
|
32
|
-
- modal?: SdSelectModalInfo — 우측 검색 버튼으로 띄울 선택 모달.
|
|
33
|
-
- editModal?: SdModalInfo<SdModalContentDef<boolean>> — 편집 버튼으로 띄울 모달.
|
|
34
|
-
- selectClass?/multiSelectionDisplayDirection?("vertical").
|
|
35
|
-
- getIsHiddenFn?(item,index)/getSearchTextFn?(item,index)/displayOrderByFn?(item) — 기본은 `__isHidden`/`__searchText`/없음. 검색·표시·정렬 재정의.
|
|
36
|
-
- (contentChild) `itemOf` 템플릿 — 항목 렌더. `undefinedTpl` 로 "미지정" 표시 커스텀.
|
|
37
|
-
- `__parentKey` 있으면 자동 트리(자식은 부모 펼침 시 노출).
|
|
25
|
+
## 선택 컨트롤
|
|
38
26
|
|
|
39
|
-
|
|
27
|
+
공유 데이터(또는 `SharedDataBase` 호환 배열)를 항목으로 받아 선택. 매직 필드(`__searchText`/`__isHidden`/`__parentKey`)를 자동 활용(검색·숨김·트리).
|
|
40
28
|
|
|
41
|
-
|
|
42
|
-
- value = model<...>(), items: TItem[](선택값→표시용 매핑), modal: input.required<SdSelectModalInfo>, selectMode(기본 single), disabled/required/inset/size.
|
|
43
|
-
- (contentChild) `itemOf` 템플릿 필수 — 선택된 항목 표시.
|
|
29
|
+
### SdSharedDataSelect (`sd-shared-data-select`)
|
|
44
30
|
|
|
45
|
-
|
|
31
|
+
드롭다운 셀렉트(검색창·트리·미지정 항목·모달 연동 내장).
|
|
46
32
|
|
|
47
|
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
- (
|
|
33
|
+
- `value: model<...>` — 선택 키(single) 또는 키 배열(multi). 미지정은 `undefined`.
|
|
34
|
+
- `items: input.required<TItem[]>` — 공유 항목 배열(`SharedDataBase` 상속).
|
|
35
|
+
- `selectMode: "single"|"multi"` — 선택 모드(기본 single).
|
|
36
|
+
- `required: boolean` — 빈 값이면 invalid.
|
|
37
|
+
- `useUndefined: boolean` — multi 에서도 "미지정" 항목 노출(single 은 required 아니면 자동 노출).
|
|
38
|
+
- `filterFn: (item, index, ...params) => boolean` + `filterFnParams: any[]` — 표시 항목 필터.
|
|
39
|
+
- `getIsHiddenFn: (item, index) => boolean` — 숨김 판정(기본 `__isHidden`; 숨김 항목은 취소선 + 검색 시에만 표시).
|
|
40
|
+
- `getSearchTextFn: (item, index) => string` — 검색 대상 텍스트(기본 `__searchText`).
|
|
41
|
+
- `displayOrderByFn: (item) => ...` — 표시 정렬 키.
|
|
42
|
+
- `modal: SdSelectModalInfo<TModal>` — 검색 버튼으로 띄울 선택 모달. `editModal: SdModalInfo<...>` — 편집 버튼 모달.
|
|
43
|
+
- `multiSelectionDisplayDirection: "vertical"` — multi 표시 세로 나열.
|
|
44
|
+
- `disabled`/`inset`/`inline`/`size`/`selectClass` — 공통/스타일.
|
|
45
|
+
- 항목 템플릿: `<ng-template [itemOf]="items()" let-item="item">`, 미지정 표시 `#undefinedTpl`.
|
|
46
|
+
- 사용: `<sd-shared-data-select [items]="sharedCustomers.items()" [(value)]="data().customerId"><ng-template [itemOf]="sharedCustomers.items()" let-item="item">{{ item.name }}</ng-template></sd-shared-data-select>`.
|
|
47
|
+
|
|
48
|
+
### SdSharedDataSelectButton (`sd-shared-data-select-button`)
|
|
49
|
+
|
|
50
|
+
값 표시 + 모달 검색 버튼(드롭다운 없이 모달 전용). 항목 수가 많아 드롭다운이 부적합할 때.
|
|
51
|
+
|
|
52
|
+
- `value: model<...>` — 선택 키/키배열.
|
|
53
|
+
- `items: TItem[]` — 표시명 매핑용 항목 배열.
|
|
54
|
+
- `modal: input.required<SdSelectModalInfo<TModal>>` — 띄울 선택 모달.
|
|
55
|
+
- `selectMode: "single"|"multi"` / `disabled` / `required` / `inset` / `size` — 공통.
|
|
56
|
+
- 선택 항목 표시 템플릿: `<ng-template [itemOf]>`(필수).
|
|
57
|
+
|
|
58
|
+
### SdSharedDataSelectList (`sd-shared-data-select-list`)
|
|
59
|
+
|
|
60
|
+
검색창 + 리스트로 단건 선택(좌측 마스터 리스트 패널 등). `flex-column fill`.
|
|
61
|
+
|
|
62
|
+
- `selectedItem: model<TItem>` — 선택된 항목(키 아닌 항목 객체). `canChangeFn: (item|undefined) => boolean|Promise<boolean>` — 변경 가드.
|
|
63
|
+
- `items: input.required<TItem[]>` — 항목 배열(`__isHidden` 항목 자동 제외).
|
|
64
|
+
- `useUndefined: boolean` — "미지정" 항목 노출.
|
|
65
|
+
- `filterFn: (item, index) => boolean` — 추가 필터.
|
|
66
|
+
- `selectedIcon: string` — 선택 표시 아이콘.
|
|
67
|
+
- `pageItemCount: number` — 페이지당 항목 수(지정 시 페이지네이션).
|
|
68
|
+
- `modal: SdSelectModalInfo<TModal>` — 우상단 외부 링크로 띄울 모달.
|
|
69
|
+
- `header: string` — 상단 헤더 텍스트.
|
|
70
|
+
- 템플릿: `#headerTpl`(헤더 우측), `#filterTpl`(검색창 대체), `<ng-template [itemOf]>`(항목), `#undefinedTpl`(미지정).
|
|
54
71
|
|
|
55
72
|
## matchesSearchText
|
|
56
73
|
|
|
57
|
-
`matchesSearchText(itemText: string, searchQuery: string | undefined): boolean` —
|
|
74
|
+
- `function matchesSearchText(itemText: string, searchQuery: string | undefined): boolean` — 공백 구분 다중 검색어 AND 매칭(대소문자 무시). 빈 쿼리면 true. 위 선택 컨트롤들이 내부 검색에 사용. 커스텀 목록에서 동일 검색 동작이 필요할 때 직접 호출.
|