@simplysm/sd-claude 14.0.98 → 14.0.99
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 -16
- package/claude/references/sd-simplysm14/apis/angular/README.md +81 -153
- package/claude/references/sd-simplysm14/apis/angular/controls.md +179 -205
- package/claude/references/sd-simplysm14/apis/angular/crud.md +71 -57
- package/claude/references/sd-simplysm14/apis/angular/directives.md +49 -109
- package/claude/references/sd-simplysm14/apis/angular/features.md +58 -86
- package/claude/references/sd-simplysm14/apis/angular/kanban.md +32 -40
- package/claude/references/sd-simplysm14/apis/angular/layout.md +38 -52
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +86 -110
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +54 -86
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +82 -74
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +56 -80
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +15 -15
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +21 -21
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +79 -53
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +9 -11
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +15 -15
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +20 -20
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +18 -18
- package/claude/references/sd-simplysm14/apis/core-common/README.md +20 -49
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +66 -55
- package/claude/references/sd-simplysm14/apis/core-common/collection-ext.md +83 -56
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +32 -21
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +57 -39
- package/claude/references/sd-simplysm14/apis/core-common/serialization.md +36 -30
- package/claude/references/sd-simplysm14/apis/core-common/value-types.md +69 -41
- package/claude/references/sd-simplysm14/apis/core-node/README.md +4 -4
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +15 -13
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +11 -7
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +8 -8
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +29 -20
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +14 -6
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +3 -3
- package/claude/references/sd-simplysm14/apis/excel/README.md +3 -3
- package/claude/references/sd-simplysm14/apis/excel/cell.md +32 -32
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +23 -24
- package/claude/references/sd-simplysm14/apis/excel/style.md +24 -30
- package/claude/references/sd-simplysm14/apis/excel/utils.md +20 -23
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +60 -71
- package/claude/references/sd-simplysm14/apis/excel/wrapper.md +36 -36
- package/claude/references/sd-simplysm14/apis/lint/README.md +7 -9
- package/claude/references/sd-simplysm14/apis/lint/recommended.md +59 -37
- package/claude/references/sd-simplysm14/apis/lint/rules.md +81 -74
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +6 -6
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +112 -78
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +131 -75
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +126 -82
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +170 -113
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +102 -48
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +12 -13
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +3 -3
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +5 -5
- package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +67 -65
- package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +130 -123
- package/claude/references/sd-simplysm14/apis/service-client/README.md +63 -63
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +22 -22
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +30 -26
- package/claude/references/sd-simplysm14/apis/service-common/README.md +8 -8
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +13 -6
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +1 -1
- package/claude/references/sd-simplysm14/apis/service-server/README.md +43 -47
- package/claude/references/sd-simplysm14/apis/service-server/built-in-services.md +35 -0
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +20 -19
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +23 -25
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +9 -9
- package/claude/references/sd-simplysm14/apis/storage/README.md +26 -26
- package/claude/references/sd-simplysm14/manuals/client-component.md +9 -1
- package/claude/references/sd-simplysm14/manuals/client-crud.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-service.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-shared-data.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-ssg.md +1 -0
- package/claude/sd-system-prompt.md +11 -26
- package/claude/skills/sd-docs/references/subagent-prompt.md +4 -3
- package/claude/skills/sd-spec/SKILL.md +87 -18
- package/claude/skills/sd-spec/references/format.md +2 -2
- package/package.json +1 -1
|
@@ -1,136 +1,104 @@
|
|
|
1
1
|
# @simplysm/angular — 라우팅·메뉴·권한(app-structure)
|
|
2
2
|
|
|
3
|
-
라우터 링크·현재 페이지 식별·뷰 컨텍스트(page/control/modal)·이탈 가드, 그리고 앱 구조 트리에서 메뉴·권한을 파생하는 군. 화면 컴포넌트의 표준 시그널 `viewType`, 권한 가드 `injectPermsSignal`, 사이드바/탑바 메뉴가 이 군에 의존.
|
|
3
|
+
라우터 링크·현재 페이지 식별·뷰 컨텍스트(page/control/modal)·이탈 가드, 그리고 앱 구조 트리에서 메뉴·권한을 파생하는 군. 화면 컴포넌트의 표준 시그널 `viewType`, 권한 가드 `injectPermsSignal`, 사이드바/탑바 메뉴가 이 군에 의존. 메뉴·권한 정의 절차는 [client-app-structure.md](../manuals/client-app-structure.md) 참조.
|
|
4
4
|
|
|
5
5
|
## 라우팅 디렉티브·프로바이더
|
|
6
6
|
|
|
7
|
-
### SdRouterLink — `[sdRouterLink]`
|
|
7
|
+
### `SdRouterLink` — `[sdRouterLink]`
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
window?: { width?: number; height?: number };
|
|
12
|
-
outletName?: string; queryParams?: Record<string,string> } | undefined>(undefined, { alias: "sdRouterLink" });
|
|
13
|
-
```
|
|
9
|
+
- `option: input<{ link: string; params?: Record<string,string>; window?: { width?: number; height?: number }; outletName?: string; queryParams?: Record<string,string> } | undefined>({ alias: "sdRouterLink" })` — 이동 대상. `link` = 라우트 경로, `params` = 라우트 파라미터, `outletName` 지정 시 named outlet, `window` 지정 시 팝업 창 크기.
|
|
10
|
+
- 클릭 동작: `Alt+click` 무시. 팝업 창 모드면 새 창; `Ctrl/Shift+click` 이면 새 탭/창; `outletName` 없으면 `Router.navigate([link, ...params])`; 있으면 outlet navigate.
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```html
|
|
18
|
-
<sd-list-item [sdRouterLink]="{ link: '/home/order/list' }">주문</sd-list-item>
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### SdNavigateWindowProvider
|
|
22
|
-
|
|
23
|
-
```ts
|
|
24
|
-
@Injectable({ providedIn: "root" }) class SdNavigateWindowProvider {
|
|
25
|
-
get isWindow: boolean;
|
|
26
|
-
open(navigate: string, params?: Record<string,string>, features?: string): void;
|
|
27
|
-
}
|
|
28
|
-
```
|
|
12
|
+
### `SdNavigateWindowProvider`
|
|
29
13
|
|
|
30
|
-
|
|
14
|
+
`@Injectable({ providedIn: "root" })`.
|
|
31
15
|
|
|
32
|
-
|
|
16
|
+
- `get isWindow(): boolean` — 현재 hash query 에 `window=true` 가 있는지(팝업 창 컨텍스트 여부).
|
|
17
|
+
- `open(navigate: string, params?: Record<string,string>, features?: string): void` — 이미 팝업 창이거나 `features` 지정 시 새 브라우저 창(`window.open`), 아니면 `_blank` 탭으로 `#{navigate};{params}` 열기.
|
|
33
18
|
|
|
34
|
-
|
|
19
|
+
## 현재 페이지·뷰 식별
|
|
35
20
|
|
|
36
|
-
###
|
|
21
|
+
### `injectCurrentPageCodeSignal` / `injectFullPageCodeSignal`
|
|
37
22
|
|
|
38
23
|
```ts
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
function injectCurrentPageCodeSignal(): Signal<string> | undefined
|
|
25
|
+
function injectFullPageCodeSignal(): Signal<string>
|
|
41
26
|
```
|
|
42
27
|
|
|
43
|
-
- `
|
|
44
|
-
- `
|
|
28
|
+
- `injectCurrentPageCodeSignal` — `ActivatedRoute` 없으면 `undefined`; 있으면 활성 라우트 URL 세그먼트(앞 2개 제외)를 `"."` 로 이은 코드.
|
|
29
|
+
- `injectFullPageCodeSignal` — `Router` URL(`NavigationEnd` 추적)을 `/` 분리, 앞 2개 제외, `;`/`?` 접미 제거 후 `"."` 로 이은 페이지 코드. 메뉴 선택 판정 등에 사용.
|
|
45
30
|
|
|
46
|
-
### injectViewTitleSignal
|
|
31
|
+
### `injectViewTitleSignal`
|
|
47
32
|
|
|
48
33
|
```ts
|
|
49
|
-
injectViewTitleSignal(): Signal<string
|
|
50
|
-
injectViewTypeSignal(): Signal<SdViewType>; // "page" | "modal" | "control"
|
|
34
|
+
function injectViewTitleSignal(): Signal<string>
|
|
51
35
|
```
|
|
52
36
|
|
|
53
|
-
-
|
|
54
|
-
- `injectViewTypeSignal` — 현재 뷰 컨텍스트. `"modal"`=모달 안, `"page"`=라우팅 진입 단위(컴포넌트 selector 가 라우트 컴포넌트와 일치+풀코드 매칭), 그 외 `"control"`(임베드). crud 골격의 `viewType` 입력에 그대로 전달.
|
|
37
|
+
- 활성 모달 안이면 모달 `title`, 아니면 `SdAppStructureProvider.findTitleByFullCode(...)` 로 화면 제목. 엑셀 파일명·탑바 제목 등에.
|
|
55
38
|
|
|
56
|
-
###
|
|
39
|
+
### `injectViewTypeSignal` / `SdViewType`
|
|
57
40
|
|
|
58
41
|
```ts
|
|
59
|
-
|
|
42
|
+
function injectViewTypeSignal(): Signal<SdViewType>
|
|
43
|
+
type SdViewType = "page" | "modal" | "control"
|
|
60
44
|
```
|
|
61
45
|
|
|
62
|
-
-
|
|
46
|
+
- `"modal"` = 활성 모달 안에서 렌더; `"page"` = 라우트가 있고 컴포넌트 selector·코드가 일치하는 최상위 페이지; `"control"` = 그 외(라우트 없음·임베드 재사용). 화면 컴포넌트가 `viewType = injectViewTypeSignal()` 으로 받아 `sd-crud-*`/`sd-base-container` 에 전달.
|
|
63
47
|
|
|
64
|
-
###
|
|
48
|
+
### `setupCanDeactivate`
|
|
65
49
|
|
|
66
50
|
```ts
|
|
67
|
-
|
|
68
|
-
getIsMenuSelected(menu: SdMenu, fullPageCode: string|undefined, customFn?: (menu: SdMenu)=>boolean): boolean;
|
|
51
|
+
function setupCanDeactivate(fn: () => boolean): void
|
|
69
52
|
```
|
|
70
53
|
|
|
71
|
-
- `
|
|
72
|
-
- `getIsMenuSelected` — 메뉴가 현재 페이지인지. `customFn` 있으면 그 결과, 없으면 코드 일치. 메뉴 컴포넌트가 선택 강조에 사용.
|
|
54
|
+
- 이탈 가드 등록. 모달 컨텍스트면 `SdActivatedModalProvider.canDeactivateFn = fn`; 라우트 페이지면 route config 의 `canDeactivate` 에 `fn()` 반환 가드를 push(파괴 시 제거). `fn()` 이 false 면 이탈 차단. detail 의 미저장 변경 가드에 사용([client-component.md](../manuals/client-component.md)).
|
|
73
55
|
|
|
74
|
-
##
|
|
56
|
+
## 메뉴 유틸
|
|
75
57
|
|
|
76
|
-
###
|
|
58
|
+
### `getMenuRouterLinkOption` / `getIsMenuSelected`
|
|
77
59
|
|
|
78
60
|
```ts
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
permRecord: WritableSignal<Record<string, boolean> | undefined>;
|
|
82
|
-
items: WritableSignal<AppStructureItem<TModule>[]>;
|
|
83
|
-
initialize(items): void;
|
|
84
|
-
usableMenus = computed<SdMenu[]>(...);
|
|
85
|
-
usableFlatMenus = computed<SdFlatMenu<TModule>[]>(...);
|
|
86
|
-
getPermissionsByStructure(items, codeChain?): SdPermission<TModule>[];
|
|
87
|
-
getTitleByFullCode(fullCode): string; // 못 찾으면 throw
|
|
88
|
-
findTitleByFullCode(fullCode): string | undefined; // 결측 보존
|
|
89
|
-
getItemChainByFullCode(fullCode): AppStructureItem<TModule>[];
|
|
90
|
-
getPermsByFullCode<K>(fullCodes: string[], permKeys: K[]): K[];
|
|
91
|
-
}
|
|
61
|
+
function getMenuRouterLinkOption(menu: SdMenu): { link: string; queryParams: Record<string,string> | undefined } | undefined
|
|
62
|
+
function getIsMenuSelected(menu: SdMenu, fullPageCode: string | undefined, customFn?: (menu: SdMenu) => boolean): boolean
|
|
92
63
|
```
|
|
93
64
|
|
|
94
|
-
- `
|
|
95
|
-
- `
|
|
96
|
-
|
|
65
|
+
- `getMenuRouterLinkOption` — 그룹 메뉴(`children != null`)·외부 링크(`url != null`)면 `undefined`; leaf 면 `link = "/home/" + codeChain.join("/")`(`?query` 는 `queryParams` 로 분리). 사이드바/탑바 메뉴가 라우터 링크 생성에 사용.
|
|
66
|
+
- `getIsMenuSelected` — `customFn` 있으면 그 결과, 아니면 `fullPageCode === menu.codeChain.join(".")`.
|
|
67
|
+
|
|
68
|
+
## 앱 구조 프로바이더
|
|
97
69
|
|
|
98
|
-
### injectPermsSignal
|
|
70
|
+
### `injectPermsSignal`
|
|
99
71
|
|
|
100
72
|
```ts
|
|
101
|
-
injectPermsSignal<K extends string>(viewCodes: string[], keys: K[]): Signal<K[]
|
|
73
|
+
function injectPermsSignal<K extends string>(viewCodes: string[], keys: K[]): Signal<K[]>
|
|
102
74
|
```
|
|
103
75
|
|
|
104
|
-
- 화면
|
|
76
|
+
- 화면 fullCode(들)에 대해 사용자가 보유한 권한 action 키 배열을 `computed` 로 반환(`SdAppStructureProvider.getPermsByFullCode` 위임).
|
|
105
77
|
|
|
106
78
|
```ts
|
|
107
|
-
perms = injectPermsSignal(["
|
|
79
|
+
perms = injectPermsSignal(["inventory.outbound-instruction"], ["use", "edit"]);
|
|
80
|
+
// this.perms().includes("use")
|
|
108
81
|
```
|
|
109
82
|
|
|
110
|
-
###
|
|
83
|
+
### `SdAppStructureProvider<TModule>`
|
|
111
84
|
|
|
112
|
-
|
|
113
|
-
abstract class SdAppStructureUtils {
|
|
114
|
-
static getTitleByFullCode(items, fullCode): string;
|
|
115
|
-
static findTitleByFullCode(items, fullCode): string | undefined;
|
|
116
|
-
static getPermsByFullCode(items, fullCodes, permKeys, permRecord): K[];
|
|
117
|
-
static getItemChainByFullCode(items, fullCode): AppStructureItem[];
|
|
118
|
-
static getMenus(items, codeChain, usableModules, permRecord): SdMenu[];
|
|
119
|
-
static getFlatMenus(items, usableModules, permRecord): SdFlatMenu[];
|
|
120
|
-
static getPermissions(items, codeChain, usableModules): SdPermission[];
|
|
121
|
-
static getFlatPermissions(items, usableModules);
|
|
122
|
-
}
|
|
123
|
-
```
|
|
85
|
+
`@Injectable({ providedIn: "root" })`. 앱 메뉴·권한 트리의 단일 소스. 부트스트랩에서 `initialize(items)` 로 연결.
|
|
124
86
|
|
|
125
|
-
-
|
|
87
|
+
- 시그널: `usableModules: WritableSignal<TModule[] | undefined>` / `permRecord: WritableSignal<Record<string, boolean> | undefined>` / `items: WritableSignal<AppStructureItem<TModule>[]>`.
|
|
88
|
+
- computed: `usableMenus: Signal<SdMenu[]>` / `usableFlatMenus: Signal<SdFlatMenu<TModule>[]>`.
|
|
89
|
+
- 메서드:
|
|
90
|
+
- `initialize(items): void` — `items` set.
|
|
91
|
+
- `getPermissionsByStructure(items, codeChain?): SdPermission<TModule>[]` — 권한 테이블용 권한 트리.
|
|
92
|
+
- `getTitleByFullCode(fullCode): string`(없으면 throw) / `findTitleByFullCode(fullCode): string | undefined`.
|
|
93
|
+
- `getItemChainByFullCode(fullCode): AppStructureItem<TModule>[]`.
|
|
94
|
+
- `getPermsByFullCode<K extends string>(fullCodes, permKeys): K[]`.
|
|
126
95
|
|
|
127
|
-
###
|
|
96
|
+
### `SdAppStructureUtils`
|
|
128
97
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
SdPermission<TModule> { title; codeChain; modules?; perms?: ("use"|"edit")[]; children? }
|
|
133
|
-
SdViewType = "page" | "modal" | "control"
|
|
134
|
-
```
|
|
98
|
+
static 메서드만 가진 abstract class(`SdAppStructureProvider` 의 순수 함수 형태). `getTitleByFullCode`/`findTitleByFullCode`/`getPermsByFullCode`/`getItemChainByFullCode`/`getMenus`/`getFlatMenus`/`getPermissions`/`getFlatPermissions` — 각각 `items: AppStructureItem[]` 을 첫 인자로 받아 메뉴·권한·제목을 파생. provider 가 이를 시그널로 래핑.
|
|
99
|
+
|
|
100
|
+
## 타입
|
|
135
101
|
|
|
136
|
-
- `SdMenu` —
|
|
102
|
+
- `SdMenu` — `{ title: string; codeChain: string[]; url?: string; icon?: string; children?: SdMenu[] }`. 메뉴 트리 노드. 사이드바/탑바 메뉴가 소비.
|
|
103
|
+
- `SdFlatMenu<TModule>` — `{ titleChain: string[]; codeChain: string[]; modulesChain: TModule[][] }`. leaf 메뉴를 평탄화한 형태.
|
|
104
|
+
- `SdPermission<TModule>` — `{ title: string; codeChain: string[]; modules: TModule[] | undefined; perms: ("use"|"edit")[] | undefined; children: SdPermission<TModule>[] | undefined }`. 권한 트리 노드(`perms`: `"use"`=조회·`"edit"`=편집). `SdPermissionTable` 의 `items` 입력 타입([crud.md](./crud.md)).
|
|
@@ -1,107 +1,115 @@
|
|
|
1
|
-
# @simplysm/angular — 공유 마스터
|
|
1
|
+
# @simplysm/angular — 공유 마스터 데이터·선택 매니저
|
|
2
2
|
|
|
3
|
-
고객사·품목 등 자주 참조하는 마스터 데이터를 한 번 등록해 어느 화면에서든 공유 시그널로 쓰고, 그 데이터를 선택하는 드롭다운/버튼/리스트
|
|
3
|
+
고객사·품목 등 자주 참조하는 마스터 데이터를 한 번 등록해 어느 화면에서든 공유 시그널로 쓰고, 그 데이터를 선택하는 드롭다운/버튼/리스트 컨트롤과, 시트·리스트의 선택/정렬/펼침 상태를 관리하는 composable 매니저를 제공하는 군. 등록·항목 추가·선택 모달·좌측목록+우측상세 절차는 [client-shared-data.md](../manuals/client-shared-data.md) 참조.
|
|
4
4
|
|
|
5
|
-
## SdSharedDataProvider
|
|
5
|
+
## `SdSharedDataProvider<T>`
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
@Injectable() abstract class SdSharedDataProvider<T extends Record<string, SharedDataBase<string|number>>> {
|
|
9
|
-
loadingCount: WritableSignal<number>;
|
|
10
|
-
abstract initialize(): void;
|
|
11
|
-
register<K>(name: K, info: SharedDataInfo<T[K]>): void;
|
|
12
|
-
getHandle<K>(name: K): SharedDataHandle<T[K]>;
|
|
13
|
-
emitAsync<K>(name: K, changeKeys?: (string|number)[]): Promise<void>;
|
|
14
|
-
wait(): Promise<void>;
|
|
15
|
-
}
|
|
16
|
-
```
|
|
7
|
+
`@Injectable()` **abstract**. 앱이 상속해 `initialize()` 에서 데이터를 `register` (root 별칭 등록 필요). `T extends Record<string, SharedDataBase<string|number>>`.
|
|
17
8
|
|
|
18
|
-
-
|
|
19
|
-
- `
|
|
20
|
-
- `
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
9
|
+
- `loadingCount: WritableSignal<number>` (초기 0) — 로드 중 카운트.
|
|
10
|
+
- `abstract initialize(): void` — 하위에서 `register` 호출.
|
|
11
|
+
- `register<K>(name: K, info: SharedDataInfo<T[K]>): void` — 데이터 항목 등록(lazy; 즉시 로드 안 함). 재등록 시 기존 리스너 제거·generation 증가로 stale 이벤트 무시.
|
|
12
|
+
- `getHandle<K>(name: K): SharedDataHandle<T[K]>` — 핸들 반환(첫 접근 시 lazy 로드·리스너 등록). 미등록 시 throw.
|
|
13
|
+
- `emitAsync<K>(name: K, changeKeys?: (string|number)[]): Promise<void>` — 변경 통지. `changeKeys` 생략 = 전체 재로드, 지정 = 그 키들만 부분 갱신. 저장·삭제 후 호출해 공유데이터를 최신화.
|
|
14
|
+
- `wait(): Promise<void>` — `loadingCount <= 0` 까지 대기.
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
타입:
|
|
17
|
+
- `SharedDataBase<TKey extends string|number>` — 항목 매직 필드: `__valueKey: TKey`(키) / `__searchText: string`(검색용) / `__isHidden: boolean`(숨김) / `__parentKey?: TKey`(트리 부모). getter select 결과에 포함 필수.
|
|
18
|
+
- `SharedDataInfo<T>` — `{ serviceKey: string; getter: (changeKeys?) => Promise<T[]>; filter?: unknown; orderBy?: (item) => string|number|DateOnly|DateTime|Time|undefined }`. `getter(changeKeys)` 는 changeKeys 주어지면 그 키만 재조회(incremental).
|
|
19
|
+
- `SharedDataHandle<T>` — `{ items: Signal<T[]>; get(key): T | undefined }`. 화면이 `useSharedSignal(name)` 으로 받아 `items()`·`get(id)` 사용.
|
|
20
|
+
- `SdSharedDataChangeEvent` — `defineEvent<{ name; filter }, (string|number)[] | undefined>("SdSharedDataChange")`. provider 내부 통지 이벤트.
|
|
25
21
|
|
|
26
|
-
|
|
27
|
-
SharedDataBase<TKey> { __valueKey: TKey; __searchText: string; __isHidden: boolean; __parentKey?: TKey }
|
|
28
|
-
SharedDataInfo<T> { serviceKey: string; getter: (changeKeys?) => Promise<T[]>; filter?; orderBy?: (item) => ...|undefined }
|
|
29
|
-
SharedDataHandle<T> { items: Signal<T[]>; get(key): T | undefined }
|
|
30
|
-
SdSharedDataChangeEvent // defineEvent — 변경 통지 이벤트 정의
|
|
31
|
-
```
|
|
22
|
+
## `SdSharedDataSelect<TItem, TMode, TModal>` — `<sd-shared-data-select>`
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
- `SharedDataInfo.getter(changeKeys)` — DB 조회 함수. changeKeys 주어지면 그 키만 재조회(incremental refresh). `orderBy` 는 정렬 키 반환. `SharedDataHandle.get(key)` 로 단건 O(1) 조회.
|
|
24
|
+
검색·트리(`__parentKey`) 가능한 공유데이터 드롭다운(`sd-select` 래핑). 폼 입력의 공유 데이터 선택지에 사용.
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
- `items: input.required<TItem[]>` — 소스 목록(`sharedX.items()`).
|
|
27
|
+
- `value: model<...>` — single 이면 `키|undefined`, multi 면 `키[]`.
|
|
28
|
+
- `selectMode: TMode` (기본 `"single"`) — `"single"`/`"multi"`.
|
|
29
|
+
- `required: boolean` — true(single)면 "미지정" 옵션 숨김.
|
|
30
|
+
- `useUndefined: boolean` — multi 에서 "미지정" 항목 표시.
|
|
31
|
+
- `disabled`/`inset`/`inline`/`size: "sm"|"lg"`/`selectClass`/`multiSelectionDisplayDirection: "vertical"`.
|
|
32
|
+
- `filterFn: (item, index, ...params) => boolean` + `filterFnParams: any[]` — 표시 전 필터.
|
|
33
|
+
- `getIsHiddenFn` (기본 `(item) => item.__isHidden`) / `getSearchTextFn` (기본 `(item) => item.__searchText`) / `displayOrderByFn` — 숨김/검색텍스트/정렬 커스터마이즈.
|
|
34
|
+
- `modal: SdSelectModalInfo<TModal>` — 설정 시 검색 모달 버튼(선택 갱신). `editModal: SdModalInfo<SdModalContentDef<boolean>>` — 관리 전용 모달 버튼(선택 안 바꿈). (선택/관리 모달 규약은 [client-shared-data.md](../manuals/client-shared-data.md))
|
|
35
|
+
- 콘텐츠: `[itemOf]` 항목 템플릿, `#undefinedTpl`("미지정" 라벨).
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<sd-shared-data-select [items]="sharedCustomers.items()" [(value)]="data().customerId" (valueChange)="mark(data)">
|
|
39
|
+
<ng-template [itemOf]="sharedCustomers.items()" let-item="item">{{ item.name }}</ng-template>
|
|
40
|
+
</sd-shared-data-select>
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
##
|
|
43
|
+
## `SdSharedDataSelectButton<TItem, TMode, TModal>` — `<sd-shared-data-select-button>`
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
모달로 선택하는 버튼(`sd-modal-select-button` 래핑).
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
disabled
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
displayOrderByFn = input<(item) => ...|undefined>();
|
|
55
|
-
// 콘텐츠: [itemOf] 템플릿(항목 렌더), #undefinedTpl(미지정 표시)
|
|
56
|
-
```
|
|
47
|
+
- `items: TItem[]` (기본 `[]`) — 선택 항목 표시 해석용.
|
|
48
|
+
- `modal: input.required<SdSelectModalInfo<TModal>>` — 선택 모달(필수).
|
|
49
|
+
- `value: model<SelectModeValue<string|number>[TMode]>` / `selectMode: TMode`(기본 `"single"`).
|
|
50
|
+
- `disabled`/`required`/`inset`/`size: "sm"|"lg"`.
|
|
51
|
+
- 콘텐츠: `[itemOf]` 항목 템플릿(필수).
|
|
52
|
+
|
|
53
|
+
## `SdSharedDataSelectList<TItem, TModal>` — `<sd-shared-data-select-list>`
|
|
54
|
+
|
|
55
|
+
검색·페이지 가능한 단일 선택 리스트. 좌측목록+우측상세 레이아웃의 마스터로 사용.
|
|
57
56
|
|
|
58
|
-
-
|
|
59
|
-
- `
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
57
|
+
- `selectedItem: model<TItem>` — 현재 선택(항목 객체). `canChangeFn` 가드(`setupModelHook`). `items` 변경 시 `__valueKey` 로 재해석 자동 동기.
|
|
58
|
+
- `items: input.required<TItem[]>`.
|
|
59
|
+
- `canChangeFn: (item: TItem | undefined) => boolean | Promise<boolean>` (기본 `() => true`) — 선택 변경 가드(다른 마스터로 전환 전 미저장 변경 확인 등).
|
|
60
|
+
- `selectedIcon: string` — 선택 항목 아이콘. `useUndefined: boolean` — "미지정" 항목. `header: string` — 헤더 텍스트. `pageItemCount: number` — `>0` 이면 그 크기로 페이지네이션.
|
|
61
|
+
- `filterFn: (item, index) => boolean`.
|
|
62
|
+
- `modal: SdSelectModalInfo<TModal>` — 설정 시 외부 링크 모달 버튼(목록 관리·선택).
|
|
63
|
+
- 콘텐츠: `#headerTpl` / `#filterTpl`(기본 검색 필드 대체) / `[itemOf]` / `#undefinedTpl`.
|
|
64
|
+
- 메서드: `select(item)` / `toggle(item)` / `onModalButtonClick()`.
|
|
62
65
|
|
|
63
66
|
```html
|
|
64
|
-
<sd-shared-data-select [items]="
|
|
65
|
-
<ng-template [itemOf]="
|
|
66
|
-
</sd-shared-data-select>
|
|
67
|
+
<sd-shared-data-select-list class="flex-min" [items]="sharedRoles.items()" [(selectedItem)]="selectedRole" [header]="'역할'" [modal]="{ type: RoleList, title: '역할', inputs: {} }">
|
|
68
|
+
<ng-template [itemOf]="sharedRoles.items()" let-item="item">{{ item.name }}</ng-template>
|
|
69
|
+
</sd-shared-data-select-list>
|
|
67
70
|
```
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
## `matchesSearchText`
|
|
70
73
|
|
|
71
74
|
```ts
|
|
72
|
-
|
|
73
|
-
items = input<TItem[]>([]); modal = input.required<SdSelectModalInfo<TModal>>();
|
|
74
|
-
selectMode = input<TMode>("single"); disabled; required; inset; size = input<"sm"|"lg">();
|
|
75
|
-
itemTplRef = contentChild.required(SdItemOfTemplate); // [itemOf] 템플릿(필수)
|
|
75
|
+
function matchesSearchText(itemText: string, searchQuery: string | undefined): boolean
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
-
|
|
78
|
+
- `searchQuery` 를 공백으로 분리한 모든 단어가 `itemText` 에 (대소문자 무시) 부분 포함되면 `true`(AND 매칭). 단어 없으면 `true`. 공유데이터 select 의 검색 매칭에 사용.
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
## 선택/정렬/펼침 매니저 (composable)
|
|
81
|
+
|
|
82
|
+
시트·리스트가 내부적으로 쓰는 상태 매니저. 직접 사용은 커스텀 그리드를 만들 때.
|
|
83
|
+
|
|
84
|
+
### `useSelectionManager<TItem, TKey>`
|
|
81
85
|
|
|
82
86
|
```ts
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
useSelectionManager(options: {
|
|
88
|
+
displayItems: Signal<TItem[]>; selectedKeys: WritableSignal<TKey[]>;
|
|
89
|
+
selectMode: Signal<"single"|"multi"|undefined>;
|
|
90
|
+
getItemSelectableFn: Signal<((item) => boolean|string) | undefined>;
|
|
91
|
+
trackByFn: Signal<(item, index) => TKey>;
|
|
92
|
+
})
|
|
89
93
|
```
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
- `pageItemCount` 지정 시 페이징. `header`/`#headerTpl`=상단 제목, `#filterTpl`=검색 대체, `modal`=목록 관리 모달. 검색은 `__searchText` 매칭, `__isHidden` 항목 제외.
|
|
95
|
+
반환: `hasSelectable`/`isAllSelected: Signal<boolean>`, `getSelectable(item): true | string | undefined`(불가=undefined, 가능=true, 사유=string), `getCanChangeFn(item)`, `select`/`deselect`/`toggle`/`toggleAll`/`isSelected`. single 은 교체, multi 는 추가(`obj.equal` 중복 제거).
|
|
93
96
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
</sd-shared-data-select-list>
|
|
97
|
+
### `useSortingManager`
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
useSortingManager(options: { sorts: WritableSignal<SortingDef[]> })
|
|
99
101
|
```
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
반환: `defMap: Signal<Map<string, { indexText?: string; desc: boolean }>>`(다중 정렬 시 `indexText` "1"…"n"), `toggle(key, multiple)`(none→asc→desc→제거; `multiple=false` 면 전체 교체), `sort<T>(items): T[]`(안정 다중 키 정렬; null < non-null). `SortingDef` = `{ key: string; desc: boolean }`.
|
|
104
|
+
|
|
105
|
+
### `useExpandingManager<T>`
|
|
102
106
|
|
|
103
107
|
```ts
|
|
104
|
-
|
|
108
|
+
useExpandingManager(binding: {
|
|
109
|
+
items: Signal<T[]>; expandedItems: WritableSignal<T[]>;
|
|
110
|
+
getChildrenFn: Signal<((item, index) => T[] | undefined) | undefined>;
|
|
111
|
+
sort: (items: T[]) => T[];
|
|
112
|
+
})
|
|
105
113
|
```
|
|
106
114
|
|
|
107
|
-
|
|
115
|
+
반환: `displayItems: Signal<T[]>`(평탄화·부모→자식 순), `hasExpandable`/`isAllExpanded: Signal<boolean>`, `toggle(item)`/`toggleAll()`/`isVisible(item)`(모든 조상 펼침 시 true)/`def(item): ExpandItemDef<T>`. `ExpandItemDef<T>` = `{ item: T; parentDef: ExpandItemDef<T> | undefined; hasChildren: boolean; depth: number }`.
|
|
@@ -1,100 +1,76 @@
|
|
|
1
1
|
# @simplysm/angular — 시트(sd-sheet)
|
|
2
2
|
|
|
3
|
-
다건 목록·편집 표(그리드). 컬럼 디렉티브 + 셀 템플릿으로
|
|
4
|
-
|
|
5
|
-
## SdSheet — `<sd-sheet>`
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
columnControlsInput = input<readonly SdSheetColumn[]>([]); // 외부에서 컬럼 주입(crud 가 사용)
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
- `key` — 지정 시 사용자 컬럼 설정(폭/고정/숨김/순서)을 `injectSdSystemConfigResource` 로 영속(설정 버튼·설정 모달 노출). 미지정이면 설정 저장 없음.
|
|
31
|
-
- `trackByFn` — 행 키 함수. `selectedKeys` 가 이 키 기준으로 동작. 서버 키가 있으면 그 키 반환.
|
|
32
|
-
- `selectMode` — `"single"`=단일(좌측 화살표), `"multi"`=다중(좌측 체크박스+전체선택). undefined=선택 비활성. `autoSelect` `"click"`=행/셀 클릭 시 선택, `"focus"`=셀 포커스만으로 선택(키보드 위주).
|
|
33
|
-
- `getItemSelectableFn` — 행별 선택 가능. `true`=가능, `false`=불가, `string`=불가+사유(툴팁). 본인 계정 삭제 차단 등.
|
|
34
|
-
- `getChildrenFn` — 자식 반환(트리). 지정 시 펼침 컬럼·들여쓰기 표시, `expandedItems` 로 펼친 항목 관리.
|
|
35
|
-
- `useAutoSort` — true 면 `sorts` 변경 시 시트가 직접 `items` 클라이언트 정렬. 서버측 정렬/페이징이면 false 로 두고 외부에서 재조회. `itemsPerPage>0`+`useAutoSort` 면 클라이언트 페이징, `totalPageCount>0` 이면 서버 페이징.
|
|
36
|
-
- `focusMode` — `"cell"`=셀 단위 포커스 이동(편집·복사), `"row"`=행 단위(셀 인디케이터 숨김). `hideConfigBar`=상단 설정/페이징 바 숨김, `inset`=테두리 제거.
|
|
37
|
-
- `getItemCellClassFn`/`getItemCellStyleFn` — 행+컬럼키별 클래스/스타일(예: 삭제행 취소선). `columnControlsInput` 은 래퍼(crud)가 자식 컬럼을 시트로 위임 투영할 때 사용.
|
|
3
|
+
다건 목록·편집 표(그리드). 컬럼 디렉티브 + 셀 템플릿으로 구성하며 선택·정렬·페이지·트리펼침·셀 편집·컬럼 고정/리사이즈/설정저장을 내장. `sd-crud-list` 가 이 시트를 감싼 표준 골격([crud.md](./crud.md)). 셀 본문·요약 행 작성 규약은 [client-component.md](../manuals/client-component.md) 의 '시트 컬럼·셀 표준' 참조.
|
|
4
|
+
|
|
5
|
+
## `SdSheet<TItem>` — `<sd-sheet>`
|
|
6
|
+
|
|
7
|
+
- `items: TItem[]` (기본 `[]`) — 행 데이터.
|
|
8
|
+
- `trackByFn: (item, index) => unknown` (기본 `(item) => item`) — 행 식별/추적.
|
|
9
|
+
- `selectMode: "single"|"multi"|undefined` — `"multi"` = 체크박스 피처 컬럼 + 헤더 전체선택 + shift-click 범위 선택; `"single"` = 행별 화살표 셀렉터; `undefined` = 선택 UI 없음.
|
|
10
|
+
- `autoSelect: "click"|"focus"|undefined` — `"click"` = 행/셀 클릭 시 선택; `"focus"` = 셀 포커스 시 선택; `undefined` = 자동 선택 없음.
|
|
11
|
+
- `getItemSelectableFn: (item) => boolean | string | undefined` — 행별 선택 가능 여부. `true`=가능, `false`=불가, `string`=불가+사유 툴팁.
|
|
12
|
+
- `getChildrenFn: (item, index) => TItem[] | undefined` — 설정 시 트리펼침 활성(펼침 피처 컬럼·depth·caret).
|
|
13
|
+
- `useAutoSort: boolean` (기본 false) — true 면 표시 전 클라이언트 정렬(정렬 매니저). 서버 정렬/페이징이면 false.
|
|
14
|
+
- `itemsPerPage: number` (기본 0) — 클라이언트 페이징 크기(`0`=페이징 없음).
|
|
15
|
+
- `totalPageCount: number` (기본 0) — 외부 총 페이지 수(서버 페이징). `0` 이면 `items`/`itemsPerPage` 로 산출.
|
|
16
|
+
- `visiblePageCount: number` (기본 10) — 페이지 번호 표시 개수.
|
|
17
|
+
- `key: string` — 컬럼 설정 영속화 키(`injectSdSystemConfigResource`). 설정 시 설정(톱니) 버튼 표시. 설정 모달은 key 없으면 throw.
|
|
18
|
+
- `focusMode: "row"|"cell"` (기본 `"cell"`) — `"cell"` = 포커스 셀 강조; `"row"` = 셀 인디케이터 숨기고 행만 강조.
|
|
19
|
+
- `inset: boolean` (기본 false) — true 면 테두리·라운드 제거(다른 컨테이너 내장용).
|
|
20
|
+
- `hideConfigBar: boolean` (기본 false) — true 면 상단 도구 바(설정 버튼+페이지네이션) 숨김.
|
|
21
|
+
- `contentStyle: string` — 스크롤 컨테이너 인라인 스타일.
|
|
22
|
+
- `getItemCellClassFn: (item, colKey) => string | undefined` / `getItemCellStyleFn: (item, colKey) => string | undefined` — 셀별 클래스/스타일.
|
|
23
|
+
- `columnControlsInput: readonly SdSheetColumn[]` (기본 `[]`) — 투영 컬럼과 합쳐질 프로그래밍 컬럼.
|
|
24
|
+
- model: `selectedKeys: unknown[]` (선택 키) / `expandedItems: TItem[]` (펼친 행) / `sorts: SortingDef[]` (정렬) / `currentPage: number` (0-base).
|
|
25
|
+
- output: `itemKeydown: SdSheetItemKeydownEventParam<TItem>` (`{ item, event }`) / `cellKeydown: SdSheetCellKeydownEventParam<TItem>` (`{ item, key, event }`).
|
|
26
|
+
- 주요 메서드: `onConfigButtonClick()` — `SdSheetConfigModal` 열어 컬럼 설정 영속화(key 없으면 throw). `onHeaderClick(event, cell)` — 정렬 토글(shift=다중 정렬).
|
|
38
27
|
|
|
39
28
|
```html
|
|
40
|
-
<sd-sheet [items]="items()" [trackByFn]="trackByFn" [(selectedKeys)]="selectedKeys"
|
|
41
|
-
[selectMode]="'multi'" [(sorts)]="sorts" [key]="'order-list'">
|
|
29
|
+
<sd-sheet [items]="items()" [trackByFn]="trackByFn" [(selectedKeys)]="selectedKeys" [(currentPage)]="page" [totalPageCount]="pageLength()">
|
|
42
30
|
<sd-sheet-column [key]="'name'" [header]="'이름'">
|
|
43
|
-
<ng-template [cell]="items()" let-item="item">{{ item.name }}</ng-template>
|
|
31
|
+
<ng-template [cell]="items()" let-item="item"><div class="p-xs-sm">{{ item.name }}</div></ng-template>
|
|
44
32
|
</sd-sheet-column>
|
|
45
33
|
</sd-sheet>
|
|
46
34
|
```
|
|
47
35
|
|
|
48
|
-
## SdSheetColumn — `<sd-sheet-column>`
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
key = input.required<string>();
|
|
52
|
-
header = input<string | string[]>(""); // string[] = 다단 헤더(병합)
|
|
53
|
-
headerStyle; tooltip; width = input<string>();
|
|
54
|
-
fixed = input(false); hidden = input(false); collapse = input(false);
|
|
55
|
-
disableSorting = input(false); disableResizing = input(false); ordering = input(0);
|
|
56
|
-
cellTplRef = contentChild.required(SdSheetColumnCellTemplate); // [cell] 템플릿(필수)
|
|
57
|
-
headerTplRef = contentChild<TemplateRef<void>>("headerTpl");
|
|
58
|
-
summaryTplRef = contentChild<TemplateRef<void>>("summaryTpl");
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
- `key` — 컬럼 식별자(정렬/설정/cellKeydown 키). `header` 배열이면 다단 헤더로 병합 표시.
|
|
62
|
-
- `width` — CSS 폭(예: `"120px"`). `fixed`=좌측 고정, `hidden`=숨김, `collapse`=설정상 접힘 후보. `disableSorting`/`disableResizing`=정렬/폭조정 비활성, `ordering`=기본 정렬 순서.
|
|
63
|
-
- `#headerTpl`/`#summaryTpl` 로 헤더/요약행 커스터마이즈. 셀 본문은 `<ng-template [cell]="items()">`(필수).
|
|
36
|
+
## `SdSheetColumn<T>` — `<sd-sheet-column>` (디렉티브)
|
|
64
37
|
|
|
65
|
-
|
|
66
|
-
// SdSheetCellContext<T> = { $implicit: T; item: T; index: number; depth: number; edit: boolean }
|
|
67
|
-
```
|
|
38
|
+
컬럼 1개 선언. `sd-sheet`/`sd-crud-list` 직속 자식으로 두면 자동 투영.
|
|
68
39
|
|
|
69
|
-
-
|
|
40
|
+
- `key: string` (required) — 컬럼 키(설정·셀/헤더 템플릿 lookup·정렬 키). select 별칭과 일치시키면 서버 정렬에 컬럼 분기 없이 처리([client-crud.md](../manuals/client-crud.md)).
|
|
41
|
+
- `header: string | string[]` (기본 `""`) — 헤더 텍스트; `string[]` = 다단/그룹 헤더.
|
|
42
|
+
- `headerStyle: string` / `tooltip: string` — 헤더 셀 스타일/툴팁.
|
|
43
|
+
- `width: string` — 컬럼 폭(미지정=자동; px 지정은 명시 지시 시만, 매뉴얼 '폭 약속').
|
|
44
|
+
- `fixed: boolean` — true 면 좌측 고정(sticky).
|
|
45
|
+
- `hidden: boolean` — true 면 미렌더.
|
|
46
|
+
- `collapse: boolean` — 레이아웃 엔진 collapse 플래그.
|
|
47
|
+
- `disableSorting: boolean` — true 면 헤더 정렬 클릭·아이콘 비활성.
|
|
48
|
+
- `disableResizing: boolean` — true 면 리사이저 핸들 제거.
|
|
49
|
+
- `ordering: number` (기본 0) — 컬럼 순서 가중치(작을수록 앞).
|
|
50
|
+
- 콘텐츠: `[cell]` 셀 템플릿(필수, `SdSheetColumnCellTemplate`), `#headerTpl`(커스텀 헤더), `#summaryTpl`(요약 행 셀).
|
|
70
51
|
|
|
71
|
-
## SdSheetColumnCellTemplate — `ng-template[cell]`
|
|
52
|
+
## `SdSheetColumnCellTemplate<T>` — `ng-template[cell]` (디렉티브)
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
cell = input.required<T[]>(); // 타입 추론용 — items() 를 그대로 전달
|
|
75
|
-
```
|
|
54
|
+
`<ng-template [cell]="items()">` 를 셀 본문으로 표시하고 컨텍스트 타입을 좁힘.
|
|
76
55
|
|
|
77
|
-
-
|
|
56
|
+
- `cell: T[]` (required) — items 배열(타입 추론용 더미, 실제 데이터는 `sd-sheet` 의 `[items]` 보유).
|
|
57
|
+
- 정적 `ngTemplateContextGuard` — 컨텍스트를 `SdSheetCellContext<T>` 로 좁힘.
|
|
78
58
|
|
|
79
|
-
|
|
59
|
+
셀 컨텍스트 `SdSheetCellContext<T>` 필드: `$implicit: T` / `item: T` / `index: number`(표시 페이지 내 행 인덱스) / `depth: number`(트리 깊이) / `edit: boolean`(인라인 편집 모드 여부). 템플릿에서 `let-item="item"`·`let-index="index"`·`let-depth="depth"`·`let-edit="edit"` 로 받음.
|
|
80
60
|
|
|
81
|
-
|
|
82
|
-
sheetKey = input.required<string>();
|
|
83
|
-
controls = input.required<readonly SdSheetColumn[]>();
|
|
84
|
-
config = input.required<SdSheetConfig | undefined>();
|
|
85
|
-
close = output<SdSheetConfig | undefined>(); // SdModalContentDef
|
|
86
|
-
```
|
|
61
|
+
## `SdSheetConfigModal` — `<sd-sheet-config-modal>`
|
|
87
62
|
|
|
88
|
-
|
|
63
|
+
컬럼 설정(고정·순서·폭·숨김) 편집 모달. `SdModalContentDef<SdSheetConfig | undefined>` 구현. `sd-sheet` 가 설정 버튼 클릭 시 자동으로 띄움 — 화면에서 직접 다룰 일은 드묾.
|
|
89
64
|
|
|
90
|
-
|
|
65
|
+
- `sheetKey: string` (required) / `controls: readonly SdSheetColumn[]` (required) / `config: SdSheetConfig | undefined` (required).
|
|
66
|
+
- `close: SdSheetConfig | undefined` — OK 시 빌드된 설정, 취소 시 `undefined`, 초기화 확정 시 `{ columnRecord: {} }`.
|
|
91
67
|
|
|
92
|
-
|
|
93
|
-
SdSheetColumnDef { key; header: string|string[]; headerStyle?; tooltip?; width?; fixed; hidden; collapse; disableSorting; disableResizing; ordering }
|
|
94
|
-
SdSheetHeaderDef { text; colspan; rowspan; isLastRow; fixed; colDef?; colIndex }
|
|
95
|
-
SdSheetConfig { columnRecord: Record<string, { width?; hidden?; fixed?; ordering? }> }
|
|
96
|
-
SdSheetItemKeydownEventParam<T> { item: T; event: KeyboardEvent }
|
|
97
|
-
SdSheetCellKeydownEventParam<T> { item: T; key: string; event: KeyboardEvent }
|
|
98
|
-
```
|
|
68
|
+
## 타입
|
|
99
69
|
|
|
100
|
-
- `SdSheetColumnDef
|
|
70
|
+
- `SdSheetColumnDef` — `{ key: string; header: string|string[]; headerStyle?: string; tooltip?: string; width?: string; fixed: boolean; hidden: boolean; collapse: boolean; disableSorting: boolean; disableResizing: boolean; ordering: number }`. 컬럼 디렉티브에서 파생한 정규화 정의.
|
|
71
|
+
- `SdSheetHeaderDef` — `{ text: string; colspan: number; rowspan: number; isLastRow: boolean; fixed: boolean; colDef: SdSheetColumnDef | undefined; colIndex: number }`. 다단 헤더 셀 1개 정의.
|
|
72
|
+
- `SdSheetConfig` — `{ columnRecord: Record<string, { width?: string; hidden?: boolean; fixed?: boolean; ordering?: number }> }`. 사용자별 영속 설정.
|
|
73
|
+
- `SdSheetItemKeydownEventParam<T>` — `{ item: T; event: KeyboardEvent }`. `itemKeydown` 페이로드.
|
|
74
|
+
- `SdSheetCellKeydownEventParam<T>` — `{ item: T; key: string; event: KeyboardEvent }`. `cellKeydown` 페이로드(`key`=컬럼 키).
|
|
75
|
+
- `SdSheetCellContext<T>` — 위 셀 컨텍스트(`sd-sheet-column.ts` 에서 export).
|
|
76
|
+
- `SortingDef` — `{ key: string; desc: boolean }`(`sd-sheet.ts` 재export; 정렬 매니저 원본은 [shared-data.md](./shared-data.md)).
|