@simplysm/sd-claude 14.0.76 → 14.0.78
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/output-styles/sd-tone.md +128 -0
- package/claude/references/sd-simplysm14/apis/angular/README.md +28 -89
- package/claude/references/sd-simplysm14/apis/angular/app-structure.md +75 -32
- package/claude/references/sd-simplysm14/apis/angular/buttons.md +65 -29
- package/claude/references/sd-simplysm14/apis/angular/crud.md +86 -21
- package/claude/references/sd-simplysm14/apis/angular/forms.md +168 -42
- package/claude/references/sd-simplysm14/apis/angular/infrastructure.md +200 -49
- package/claude/references/sd-simplysm14/apis/angular/kanban.md +64 -20
- package/claude/references/sd-simplysm14/apis/angular/layout.md +75 -30
- package/claude/references/sd-simplysm14/apis/angular/modal.md +92 -40
- package/claude/references/sd-simplysm14/apis/angular/routing.md +86 -25
- package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +72 -41
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +113 -21
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +108 -33
- package/claude/references/sd-simplysm14/apis/angular/toast.md +81 -30
- package/claude/references/sd-simplysm14/apis/angular/visual.md +140 -32
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +46 -43
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +59 -48
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +17 -7
- package/claude/references/sd-simplysm14/apis/core-common/README.md +43 -116
- package/claude/references/sd-simplysm14/apis/core-common/extensions.md +74 -109
- package/claude/references/sd-simplysm14/apis/core-common/features.md +40 -35
- package/claude/references/sd-simplysm14/apis/core-common/types.md +80 -106
- package/claude/references/sd-simplysm14/apis/core-common/utils.md +142 -111
- package/claude/references/sd-simplysm14/apis/core-node/README.md +7 -16
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +33 -38
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +25 -33
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +27 -38
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +32 -60
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +14 -45
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +35 -81
- package/claude/references/sd-simplysm14/apis/excel/README.md +178 -80
- package/claude/references/sd-simplysm14/apis/lint/README.md +5 -0
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +1 -1
- package/claude/references/sd-simplysm14/apis/sd-claude/README.md +28 -5
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +1 -1
- package/claude/references/sd-simplysm14/apis/service-client/README.md +57 -50
- package/claude/references/sd-simplysm14/apis/service-server/README.md +8 -15
- package/claude/references/sd-simplysm14/apis/service-server/auth.md +24 -16
- package/claude/references/sd-simplysm14/apis/service-server/builtin-services.md +55 -31
- package/claude/references/sd-simplysm14/apis/service-server/define-service.md +28 -44
- package/claude/references/sd-simplysm14/apis/service-server/internals.md +59 -18
- package/claude/references/sd-simplysm14/apis/service-server/server.md +37 -46
- package/claude/references/sd-simplysm14/manuals/client-component.md +3 -1
- package/claude/references/sd-simplysm14/manuals/logging.md +9 -8
- package/claude/rules/sd-base-rules.md +377 -219
- package/claude/settings.json +1 -0
- package/claude/skills/sd-commit/SKILL.md +31 -8
- package/claude/skills/sd-docs/SKILL.md +15 -10
- package/claude/skills/sd-docs/references/subagent-prompt.md +26 -8
- package/claude/skills/sd-impl/SKILL.md +1 -1
- package/claude/skills/sd-skill/references/skill-authoring.md +1 -1
- package/claude/skills/sd-spec/SKILL.md +22 -13
- package/claude/skills/sd-spec/references/spec-authoring.md +1 -1
- package/claude/skills/sd-unpack/SKILL.md +150 -26
- package/claude/skills/sd-unpack/scripts/handlers/__pycache__/_common.cpython-314.pyc +0 -0
- package/claude/skills/sd-unpack/scripts/handlers/__pycache__/eml_handler.cpython-314.pyc +0 -0
- package/claude/skills/sd-unpack/scripts/handlers/__pycache__/office_com.cpython-314.pyc +0 -0
- package/claude/skills/sd-unpack/scripts/handlers/__pycache__/pdf_handler.cpython-314.pyc +0 -0
- package/claude/skills/sd-unpack/scripts/handlers/_common.py +17 -2
- package/claude/skills/sd-unpack/scripts/handlers/eml_handler.py +100 -24
- package/claude/skills/sd-unpack/scripts/handlers/msg_handler.py +140 -27
- package/claude/skills/sd-unpack/scripts/handlers/office_com.py +698 -107
- package/claude/skills/sd-unpack/scripts/handlers/office_worker.py +34 -26
- package/claude/skills/sd-unpack/scripts/handlers/pdf_handler.py +130 -8
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sd-tone
|
|
3
|
+
description: simplysm 워크스페이스 기본 톤·표현 규칙
|
|
4
|
+
keep-coding-instructions: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 톤·표현 규칙
|
|
8
|
+
|
|
9
|
+
**적용**: 모든 응답 + 산출물(spec.md·문서·코드 주석 등 Write/Edit 본문).
|
|
10
|
+
|
|
11
|
+
**자가 점검** (매 응답·Write/Edit 직전):
|
|
12
|
+
|
|
13
|
+
- 압축 룰을 적용했는가?
|
|
14
|
+
- 한국어 모국어 사용자가 한 번 읽고 흐름대로 이해되는가?
|
|
15
|
+
|
|
16
|
+
## 도메인 어휘로 풀이
|
|
17
|
+
|
|
18
|
+
- 산출물 소비자의 도메인 어휘로 응답.
|
|
19
|
+
- 시스템 내부 용어 회피.
|
|
20
|
+
- 간결·명확.
|
|
21
|
+
- 다음은 단독 노출 금지 — 옆에 의미 동반 또는 도메인 어휘·시나리오로 풀이:
|
|
22
|
+
- 식별자 — 실제 의미를 옆에 표기 (원본 없이도 문장만으로 의미 전달):
|
|
23
|
+
- 코드 심볼
|
|
24
|
+
- 영문 변수명·함수명 (예: `surplus`·`isCompleted`·`joinSingle`)
|
|
25
|
+
- 약어·라벨
|
|
26
|
+
- 번호·§번호
|
|
27
|
+
- 수식·계산식 (예: `(A − B) − C`) — 값 대입 시나리오 1건 동반
|
|
28
|
+
- SQL·프레임워크·구현 용어 (예: "LEFT JOIN 깊이 1 자르기"·"subagent 위탁") — 도메인 흐름으로 풀이
|
|
29
|
+
- "이해 못함"·"무슨 소리야" 피드백 시 같은 내용 반복 X. 도메인 시나리오로 재풀이.
|
|
30
|
+
|
|
31
|
+
## 응답·산출물 표현
|
|
32
|
+
|
|
33
|
+
**구조 선호** (산문체 회피·세로 정돈):
|
|
34
|
+
|
|
35
|
+
- 2개 이상의 정보·예시·항목은 라벨/헤더 + bullet 으로. 줄글로 풀지 말 것.
|
|
36
|
+
- 한 bullet 안 열거가 3개 이상이거나 한 줄이 시각적으로 길면 sub-bullet 으로 세로 분리.
|
|
37
|
+
- 예외: 짧은 토큰(부연 없는 단어급)만의 묶음은 시각적 길이 기준만 적용.
|
|
38
|
+
- 라벨/헤더 뒤 부연이 두 절(clause) 이상이면 bullet 으로 분리.
|
|
39
|
+
|
|
40
|
+
**압축 룰**:
|
|
41
|
+
|
|
42
|
+
- 어미·조사 압축 — "~할 수도 있을 것 같습니다" → "~ 가능"
|
|
43
|
+
- 접속어 제거. 인과는 화살표 `X → Y` 로 표현. 예시 접속어:
|
|
44
|
+
- 인과: 그래서·따라서
|
|
45
|
+
- 대등·역접: 또한·하지만
|
|
46
|
+
- 1단어 가능 시 1단어
|
|
47
|
+
- preamble·sign-off 금지. 예시:
|
|
48
|
+
- 인사
|
|
49
|
+
- 작업 개시
|
|
50
|
+
- 마무리
|
|
51
|
+
- 키워드+기호 구조 권장 — `원인: X → Y` · `해결: Z`
|
|
52
|
+
- 중복 bullet 병합
|
|
53
|
+
|
|
54
|
+
**절대 보존** (압축·약어화·재서술 X):
|
|
55
|
+
|
|
56
|
+
- 코드 심볼·함수명
|
|
57
|
+
- API명·에러 문자열
|
|
58
|
+
- URL·파일경로
|
|
59
|
+
- 명령어
|
|
60
|
+
- 기술 용어·고유명사
|
|
61
|
+
- 날짜·버전
|
|
62
|
+
- 숫자·환경변수
|
|
63
|
+
- 사용자 발언 verbatim 인용
|
|
64
|
+
- 도메인 어휘 (위 "도메인 어휘로 풀이" 룰)
|
|
65
|
+
- 구조 (보존하고 안의 텍스트만 압축 룰 적용):
|
|
66
|
+
- 헤딩
|
|
67
|
+
- bullet 계층·numbered
|
|
68
|
+
- 표·frontmatter
|
|
69
|
+
- 질문 구조 `[맥락+선택지+추천+질문]`
|
|
70
|
+
|
|
71
|
+
**압축 미적용 조건** (표준 톤 응답):
|
|
72
|
+
|
|
73
|
+
- 보안 경고·되돌릴 수 없는 작업 컨펌
|
|
74
|
+
- 다단계 시퀀스에서 압축이 오독 위험
|
|
75
|
+
- 압축 자체가 기술 모호함 생성
|
|
76
|
+
|
|
77
|
+
## 한국어 가독성 가드
|
|
78
|
+
|
|
79
|
+
원칙:
|
|
80
|
+
|
|
81
|
+
- 압축 강도 유지.
|
|
82
|
+
- 영어 직역체로 인한 가독성 저하만 차단.
|
|
83
|
+
|
|
84
|
+
**직역체 회피**:
|
|
85
|
+
|
|
86
|
+
- 어순 — 한국어 SOV: 중요 정보·결론은 문장 뒤.
|
|
87
|
+
- 수동태 — `X 가 Y 에 의해 Z 되었다` → `Y 가 X 를 Z 했다`.
|
|
88
|
+
- 직역 패턴:
|
|
89
|
+
- `~에 의해(서)` → 주어를 능동형으로
|
|
90
|
+
- `~에 대하여`·`~에 관하여` → 생략 또는 `~을/를`
|
|
91
|
+
- `~로부터` → `~에서`
|
|
92
|
+
- `~을 통해` → `~로`·`~으로써`·동사로 풀이
|
|
93
|
+
- `~에 있어` → `~에`·`~에서`
|
|
94
|
+
- `~하기 위해` → `~하려고`·`~할`
|
|
95
|
+
- `~로 인해` → `~때문에`
|
|
96
|
+
- `~의 경우` (첫머리) → `~는/은`·생략
|
|
97
|
+
- `X 를 가진`·`가지고 있다` → `X 가 있다`·`X 다`
|
|
98
|
+
- `~하는 중이다` → 현재형
|
|
99
|
+
- `~에도 불구하고` → `~지만`·`~인데도`
|
|
100
|
+
- `위치하다` → `있다`
|
|
101
|
+
|
|
102
|
+
**남용 회피**:
|
|
103
|
+
|
|
104
|
+
- 대명사 (그·그것·그녀·그들) — 명사 반복 또는 생략
|
|
105
|
+
- 복수 표지 `들` — 한국어는 단수형으로 다수 표현 가능
|
|
106
|
+
- `의` — 띄어쓰기 가능 시 생략
|
|
107
|
+
|
|
108
|
+
**허용**:
|
|
109
|
+
|
|
110
|
+
- 일상 한국어 단어 — 일상에 정착한 압축어(예: `비추`) 포함
|
|
111
|
+
- 명사구 종결 — 압축 일관성 유지
|
|
112
|
+
|
|
113
|
+
## ASCII 그림
|
|
114
|
+
|
|
115
|
+
적용 대상 — 모든 ASCII 그림:
|
|
116
|
+
|
|
117
|
+
- 다이어그램
|
|
118
|
+
- 구성도
|
|
119
|
+
- 와이어프레임 등
|
|
120
|
+
|
|
121
|
+
룰:
|
|
122
|
+
|
|
123
|
+
- 이모지(✏ ☐ ❌ ⭐ ♥ 등) 금지 — 렌더러별 1칸/2칸 변동 → 정렬 깨짐.
|
|
124
|
+
- 그 외 폭 안정 문자 허용:
|
|
125
|
+
- ASCII·한글
|
|
126
|
+
- 박스 라인 ┌─┐ │ └┘ ├┤
|
|
127
|
+
- 도형 ▲ ▼ ► ◄
|
|
128
|
+
- 화살표 ← → ↑ ↓
|
|
@@ -1,98 +1,37 @@
|
|
|
1
1
|
# @simplysm/angular
|
|
2
2
|
|
|
3
|
-
Angular
|
|
3
|
+
Angular 기반 simplysm 공통 UI/상태/인프라 컴포넌트·디렉티브·서비스 모음. zoneless·signal 기반. 모든 컴포넌트 standalone.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- **`SdTiptapEditor`** — 리치 텍스트 에디터. 본문 인라인.
|
|
28
|
-
- **유틸 디렉티브/파이프** — 이벤트(`SdResize`/`SdIntersection`/`SdEvents`)·단축키(`SdCommandDirective`)·표시 효과(`SdRipple`/`SdShowEffect`)·검증(`SdInvalid`)·템플릿(`SdTypedTemplate`/`SdItemOfTemplate`)·포맷(`FormatPipe`)·spacer(`SdGap`)·접힘(`SdCollapse`/`SdCollapseIcon`)·탭(`SdTab`/`SdTabItem`)·리스트(`SdList`/`SdListItem`)·페이저(`SdPagination`)·signal 헬퍼(`mark`/`setSafeStyle`/`setupModelHook`). 본문 인라인.
|
|
29
|
-
- **유틸 타입** — `DirectiveInputSignals`/`UndefToOptional`/`WithOptional`/`SelectModalOutputResult`. 본문 인라인.
|
|
30
|
-
|
|
31
|
-
## 앱 부트스트랩
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
bootstrapApplication(AppComponent, {
|
|
35
|
-
providers: [provideSdAngular({ clientName: "myapp" }), provideRouter(routes)],
|
|
36
|
-
});
|
|
7
|
+
- **provideSdAngular / SdAngularConfigProvider** — 앱 부트스트랩 시 1회. 아래 "부트스트랩" 참조.
|
|
8
|
+
- **버튼류** (`SdButton`/`SdAnchor`/`SdAdditionalButton`/`SdModalSelectButton`/`SdSelectModal`/`SdSelectModalInfo`) — 클릭 트리거 UI. 자세히: [buttons.md](./buttons.md)
|
|
9
|
+
- **폼 입력류** (`SdTextfield`/`SdTextfieldTypes`/`sdTextfieldTypes`/`SdTextarea`/`SdNumpad`/`SdRange`/`SdDateRangePicker`/`SdSelect`/`SelectModeValue`/`SdSelectItem`/`SdSelectButton`/`SdCheckbox`/`SdSwitch`/`SdCheckboxGroup`/`SdCheckboxGroupItem`/`SdForm`/`SdDropdown`/`SdDropdownPopup`) — 값 입력·서밋. 자세히: [forms.md](./forms.md)
|
|
10
|
+
- **모달** (`SdModalProvider`/`SdModal`/`SdActivatedModalProvider`/`SdModalContentDef`/`SdModalInfo`/`SdModalOptions`/`SdPromptModal`/`SdConfirmModal`/`SelectModalOutputResult`) — 프로그래밍 다이얼로그. 자세히: [modal.md](./modal.md)
|
|
11
|
+
- **토스트·바쁨·프린트** (`SdToastProvider`/`SdToast`/`SdToastContainer`/`SdToastSeverity`/`SdToastTheme`/`SdToastContentDef`/`SdToastInput`/`SdBusyProvider`/`SdBusyContainer`/`SdBusyType`/`SdPrintProvider`/`SdPrint`/`SdPrintInput`) — 알림·로딩·인쇄. 자세히: [toast.md](./toast.md)
|
|
12
|
+
- **앱 구조·권한** (`SdAppStructureProvider`/`SdAppStructureUtils`/`SdMenu`/`SdFlatMenu`/`SdPermission`/`injectPermsSignal`/`SdPermissionTable`) — 메뉴 트리·권한 매트릭스. 자세히: [app-structure.md](./app-structure.md)
|
|
13
|
+
- **공유 데이터** (`SdSharedDataProvider`/`SharedDataBase`/`SharedDataInfo`/`SharedDataHandle`/`SdSharedDataChangeEvent`/`SdSharedDataSelect`/`SdSharedDataSelectButton`/`SdSharedDataSelectList`/`matchesSearchText`) — 서버 마스터데이터 캐시+선택 UI. 자세히: [shared-data.md](./shared-data.md)
|
|
14
|
+
- **시트** (`SdSheet`/`SdSheetColumn`/`SdSheetColumnCellTemplate`/`SdSheetConfigModal`/`SdSheetCellContext`/`SdSheetColumnDef`/`SdSheetConfig`/`SdSheetHeaderDef`/`SdSheetItemKeydownEventParam`/`SdSheetCellKeydownEventParam`) — 표 그리드. 자세히: [sheet.md](./sheet.md)
|
|
15
|
+
- **칸반** (`SdKanbanBoard`/`SdKanban`/`SdKanbanLane`/`SdKanbanBoardDropInfo`/`SdKanbanDragRef`/`SdKanbanDropTarget`) — 드래그 보드. 자세히: [kanban.md](./kanban.md)
|
|
16
|
+
- **CRUD 화면 골격** (`SdBaseContainer`/`SdCrudList`/`SdCrudDetail`/`SdStatePreset`/`SdStatePresetDef`) — 목록/상세 페이지 컨테이너. 자세히: [crud.md](./crud.md)
|
|
17
|
+
- **레이아웃** (`SdSidebarContainer`/`SdSidebar`/`SdSidebarMenu`/`SdSidebarUser`/`SdSidebarUserMenu`/`SdTopbarContainer`/`SdTopbar`/`SdTopbarMenu`/`SdTopbarUser`/`SdTopbarUserMenu`) — 사이드바·탑바 골격. 자세히: [layout.md](./layout.md)
|
|
18
|
+
- **셀렉트/확장/정렬 매니저** (`useSelectionManager`/`useExpandingManager`/`useSortingManager`/`ExpandItemDef`/`SortingDef`) — 리스트 내부 상태 헬퍼. 자세히: [selection-managers.md](./selection-managers.md)
|
|
19
|
+
- **라우팅** (`SdRouterLink`/`SdNavigateWindowProvider`/`injectCurrentPageCodeSignal`/`injectFullPageCodeSignal`/`injectViewTitleSignal`/`injectViewTypeSignal`/`SdViewType`/`setupCanDeactivate`/`getMenuRouterLinkOption`/`getIsMenuSelected`) — 라우터 보조. 자세히: [routing.md](./routing.md)
|
|
20
|
+
- **인프라/유틸** (`SdSystemLogProvider`/`SdLocalStorageProvider`/`SdSystemConfigProvider`/`injectSdSystemConfigResource`/`SdServiceClientFactoryProvider`/`SdFileDialogProvider`/`SdGlobalErrorHandlerPlugin`/`SdThemeProvider`/`SdThemeSelector`/`FormatPipe`/`mark`/`setSafeStyle`/`setupBgTheme`/`setupModelHook`/`DirectiveInputSignals`/`UndefToOptional`/`WithOptional`/`SdEvents`/`SdOptionEventPlugin`/`SdResizeDirective`/`SdResizeEvent`/`SdIntersectionDirective`/`SdIntersectionEvent`/`SdCommandDirective`/`SdRipple`/`setupRipple`/`SdShowEffect`/`setupRevealOnShow`/`SdInvalid`/`setupInvalid`/`SdTypedTemplate`/`SdItemOfTemplate`/`SdItemOfTemplateContext`) — 자세히: [infrastructure.md](./infrastructure.md)
|
|
21
|
+
- **시각 위젯** (`SdLabel`/`SdNote`/`SdProgress`/`SdCalendar`/`SdBarcode`/`BarcodeType`/`SdEcharts`/`SdTiptapEditor`/`SdAddressSearchModal`/`Address`/`SdCollapse`/`SdCollapseIcon`/`SdTab`/`SdTabItem`/`SdList`/`SdListItem`/`SdGap`/`SdPagination`) — 자세히: [visual.md](./visual.md)
|
|
22
|
+
|
|
23
|
+
## 부트스트랩
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
provideSdAngular(opt: { clientName: string }): EnvironmentProviders
|
|
37
27
|
```
|
|
38
28
|
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
- `SdSystemLogProvider.writeFn?: (severity: "error"|"warn"|"log", ...data) => Promise<void> | void`: severity별 로그 후크 등록(서버 전송 등). 호출 시 console에도 항상 출력.
|
|
42
|
-
- `setupBgTheme({ theme?, lightness? })`: 컴포넌트 constructor 내에서 호출. body `--background-color` CSS 변수 토글, destroy 시 자동 복원. `theme: "primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"`, `lightness: "lightest"|"lighter"` (default `"lightest"`).
|
|
43
|
-
|
|
44
|
-
## 테마
|
|
45
|
-
|
|
46
|
-
- `SdThemeProvider`: `dark = signal<boolean>`, `fontSize = signal<number>` (presets `[12,14,16,20,24,28]`), `increaseFontSize()`/`decreaseFontSize()`. dark=true 시 body에 `sd-theme-dark` 클래스, fontSize는 html `font-size` 적용. `provideSdAngular`가 localStorage 영속화.
|
|
47
|
-
- `SdThemeSelector`: dropdown 형 토글 UI (글자 크기 ± 버튼 + dark 스위치). 별도 입력 없음.
|
|
48
|
-
|
|
49
|
-
## SdBusyContainer / SdBusyProvider
|
|
50
|
-
|
|
51
|
-
`<sd-busy-container [busy] [message] [type] [progressPercent]>`. type: `"spinner" | "bar" | "cube"` (default = `SdBusyProvider.type()` = `"bar"`). `busy=true` 동안 keydown 차단.
|
|
52
|
-
|
|
53
|
-
`SdBusyProvider`:
|
|
54
|
-
- `globalBusyCount = signal(0)`. > 0이면 body 전면 오버레이.
|
|
55
|
-
- `type = signal<SdBusyType>("bar")`: 전역 busy 컨테이너의 기본 type. 변경 시 즉시 반영.
|
|
56
|
-
|
|
57
|
-
## SdPermissionTable
|
|
58
|
-
|
|
59
|
-
`<sd-permission-table [items] [(value)] [disabled]>`. `items: SdPermission<TModule>[]` (`SdAppStructureUtils.getPermissions` 결과), `value: Record<string, boolean>` (`<fullCode>.use|edit` 형식). 트리 접기/펼치기 + 그룹 일괄 토글.
|
|
29
|
+
- `clientName` — `SdAngularConfigProvider.clientName` 으로 저장. `SdLocalStorageProvider` 키 prefix, `SdServiceClientFactoryProvider` 의 `createServiceClient(clientName, …)`, `SdAppStructureProvider.initialize` 의 `itemsMap[clientName]` 조회에 사용.
|
|
30
|
+
- 호출 부수효과: zoneless change detection 활성, `IMAGE_CONFIG` 경고 끔, ng-icons 기본(stroke 1.5/size 1.33em), `EVENT_MANAGER_PLUGINS` 에 `SdOptionEventPlugin` 추가, `ErrorHandler` 를 `SdGlobalErrorHandlerPlugin` 으로 교체, `unhandledrejection`·`error` 글로벌 리스너 등록, `SdThemeProvider.dark`/`fontSize` 를 `SdLocalStorageProvider` 와 양방향 sync(`sd-theme-dark`·`sd-theme-font-size` 키), `Router` 네비게이션 동안 `SdBusyProvider.globalBusyCount` 증감, `SwUpdate` 활성 시 5분~1시간 백오프로 업데이트 확인 후 사용자 컨펌 → reload.
|
|
60
31
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
## SdTiptapEditor
|
|
66
|
-
|
|
67
|
-
`<sd-tiptap-editor [(value)] [disabled] [readonly] [required] [placeholder] [validatorFn] [extensions]>`. value=HTML string. 기본 extensions: StarterKit + TextStyle + Color + Highlight + TextAlign + Image + Underline. `extensions?: AnyExtension[]` 으로 Tiptap 확장 주입(기본 위에 추가).
|
|
68
|
-
|
|
69
|
-
## 유틸 디렉티브/파이프
|
|
70
|
-
|
|
71
|
-
이벤트·표시 보조용. constructor injection 또는 셀렉터 attach.
|
|
72
|
-
|
|
73
|
-
- `SdOptionEventPlugin`: `(click.capture)`, `(scroll.passive)`, `(touchmove.capture.passive)`, `(transitionend.once)` 등 `.capture/.passive/.once` 변형 이벤트 바인딩 활성화. `provideSdAngular`로 자동 등록.
|
|
74
|
-
- `SdResizeDirective` (`[sdResize]`): ResizeObserver 기반 size 변화 emit (`SdResizeEvent { heightChanged, widthChanged, target, contentRect }`). requestAnimationFrame 디바운스.
|
|
75
|
-
- `SdIntersectionDirective` (`[sdIntersection]`): IntersectionObserver entry emit (`SdIntersectionEvent { entry }`).
|
|
76
|
-
- `SdEvents`: 다양한 native event의 `.capture`/`.passive`/`.once` output 디렉티브 (예: `(scroll.passive)`, `(touchstart.passive)`, `(focus.capture)`, `(transitionend.once)`).
|
|
77
|
-
- `SdCommandDirective` (`[sdRefreshCommand]`/`[sdSaveCommand]`/`[sdInsertCommand]`): Ctrl+Alt+L/Ctrl+S/Insert 단축키 emit. 최상위 열린 모달 내부 또는 모달 없는 페이지일 때만 처리.
|
|
78
|
-
- `SdRipple` (`[sdRipple]="bool"`) / `setupRipple(enableFn?)`: pointerdown 시 원형 ripple.
|
|
79
|
-
- `SdShowEffect` (`[sdShowEffect]="bool"` + `[sdShowEffectType]="'l2r'|'t2b'"`) / `setupRevealOnShow`: viewport intersection 시 fade-in.
|
|
80
|
-
- `SdInvalid` (`[sdInvalid]="msg"`) / `setupInvalid(getMsg)`: hidden input의 customValidity 로 form 검증 + 좌상단 빨간 점 인디케이터.
|
|
81
|
-
- `SdTypedTemplate` (`<ng-template [typed]="typeToken">`): template context 타입 추론용.
|
|
82
|
-
- `SdItemOfTemplate` (`<ng-template [itemOf]="items">`, ctx `SdItemOfTemplateContext { $implicit, item, index, depth }`) — 컬렉션 컴포넌트(`SdSelect`/`SdCalendar` 등) 항목 템플릿.
|
|
83
|
-
- `FormatPipe` (`{{ v | format:fmt }}`): `DateTime`/`DateOnly`는 `toFormatString(fmt)`, string은 `X` 자리표시(예: `'XXX-XXXX-XXXX'`, `|` 로 다중 길이).
|
|
84
|
-
- `SdGap`: spacer. `height|width` 단위 키(`xxs|xs|sm|default|lg|xl|xxl`), `heightPx|widthPx|widthEm` 픽셀/em. 값 0이면 `display:none`.
|
|
85
|
-
- `SdCollapse [open]` / `SdCollapseIcon [open] [openRotate=90] [icon]`: 접힘 패널/아이콘.
|
|
86
|
-
- `SdTab [(value)]`/`SdTabItem [value]`: 탭.
|
|
87
|
-
- `SdList [inset]`/`SdListItem [layout="accordion"|"flat"] [open] [selected] [selectedIcon] [readonly] [contentStyle/Class]` + `<ng-template #toolTpl>` (옵션 도구 영역).
|
|
88
|
-
- `SdPagination [(currentPage)] [totalPageCount] [visiblePageCount=10]`. 그룹 단위 페이지 이동.
|
|
89
|
-
- `mark(signal)`: array/object signal의 in-place mutation 후 shallow copy로 trigger.
|
|
90
|
-
- `setSafeStyle(renderer, el, partial)`: renderer.setStyle 일괄.
|
|
91
|
-
- `setupModelHook(model, canFnSignal)`: WritableSignal의 set/update를 `canFn(value) -> boolean | Promise<boolean>`로 가로채기. `canFn` 자체가 `Signal<...>` 형식 (`input<(v)=>...>()` 그대로 전달). constructor 내에서 호출.
|
|
92
|
-
|
|
93
|
-
## 유틸 타입/기타
|
|
32
|
+
```ts
|
|
33
|
+
@Injectable({ providedIn: "root" }) class SdAngularConfigProvider { clientName!: string }
|
|
34
|
+
```
|
|
94
35
|
|
|
95
|
-
-
|
|
96
|
-
- `
|
|
97
|
-
- `WithOptional<T, K>`: 특정 키만 optional 로.
|
|
98
|
-
- `SelectModalOutputResult<TKey> = { selectedKeys: TKey[] }`: 모달 선택 결과.
|
|
36
|
+
- 직접 쓸 일은 거의 없음. 다른 simplysm 프로바이더가 inject 해 prefix·키로 사용.
|
|
37
|
+
- 사용 예: `bootstrapApplication(App, { providers: [provideSdAngular({ clientName: "my-app" })] })`
|
|
@@ -1,49 +1,92 @@
|
|
|
1
1
|
# @simplysm/angular — app-structure
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
서버 `AppStructureService` 에서 받은 메뉴·권한 트리(`AppStructureItem<TModule>[]`)를 클라이언트에서 사용 가능 형태로 변환·캐시.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## SdAppStructureProvider<TModule> (root)
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
sas.permRecord.set({ "order.list.use": true });
|
|
7
|
+
```ts
|
|
8
|
+
usableModules: WritableSignal<TModule[]|undefined>;
|
|
9
|
+
permRecord: WritableSignal<Record<string, boolean>|undefined>;
|
|
10
|
+
items: WritableSignal<AppStructureItem<TModule>[]>;
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
usableMenus: Signal<SdMenu[]>; // items × modules × perms 필터된 트리 메뉴
|
|
13
|
+
usableFlatMenus: Signal<SdFlatMenu<TModule>[]>; // 평탄화된 메뉴 리스트 (검색 등)
|
|
14
|
+
|
|
15
|
+
initialize(serviceKey: string): Promise<void>;
|
|
16
|
+
getPermissionsByStructure(items, codeChain?): SdPermission<TModule>[];
|
|
17
|
+
getTitleByFullCode(fullCode: string): string; // 부모 chain 포함 타이틀("[A > B] C")
|
|
18
|
+
getItemChainByFullCode(fullCode: string): AppStructureItem<TModule>[];
|
|
19
|
+
getPermsByFullCode<K extends string>(fullCodes: string[], permKeys: K[]): K[];
|
|
18
20
|
```
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
- `initialize` — `SdServiceClientFactoryProvider.get(serviceKey)` 에서 `AppStructureService.getItems()` 호출, `clientName` (`SdAngularConfigProvider`) 키로 트리 적재.
|
|
23
|
+
- `usableModules` — 활성 모듈 식별자 배열. 메뉴/권한 필터링에 사용. 미세팅(`undefined`) 이면 모듈 체크 통과(전체 허용).
|
|
24
|
+
- `permRecord` — `<fullCode>.<permKey>` (예: `sales.invoice.use`) → boolean. `undefined` 면 권한 체크 통과.
|
|
25
|
+
- `usableMenus` — 그룹 메뉴는 표시 가능한 leaf 자식이 있어야 포함. leaf 는 `<code>.use` 권한 검사.
|
|
26
|
+
- `usableFlatMenus` — leaf 만 평탄화. modulesChain 정보 포함.
|
|
27
|
+
- `getPermsByFullCode` — 해당 화면들에 대해 사용자가 가진 권한키들 추출(`perms` 자체가 정의 안된 화면은 모든 permKey 통과).
|
|
21
28
|
|
|
22
|
-
##
|
|
29
|
+
## SdAppStructureUtils (abstract static class)
|
|
23
30
|
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
```ts
|
|
32
|
+
static getTitleByFullCode/getPermsByFullCode/getItemChainByFullCode
|
|
33
|
+
static getMenus(items, codeChain, usableModules, permRecord): SdMenu[]
|
|
34
|
+
static getFlatMenus(items, usableModules, permRecord): SdFlatMenu<TModule>[]
|
|
35
|
+
static getPermissions(items, codeChain, usableModules): SdPermission<TModule>[]
|
|
36
|
+
static getFlatPermissions(items, usableModules) // service-common 의 동명 함수 위임
|
|
27
37
|
```
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
- 프로바이더가 내부적으로 호출. 트리 변환 로직 직접 쓰고 싶으면 호출 가능.
|
|
40
|
+
|
|
41
|
+
## injectPermsSignal
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
function injectPermsSignal<K extends string>(viewCodes: string[], keys: K[]): Signal<K[]>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- 컴포넌트/페이지에서 자기 화면 코드들과 검사할 권한키 배열을 주면, 현재 사용자가 가진 키만 담은 signal 반환. 버튼 enable 조건 등에 사용.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
readonly perms = injectPermsSignal(["sales.invoice"], ["use", "edit"]);
|
|
51
|
+
// 템플릿: @if (perms().includes("edit")) { <sd-button>편집</sd-button> }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## SdPermissionTable — `<sd-permission-table>`
|
|
30
55
|
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
56
|
+
```ts
|
|
57
|
+
class SdPermissionTable<TModule>
|
|
58
|
+
value = model<Record<string, boolean>>({}); // permRecord 형태(key: <fullCode>.<permKey>)
|
|
59
|
+
items = input<SdPermission<TModule>[]>([]);
|
|
60
|
+
disabled = input(false);
|
|
35
61
|
```
|
|
36
62
|
|
|
37
|
-
|
|
63
|
+
- 권한 트리를 표 형태로 표시·편집. `value` 양방향. 관리자 권한 설정 화면용.
|
|
38
64
|
|
|
39
|
-
|
|
40
|
-
- `getFlatMenus(items, usableModules, permRecord)` — 평탄화 + 부모 modules 누적 검사.
|
|
41
|
-
- `getPermissions(items, codeChain, usableModules)` — 권한 트리 (`SdPermissionTable` 입력용).
|
|
42
|
-
- `getFlatPermissions(items, usableModules)` — `@simplysm/service-common` 재노출.
|
|
43
|
-
- `getTitleByFullCode`, `getItemChainByFullCode`, `getPermsByFullCode`.
|
|
65
|
+
## 타입
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
```ts
|
|
68
|
+
interface SdMenu {
|
|
69
|
+
title: string; codeChain: string[]; url?: string; icon?: string; children?: SdMenu[];
|
|
70
|
+
}
|
|
71
|
+
interface SdFlatMenu<TModule = unknown> {
|
|
72
|
+
titleChain: string[]; codeChain: string[]; modulesChain: TModule[][];
|
|
73
|
+
}
|
|
74
|
+
interface SdPermission<TModule = unknown> {
|
|
75
|
+
title: string; codeChain: string[]; modules: TModule[]|undefined;
|
|
76
|
+
perms: ("use"|"edit")[]|undefined;
|
|
77
|
+
children: SdPermission<TModule>[]|undefined;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
46
80
|
|
|
47
|
-
- `
|
|
48
|
-
-
|
|
49
|
-
-
|
|
81
|
+
- `SdMenu` — `url` 또는 `children` 중 하나. 라우터 링크 분기는 `getMenuRouterLinkOption` 이 담당 ([routing.md](./routing.md)).
|
|
82
|
+
- `SdFlatMenu.modulesChain` — 조상부터 자신까지 누적된 modules 배열 묶음. 모듈 활성 여부 검사 시 사용.
|
|
83
|
+
- `SdPermission.perms` — 해당 화면이 정의한 권한 키들. undefined 면 권한 개념 없음(모두 허용).
|
|
84
|
+
|
|
85
|
+
## 부트스트랩 순서
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
const sdAppStructure = inject(SdAppStructureProvider);
|
|
89
|
+
sdAppStructure.usableModules.set(myActiveModules);
|
|
90
|
+
sdAppStructure.permRecord.set(myPermRecord);
|
|
91
|
+
await sdAppStructure.initialize("main"); // serviceKey = SdServiceClientFactoryProvider 의 등록 key
|
|
92
|
+
```
|
|
@@ -1,52 +1,88 @@
|
|
|
1
1
|
# @simplysm/angular — buttons
|
|
2
2
|
|
|
3
|
-
## `<sd-button>`
|
|
3
|
+
## SdButton — `<sd-button>`
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```ts
|
|
6
|
+
type = input<"button" | "submit">("button");
|
|
7
|
+
theme = input<"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"|"link"|"link-primary"|"link-secondary"|"link-info"|"link-success"|"link-warning"|"link-danger"|"link-gray"|"link-blue-gray"|"link-rev">();
|
|
8
|
+
inline = input(false); inset = input(false); size = input<"sm"|"lg">();
|
|
9
|
+
disabled = input(false); buttonStyle = input<string>(); buttonClass = input<string>();
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
- `type` — 내부 `<button type>`. `submit` 이면 둘러싼 `<sd-form>`·`<form>` 의 서밋을 트리거.
|
|
13
|
+
- `theme` — 색상·강조. `link-*` 는 배경 없는 텍스트 링크 룩. 미지정이면 디폴트 회색.
|
|
14
|
+
- `inline` — true 면 인라인 블록 폭(콘텐츠 크기). false 면 부모 폭 채움.
|
|
15
|
+
- `inset` — true 면 외곽 보더/그림자 제거(컨테이너 안에 박힌 룩).
|
|
16
|
+
- `size` — `sm`/`lg` 만. 미지정 = 기본 크기.
|
|
17
|
+
- `disabled` — true 면 클릭·포커스 차단.
|
|
18
|
+
- `buttonStyle`/`buttonClass` — 내부 `<button>` 에 style/class 추가.
|
|
6
19
|
|
|
7
20
|
```html
|
|
8
|
-
<sd-button
|
|
21
|
+
<sd-button theme="primary" (click)="onSave()">저장</sd-button>
|
|
9
22
|
```
|
|
10
23
|
|
|
11
|
-
## `<sd-anchor>`
|
|
24
|
+
## SdAnchor — `<sd-anchor>`
|
|
12
25
|
|
|
13
|
-
|
|
26
|
+
```ts
|
|
27
|
+
disabled = input(false);
|
|
28
|
+
theme = input<"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"|...>();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- 링크 룩 클릭 영역. 버튼보다 강조 낮음. `theme` 미지정이면 현재 텍스트 색 상속.
|
|
32
|
+
- `disabled` — 클릭·포커스 차단.
|
|
14
33
|
|
|
15
34
|
```html
|
|
16
|
-
<sd-anchor
|
|
35
|
+
<sd-anchor (click)="onEdit()">수정</sd-anchor>
|
|
17
36
|
```
|
|
18
37
|
|
|
19
|
-
## `<sd-additional-button>`
|
|
38
|
+
## SdAdditionalButton — `<sd-additional-button>`
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
size = input<"sm"|"lg">(); inset = input(false);
|
|
42
|
+
```
|
|
20
43
|
|
|
21
|
-
|
|
44
|
+
- 입력 컨트롤(`<sd-textfield>` 등) 옆에 붙이는 보조 버튼 슬롯. `<ng-content>` 로 아이콘/텍스트 투영. 키패드 등 입력 우측에 액션 붙일 때.
|
|
22
45
|
|
|
23
46
|
```html
|
|
24
|
-
<sd-additional-button>
|
|
25
|
-
본문 내용
|
|
26
|
-
<sd-button (click)="...">+</sd-button>
|
|
27
|
-
</sd-additional-button>
|
|
47
|
+
<sd-textfield type="text" [(value)]="q" /><sd-additional-button (click)="onSearch()">검색</sd-additional-button>
|
|
28
48
|
```
|
|
29
49
|
|
|
30
|
-
## `<sd-modal-select-button>`
|
|
50
|
+
## SdModalSelectButton — `<sd-modal-select-button>`
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
class SdModalSelectButton<M extends "single"|"multi", K, T extends SdSelectModal<K>>
|
|
54
|
+
modal = input.required<SdSelectModalInfo<SdSelectModal<K>>>();
|
|
55
|
+
value = model<SelectModeValue<K>[M]>();
|
|
56
|
+
disabled = input(false); required = input(false); inset = input(false);
|
|
57
|
+
size = input<"sm"|"lg">(); selectMode = input<M>("single" as M);
|
|
58
|
+
modalOptions = input<SdModalOptions>();
|
|
59
|
+
searchIcon = input(tablerSearch);
|
|
31
60
|
|
|
32
|
-
|
|
61
|
+
interface SdSelectModal<TKey> extends SdModalContentDef<SelectModalOutputResult<TKey>> {
|
|
62
|
+
selectMode: InputSignal<"single"|"multi"|undefined>;
|
|
63
|
+
selectedKeys: InputSignal<TKey[]>;
|
|
64
|
+
}
|
|
65
|
+
type SdSelectModalInfo<T extends SdSelectModal<any>> = SdModalInfo<T, "selectMode"|"selectedKeys">;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- 입력 옆에 검색 버튼이 붙은 모달 트리거 컨트롤. 검색 아이콘 클릭 → 지정 모달 표시 → 모달이 `SelectModalOutputResult<TKey>` emit → `value` 에 반영.
|
|
69
|
+
- `modal` — 표시할 모달 컴포넌트 정의(`SdSelectModal` 구현). 필수.
|
|
70
|
+
- `value` — `single` 모드면 단일 키, `multi` 면 키 배열. `model` 이므로 양방향.
|
|
71
|
+
- `selectMode` — 모달에 전달되는 선택 모드. `single` 기본.
|
|
72
|
+
- `required` — true 면 값이 있어도 지우개 아이콘 표시 안 함. false + 값 있음 → 우측에 지우개 아이콘 노출.
|
|
73
|
+
- `inset` — 컨테이너 안에 박힌 룩(보더 제거).
|
|
74
|
+
- `disabled` — 검색·지우개 버튼 모두 숨김.
|
|
75
|
+
- `modalOptions` — `SdModalProvider.showAsync` 에 전달되는 옵션 ([modal.md](./modal.md)).
|
|
76
|
+
- `searchIcon` — 우측 버튼 아이콘. 기본 `tablerSearch`.
|
|
77
|
+
- `<ng-content>` — 좌측 값 표시 영역.
|
|
33
78
|
|
|
34
79
|
```html
|
|
35
|
-
<sd-modal-select-button
|
|
36
|
-
|
|
37
|
-
[(value)]="selectedKey" <!-- single 모드: TKey | multi 모드: TKey[] -->
|
|
38
|
-
[selectMode]="'single'"
|
|
39
|
-
[modalOptions]="{ resizable: true }"
|
|
40
|
-
[required]="true"
|
|
41
|
-
[disabled]="false"
|
|
42
|
-
[size]="'sm'"
|
|
43
|
-
[inset]="false"
|
|
44
|
-
[searchIcon]="customIcon">
|
|
45
|
-
{{ displayLabel() }}
|
|
80
|
+
<sd-modal-select-button [(value)]="userId" [modal]="{ title: '직원선택', type: EmpSelectModal, inputs: {} }">
|
|
81
|
+
{{ userName() }}
|
|
46
82
|
</sd-modal-select-button>
|
|
47
83
|
```
|
|
48
84
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
85
|
+
## 공통 주의
|
|
86
|
+
|
|
87
|
+
- 모든 버튼류는 standalone. 별도 NgModule 등록 불필요.
|
|
88
|
+
- `theme` 의 같은 8개 baseline(`primary`~`blue-gray`)은 디자인 토큰 `--theme-<name>-default` 에 연결. `SdButton.theme` 만 `link-*` 변종 추가.
|