@simplysm/sd-claude 14.0.87 โ 14.0.89
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 +17 -18
- package/claude/references/sd-simplysm14/apis/angular/README.md +35 -0
- package/claude/references/sd-simplysm14/apis/angular/controls.md +51 -0
- package/claude/references/sd-simplysm14/apis/angular/crud.md +53 -0
- package/claude/references/sd-simplysm14/apis/angular/directives.md +34 -0
- package/claude/references/sd-simplysm14/apis/angular/features.md +40 -0
- package/claude/references/sd-simplysm14/apis/angular/infra.md +74 -0
- package/claude/references/sd-simplysm14/apis/angular/layout.md +27 -0
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +103 -0
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +69 -0
- package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +28 -0
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +57 -0
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +73 -0
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +78 -0
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +66 -0
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +71 -0
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +62 -0
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +70 -0
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +62 -0
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +80 -0
- package/claude/references/sd-simplysm14/apis/core-common/README.md +262 -0
- package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +121 -0
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +128 -0
- package/claude/references/sd-simplysm14/apis/core-common/datetime.md +129 -0
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +91 -0
- package/claude/references/sd-simplysm14/apis/core-common/json-transfer.md +53 -0
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +117 -0
- package/claude/references/sd-simplysm14/apis/core-node/README.md +17 -0
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +43 -0
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +50 -0
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +41 -0
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +72 -0
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +39 -0
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +52 -0
- package/claude/references/sd-simplysm14/apis/excel/README.md +43 -0
- package/claude/references/sd-simplysm14/apis/excel/cell.md +54 -0
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +51 -0
- package/claude/references/sd-simplysm14/apis/excel/style.md +67 -0
- package/claude/references/sd-simplysm14/apis/excel/utils.md +35 -0
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +97 -0
- package/claude/references/sd-simplysm14/apis/excel/wrapper.md +83 -0
- package/claude/references/sd-simplysm14/apis/lint/README.md +49 -0
- package/claude/references/sd-simplysm14/apis/lint/rules.md +130 -0
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +13 -0
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +111 -0
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +128 -0
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +145 -0
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +147 -0
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +62 -0
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +90 -0
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +94 -0
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +26 -0
- package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +117 -0
- package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +291 -0
- package/claude/references/sd-simplysm14/apis/service-client/README.md +150 -0
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +48 -0
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +59 -0
- package/claude/references/sd-simplysm14/apis/service-common/README.md +84 -0
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +48 -0
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +72 -0
- package/claude/references/sd-simplysm14/apis/service-server/README.md +118 -0
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +71 -0
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +62 -0
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +39 -0
- package/claude/references/sd-simplysm14/apis/storage/README.md +120 -0
- package/claude/skills/sd-demo/SKILL.md +6 -0
- package/claude/skills/sd-impl/SKILL.md +4 -7
- package/claude/skills/sd-spec/SKILL.md +31 -858
- package/claude/skills/sd-spec/references/spec-authoring.md +519 -0
- package/claude/workflows/sd-docs.js +84 -0
- package/claude/{skills/sd-docs/references/subagent-prompt.md โ workflows/sd-docs.rules.md} +25 -40
- package/package.json +1 -1
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/.specs/inventory/spec.md +0 -99
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/package.json +0 -12
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/index.ts +0 -3
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inbound/inbound.list.ts +0 -150
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inventory/inventory-master.list.ts +0 -143
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/outbound/outbound.list.ts +0 -150
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/pnpm-workspace.yaml +0 -2
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/sd.config.ts +0 -12
- package/claude/skills/sd-demo/evals/golden.jsonl +0 -1
- package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/package.json +0 -8
- package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/src/.gitkeep +0 -0
- package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tests/.gitkeep +0 -0
- package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tsconfig.json +0 -10
- package/claude/skills/sd-dev/evals/golden.jsonl +0 -1
- package/claude/skills/sd-docs/SKILL.md +0 -58
- package/claude/skills/sd-docs/evals/fixtures/new-write/.claude/references/sd-simplysm14/README.md +0 -7
- package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/package.json +0 -5
- package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/src/index.ts +0 -3
- package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/package.json +0 -6
- package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/src/index.ts +0 -1
- package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/package.json +0 -5
- package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/src/index.ts +0 -8
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/README.md +0 -7
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/apis/foo/README.md +0 -3
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/package.json +0 -5
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/src/index.ts +0 -3
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/package.json +0 -6
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/src/index.ts +0 -1
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/package.json +0 -5
- package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/src/index.ts +0 -8
- package/claude/skills/sd-docs/evals/golden.jsonl +0 -2
- package/claude/skills/sd-impl/evals/fixtures/case-a-new-screen/.specs/260513120000_warehouse/spec.md +0 -101
- package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/.specs/260513120000_warehouse/spec.md +0 -101
- package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/packages/app/src/screens/box-register/box-register.view.ts +0 -46
- package/claude/skills/sd-impl/evals/fixtures/case-c-new-cross/.specs/260513120000_warehouse/spec.md +0 -89
- package/claude/skills/sd-impl/evals/fixtures/case-d-spec-modify/.specs/260513120000_warehouse/spec.md +0 -101
- package/claude/skills/sd-impl/evals/golden.jsonl +0 -4
- package/claude/skills/sd-manual/evals/fixtures/new-manual/src/notification.ts +0 -25
- package/claude/skills/sd-manual/evals/fixtures/update-manual/.claude/references/sd-simplysm14/manuals/notification.md +0 -14
- package/claude/skills/sd-manual/evals/fixtures/update-manual/src/notification.ts +0 -37
- package/claude/skills/sd-manual/evals/golden.jsonl +0 -2
- package/claude/skills/sd-review/evals/fixtures/code-review/src/foo.ts +0 -7
- package/claude/skills/sd-review/evals/fixtures/doc-review/docs/foo.md +0 -4
- package/claude/skills/sd-review/evals/golden.jsonl +0 -2
- package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +0 -14
- package/claude/skills/sd-skill/evals/fixtures/new-skill/.gitkeep +0 -0
- package/claude/skills/sd-skill/evals/golden.jsonl +0 -2
- package/claude/skills/sd-spec/evals/fixtures/case-a-split//355/232/214/354/235/230/353/241/235.md +0 -20
- package/claude/skills/sd-spec/evals/fixtures/case-b-detail/.specs/260513120000_warehouse/spec.md +0 -95
- package/claude/skills/sd-spec/evals/golden.jsonl +0 -2
- package/claude/skills/sd-unpack/evals/fixtures/eml-with-text-attachment/meeting.eml +0 -21
- package/claude/skills/sd-unpack/evals/fixtures/simple-eml/meeting.eml +0 -10
- package/claude/skills/sd-unpack/evals/golden.jsonl +0 -2
- package/claude/skills/sd-use/evals/fixtures/empty/.gitkeep +0 -0
- package/claude/skills/sd-use/evals/golden.jsonl +0 -6
|
@@ -44,21 +44,20 @@ ORM ํธ์ถ, ํ์ผ ๋ณํ, ๋น์ฆ๋์ค ๋ก์ง ๋ฑ์ ์ ๋ ๊ฒฝ์ฐ์ ํด๋น
|
|
|
44
44
|
|
|
45
45
|
## ํจํค์ง ์ธ๋ฑ์ค
|
|
46
46
|
|
|
47
|
-
- **angular** โ Angular
|
|
48
|
-
- **capacitor-plugin-auto-update** โ Android
|
|
49
|
-
- **capacitor-plugin-file-system** โ Capacitor
|
|
50
|
-
- **capacitor-plugin-intent** โ Android ์ธํ
ํธ ๋ธ๋ก๋์บ์คํธ
|
|
51
|
-
- **capacitor-plugin-usb-storage** โ
|
|
52
|
-
- **core-browser** โ ๋ธ๋ผ์ฐ์
|
|
53
|
-
- **core-common** โ ๊ณตํต
|
|
54
|
-
- **core-node** โ Node ์ ์ฉ IO
|
|
55
|
-
- **excel** โ xlsx ์ํฌ๋ถ์
|
|
56
|
-
- **lint** โ ESLint flat
|
|
57
|
-
- **orm-common** โ Dialect ๋
๋ฆฝ ORM
|
|
58
|
-
- **orm-node** โ Node ํ๊ฒฝ์์
|
|
59
|
-
- **sd-
|
|
60
|
-
- **
|
|
61
|
-
- **service-
|
|
62
|
-
- **service-
|
|
63
|
-
- **
|
|
64
|
-
- **storage** โ FTP/FTPS/SFTP ์๊ฒฉ ์คํ ๋ฆฌ์ง์ ๋์ผ ์ธํฐํ์ด์ค(`StorageClient`)๋ก ํ์ผ ์ฝ๊ธฐ/์ฐ๊ธฐ/๊ด๋ฆฌ. ์์ธํ: [apis/storage/README.md](./apis/storage/README.md)
|
|
47
|
+
- **angular** โ Angular(zonelessยทsignal) ์
๋ฌด ํ๋ก ํธ์๋ ์ปดํฌ๋ํธยท๋๋ ํฐ๋ธยทํ๋ก๋ฐ์ด๋ โ ์ฑ ๋ถํธ์คํธ๋ฉ(provideSdAngular)ยท๋ชจ๋ฌ/ํ ์คํธ/busy/์ธ์ยท๋ผ์ฐํ
/๋ฉ๋ด/๊ถํยทํผ ์ปจํธ๋กคยท๋ ์ด์์ยทsd-sheetยท๊ณต์ ๋ฐ์ดํฐยทCRUD ํ๋ฉด ๊ณจ๊ฒฉยท์ฃผ์๊ฒ์/์๋ํฐ/์ฐจํธ/์นธ๋ฐ์ ๋ค๋ฃฐ ๋. ์์ธํ: [apis/angular/README.md](./apis/angular/README.md)
|
|
48
|
+
- **capacitor-plugin-auto-update** โ Capacitor(Android) ์ฑ์์ APK ์ค์น ์ธํ
ํธ ์คํยท์ค์น ๊ถํ ๊ด๋ฆฌ, ์๋ฒ/์ธ๋ถ ์ ์ฅ์ ๊ธฐ๋ฐ ์ต์ APK ์๋ ๊ฐ์งยท๋ค์ด๋ก๋ยท์ค์น ํ๋ฆ์ ๋๋ฆด ๋. ์์ธํ: [apis/capacitor-plugin-auto-update/README.md](./apis/capacitor-plugin-auto-update/README.md)
|
|
49
|
+
- **capacitor-plugin-file-system** โ Capacitor ํ์ผ ์์คํ
ํ๋ฌ๊ทธ์ธ. ๋ค์ดํฐ๋ธ(Android ์ธ๋ถ/์ฑ ์ ์ฅ์)ยท๋ธ๋ผ์ฐ์ (IndexedDB ์๋ฎฌ๋ ์ด์
)์์ ํ์ผ ์ฝ๊ธฐ/์ฐ๊ธฐ, ๋๋ ํ ๋ฆฌ ์กฐํ/์์ฑ/์ญ์ , ์กด์ฌ ํ์ธ, ๊ถํ ํ์ธ/์์ฒญ, ์ ์ฅ์ ๊ฒฝ๋กยทURI ์กฐํ๋ฅผ static FileSystem ํด๋์ค๋ก ์ ๊ณต. ์์ธํ: [apis/capacitor-plugin-file-system/README.md](./apis/capacitor-plugin-file-system/README.md)
|
|
50
|
+
- **capacitor-plugin-intent** โ Android ์ธํ
ํธ ์ก์์ Capacitor ํ๋ฌ๊ทธ์ธ โ ๋ธ๋ก๋์บ์คํธ ๊ตฌ๋
/์ ์กยท์คํ ์ธํ
ํธ ์กฐํยทnewIntent ๋ฆฌ์ค๋ยทstartActivityForResult ์ธ๋ถ Activity ์คํ์ ์ ์ ํด๋์ค Intent ๋ก ์ํ(๋ฐ์ฝ๋ ์ค์บ๋ยทPDA ์ฐ๋, ์น์ ๋ฏธ์ง์ ์คํ
). ์์ธํ: [apis/capacitor-plugin-intent/README.md](./apis/capacitor-plugin-intent/README.md)
|
|
51
|
+
- **capacitor-plugin-usb-storage** โ USB Mass Storage ์ฅ์น(Android=libaums ์ค๋ฌผ, web=IndexedDB ๊ฐ์)์ ์ฅ์น ๋ชฉ๋ก ์กฐํยท๊ถํ ์์ฒญ/ํ์ธยท๋๋ ํ ๋ฆฌ/ํ์ผ ์ฝ๊ธฐ๊ฐ ํ์ํ ๋ โ ์ ์ ํด๋์ค UsbStorage. ์์ธํ: [apis/capacitor-plugin-usb-storage/README.md](./apis/capacitor-plugin-usb-storage/README.md)
|
|
52
|
+
- **core-browser** โ ๋ธ๋ผ์ฐ์ ์ ์ฉ ์ ํธ โ DOM ์์ ํ์ฅ ๋ฉ์๋(์กฐํยทํญ์ด๋ยท๊ฐ์์ฑยท์๋์ขํยท์คํฌ๋กคยทํด๋ฆฝ๋ณด๋ยท๊ฒฝ๊ณ์ธก์ ), Blob ๋ค์ด๋ก๋/ํ์ผ์ ํ/์งํ๋ฅ fetch, IndexedDB KV ์ ์ฅ์ ๋ฐ ๊ฐ์ ํ์ผ์์คํ
. ์์ธํ: [apis/core-browser/README.md](./apis/core-browser/README.md)
|
|
53
|
+
- **core-common** โ ๋ฐํ์ ๋ฌด๊ด ๊ณตํต ์ ํธ โ ๋ ์ง/์๊ฐ ๊ฐ ํ์
(DateTime/DateOnly/Time), ์๋ฌ ํธ๋ฆฌ(SdError ๋ฑ), ๋น๋๊ธฐ ํ/์ด๋ฒคํธ/์บ์, Array/Set/Map ํ๋กํ ํ์
ํ์ฅ, obj/json/transfer/str/num/bytes/path/xml ์ ํธ ๋ค์์คํ์ด์ค๊ฐ ํ์ํ ๋. ์์ธํ: [apis/core-common/README.md](./apis/core-common/README.md)
|
|
54
|
+
- **core-node** โ Node ๋ฐํ์ ์ ์ฉ ์ ํธ โ ํ์ผ์์คํ
IO(fsx), ์์ ํ๋ก์ธ์ค ์คํยท์ธ์ฝ๋ฉ(cpx), POSIX ๊ฒฝ๋ก ๊ฐ๊ณต(pathx), ํ์ผ ๋ณ๊ฒฝ ๊ฐ์(FsWatcher), consola ๋ก๊น
์
์
, worker_threads ํ์
์์ ๋ํผ(worker). ์์ธํ: [apis/core-node/README.md](./apis/core-node/README.md)
|
|
55
|
+
- **excel** โ OOXML(.xlsx) ์ํฌ๋ถ์ ZIP lazy-load ๋ก ์ฝ๊ณ ์ฐ๊ธฐ โ ExcelWorkbook/Worksheet ์ง์
, ์
๊ฐยท์์ยท์คํ์ผยท๋ณํฉ, ์กฐ๊ฑด๋ถ ์์, ์ด๋ฏธ์ง, Zod ๊ธฐ๋ฐ ExcelWrapper, ์ฃผ์ยท๋ ์งยท์ซ์ํ์ ๋ณํ ์ ํธ์ด ํ์ํ ๋. ์์ธํ: [apis/excel/README.md](./apis/excel/README.md)
|
|
56
|
+
- **lint** โ ESLint 9 flat-config ํ๋ฆฌ์
(eslint-recommended)๊ณผ simplysm ์ปค์คํ
๊ท์น 9์ข
(eslint-plugin)์ subpath export ๋ก ์ ๊ณต โ ํ๋ก์ ํธ lint ์ค์ ์ ์ก๊ฑฐ๋ ์ปค์คํ
๊ท์น ๋์์ ๊ฒํ ํ ๋. ์์ธํ: [apis/lint/README.md](./apis/lint/README.md)
|
|
57
|
+
- **orm-common** โ Dialect ๋
๋ฆฝ ORM ์ฝ์ด โ Table/View/Procedure fluent ๋น๋๋ก ์คํค๋ง๋ฅผ ์ ์ํ๊ณ DbContext ์ ๋ฑ๋กํด connect/transaction/DDL ์ ๋๋ฆฌ๋ฉฐ, Queryable ์ฒด์ด๋๊ณผ expr ํํ์์ผ๋ก SELECT/CUD/ํ๋ก์์ ์ฟผ๋ฆฌ๋ฅผ JSON AST(QueryDef/Expr)๋ก ์กฐ๋ฆฝํ ๋(์ค์ SQL ๋ ๋๋งยท๊ฒฐ๊ณผ ํ์ฑ์ mysql/mssql/postgresql ๋น๋ยทexecutor ๊ฐ ๋ด๋น). ์์ธํ: [apis/orm-common/README.md](./apis/orm-common/README.md)
|
|
58
|
+
- **orm-node** โ Node.js ํ๊ฒฝ์์ @simplysm/orm-common ์ DbContext ๋ฅผ MSSQL/MySQL/PostgreSQL ์ค DB ์ ์ฐ๊ฒฐํด ์คํ โ createOrm ์ผ๋ก ํธ๋์ญ์
๋จ์ ORM ์คํ์ ํ๊ฑฐ๋, ์ ์์ค DbConn ์ผ๋ก raw SQLยทํ๋ผ๋ฏธํฐ ์ฟผ๋ฆฌยทbulk insertยท์๋ ํธ๋์ญ์
์ ์ง์ ๋ค๋ฃฐ ๋. ์์ธํ: [apis/orm-node/README.md](./apis/orm-node/README.md)
|
|
59
|
+
- **sd-cli** โ sd.config.ts ์ค์ ํ์
(๋น๋ ํ๊ฒยท๋ฐฐํฌยทCapacitor/Electron/PWA), ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์ TS/Angular AOT ์ฆ๋ถ ์ปดํ์ผ๋ฌ(SdTsCompiler), Vitest์ฉ Angular AOT Vite ํ๋ฌ๊ทธ์ธ(sdAngularPlugin)์ ๋ค๋ฃฐ ๋. ์์ธํ: [apis/sd-cli/README.md](./apis/sd-cli/README.md)
|
|
60
|
+
- **service-client** โ WebSocket ์๋น์ค ์๋ฒ์ ์ ์ํด ์๋น์ค ๋ฉ์๋ RPC ํธ์ถยท์ธ์ฆยท์๋ฒ ์ด๋ฒคํธ ๊ตฌ๋
ยทํ์ผ ์
๋ค์ด๋ก๋ยทORM ์๊ฒฉ ํธ๋์ญ์
์คํ์ด ํ์ํ ๋ (๋ธ๋ผ์ฐ์ /Node ๊ณต์ฉ ํด๋ผ์ด์ธํธ). ์์ธํ: [apis/service-client/README.md](./apis/service-client/README.md)
|
|
61
|
+
- **service-common** โ ์๋ฒยทํด๋ผ์ด์ธํธ ๊ณต์ ํต์ ๊ณ์ฝ โ ๋ฐ์ด๋๋ฆฌ ํ๋กํ ์ฝ(์ธ์ฝ๋ฉ/์ฒญํน/์ฌ์กฐ๋ฆฝ)ยท๋ฉ์์ง ํ์
, ORM/์๋์
๋ฐ์ดํธ/์
๋ก๋ ์๋น์ค ์ธํฐํ์ด์ค, ํ์
์์ ์ด๋ฒคํธ ์ ์(defineEvent), ์ฑ ๋ฉ๋ดยท๊ถํ ํธ๋ฆฌ ๋ชจ๋ธ์ ๋ค๋ฃฐ ๋. ์์ธํ: [apis/service-common/README.md](./apis/service-common/README.md)
|
|
62
|
+
- **service-server** โ Fastify ๊ธฐ๋ฐ WebSocket/HTTP RPC ์๋น์ค ์๋ฒ โ defineService/auth ๋ก ์๋น์ค ์ ์, JWT ์ธ์ฆ, ์ ์ ํ์ผยท์
๋ก๋, ์๋ฒโํด๋ผ์ด์ธํธ ์ด๋ฒคํธ ๋ธ๋ก๋์บ์คํธ, ORM/์๋์
๋ฐ์ดํธ ๋ด์ฅ ์๋น์ค, V1 ๋ ๊ฑฐ์ ํธํ์ ๋ค๋ฃฐ ๋. ์์ธํ: [apis/service-server/README.md](./apis/service-server/README.md)
|
|
63
|
+
- **storage** โ FTP/FTPS/SFTP ์๊ฒฉ ์คํ ๋ฆฌ์ง์ ์ฐ๊ฒฐํด ํ์ผยท๋๋ ํ ๋ฆฌ๋ฅผ ์
๋ก๋ยท๋ค์ด๋ก๋ยท์กฐํยท์ญ์ ํ ๋. ์ง์
์ ์ StorageFactory.connect(ํ๋กํ ์ฝ, ์ ์์ ๋ณด, ์ฝ๋ฐฑ)๋ก ์ฐ๊ฒฐยท์ข
๋ฃ ์๋ ๊ด๋ฆฌ. ์์ธํ: [apis/storage/README.md](./apis/storage/README.md)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @simplysm/angular
|
|
2
|
+
|
|
3
|
+
Angular 19+ (zoneless, signal ๊ธฐ๋ฐ) ์
๋ฌด ํ๋ก ํธ์๋์ฉ ์ปดํฌ๋ํธยท๋๋ ํฐ๋ธยทํ๋ก๋ฐ์ด๋ ๋ชจ์. ๋ชจ๋ ์ปดํฌ๋ํธ๋ standalone, `OnPush`, signal input/model/output ์ฌ์ฉ. ๋ถํธ์คํธ๋ฉ์ `provideSdAngular` 1๊ฐ๋ก ์์.
|
|
4
|
+
|
|
5
|
+
## ์ฌ์ฉ ํธ๋ฆฌ๊ฑฐ ์ธ๋ฑ์ค
|
|
6
|
+
|
|
7
|
+
- **์ฑ ๋ถํธ์คํธ๋ฉยท์ ์ญ ์ค์ ** โ ์ฑ ์์ ์ `provideSdAngular` ํธ์ถ, ์ ์ญ ์๋ฌ ์ฒ๋ฆฌยทํ
๋งยท๋ก์ปฌ์คํ ๋ฆฌ์งยท์๋ฒ์ฐ๊ฒฐยท์์คํ
์ค์ ํ๋ก๋ฐ์ด๋ ์ฃผ์
. ์์ธํ: [infra.md](./infra.md)
|
|
8
|
+
- **๋ชจ๋ฌยทํ ์คํธยท๋ฐ์จยท์ธ์(์ค๋ฒ๋ ์ด)** โ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ชจ๋ฌ/ํ ์คํธ ๋์ฐ๊ธฐ, busy ํ์, ํ๋ฉด ์ธ์/PDF. ์์ธํ: [overlay.md](./overlay.md)
|
|
9
|
+
- **๋ผ์ฐํ
ยท์ฑ ๊ตฌ์กฐยท๋ฉ๋ดยท๊ถํ** โ ํ์ด์ง ์ฝ๋ยท๋ทฐ ํ์
ยท๋ทฐ ์ ๋ชฉ signal, ๋ผ์ฐํฐ ๋งํฌ, ์ฌ์ด๋๋ฐ/ํ๋ฐ ๋ฉ๋ด ํธ๋ฆฌ, ๊ถํ ํ์ . ์์ธํ: [routing-appstructure.md](./routing-appstructure.md)
|
|
10
|
+
- **ํธ์คํธ ๋๋ ํฐ๋ธยทsetup ํ
** โ ์๋ฆฌ๋จผํธ์ ripple/show-effect/invalid ํ์ ๋ถ์ฐฉ, ๋ฆฌ์ฌ์ด์ฆ/๊ต์ฐจ/๋ช
๋ น(ctrl+s ๋ฑ) ์ด๋ฒคํธ, ์ต์
์ด๋ฒคํธ(`.capture`/`.passive`), ํ์
๋ ํ
ํ๋ฆฟ. ์์ธํ: [directives.md](./directives.md)
|
|
11
|
+
- **์
๋ ฅยท๋ฒํผ ์ปจํธ๋กค** โ textfield/textarea/numpad/range/checkbox/switch/select/dropdown/form/button ๋ฑ ํผ ์ปจํธ๋กค. ์์ธํ: [controls.md](./controls.md)
|
|
12
|
+
- **๋ ์ด์์(์ฌ์ด๋๋ฐยทํ๋ฐ)** โ ํ๋ฉด ๊ณจ๊ฒฉ(์ฌ์ด๋๋ฐ ์ปจํ
์ด๋/๋ฉ๋ด/์ ์ , ํ๋ฐ ์ปจํ
์ด๋/๋ฉ๋ด/์ ์ ). ์์ธํ: [layout.md](./layout.md)
|
|
13
|
+
- **์ํธ(๋ฐ์ดํฐ ๊ทธ๋ฆฌ๋)** โ `sd-sheet` ์ ์ปฌ๋ผ ์ ์, ์ ๋ ฌ/์ ํ/ํ์ด์ง/๊ณ ์ /์
ํธ์ง. ์์ธํ: [sheet.md](./sheet.md)
|
|
14
|
+
- **๊ณต์ ๋ฐ์ดํฐ(shared-data)** โ ์๋ฒ ๋ง์คํฐ ๋ฐ์ดํฐ ์บ์ ํ๋ก๋ฐ์ด๋์ ๊ทธ select/list/button UI. ์์ธํ: [shared-data.md](./shared-data.md)
|
|
15
|
+
- **์ ํยท์ ๋ ฌยทํ์ฅ ๋งค๋์ (use* ์ปดํฌ์ ๋ธ)** โ ์ปค์คํ
๋ฆฌ์คํธ์ ์ ํ/์ ๋ ฌ/ํธ๋ฆฌํ์ฅ ๋ก์ง ๋ถ์ฐฉ. ์์ธํ: [selection-managers.md](./selection-managers.md)
|
|
16
|
+
- **CRUD ํ๋ฉด ๊ณจ๊ฒฉยท์ํํ๋ฆฌ์
ยท๊ถํํ** โ ๋ชฉ๋ก/์์ธ ํ๋ฉด ์ปจํ
์ด๋, ์ํ ํ๋ฆฌ์
์ ์ฅ, ๊ถํ ํธ์ง ํ
์ด๋ธ. ์์ธํ: [crud.md](./crud.md)
|
|
17
|
+
- **๊ธฐ๋ฅ ์ปดํฌ๋ํธ(์ฃผ์๊ฒ์ยท์๋ํฐยท์๊ฐํยท์นธ๋ฐ)** โ ๋ค์ ์ฃผ์๊ฒ์ ๋ชจ๋ฌ, tiptap ์๋ํฐ, ๋ฐ์ฝ๋/๋ฌ๋ ฅ/์ฐจํธ/๋ผ๋ฒจ/๋
ธํธ/์งํ๋ฅ , ์นธ๋ฐ ๋ณด๋. ์์ธํ: [features.md](./features.md)
|
|
18
|
+
- **FormatPipe** โ ํ
ํ๋ฆฟ์์ ๋ฌธ์์ด/๋ ์ง ํฌ๋งท ํ์. ์๋ ์ธ๋ผ์ธ ์ฐธ์กฐ.
|
|
19
|
+
- **SelectModalOutputResult / DirectiveInputSignals / UndefToOptional / WithOptional** โ ๋ชจ๋ฌ ์ ํ ๊ฒฐ๊ณผยทinput signal ํ์
์ ํธ. ์๋ ์ธ๋ผ์ธ ์ฐธ์กฐ.
|
|
20
|
+
|
|
21
|
+
## FormatPipe
|
|
22
|
+
|
|
23
|
+
`{{ value | format: formatStr }}` โ ํ์ดํ. value ๊ฐ `DateTime`/`DateOnly` ๋ฉด `toFormatString(formatStr)`, `string` ์ด๋ฉด `X` ๋ง์คํฌ ํฌ๋งท ์ ์ฉ(์: `format: 'XXX-XXXX'`, `|` ๋ก ๊ธธ์ด๋ณ ๋ค์ค ํจํด ๋ถ๊ธฐ โ `X` ๊ฐ์๊ฐ value.length ์ ์ผ์นํ๋ ํจํด ์ ํ). value ๊ฐ null/undefined ๋ฉด `""` ๋ฐํ(๊ฒฐ์ธก์ ๋น ๋ฌธ์์ด๋ก ํ์). standalone import ํ ์ฌ์ฉ.
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<span>{{ phone | format: 'XXX-XXXX-XXXX|XXX-XXX-XXXX' }}</span>
|
|
27
|
+
<span>{{ dateOnly | format: 'yyyy-MM-dd' }}</span>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## ํ์
์ ํธ
|
|
31
|
+
|
|
32
|
+
- **SelectModalOutputResult<TKey>** โ `{ selectedKeys: TKey[] }`. ์ ํ ๋ชจ๋ฌ์ด `close.emit` ์ผ๋ก ๋๋ ค์ฃผ๋ ๊ฒฐ๊ณผ ํํ. ์ ํ ๋ชจ๋ฌ ์ปดํฌ๋ํธ ์์ฑ ์ close output ํ์
์ผ๋ก ์ฌ์ฉ.
|
|
33
|
+
- **DirectiveInputSignals<T>** โ ์ปดํฌ๋ํธ/๋๋ ํฐ๋ธ ํด๋์ค T ์ `InputSignal` prop ๋ค๋ง ๊ณจ๋ผ `{ prop: ๊ฐํ์
}` ๊ฐ์ฒด ํ์
์ผ๋ก ์ถ์ถ. `undefined` ํฌํจ ํ๋๋ optional ๋ก ๋ณํ. ๋ชจ๋ฌ/ํ ์คํธ/์ธ์์ ์ปดํฌ๋ํธ๋ฅผ ๋๊ธธ ๋ inputs ํ์
์ฐ์ถ์ ๋ด๋ถ์ ์ผ๋ก ์ฐ์.
|
|
34
|
+
- **UndefToOptional<T>** โ `value: T | undefined` ํ๋๋ฅผ `value?: T` ๋ก ๋ณํํ๋ ๋งคํ ํ์
. `DirectiveInputSignals` ๊ฐ ๋ด๋ถ์์ ์ฌ์ฉ.
|
|
35
|
+
- **WithOptional<T, K>** โ T ์์ ํค K ๋ค๋ง optional ๋ก ๋ง๋๋ ํ์
. ๋ชจ๋ฌ/์ธ์ inputs ์์ ์ผ๋ถ input ์ ์ ํ ํญ๋ชฉ์ผ๋ก ํ์ํ ๋ ์ฌ์ฉ.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @simplysm/angular โ ํผ ์ปจํธ๋กคยท๋ฒํผยท์ ํ ์ปจํธ๋กค
|
|
2
|
+
|
|
3
|
+
ํผ ํ๋ฉด์ ๊ตฌ์ฑํ๋ ์
๋ ฅ/๋ฒํผ/์ ํ ์ปดํฌ๋ํธ ๋ฌถ์. ๋๋ถ๋ถ `value = model()` ์๋ฐฉํฅ ๋ฐ์ธ๋ฉ๊ณผ `theme`/`size`/`inline`/`inset`/`disabled` ๊ณตํต input ์ ๊ฐ์ง. ๊ณตํต enum:
|
|
4
|
+
- theme(๊ธฐ๋ณธ 8์): `"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"` โ ์์ ํ
๋ง.
|
|
5
|
+
- size: `"sm"|"lg"` โ ์๊ฒ/ํฌ๊ฒ(๋ฏธ์ง์ =๊ธฐ๋ณธ).
|
|
6
|
+
- inline: boolean โ inline-block ์ผ๋ก ๋ฐฐ์น(ํญ ์๋).
|
|
7
|
+
- inset: boolean โ ํ
๋๋ฆฌยท๋ผ์ด๋ ์ ๊ฑฐ(์
/๊ทธ๋ฃน ๋ด๋ถ ์ฝ์
์ฉ).
|
|
8
|
+
- disabled: boolean โ ๋นํ์ฑ.
|
|
9
|
+
|
|
10
|
+
## ๋ฒํผ๋ฅ
|
|
11
|
+
|
|
12
|
+
- **SdButton** `<sd-button>` โ ๋ฒํผ. `type`("button"|"submit", ๊ธฐ๋ณธ button), `theme`(8์ + `"link"`/`"link-<์>"`/`"link-rev"` ํ
์คํธํ), `inline`/`inset`/`size`/`disabled`, `buttonStyle`/`buttonClass`(๋ด๋ถ button ์๋ฆฌ๋จผํธ ์คํ์ผ/ํด๋์ค). ํผ ์ ์ถ ๋ฒํผ์ด๋ฉด `type="submit"`.
|
|
13
|
+
- **SdAnchor** `<sd-anchor>` โ ํ
์คํธ ๋งํฌ. `theme`(8์, ๊ธฐ๋ณธ primary), `disabled`. ์ธ๋ผ์ธ ํด๋ฆญ ์์(์์ด์ฝ ๋ฒํผ ๋ฑ)์.
|
|
14
|
+
- **SdAdditionalButton** `<sd-additional-button>` โ ๋ด์ฉ + ์ฐ์ธก ๋ถ์ ๋ฒํผ(`sd-anchor`/`sd-button` ํฌ์) ์ปจํ
์ด๋. `size`/`inset`.
|
|
15
|
+
- **SdModalSelectButton** `<sd-modal-select-button>` โ ํด๋ฆญ ์ ์ ํ ๋ชจ๋ฌ์ ๋์ ๊ฐ ์ ํ. `modal = input.required<SdSelectModalInfo<...>>()`, `value = model()`, `selectMode`("single"|"multi", ๊ธฐ๋ณธ single โ single ์ด๋ฉด ๋จ์ผ ํค, multi ๋ฉด ํค ๋ฐฐ์ด), `required`(๋ฏธ์ ํ ์ ๊ฒ์ฆ ์ค๋ฅ + ์ง์ฐ๊ฐ ์จ๊น), `disabled`/`inset`/`size`, `modalOptions`, `searchIcon`. required ์๋๊ณ ๊ฐ ์์ผ๋ฉด ์ง์ฐ๊ฐ ํ์. ํ์
: `SdSelectModal<TKey>`(์ ํ๋ชจ๋ฌ์ด ๊ตฌํ, `SdModalContentDef<SelectModalOutputResult<TKey>>` + `selectMode`/`selectedKeys` input), `SdSelectModalInfo<T>`(selectMode/selectedKeys ์ ์ธํ ๋ชจ๋ฌ ์ ๋ณด).
|
|
16
|
+
|
|
17
|
+
## ํ
์คํธยท์ซ์ ์
๋ ฅ
|
|
18
|
+
|
|
19
|
+
- **SdTextfield<K>** `<sd-textfield [type]="...">` โ ํ์
๋ณ ๋จ์ผ ์
๋ ฅ. `type = input.required<K>()`(K = `SdTextfieldTypes` ํค), `value = model<SdTextfieldTypes[K]>()`. ์ถ๊ฐ input: `placeholder`/`title`, `min`/`max`(ํ์
์ ๋ง๋ ๊ฐ), `minlength`/`maxlength`/`pattern`(๋ฌธ์ํ ๊ฒ์ฆ), `validatorFn`(์ปค์คํ
๊ฒ์ฆ, ๋ฉ์์ง ๋ฐํ), `format`(format ํ์
์ X ๋ง์คํฌ), `step`, `autocomplete`, `useNumberComma`(์ซ์ ์ฒ๋จ์ ์ฝค๋ง, ๊ธฐ๋ณธ true), `minDigits`(์ซ์ ์์ ์ต์ ์๋ฆฟ์), `required`, `readonly`, `inline`/`inset`/`size`/`theme`. ๊ฒ์ฆ ์คํจ ์ `setupInvalid` ๋ก ํผ ์ฐ๋.
|
|
20
|
+
- **SdTextfieldTypes / sdTextfieldTypes** โ ํ์
โ๊ฐ ๋งคํ: `number`:number, `text`/`password`/`color`/`email`/`format`:string, `date`/`month`/`year`:DateOnly, `datetime`/`datetime-sec`:DateTime, `time`/`time-sec`:Time. `sdTextfieldTypes` ๋ ํค ๋ฐฐ์ด(์: select ์ต์
์์ฑ).
|
|
21
|
+
- **SdTextarea** `<sd-textarea>` โ ์ฌ๋ฌ ์ค ํ
์คํธ. `value = model<string>()`, `minRows`(๊ธฐ๋ณธ 1, ๋ด์ฉ ์ค ์๋งํผ ์๋ ํ์ฅ), `placeholder`/`title`/`required`/`readonly`/`validatorFn`/`inline`/`inset`/`size`/`theme`/`inputStyle`/`inputClass`.
|
|
22
|
+
- **SdNumpad** `<sd-numpad>` โ ํ๋ฉด ์ซ์ ํคํจ๋. `value = model<number>()`, `placeholder`, `required`, `inputDisabled`(์๋จ ์
๋ ฅ์นธ ์ง์ ์
๋ ฅ ๋ง๊ธฐ), `useEnterButton`/`useMinusButton`(ENT/โ ๋ฒํผ ํ์), `enterButtonClick = output()`.
|
|
23
|
+
- **SdRange<K>** `<sd-range [type]="...">` โ ๋์ผ ํ์
๋ ๊ฐ์ ๋ฒ์(`from ~ to`). `type = input.required<K>()`, `from`/`to` = model<SdTextfieldTypes[K]>(), `required`/`disabled`/`inputStyle`. to ์ min ์ from ์ผ๋ก ์๋ ์ ํ.
|
|
24
|
+
- **SdDateRangePicker** `<sd-date-range-picker>` โ ์ผ/์/๋ฒ์ ์ ํ. `periodType = model<"์ผ"|"์"|"๋ฒ์">("๋ฒ์")`(์ผ=from=to ๋๊ธฐํ, ์=ํด๋น ์ 1์ผ~๋ง์ผ ์๋, ๋ฒ์=from~to ์์ ), `from`/`to` = model<DateOnly>(), `required`.
|
|
25
|
+
|
|
26
|
+
## ์ฒดํฌยท์ค์์น
|
|
27
|
+
|
|
28
|
+
- **SdCheckbox** `<sd-checkbox>` โ ์ฒดํฌ๋ฐ์ค/๋ผ๋์ค. `value = model(false)`, `canChangeFn`(๋ณ๊ฒฝ ๊ฐ๋, boolean|Promise), `icon`(์ฒดํฌ ์์ด์ฝ), `radio`(๋ผ๋์ค ๋ชจ์ยทํด์ ๋ถ๊ฐ), `disabled`/`size`/`inline`/`inset`, `theme`(8์ + `"white"`), `contentStyle`.
|
|
29
|
+
- **SdSwitch** `<sd-switch>` โ ํ ๊ธ ์ค์์น. `value = model(false)`, `canChangeFn`, `disabled`/`inline`/`inset`/`size`/`theme`(8์).
|
|
30
|
+
- **SdCheckboxGroup<T>** / **SdCheckboxGroupItem<T>** โ ๊ทธ๋ฃน ๋ค์ค์ ํ. group: `value = model<T[]>([])`, `disabled`. item: `value = input.required<T>()`, `inline`. ํญ๋ชฉ ํด๋ฆญ ์ ๊ทธ๋ฃน value ๋ฐฐ์ด์ ์ถ๊ฐ/์ ๊ฑฐ.
|
|
31
|
+
|
|
32
|
+
## ์ ํ(๋๋กญ๋ค์ด)
|
|
33
|
+
|
|
34
|
+
- **SdSelect<M, T>** `<sd-select>` โ ๋๋กญ๋ค์ด ์ ํ. `selectMode = input("single" as M)`("single"|"multi" โ multi ๋ฉด value ๊ฐ ๋ฐฐ์ดยท์ ์ฒด์ ํ ๋ฐ ํ์), `value = model<...>()`, `placeholder`, `required`(๋ฏธ์ ํ ์ ๊ฒ์ฆ์ค๋ฅ), `disabled`/`inline`/`inset`/`size`, `hideSelectAll`(multi ์ ์ฒด์ ํ ๋ฐ ์จ๊น), `multiSelectionDisplayDirection`("vertical" ์ด๋ฉด ์ ํ ํญ๋ชฉ ์ธ๋ก ํ์), `items`/`trackByFn`/`getChildrenFn`(items ์ง์ ์ `itemOf` ํ
ํ๋ฆฟ์ผ๋ก ๋ ๋ยทํธ๋ฆฌ ์ง์), `contentClass`/`contentStyle`, `dropdownOpen = model(false)`. ๋ฉ์๋: selectItem/toggleItem/openDropdown/closeDropdown/onSelectAll/onDeselectAll. ํค๋ณด๋ โโ ๋ก ํญ๋ชฉ ์ด๋. ํ์
`SelectModeValue<T> = { multi: T[]; single: T }`.
|
|
35
|
+
- **SdSelectItem<T>** `<sd-select-item [value]="...">` โ ์ ํ ํญ๋ชฉ. `value`, `disabled`, `hidden`(๊ฒ์ ํํฐ ๋ฑ์ผ๋ก ์จ๊น). multi ๋ชจ๋๋ฉด ์ข์ธก ์ฒดํฌ๋ฐ์ค ํ์. Enter/Space ๋ก ์ ํยทํ ๊ธ.
|
|
36
|
+
- **SdSelectButton** `<sd-select-button>` โ sd-select ์ฐ์ธก์ ๋ถ๋ ๋ถ์ ๋ฒํผ(๊ฒ์/ํธ์ง ๋ฑ ํธ๋ฆฌ๊ฑฐ). input ์์, ํด๋ฆญ ์ด๋ฒคํธ๋ ํฌ์๋ ๋ด์ฉ์์ ์ฒ๋ฆฌ.
|
|
37
|
+
|
|
38
|
+
## ๋๋กญ๋ค์ด(์ ์์ค)
|
|
39
|
+
|
|
40
|
+
- **SdDropdown** `<sd-dropdown>` โ ํธ๋ฆฌ๊ฑฐ + `sd-dropdown-popup` ํ์
. `open = model(false)`, `disabled`. ํ๋ฉด ์์น ์๋ ๋ฐฐ์น, ๋ชจ๋ฐ์ผ(โค520px)์์ ํ๋จ ์ํธ + backdrop. ํค๋ณด๋ โ ๋ก ์ด๊ณ โ/ESC ๋ก ๋ซ์. `popupElRef`(contentChild)๋ก ํ์
์๋ฆฌ๋จผํธ ์ ๊ทผ.
|
|
41
|
+
- **SdDropdownPopup** `<sd-dropdown-popup>` โ ๋๋กญ๋ค์ด ๋ด์ฉ. input ์์. ๋ด์ฉ ๋์ด 300px ์ด๊ณผ ์ ์๋ ์คํฌ๋กค ์บก.
|
|
42
|
+
|
|
43
|
+
## ํผยท์ ๊ธฐยทํญยท๋ฆฌ์คํธยท์ฌ๋ฐฑยทํ์ด์ง
|
|
44
|
+
|
|
45
|
+
- **SdForm** `<sd-form>` โ `(formSubmit)`(๊ฒ์ฆ ํต๊ณผ ์ SubmitEvent), `(formInvalid)`(๊ฒ์ฆ ์คํจ ์, ๋ค์ดํฐ๋ธ ๋ฉ์์งยทํฌ์ปค์ค ์๋). `requestSubmit()` ๋ฉ์๋, `formElRef`/`formEl`(ํผ ์๋ฆฌ๋จผํธ ์ ๊ทผ). ๋ด๋ถ ์ปจํธ๋กค๋ค์ `setupInvalid` ๊ฒ์ฆ์ ๋ชจ์ ์ ์ถ ์ ์ด.
|
|
46
|
+
- **SdCollapse** `<sd-collapse [open]="...">` โ ๋์ด ์ ๋๋ฉ์ด์
์ ๊ธฐ. `open`(boolean). ๋ด์ฉ ๋์ด ์๋ ์ธก์ .
|
|
47
|
+
- **SdCollapseIcon** `<sd-collapse-icon [open]="...">` โ ํผ์นจ ์ํ ํ์ ์์ด์ฝ. `icon`(๊ธฐ๋ณธ chevronDown), `open`, `openRotate`(ํผ์น ๋ ํ์ ๊ฐ๋, ๊ธฐ๋ณธ 90).
|
|
48
|
+
- **SdTab<any>** / **SdTabItem** โ ํญ. tab: `value = model<any>()`. item: `value = input<any>()`(ํด๋ฆญ ์ ๋ถ๋ชจ value ์ค์ , ์ผ์นํ๋ฉด ์ ํ ํ์).
|
|
49
|
+
- **SdList** / **SdListItem** โ ๋ฆฌ์คํธ(ํธ๋ฆฌ). list: `inset`. item: `layout`("accordion"|"flat", ๊ธฐ๋ณธ accordion โ accordion ์ ํด๋ฆญ ์ ์์ ์ ๊ธฐ/ํผ์น๊ธฐ, flat ์ ํญ์ ํผ์นจยทํค๋ ๋นํด๋ฆญ), `open = model(false)`, `selected`(์ ํ ๊ฐ์กฐ), `selectedIcon`(์ ํ ์์ด์ฝ ํ์), `readonly`(ํด๋ฆญ ๋นํ์ฑ), `contentStyle`/`contentClass`, `toolTpl`(์ฐ์ธก ๋๊ตฌ ํ
ํ๋ฆฟ). ์์ `sd-list` ํฌ์ ์ ํ์ ํธ๋ฆฌ.
|
|
50
|
+
- **SdGap** `<sd-gap>` โ ์ฌ๋ฐฑ ์คํ์ด์. `height`/`width`("xxs"|"xs"|"sm"|"default"|"lg"|"xl"|"xxl" CSS ๋ณ์ ๋จ์), `heightPx`/`widthPx`/`widthEm`(์ซ์, 0 ์ด๋ฉด display:none). width ๊ณ์ด ์ง์ ์ inline-block, height ๊ณ์ด์ด๋ฉด block.
|
|
51
|
+
- **SdPagination** `<sd-pagination>` โ ํ์ด์ง ๋ค๋น๊ฒ์ด์
. `currentPage = model(0)`(0 ๊ธฐ๋ฐ), `totalPageCount`(์ ์ฒด ํ์ด์ง ์), `visiblePageCount`(ํ ๊ทธ๋ฃน ํ์ ์, ๊ธฐ๋ณธ 10). ์ฒ์/์ด์ ๊ทธ๋ฃน/ํ์ด์ง๋ฒํธ/๋ค์๊ทธ๋ฃน/๋ ๋ฒํผ.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @simplysm/angular โ CRUD ํ๋ฉด ๊ณจ๊ฒฉยท์ํํ๋ฆฌ์
ยท๊ถํํ
|
|
2
|
+
|
|
3
|
+
์
๋ฌด ๋ชฉ๋ก/์์ธ ํ๋ฉด์ ๊ณตํต ๊ณจ๊ฒฉ(ํ๋ฐยทbusyยท๊ถํ ์ ํยท๋๊ตฌ๋ฐ)๊ณผ ๋ณด์กฐ ์ปดํฌ๋ํธ. ๋ชจ๋ `viewType = input.required<SdViewType>()` ๋ก page/modal/control ๋งฅ๋ฝ์ ๋ฐ์(`injectViewTypeSignal()` ๊ฒฐ๊ณผ ์ ๋ฌ). ํ๋ฉด ์ง์
์ ๊ณต์ ๋ฐ์ดํฐ ์ค๋น๋ฅผ ๋๊ธฐํ๊ณ `ready` ๋ก ์๋ฆผ.
|
|
4
|
+
|
|
5
|
+
## SdBaseContainer
|
|
6
|
+
|
|
7
|
+
`<sd-base-container [viewType]="...">` โ ๊ฐ์ฅ ๋จ์ํ ํ๋ฉด ์ปจํ
์ด๋(ํ๋ฐ + busy + ๊ถํ์ ํ + ๋๊ตฌ๋ฐ).
|
|
8
|
+
- ready = model(false) โ ๊ณต์ ๋ฐ์ดํฐ ๋๊ธฐ ์๋ฃ ์ true. ํ๋ฉด ๋ณธ๋ฌธ ํ์ ์กฐ๊ฑด์.
|
|
9
|
+
- initialized: boolean โ ๋ฐ์ดํฐ ๋ก๋ ์๋ฃ ์ฌ๋ถ(false ๋ฉด busy).
|
|
10
|
+
- busyCount = model(0) โ busy ์นด์ดํธ(>0 ๋ฉด ์ค๋ฒ๋ ์ด).
|
|
11
|
+
- restricted: boolean โ true ๋ฉด "์ฌ์ฉ๊ถํ ์์" ์๋ด๋ง ํ์.
|
|
12
|
+
- viewType: input.required<SdViewType> โ page ๋ฉด ํ๋ฐ(์ ๋ชฉ+topbarTpl) ๊ฐ์ธ๊ณ , ์๋๋ฉด ๋ณธ๋ฌธ๋ง.
|
|
13
|
+
- (contentChild) topbarTpl/commandTpl/contentTpl/bottomCommandTpl โ ํ๋ฐ ์ฐ์ธก/์๋จ ๋ช
๋ น/๋ณธ๋ฌธ/ํ๋จ ๋ช
๋ น ์์ญ.
|
|
14
|
+
|
|
15
|
+
## SdCrudDetail
|
|
16
|
+
|
|
17
|
+
`<sd-crud-detail [viewType]="...">` โ ๋จ๊ฑด ์์ธ/ํธ์ง ํ๋ฉด(ํผ ํฌํจ).
|
|
18
|
+
- ready/initialized/busyCount/restricted/viewType โ ์์ ๋์ผ.
|
|
19
|
+
- readonly: boolean โ ์ฝ๊ธฐ ์ ์ฉ.
|
|
20
|
+
- (viewChild) formCtrl: SdForm โ ๋ด๋ถ ํผ.
|
|
21
|
+
- (output) submit โ ํผ ์ ์ถ(๊ฒ์ฆ ํต๊ณผ).
|
|
22
|
+
- (contentChild) commandTpl/contentTpl/bottomCommandTpl.
|
|
23
|
+
|
|
24
|
+
## SdCrudList<TItem, TKey>
|
|
25
|
+
|
|
26
|
+
`<sd-crud-list [viewType]="...">` โ ๋ชฉ๋ก ํ๋ฉด(ํํฐ ํผ + ์ํธ + ํ์ด์ง + ์ ํ/์ญ์ /๋ณต์).
|
|
27
|
+
- ready/initialized/busyCount/restricted/viewType/readonly โ ์์ ๋์ผ.
|
|
28
|
+
- selectMode?: "single"|"multi" โ ํ ์ ํ ๋ชจ๋.
|
|
29
|
+
- key: input.required<string> โ ์ํธ ์ค์ ์์ ํค.
|
|
30
|
+
- (viewChild) formCtrl: SdForm.
|
|
31
|
+
- (output) filterSubmit โ ํํฐ ํผ ์ ์ถ. submit โ ์ผ๋ฐ ์ ์ถ. create โ ์ถ๊ฐ ๋ฒํผ. delete: TItem[] โ ์ญ์ ๋์. restore: TItem[] โ ๋ณต์ ๋์.
|
|
32
|
+
- items: TItem[] โ ๋ชฉ๋ก ๋ฐ์ดํฐ.
|
|
33
|
+
- selectedKeys = model<NonNullable<TKey>[]>([]) โ ์ ํ ํค.
|
|
34
|
+
- currDeletedItems: TItem[] โ ํ์ฌ ์ญ์ ํ์๋ ํญ๋ชฉ(๋ณต์ ๋์ ํ์).
|
|
35
|
+
- currentPage = model(0) / totalPageCount / itemsPerPage / visiblePageCount(๊ธฐ๋ณธ 10) โ ํ์ด์ง(์ํธ๋ก ์์).
|
|
36
|
+
- sorts = model<SortingDef[]>([]) โ ์ ๋ ฌ ์ํ.
|
|
37
|
+
- trackByFn: input.required<(item) => TKey> โ ํ ํค.
|
|
38
|
+
- (contentChild) commandTpl/filterTpl/toolTpl/bottomCommandTpl, `sd-sheet-column` ๋ค โ ๋ช
๋ น/ํํฐ/๋๊ตฌ/ํ๋จ ๋ช
๋ น ์์ญ๊ณผ ์ํธ ์ปฌ๋ผ.
|
|
39
|
+
|
|
40
|
+
## SdStatePreset<TState>
|
|
41
|
+
|
|
42
|
+
`<sd-state-preset [key]="..." [(state)]="...">` โ ํ๋ฉด ์ํ(ํํฐ ๋ฑ) ํ๋ฆฌ์
์ ์ฅ/์ ์ฉ ๋ฐ.
|
|
43
|
+
- key: input.required<string> โ ํ๋ฆฌ์
์์ ํค(`SdSystemConfigProvider`).
|
|
44
|
+
- state = model.required<TState> โ ํ์ฌ ์ํ(์ ์ฅยท์ ์ฉ ๋์).
|
|
45
|
+
- size?: "sm"|"lg".
|
|
46
|
+
- โ
๋ฒํผ์ผ๋ก ํ์ฌ ์ํ๋ฅผ ์ด๋ฆ ๋ถ์ฌ ์ ์ฅ, ํ๋ฆฌ์
ํด๋ฆญ ์ ์ํ ์ ์ฉ, ๊ฐ ํ๋ฆฌ์
์ ์ฅ(๋ฎ์ด์ฐ๊ธฐ)ยท์ญ์ . ํ์
`SdStatePresetDef<TState> = { name: string; state: TState }`.
|
|
47
|
+
|
|
48
|
+
## SdPermissionTable<TModule>
|
|
49
|
+
|
|
50
|
+
`<sd-permission-table [items]="...">` โ ๊ถํ(use/edit) ํธ์ง ํ
์ด๋ธ.
|
|
51
|
+
- value = model<Record<string, boolean>>({}) โ `<์ฝ๋>.<use|edit>` โ ํ์ฉ ๋งต.
|
|
52
|
+
- items: SdPermission<TModule>[] โ ๊ถํ ํธ๋ฆฌ(`SdAppStructureProvider.getPermissionsByStructure` ๊ฒฐ๊ณผ).
|
|
53
|
+
- disabled: boolean โ ํธ์ง ๋นํ์ฑ.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @simplysm/angular โ ํธ์คํธ ๋๋ ํฐ๋ธยท๋์ ์
์
ยทํ
ํ๋ฆฟ
|
|
2
|
+
|
|
3
|
+
์๋ฆฌ๋จผํธ/์ปดํฌ๋ํธ์ ๋์์ ๋ถ์ฐฉํ๋ ๋๋ ํฐ๋ธ์, ์ปดํฌ๋ํธ constructor ์์ ํธ์ถํ๋ `setup*` ํ
, ํ์
๋ ng-template ๋ฌถ์. ์ปดํฌ๋ํธ ๋์์ ์ง์ ์กฐ๋ฆฝํ ๋ ํจ๊ป ์ฝํ.
|
|
4
|
+
|
|
5
|
+
## ์ด๋ฒคํธ ๋๋ ํฐ๋ธ
|
|
6
|
+
|
|
7
|
+
์ต์
์ด๋ฒคํธ(`.capture`/`.passive`/`.once`)๋ `provideSdAngular` ๊ฐ ๋ฑ๋กํ `SdOptionEventPlugin` ์ผ๋ก ๋์. ์ง์ inject ์ ํจ.
|
|
8
|
+
|
|
9
|
+
- **SdEvents** โ ํ์ค ์ด๋ฒคํธ์ ์ต์
๋ณํ์ output ์ผ๋ก ๋
ธ์ถํ๋ ๋๋ ํฐ๋ธ. `(click.capture)`, `(scroll.passive)`, `(touchstart.passive)`, `(wheel.capture.passive)`, `(transitionend.once)` ๋ฑ(์
๋ ํฐ์ ์ด๊ฑฐ๋ ์กฐํฉ๋ง). ๋ฒ๋ธ๋ง ์ ๋๋ focus/blur ๋ฅผ capture ๋ก ๋ฐ๊ฑฐ๋ ์ฑ๋ฅ์ passive ์คํฌ๋กค์ด ํ์ํ ๋ ์ฌ์ฉ.
|
|
10
|
+
- **SdResizeDirective** โ `(sdResize)` ์ถ๋ ฅ. ResizeObserver ๊ธฐ๋ฐ, requestAnimationFrame ๋๋ฐ์ด์ค. ์ด๋ฒคํธ `SdResizeEvent = { heightChanged; widthChanged; target: HTMLElement; contentRect: DOMRectReadOnly }`. ํฌ๊ธฐ ๋ณํ์ ๋ฐ์ํ ๋.
|
|
11
|
+
- **SdIntersectionDirective** โ `(sdIntersection)` ์ถ๋ ฅ. IntersectionObserver ๊ธฐ๋ฐ. ์ด๋ฒคํธ `SdIntersectionEvent = { entry: IntersectionObserverEntry }`. ํ๋ฉด ์ง์
๊ฐ์ง(์ง์ฐ ๋ก๋ ๋ฑ)์.
|
|
12
|
+
- **SdCommandDirective** โ `(sdRefreshCommand)`(Ctrl+Alt+L), `(sdSaveCommand)`(Ctrl+S), `(sdInsertCommand)`(Insert) ์ถ๋ ฅ(`KeyboardEvent`). ์ต์์๋ก ์ด๋ฆฐ ๋ชจ๋ฌ ์์์๋ง ๋์(๊ฐ๋ ค์ง ํ๋ฉด ๋จ์ถํค ์ฐจ๋จ). ์๋ก๊ณ ์นจ/์ ์ฅ/์ถ๊ฐ ๋จ์ถํค ๋ฐ์ธ๋ฉ์.
|
|
13
|
+
|
|
14
|
+
## ํ์ ํจ๊ณผ ๋๋ ํฐ๋ธ + ์
์
ํ
|
|
15
|
+
|
|
16
|
+
- **SdRipple** / **setupRipple** โ `[sdRipple]="enabled"` ๋๋ ํฐ๋ธ ๋๋ `setupRipple(enableFn?: () => boolean)` ํ
. ํฌ์ธํฐ ๋ค์ด ์์น์์ ํผ์ง๋ ๋ฌผ๊ฒฐ ํจ๊ณผ. enabled/enableFn false ๋ฉด ๋นํ์ฑ. ๋ฒํผ๋ฅ์ ๋ถ์ฐฉ.
|
|
17
|
+
- **SdShowEffect** / **setupRevealOnShow** โ `[sdShowEffect]="enabled"` + `sdShowEffectType`("l2r"|"t2b", ๊ธฐ๋ณธ t2b) ๋๋ ํฐ๋ธ, ๋๋ `setupRevealOnShow(optFn?: () => { type?; enabled? })` ํ
. ํ๋ฉด ์ง์
์ ํ์ด๋+์ฌ๋ผ์ด๋๋ก ๋ํ๋จ. type ์ ์ฌ๋ผ์ด๋ ๋ฐฉํฅ(t2b=์โ์๋, l2r=์ผโ์ค). ์ง์
์ ๋๋ฉ์ด์
์.
|
|
18
|
+
- **SdInvalid** / **setupInvalid** โ `[sdInvalid]="message"` ๋๋ ํฐ๋ธ, ๋๋ `setupInvalid(getInvalidMessage: () => string)` ํ
. ๋ฉ์์ง๊ฐ ๋น ๋ฌธ์์ด์ด ์๋๋ฉด ํธ์คํธ ์ข์๋จ์ ๋นจ๊ฐ ์ ํ์ + ์จ๊น input ์ `setCustomValidity` ๋ก ํผ ๊ฒ์ฆ ์ฐ๋(ํผ submit ์ ๋ฉ์์ง ๋
ธ์ถ). ์ปค์คํ
์ปจํธ๋กค์ ์ ํจ์ฑ ํ์์. (sd-textfield ๋ฑ ๋ด์ฅ ์ปจํธ๋กค์ด ์ด๋ฏธ ์ฌ์ฉ)
|
|
19
|
+
|
|
20
|
+
## ๊ธฐํ ์
์
ํ
ยท์ ํธ
|
|
21
|
+
|
|
22
|
+
- **setupModelHook<T>(model, canFn: Signal<(item) => boolean | Promise<boolean>>)** โ model ์ set/update ๋ฅผ ๊ฐ๋ก์ฑ canFn ๊ฒฐ๊ณผ๊ฐ false ๋ฉด ๋ณ๊ฒฝ ์ฐจ๋จ(Promise ๋ฉด ๋น๋๊ธฐ ํ์ฉ). ์ฒดํฌ๋ฐ์ค/์ค์์น/๋ฆฌ์คํธ ์ ํ์ ๋ณ๊ฒฝ ๊ฐ๋(`canChangeFn`)์ ์ฌ์ฉ.
|
|
23
|
+
- **setupBgTheme(options?: { theme?; lightness? })** โ body ๋ฐฐ๊ฒฝ์ CSS ๋ณ์๋ฅผ ํ
๋ง์์ผ๋ก ์ค์ (์ปดํฌ๋ํธ ํ๊ดด ์ ๋ณต์). theme = `"primary"|...|"gray"|"blue-gray"`, lightness = `"lightest"|"lighter"`(๊ธฐ๋ณธ lightest). ํ๋ฉด ๋ฐฐ๊ฒฝ ํค ์ง์ ์.
|
|
24
|
+
- **setSafeStyle(renderer: Renderer2, el, style: Partial<CSSStyleDeclaration>)** โ Renderer2 ๋ก ์ฌ๋ฌ ์คํ์ผ ์ผ๊ด ์ ์ฉ. ๋๋ ํฐ๋ธ์์ DOM ์คํ์ผ ์ง์ ์กฐ์ ์.
|
|
25
|
+
- **mark(sig: WritableSignal<any>)** โ in-place ๋ณ๊ฒฝ(๋ฐฐ์ด push ๋ฑ) ํ shallow copy ์ ์ฐธ์กฐ๋ก set ํ์ฌ signal ์๋น์์๊ฒ ๋ณ๊ฒฝ ํต์ง. ๋ฐฐ์ด/๊ฐ์ฒด๋ฅผ ์ง์ ๋ณํํ์ ๋.
|
|
26
|
+
|
|
27
|
+
## ํ์
๋ ํ
ํ๋ฆฟ ๋๋ ํฐ๋ธ
|
|
28
|
+
|
|
29
|
+
- **SdTypedTemplate<T>** โ `<ng-template [typed]="typeToken" let-x="...">`. ng-template ์ปจํ
์คํธ์ ํ์
์ ๋ถ์ฌ(ํ์
๊ฐ๋). ์ฌ๊ท ๋ฉ๋ด ํ
ํ๋ฆฟ ๋ฑ์์ ์ปจํ
์คํธ ํ์
๋ณด์ฅ์ ์ฌ์ฉ.
|
|
30
|
+
- **SdItemOfTemplate<TItem>** / **SdItemOfTemplateContext<TItem>** โ `<ng-template [itemOf]="items" let-item="item" let-index="index" let-depth="depth">`. ์ปจํ
์คํธ `{ $implicit; item; index; depth }`. select/shared-data/calendar ๋ฑ์ด ํญ๋ชฉ ๋ ๋ ํ
ํ๋ฆฟ ๊ท์ฝ์ผ๋ก ์ฌ์ฉ.
|
|
31
|
+
|
|
32
|
+
## SdOptionEventPlugin
|
|
33
|
+
|
|
34
|
+
`provideSdAngular` ๊ฐ ๋ฑ๋กํ๋ `EventManagerPlugin`. `.capture`/`.passive`/`.once` ์ ๋ฏธ ์ด๋ฒคํธ๋ฅผ ํด์. ์ง์ ์ฌ์ฉ ์ ํจ.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @simplysm/angular โ ๊ธฐ๋ฅ ์ปดํฌ๋ํธ(์ฃผ์๊ฒ์ยท์๋ํฐยท์๊ฐํยท์นธ๋ฐ)
|
|
2
|
+
|
|
3
|
+
ํน์ ๋๋ฉ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๋
๋ฆฝ ์ปดํฌ๋ํธ ๋ฌถ์. ํ์ํ ํ๋ฉด์์ ๊ฐ๋ณ์ ์ผ๋ก ๊ฐ์ ธ๋ค ์.
|
|
4
|
+
|
|
5
|
+
## ์ฃผ์ ๊ฒ์
|
|
6
|
+
|
|
7
|
+
- **SdAddressSearchModal** โ ๋ค์(์นด์นด์ค) ์ฐํธ๋ฒํธ ๊ฒ์ ๋ชจ๋ฌ ์ปดํฌ๋ํธ. `SdModalContentDef<Address>` ๊ตฌํ์ด๋ผ `SdModalProvider.showAsync({ type: SdAddressSearchModal, ... })` ๋ก ๋์. ์ธ๋ถ ์คํฌ๋ฆฝํธ(daum postcode) ๋ฅผ ๋์ ๋ก๋. `close = output<Address>()`.
|
|
8
|
+
- **Address** โ `{ postNumber: string | undefined; address: string | undefined; buildingName: string | undefined }`. ๊ฒฐ์ธก์ undefined ๋ณด์กด.
|
|
9
|
+
|
|
10
|
+
## ์๋ํฐ
|
|
11
|
+
|
|
12
|
+
- **SdTiptapEditor** `<sd-tiptap-editor [(value)]="...">` โ tiptap ๊ธฐ๋ฐ ๋ฆฌ์นํ
์คํธ ์๋ํฐ(HTML ๋ฌธ์์ด).
|
|
13
|
+
- value = model<string>() โ HTML ๋ณธ๋ฌธ.
|
|
14
|
+
- disabled/readonly/required: boolean โ ๋นํ์ฑ/์ฝ๊ธฐ์ ์ฉ/ํ์(๋น ๊ฐ ๊ฒ์ฆ).
|
|
15
|
+
- placeholder?: string.
|
|
16
|
+
- validatorFn?: (value) => string | undefined โ ์ปค์คํ
๊ฒ์ฆ ๋ฉ์์ง.
|
|
17
|
+
- extensions?: AnyExtension[] โ ์ถ๊ฐ tiptap ํ์ฅ.
|
|
18
|
+
|
|
19
|
+
## ์๊ฐํ
|
|
20
|
+
|
|
21
|
+
- **SdLabel** `<sd-label>` โ ์์ ๋ฐฐ์ง/ํ๊ทธ. `theme`(8์), `color?: string`(์์ ๋ฐฐ๊ฒฝ์), `clickable: boolean`(ํธ๋ฒ ๊ฐ์กฐ + ์ปค์).
|
|
22
|
+
- **SdNote** `<sd-note>` โ ์๋ด ๋ฐ์ค. `theme`(8์), `size`("sm"|"lg"), `inset: boolean`.
|
|
23
|
+
- **SdProgress** `<sd-progress [theme]="..." [value]="...">` โ ์งํ๋ฅ ๋ง๋. `theme: input.required`(8์), `value: input.required<number>`(0~1, ๋ฐฑ๋ถ์จ ํ์ยท๋ง๋ ํญ์ 0~100% clamp), `size`("sm"|"lg"), `inset: boolean`.
|
|
24
|
+
- **SdCalendar<T>** `<sd-calendar [items]="..." [getItemDateFn]="...">` โ ์๊ฐ ๋ฌ๋ ฅ์ ํญ๋ชฉ ๋ฐฐ์น.
|
|
25
|
+
- items: input.required<T[]>.
|
|
26
|
+
- getItemDateFn: input.required<(item, index) => DateOnly> โ ํญ๋ชฉ์ ๋ ์ง.
|
|
27
|
+
- yearMonth: input(๊ธฐ๋ณธ ์ด๋ฒ ๋ฌ 1์ผ) โ ํ์ ์.
|
|
28
|
+
- weekStartDay: number(๊ธฐ๋ณธ 0=์ผ์์ผ) / minDaysInFirstWeek: number(๊ธฐ๋ณธ 1) โ ์ฃผ ์์ยท์ฒซ ์ฃผ ๊ธฐ์ค.
|
|
29
|
+
- (contentChild) `itemOf` ํ
ํ๋ฆฟ ํ์ โ ๋ ์ง ์นธ ํญ๋ชฉ ๋ ๋.
|
|
30
|
+
- **SdBarcode** `<sd-barcode [type]="..." [value]="...">` โ bwip-js ๋ก ๋ฐ์ฝ๋ SVG ๋ ๋. `type: input.required<BarcodeType>`(qrcode/code128/ean13 ๋ฑ ๋ค์ โ `BarcodeType` ์ ๋์จ ์ฐธ์กฐ), `value?: string`(๋น ๊ฐ์ด๋ฉด ๋ฏธํ์).
|
|
31
|
+
- **SdEcharts** `<sd-echarts [option]="...">` โ ECharts ์ฐจํธ. `option: input.required<echarts.EChartsOption>`, `notMerge: boolean`(๊ธฐ๋ณธ false, true ๋ฉด ์ต์
๋ณํฉ ๋์ ๊ต์ฒด), `loading: boolean`(๋ก๋ฉ ์ค๋ฒ๋ ์ด).
|
|
32
|
+
|
|
33
|
+
## ์นธ๋ฐ
|
|
34
|
+
|
|
35
|
+
- **SdKanbanBoard<L, T>** `<sd-kanban-board>` โ ์นธ๋ฐ ๋ณด๋ ์ปจํ
์ด๋(๋๋๊ทธ ์ค ๋๋กญ ์กฐ์จ).
|
|
36
|
+
- selectedValues = model<T[]>([]) โ ์ ํ๋ ์นด๋ ๊ฐ(Shift+ํด๋ฆญ ๋ค์ค ์ ํ).
|
|
37
|
+
- (output) drop: `SdKanbanBoardDropInfo<L,T>` = `{ sourceKanbanValue?; targetLaneValue?; targetKanbanValue? }` โ ๋๋กญ ์ ๋ฐ์(์์ค ์นด๋โ๋์ ๋ ์ธ/์นด๋).
|
|
38
|
+
- **SdKanbanLane<L, T>** `<sd-kanban-lane [value]="...">` โ ๋ ์ธ(์ด). `value?: L`(๋ ์ธ ์๋ณ), `busy: boolean`, `useCollapse: boolean`(์ ๊ธฐ ๋ฒํผ) + `collapse = model(false)`, `toolTpl`/`titleTpl`(๋๊ตฌยท์ ๋ชฉ ํ
ํ๋ฆฟ). ์ ์ฒด์ ํ ์ฒดํฌ๋ฐ์ค(์ ํ๊ฐ๋ฅ ์นด๋ ์์ ๋).
|
|
39
|
+
- **SdKanban<L, T>** `<sd-kanban [value]="...">` โ ์นด๋. `value?: T`, `selectable: boolean`(Shift+ํด๋ฆญ ์ ํ ํ์ฉ), `draggable: boolean`(๋๋๊ทธ ํ์ฉ), `contentClass?: string`. ๋๋๊ทธ ์ ๋ค๋ฅธ ์นด๋/๋ ์ธ ์์ ๋๋กญ ์์น ํ์.
|
|
40
|
+
- ํ์
: **SdKanbanBoardDropInfo<L,T>**(์), **SdKanbanDragRef<L,T>**(`{ value(); heightOnDrag() }`), **SdKanbanDropTarget<L,T>**(`{ targetLaneValue(); targetKanbanValue?() }`) โ ๋ณด๋ ๋ด๋ถ ๋๋๊ทธ/๋๋กญ ๋์ ๊ท์ฝ.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @simplysm/angular โ ๋ถํธ์คํธ๋ฉยท์ค์ ยท๋ก๊น
ยท์๋น์ค ์ธํ๋ผ
|
|
2
|
+
|
|
3
|
+
์ฑ ์์ ์ 1ํ ์ค์ ํ๋ ๋ถํธ์คํธ๋ฉ ํจ์์ ์ ์ญ ํ๋ก๋ฐ์ด๋ ๋ฌถ์. ์ฑ ๋ถํ
์ฝ๋(`appConfig`/`main.ts`)ยท์ ์ญ ์๋ฌยท์๋ฒ ์ฐ๊ฒฐยท์์คํ
์ค์ ์ ์ฅ์ ๋ค๋ฃฐ ๋ ํจ๊ป ์ฝํ.
|
|
4
|
+
|
|
5
|
+
## provideSdAngular
|
|
6
|
+
|
|
7
|
+
`provideSdAngular(opt: { clientName: string }): EnvironmentProviders` โ ์ฑ `providers` ์ 1๊ฐ ์ถ๊ฐํ๋ฉด ๋ค์์ ์ผ๊ด ์ค์ . zoneless ๋ณ๊ฒฝ๊ฐ์ง ํ์ฑ, ์ ์ญ ์๋ฌ ํธ๋ค๋ฌ(`SdGlobalErrorHandlerPlugin`) ๋ฑ๋ก, ์ต์
์ด๋ฒคํธ ํ๋ฌ๊ทธ์ธ(`SdOptionEventPlugin`) ๋ฑ๋ก, ng-icons ๊ธฐ๋ณธ์ค์ (strokeWidth 1.5, size 1.33em), `IMAGE_CONFIG` ๊ฒฝ๊ณ ๋นํ์ฑ, ํ
๋ง dark/fontSize ๋ฅผ ๋ก์ปฌ์คํ ๋ฆฌ์ง(`sd-theme-dark`/`sd-theme-font-size`)์ ์๋ ์์, service worker ์
๋ฐ์ดํธ ํด๋ง(5๋ถ~์ต๋1์๊ฐ ์ง์ ๋ฐฑ์คํ, ๊ฐฑ์ ๊ฐ์ง ์ ์๋ก๊ณ ์นจ ํ์ธ), ๋ผ์ฐํฐ ๋ค๋น๊ฒ์ด์
๋์ ๊ธ๋ก๋ฒ busy ์นด์ดํธ ์ฆ๊ฐ.
|
|
8
|
+
|
|
9
|
+
- opt.clientName: string โ ์ด ํด๋ผ์ด์ธํธ ์๋ณ์. ๋ก์ปฌ์คํ ๋ฆฌ์ง ํค prefixยทservice-client ์ฐ๊ฒฐ ์ด๋ฆ์ผ๋ก ์ฌ์ฉ. ์ฑ๋ง๋ค ๊ณ ์ ๋ฌธ์์ด.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
bootstrapApplication(AppComponent, {
|
|
13
|
+
providers: [provideRouter(routes), provideSdAngular({ clientName: "my-app" })],
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## SdAngularConfigProvider
|
|
18
|
+
|
|
19
|
+
`@Injectable({providedIn:"root"})`. `clientName: string` ํ๋ 1๊ฐ. `provideSdAngular` ๊ฐ ์ฑ์์ค. ๋ค๋ฅธ ํ๋ก๋ฐ์ด๋๊ฐ clientName ์ ์ฐธ์กฐํ ๋ inject.
|
|
20
|
+
|
|
21
|
+
## SdSystemLogProvider
|
|
22
|
+
|
|
23
|
+
์ ์ญ ๋ก๊ทธ ๊ธฐ๋ก ํ๋ก๋ฐ์ด๋. ์ฝ์ ๋ก๊ทธ + ์ ํ์ ์๋ฒ ์ ์ก.
|
|
24
|
+
|
|
25
|
+
- writeFn?: (severity, ...data) => Promise<void> | void โ ์ธ๋ถ(์๋ฒ) ์ ์ก ํ
. ์ง์ ํ๋ฉด ๋งค ๋ก๊ทธ๋ง๋ค ํธ์ถ. ์๋ฒ ๋ก๊ทธ ์ ์ฌ๊ฐ ํ์ํ๋ฉด ์ฑ ์ด๊ธฐํ ๋ ํ ๋น.
|
|
26
|
+
- writeAsync(severity: "error"|"warn"|"log", ...data): Promise<void> โ ๋ก๊ทธ ๊ธฐ๋ก. ์ฝ์์ ๋จผ์ ์ถ๋ ฅ ํ writeFn ํธ์ถ. writeFn ์ด throw ํด๋ ๋ก๊น
์์ฒด๋ ์คํจํ์ง ์์(๋ด๋ถ logger.error ๋ก ๊ธฐ๋ก).
|
|
27
|
+
|
|
28
|
+
## SdLocalStorageProvider<T>
|
|
29
|
+
|
|
30
|
+
`clientName.<key>` ํํ๋ก localStorage ์ JSON ์ ์ฅ/์กฐํ. T ๋ `{ key: ๊ฐํ์
}` ๋งต.
|
|
31
|
+
|
|
32
|
+
- set<K>(key, value) โ JSON.stringify ํ ์ ์ฅ.
|
|
33
|
+
- get<K>(key): T[K] | undefined โ ์๊ฑฐ๋ ํ์ฑ ์คํจ ์ undefined(๊ฒฐ์ธก ๋ณด์กด).
|
|
34
|
+
- remove(key) โ ์ญ์ .
|
|
35
|
+
|
|
36
|
+
## SdSystemConfigProvider<T>
|
|
37
|
+
|
|
38
|
+
ํ๋ฉด๋ณ ์ค์ (์ํธ ์ปฌ๋ผ ์ํ, ๋ชจ๋ฌ ์์น, ์ํ ํ๋ฆฌ์
๋ฑ) ์์ ํ๋ก๋ฐ์ด๋. `fn` ๋ฏธ์ง์ ์ ๋ก์ปฌ์คํ ๋ฆฌ์ง๋ก ํด๋ฐฑ.
|
|
39
|
+
|
|
40
|
+
- fn?: { set(key, data): Promise|void; get(key): PromiseLike<unknown> } โ ์๋ฒ ์์ ํ
. ์ง์ ํ๋ฉด ์๋ฒ์ ์ ์ฅ/์กฐํ, ๋ฏธ์ง์ ์ด๋ฉด `SdLocalStorageProvider` ๋ก ํด๋ฐฑ. ์๋ฒ ๋๊ธฐํ๊ฐ ํ์ํ๋ฉด ์ฑ ์ด๊ธฐํ ๋ ํ ๋น.
|
|
41
|
+
- setAsync<K>(key, data) โ data ๊ฐ null ์ด๋ฉด ์ ๊ฑฐ(ํด๋ฐฑ ์), ์๋๋ฉด ์ ์ฅ.
|
|
42
|
+
- getAsync(key) โ ์ ์ฅ๋ ๊ฐ ์กฐํ.
|
|
43
|
+
|
|
44
|
+
## injectSdSystemConfigResource<T>
|
|
45
|
+
|
|
46
|
+
`injectSdSystemConfigResource<T>({ key: Signal<string|undefined> })` โ ์ปดํฌ๋ํธ ๋ด์์ ํธ์ถ. ํธ์คํธ ์๋ฆฌ๋จผํธ ํ๊ทธ๋ช
+ key ๋ฅผ ํฉ์น ํค๋ก `SdSystemConfigProvider` ์ ์ฐ๋๋๋ resource ํธ๋ค ๋ฐํ. key ๊ฐ undefined ๋ฉด ๋ก๋/์ ์ฅ ์ ํจ.
|
|
47
|
+
|
|
48
|
+
- key: Signal<string|undefined> โ ์ค์ ํค signal. ๋น ๊ฐ์ด๋ฉด ๋นํ์ฑ.
|
|
49
|
+
- ๋ฐํ: `{ value, isLoading, status, hasValue(), reload(), set(v), update(fn) }`. set/update ๋ ์ฆ์ ๋ก์ปฌ ๋ฐ์ ํ microtask ๋ก ๋น๋๊ธฐ ์์(์คํจ ์ errorHandler ๋ก ์ ๋ฌ). ์ํธ/์ํํ๋ฆฌ์
์ด ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ.
|
|
50
|
+
|
|
51
|
+
## SdServiceClientFactoryProvider
|
|
52
|
+
|
|
53
|
+
`@simplysm/service-client` ์ฐ๊ฒฐ์ key ๋จ์๋ก ๊ด๋ฆฌํ๋ ํฉํ ๋ฆฌ. ์์ฒญ/์๋ต ์งํ๋ฅ ์ ํ ์คํธ๋ก ํ์.
|
|
54
|
+
|
|
55
|
+
- connectAsync(key: string, options?: Partial<ServiceConnectionOptions>): Promise<void> โ ์ฐ๊ฒฐ ์์ฑ. host/port/ssl ๋ฏธ์ง์ ์ ํ์ฌ location ๊ธฐ์ค ๊ธฐ๋ณธ๊ฐ. ๊ฐ์ key ์ฌ์ฐ๊ฒฐยท๋๊ธด key ์ฌ์ฌ์ฉ ์ throw.
|
|
56
|
+
- closeAsync(key): Promise<void> โ ์ฐ๊ฒฐ ์ข
๋ฃ. ๋ฏธ์ฐ๊ฒฐ key ๋ฉด throw.
|
|
57
|
+
- get(key): ServiceClient โ ์ฐ๊ฒฐ๋ ํด๋ผ์ด์ธํธ ๋ฐํ. ๋ฏธ์ฐ๊ฒฐ/๋๊น์ด๋ฉด throw. ์๋น์ค ํธ์ถ ์ ์ด๊ฑธ๋ก ServiceClient ํ๋.
|
|
58
|
+
|
|
59
|
+
## SdGlobalErrorHandlerPlugin
|
|
60
|
+
|
|
61
|
+
`ErrorHandler` ๊ตฌํ. `provideSdAngular` ๊ฐ ๋ฑ๋กํ๋ฏ๋ก ์ง์ ์ธ ์ผ์ ๋๋ฌพ. ์ฒ๋ฆฌ๋์ง ์์ ์๋ฌ/Promise ๊ฑฐ๋ถ๋ฅผ ์์คํ
๋ก๊ทธ์ ๊ธฐ๋กํ๊ณ ์ ์ฒดํ๋ฉด ์ค๋ฅ ์ค๋ฒ๋ ์ด๋ฅผ 1ํ ํ์ ํ ์ฑ์ destroy(ํด๋ฆญ ์ ์๋ก๊ณ ์นจ). ์ง์ inject ํ์ง ๋ง๊ณ `throw` ๋ก ์์.
|
|
62
|
+
|
|
63
|
+
## SdThemeProvider
|
|
64
|
+
|
|
65
|
+
`@Injectable({providedIn:"root"})`. ๋คํฌ๋ชจ๋ยทํฐํธํฌ๊ธฐ ์ ์ญ ์ํ.
|
|
66
|
+
|
|
67
|
+
- dark: WritableSignal<boolean> โ ๋คํฌ๋ชจ๋. true ๋ฉด body ์ `sd-theme-dark` ํด๋์ค ํ ๊ธ.
|
|
68
|
+
- fontSize: WritableSignal<number> โ ๋ฃจํธ ํฐํธ ํฌ๊ธฐ(px). ๋ณ๊ฒฝ ์ `documentElement.style.fontSize` ๋ฐ์.
|
|
69
|
+
- fontSizePresets: readonly number[] โ `[12,14,16,20,24,28]`. ์ฆ๊ฐ ๋จ๊ณ.
|
|
70
|
+
- increaseFontSize() / decreaseFontSize() โ ํ๋ฆฌ์
๋ด ๋ค์/์ด์ ๋จ๊ณ๋ก ์ด๋.
|
|
71
|
+
|
|
72
|
+
## SdThemeSelector
|
|
73
|
+
|
|
74
|
+
`<sd-theme-selector />` โ ํฐํธํฌ๊ธฐ ์ฆ๊ฐยท๋คํฌ๋ชจ๋ ์ค์์น๋ฅผ ๋๋กญ๋ค์ด์ผ๋ก ์ ๊ณตํ๋ ์ปดํฌ๋ํธ. input ์์. `SdThemeProvider` ๋ฅผ ์ง์ ์กฐ์. ํ๋ฐ ๋ฑ์ ๋ฐฐ์น.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @simplysm/angular โ ๋ ์ด์์(์ฌ์ด๋๋ฐยทํ๋ฐ)
|
|
2
|
+
|
|
3
|
+
ํ๋ฉด ๊ณจ๊ฒฉ์ ๋ง๋๋ ์ฌ์ด๋๋ฐยทํ๋ฐ ์ปดํฌ๋ํธ ๋ฌถ์. ๋ฉ๋ด ๋ฐ์ดํฐ๋ `SdMenu`(routing-appstructure.md ์ฐธ์กฐ) ๋๋ ์์ฒด ๋ฉ๋ด ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ.
|
|
4
|
+
|
|
5
|
+
## ์ฌ์ด๋๋ฐ
|
|
6
|
+
|
|
7
|
+
- **SdSidebarContainer** `<sd-sidebar-container>` โ ์ฌ์ด๋๋ฐ + ๋ณธ๋ฌธ ๋ ์ด์์ ์ปจํ
์ด๋. input ์์. `toggle: WritableSignal<boolean>`(์ ํ ์ํ, ๋ชจ๋ฐ์ผ์ backdrop ํ์). ๋ผ์ฐํฐ ๋ค๋น๊ฒ์ด์
์์ ์ ์๋ ์ ํ. ์์์ผ๋ก `sd-sidebar` ์ ๋ณธ๋ฌธ์ ๋ .
|
|
8
|
+
- **SdSidebar** `<sd-sidebar>` โ ์ฌ์ด๋๋ฐ ํจ๋. input ์์(์ปจํ
์ด๋์ toggle ์ ๋ฐ๋ฆ). ์ข์ธก ๊ณ ์ , ๋ชจ๋ฐ์ผ์์ ์ค๋ฒ๋ ์ด.
|
|
9
|
+
- **SdSidebarMenu** `<sd-sidebar-menu>` โ ๋ฉ๋ด ํธ๋ฆฌ ๋ ๋. `menus = input<SdMenu[]>([])`, `layout`("accordion"|"flat" โ ๋ฏธ์ง์ ์ ์ต์์ 3๊ฐ ์ดํ๋ฉด flat, ์๋๋ฉด accordion), `getMenuIsSelectedFn`(์ ํ ํ์ ์ปค์คํ
). leaf ๋ `sdRouterLink` ๋ก ์ด๋, `menu.url` ์์ผ๋ฉด ์ ์ฐฝ.
|
|
10
|
+
- **SdSidebarUser** `<sd-sidebar-user>` โ ์ฌ์ฉ์ ์์ญ + ์ ์ด์ ๋ฉ๋ด. `userMenu = input<SdSidebarUserMenu>()`. ํฌ์ ๋ด์ฉ(ํ๋กํ) + ํด๋ฆญ ์ ํผ์ณ์ง๋ ๋ฉ๋ด ๋ชฉ๋ก. ํ์
`SdSidebarUserMenu = { title: string; menus: { title; onClick }[] }`.
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<sd-sidebar-container>
|
|
14
|
+
<sd-sidebar>
|
|
15
|
+
<sd-sidebar-user [userMenu]="userMenu">{{ userName }}</sd-sidebar-user>
|
|
16
|
+
<sd-sidebar-menu [menus]="appStructure.usableMenus()" />
|
|
17
|
+
</sd-sidebar>
|
|
18
|
+
<router-outlet />
|
|
19
|
+
</sd-sidebar-container>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## ํ๋ฐ
|
|
23
|
+
|
|
24
|
+
- **SdTopbarContainer** `<sd-topbar-container>` โ ํ๋ฐ + ๋ณธ๋ฌธ ์ธ๋ก ๋ ์ด์์. input ์์.
|
|
25
|
+
- **SdTopbar** `<sd-topbar>` โ ์๋จ ๋ฐ. `sidebarContainer = input<SdSidebarContainer>()`(๋ฏธ์ง์ ์ ์ฃผ์
๋ ์ปจํ
์ด๋ ์๋ ์ฌ์ฉ). ์ฌ์ด๋๋ฐ๊ฐ ์์ผ๋ฉด ์ข์ธก ํ ๊ธ(ํ๋ฒ๊ฑฐ) ๋ฒํผ ํ์. ์ ๋ชฉยท๋๊ตฌ๋ ํฌ์.
|
|
26
|
+
- **SdTopbarMenu** `<sd-topbar-menu>` โ ๋๋กญ๋ค์ดํ ์๋จ ๋ฉ๋ด ํธ๋ฆฌ. `menus = input<SdMenu[]>([])`, `getMenuIsSelectedFn`. ์ต์์ ๋ฉ๋ด๋ณ ๋๋กญ๋ค์ด, leaf ํด๋ฆญ ์ ์ด๋ยท๋๋กญ๋ค์ด ๋ซํ.
|
|
27
|
+
- **SdTopbarUser** `<sd-topbar-user>` โ ์ฌ์ฉ์ ๋๋กญ๋ค์ด ๋ฉ๋ด. `menus = input.required<SdTopbarUserMenu[]>()`. ํฌ์ ๋ด์ฉ(์ด๋ฆ) ํด๋ฆญ ์ ๋ฉ๋ด ๋ชฉ๋ก. ํ์
`SdTopbarUserMenu = { title: string; onClick: () => void }`.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @simplysm/angular โ ๋ชจ๋ฌยทํ ์คํธยทBusyยท์ธ์ (์ค๋ฒ๋ ์ด)
|
|
2
|
+
|
|
3
|
+
ํ๋ฉด ์์ ๋์ฐ๋ ํผ๋๋ฐฑยท์ค๋ฒ๋ ์ด ๋ฌถ์. ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ชจ๋ฌ/ํ ์คํธ๋ฅผ ๋์ฐ๊ฑฐ๋ ์์
์งํ ํ์, ํ๋ฉด ์ธ์/PDF ๊ฐ ํ์ํ ๋ ํจ๊ป ์ฝํ.
|
|
4
|
+
|
|
5
|
+
## SdModalProvider
|
|
6
|
+
|
|
7
|
+
`@Injectable({providedIn:"root"})`. ์ปดํฌ๋ํธ๋ฅผ ๋ชจ๋ฌ๋ก ๋์ ์์ฑ.
|
|
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 โ ์ฒซ ์ปจํธ๋กค ์๋ ํฌ์ปค์ค ๋นํ์ฑ(๋ค์ด์ผ๋ก๊ทธ ์์ฒด์ ํฌ์ปค์ค).
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const result = await sdModal.showAsync(
|
|
37
|
+
{ title: "์ฌ์ฉ์ ์ ํ", type: UserSelectModal, inputs: { teamId } },
|
|
38
|
+
{ resizable: true, key: "user-select" },
|
|
39
|
+
);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## SdModal
|
|
43
|
+
|
|
44
|
+
`<sd-modal>` โ `SdModalProvider` ๊ฐ ๋ด๋ถ์ ์ผ๋ก ์์ฑํ๋ ์
ธ ์ปดํฌ๋ํธ. ์ง์ ํ
ํ๋ฆฟ์ ์ฐ๊ธฐ๋ณด๋ค provider ๊ฒฝ์ ๊ถ์ฅ. ์ `SdModalOptions` ์ ๋์ผํ input ๋ค + `open = model(false)`, `closeRequest = output<void>()`, `title`/`actionTplRef` input ๋ณด์ .
|
|
45
|
+
|
|
46
|
+
## SdActivatedModalProvider
|
|
47
|
+
|
|
48
|
+
๋ชจ๋ฌ ์ปจํ
์ธ ์ปดํฌ๋ํธ ๋ด๋ถ์์ inject. ํ์ฌ ๋ชจ๋ฌ ์ ์ด.
|
|
49
|
+
- modalComponent: Signal<SdModal | undefined> / contentComponent: Signal<T | undefined>.
|
|
50
|
+
- canDeactivateFn: () => boolean โ ๋ซ๊ธฐ ์ฐจ๋จ ํ์ . `setupCanDeactivate` ๊ฐ ์ค์ . true ๊ฐ ์๋๋ฉด ๋ฐฐ๊ฒฝ/ESC/๋ฒํผ ๋ซ๊ธฐ ๋ฌด์.
|
|
51
|
+
|
|
52
|
+
## SdPromptModal / SdConfirmModal
|
|
53
|
+
|
|
54
|
+
provider ์ ๋ฐ๋ก ๋๊ธธ ์ ์๋ ๋ฒ์ฉ ๋ชจ๋ฌ ์ปดํฌ๋ํธ.
|
|
55
|
+
- SdPromptModal: `SdModalContentDef<string>`. `message = input.required<string>()`. ํ
์คํธ ์
๋ ฅ(ํ์) ํ ํ์ธ ์ ์
๋ ฅ๊ฐ, ์ทจ์ ์ undefined emit.
|
|
56
|
+
- SdConfirmModal: `SdModalContentDef<boolean>`. `message = input.required<string>()`. ํ์ธ ์ `true`, ์ทจ์ ์ undefined emit.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
const name = await sdModal.showAsync({ title: "์ด๋ฆ", type: SdPromptModal, inputs: { message: "์ด๋ฆ?" } });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## SdToastProvider
|
|
63
|
+
|
|
64
|
+
`@Injectable({providedIn:"root"})`. ํ ์คํธ ์๋ฆผ.
|
|
65
|
+
|
|
66
|
+
- info/success/warning/danger(message: string, useProgress?: boolean) โ ์ฌ๊ฐ๋๋ณ ํ ์คํธ. useProgress=true ๋ฉด ์งํ๋ฅ ํ ์คํธ๊ฐ ๋์ด `WritableSignal<number>`(0~100) ๋ฐํ, 100 ๋๋ฌ 1์ด ๋ค ์๋ ํด์ . useProgress ์๊ฑฐ๋ false ๋ฉด 3์ด ํ ์๋ ํด์ (ํธ๋ฒ ์ค ์ง์ฐ), ๋ฐํ void.
|
|
67
|
+
- notify<T>(input: SdToastInput<T>): Promise<close๊ฒฐ๊ณผ | undefined> โ ์ปค์คํ
์ปดํฌ๋ํธ ํ ์คํธ. `SdToastInput<T>` = `{ type: Type<T>; inputs }`(์ปจํ
์ธ ๋ `SdToastContentDef<O>` = `{ close: OutputEmitterRef<O|undefined> }` ๊ตฌํ). 5์ด ํ ์๋ ํด์ .
|
|
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 โ ํ ์คํธ ํ์ ์ง์ ์ฝ๋ฐฑ(์: ์ฌ์ด๋).
|
|
72
|
+
|
|
73
|
+
ํ์
: `SdToastSeverity = "info"|"success"|"warning"|"danger"`, `SdToastTheme = "primary"|"secondary"|SdToastSeverity|"gray"|"blue-gray"`.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
await sdToast.try(async () => { await save(); sdToast.success("์ ์ฅ๋จ"); });
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## SdToast / SdToastContainer
|
|
80
|
+
|
|
81
|
+
`SdToastProvider` ๊ฐ ๋ด๋ถ ์์ฑ. ์ง์ ์ธ ์ผ ๋๋ฌพ. SdToast: `open`/`progress`/`message` model, `useProgress`/`theme` input, severity ์ ๋ฐ๋ผ `role`/`aria-live` ์๋(infoยทsuccess=status/polite, warningยทdanger=alert/assertive). SdToastContainer: `overlap` input.
|
|
82
|
+
|
|
83
|
+
## SdBusyProvider
|
|
84
|
+
|
|
85
|
+
`@Injectable({providedIn:"root"})`. ์ ์ญ ๋ก๋ฉ ํ์.
|
|
86
|
+
- globalBusyCount: WritableSignal<number> โ >0 ์ด๋ฉด ์ ์ญ busy ์ค๋ฒ๋ ์ด ํ์(๋ผ์ฐํ
ยท์ธ์๊ฐ ์๋ ์ฆ๊ฐ). ์ง์ ์์
๊ฐ์ ๋ update ๋ก ์ฆ๊ฐ.
|
|
87
|
+
- type: WritableSignal<SdBusyType> โ ๊ธฐ๋ณธ ํ์ ์ ํ. `SdBusyType = "spinner"|"bar"|"cube"`.
|
|
88
|
+
|
|
89
|
+
## SdBusyContainer
|
|
90
|
+
|
|
91
|
+
`<sd-busy-container [busy]="..." />` โ ์์ญ ๋จ์ busy ์ค๋ฒ๋ ์ด. ๋ด๋ถ ์ปจํ
์ธ ์์ ํ์.
|
|
92
|
+
- busy: boolean โ true ๋ฉด ์ค๋ฒ๋ ์ด ํ์ + ์์ญ ๋ด ํค์
๋ ฅ ์ฐจ๋จ.
|
|
93
|
+
- message?: string โ ํ์ ๋ฉ์์ง.
|
|
94
|
+
- type?: "spinner"|"bar"|"cube" โ ๋ฏธ์ง์ ์ `SdBusyProvider.type` ์ฌ์ฉ.
|
|
95
|
+
- progressPercent?: number โ ์ง์ ์ ์๋จ ์งํ ๋ฐ ํ์(0~100).
|
|
96
|
+
|
|
97
|
+
## SdPrintProvider
|
|
98
|
+
|
|
99
|
+
`@Injectable({providedIn:"root"})`. ์ปดํฌ๋ํธ๋ฅผ ์ธ์/PDF ๋ก ๋ ๋.
|
|
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.
|
|
102
|
+
|
|
103
|
+
`SdPrintInput<T, X>` = `{ type: Type<T>; inputs }`. ์ปจํ
์ธ ๋ `SdPrint`(= `{ initialized: Signal<boolean>; _optionalPrintInputs?: string }`) ๊ตฌํ. `initialized()` ๊ฐ true ๊ฐ ๋๊ณ ์ด๋ฏธ์ง ๋ก๋ ์๋ฃ๊น์ง ๋๊ธฐ ํ ์ธ์.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @simplysm/angular โ ๋ผ์ฐํ
/ ์ฑ ๊ตฌ์กฐ(๋ฉ๋ดยท๊ถํ)
|
|
2
|
+
|
|
3
|
+
ํ์ฌ ํ์ด์ง ์๋ณยท๋ทฐ ์ ๋ชฉ/ํ์
ํ์ , ๋ผ์ฐํฐ ๋งํฌ, ์ฑ ๋ฉ๋ด/๊ถํ ํธ๋ฆฌ ๊ตฌ์ฑ์ ๋ค๋ฃฐ ๋ ํจ๊ป ์ฝํ. ์ฑ ๊ตฌ์กฐ ๋ฐ์ดํฐ ์๋ณธ์ `@simplysm/service-common` ์ `AppStructureItem`.
|
|
4
|
+
|
|
5
|
+
## injectFullPageCodeSignal
|
|
6
|
+
|
|
7
|
+
`injectFullPageCodeSignal(): Signal<string>` โ ํ์ฌ ๋ผ์ฐํฐ URL ์์ ์ 2 ์ธ๊ทธ๋จผํธ(`/home` ๋ฑ)๋ฅผ ์ ์ธํ ๋๋จธ์ง๋ฅผ `.` ์ผ๋ก ์ด์ ํ์ด์ง ์ฝ๋. ๋ค๋น๊ฒ์ด์
์ข
๋ฃ๋ง๋ค ๊ฐฑ์ . ๋ฉ๋ด ์ ํ ํ์ยท๋ทฐ ์ ๋ชฉ ์กฐํ์ ์ฌ์ฉ.
|
|
8
|
+
|
|
9
|
+
## injectCurrentPageCodeSignal
|
|
10
|
+
|
|
11
|
+
`injectCurrentPageCodeSignal(): Signal<string> | undefined` โ ํ์ฌ `ActivatedRoute` ์ pathFromRoot ๊ธฐ์ค ์ฝ๋(์ค์ฒฉ outlet/๋ชจ๋ฌ ์์์ ์๊ธฐ ์์ ๊ฒฝ๋ก). ActivatedRoute ์์ผ๋ฉด undefined. fullPageCode ์ ๋น๊ตํด page/control ํ์ ์ ์ฌ์ฉ.
|
|
12
|
+
|
|
13
|
+
## injectViewTitleSignal
|
|
14
|
+
|
|
15
|
+
`injectViewTitleSignal(): Signal<string>` โ ๋ชจ๋ฌ ์์ด๋ฉด ๋ชจ๋ฌ ์ ๋ชฉ, ์๋๋ฉด ์ฑ ๊ตฌ์กฐ์์ ํ์ฌ ํ์ด์ง ์ฝ๋๋ก ์ฐพ์ ์ ๋ชฉ(`[์์ > ์์] ํ์ฌ`). ๋ชป ์ฐพ์ผ๋ฉด `""`. ํ๋ฉด ์ปจํ
์ด๋ ์ ๋ชฉ ํ์์ ์ฌ์ฉ.
|
|
16
|
+
|
|
17
|
+
## injectViewTypeSignal
|
|
18
|
+
|
|
19
|
+
`injectViewTypeSignal(): Signal<SdViewType>` โ ํ์ฌ ์ปดํฌ๋ํธ๊ฐ ์ด๋ค ๋งฅ๋ฝ์ผ๋ก ๋ ์๋์ง ํ์ . `SdViewType = "page"|"modal"|"control"`. ๋ชจ๋ฌ ์์ด๋ฉด "page"๊ฐ ์๋ "modal", ๋ผ์ฐํธ์ ํ์ด์ง ์ปดํฌ๋ํธ๋ก ์ง์ ๋ ์๊ณ fullPageCode===currPageCode ๋ฉด "page", ๊ทธ ์ธ "control"(๋ค๋ฅธ ํ๋ฉด์ ๋ฐํ ์ฌ์ฌ์ฉ ์ปดํฌ๋ํธ). CRUD ์ปจํ
์ด๋์ `viewType` input ์ ๊ทธ๋๋ก ์ ๋ฌ.
|
|
20
|
+
|
|
21
|
+
## setupCanDeactivate
|
|
22
|
+
|
|
23
|
+
`setupCanDeactivate(fn: () => boolean): void` โ ์ปดํฌ๋ํธ ๋ด ํธ์ถ. ๋ชจ๋ฌ ์์ด๋ฉด `SdActivatedModalProvider.canDeactivateFn` ์, ๋ผ์ฐํธ๋ฉด ํด๋น route ์ `canDeactivate` ๊ฐ๋์ fn ์ ๋ฑ๋ก(์ปดํฌ๋ํธ ํ๊ดด ์ ํด์ ). fn ์ด false ๋ฉด ์ดํ/๋ซ๊ธฐ ์ฐจ๋จ. ๋ฏธ์ ์ฅ ๋ณ๊ฒฝ ๋ณดํธ์ ์ฌ์ฉ.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
setupCanDeactivate(() => !this.dirty() || confirm("์ ์ฅํ์ง ์๊ณ ๋๊ฐ๊น์?"));
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## SdRouterLink
|
|
30
|
+
|
|
31
|
+
`[sdRouterLink]="option"` ๋๋ ํฐ๋ธ. ํด๋ฆญ ์ option ์ผ๋ก ๋ผ์ฐํฐ ์ด๋(๋๋ ์ ์ฐฝ).
|
|
32
|
+
- option: `{ link: string; params?; window?: {width?;height?}; outletName?: string; queryParams? } | undefined` โ undefined ๋ฉด ๋์ ์์(์ปค์๋ ๊ธฐ๋ณธ). ํ์ฌ๊ฐ window ๋ชจ๋๊ฑฐ๋ Ctrl/Shift+ํด๋ฆญ์ด๋ฉด ์ ์ฐฝ์ผ๋ก, outletName ์์ผ๋ฉด named outlet ์ผ๋ก ์ด๋. Alt+ํด๋ฆญ์ ๋ฌด์.
|
|
33
|
+
|
|
34
|
+
## SdNavigateWindowProvider
|
|
35
|
+
|
|
36
|
+
`@Injectable({providedIn:"root"})`. ์ ์ฐฝ/ํ์
๋ค๋น๊ฒ์ด์
.
|
|
37
|
+
- isWindow: boolean โ ํ์ฌ URL ํด์์ `window=true` ๊ฐ ์๋์ง(ํ์
์ผ๋ก ์ด๋ฆฐ ์ฐฝ์ธ์ง).
|
|
38
|
+
- open(navigate: string, params?, features?): void โ window ๋ชจ๋๊ฑฐ๋ features ์ง์ ์ `window.open` ํ์
(๋ซํ ๋ ๋ถ๋ชจ์ ํจ๊ป ์ ๋ฆฌ), ์๋๋ฉด `_blank` ํญ.
|
|
39
|
+
|
|
40
|
+
## getMenuRouterLinkOption / getIsMenuSelected
|
|
41
|
+
|
|
42
|
+
- `getMenuRouterLinkOption(menu: SdMenu): { link; queryParams } | undefined` โ leaf ๋ฉ๋ด(children/url ์์)๋ฉด `/home/<์ฝ๋์ฒด์ธ>` ๋งํฌ + ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ ์ต์
, ๊ทธ ์ธ undefined. `SdRouterLink` ์ ๋ฐ๋ก ์ ๋ฌ.
|
|
43
|
+
- `getIsMenuSelected(menu, fullPageCode, customFn?): boolean` โ customFn ์์ผ๋ฉด ๊ทธ ๊ฒฐ๊ณผ, ์์ผ๋ฉด `fullPageCode === menu.codeChain.join(".")`. ๋ฉ๋ด ์ ํ ๊ฐ์กฐ์ ์ฌ์ฉ.
|
|
44
|
+
|
|
45
|
+
## SdAppStructureProvider<TModule>
|
|
46
|
+
|
|
47
|
+
`@Injectable({providedIn:"root"})`. ์ฑ ๋ฉ๋ดยท๊ถํ ํธ๋ฆฌ์ ๋จ์ผ ์์ค.
|
|
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) โ ํด๋น ์ฝ๋๋ค์์ ๋ณด์ ํ ๊ถํ ํค ๋ชฉ๋ก.
|
|
58
|
+
|
|
59
|
+
`injectPermsSignal<K>(viewCodes: string[], keys: K[]): Signal<K[]>` โ ํ์ฌ ๋ณด์ ๊ถํ ํค๋ฅผ computed signal ๋ก. ํ๋ฉด์์ ํธ์ง/์ฌ์ฉ ๊ถํ ๋ถ๊ธฐ์ ์ฌ์ฉ.
|
|
60
|
+
|
|
61
|
+
## SdAppStructureUtils
|
|
62
|
+
|
|
63
|
+
`abstract class`. `SdAppStructureProvider` ๊ฐ ๋ด๋ถ ์ฌ์ฉํ๋ ์ ์ ์ ํธ ๋ชจ์(์ง์ ํธ์ถ ๊ฐ๋ฅ): `getMenus`/`getFlatMenus`/`getPermissions`/`getFlatPermissions`/`getTitleByFullCode`/`findTitleByFullCode`/`getItemChainByFullCode`/`getPermsByFullCode`. ์๊ทธ๋์ฒ๋ provider ๋ฉ์๋์ ๋์(์ถ๊ฐ๋ก items/usableModules/permRecord ๋ฅผ ์ธ์๋ก ๋ฐ์).
|
|
64
|
+
|
|
65
|
+
## ํ์
|
|
66
|
+
|
|
67
|
+
- **SdMenu** โ `{ title; codeChain: string[]; url?; icon?; children?: SdMenu[] }`. ๋ฉ๋ด ํธ๋ฆฌ ๋
ธ๋.
|
|
68
|
+
- **SdFlatMenu<TModule>** โ `{ titleChain: string[]; codeChain: string[]; modulesChain: TModule[][] }`. ํํ ๋ฉ๋ด.
|
|
69
|
+
- **SdPermission<TModule>** โ `{ title; codeChain; modules; perms: ("use"|"edit")[]|undefined; children }`. ๊ถํ ํธ๋ฆฌ ๋
ธ๋(๊ถํํ ์
๋ ฅ).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @simplysm/angular โ ์ ํยท์ ๋ ฌยทํ์ฅ ๋งค๋์ (use* ์ปดํฌ์ ๋ธ)
|
|
2
|
+
|
|
3
|
+
์ปค์คํ
๋ฆฌ์คํธ/๊ทธ๋ฆฌ๋ ์ปดํฌ๋ํธ์ ์ ํยท์ ๋ ฌยทํธ๋ฆฌ ํ์ฅ ๋ก์ง์ ๋ถ์ด๋ ํจ์ํ ์ปดํฌ์ ๋ธ. signal ๋ฐ์ธ๋ฉ์ ๋๊ธฐ๋ฉด ํ์ signal ๊ณผ ์กฐ์ ๋ฉ์๋๋ฅผ ๋๋ ค์ค. `sd-sheet` ๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ด๋ค์ ์กฐํฉํจ.
|
|
4
|
+
|
|
5
|
+
## useSelectionManager<TItem, TKey>
|
|
6
|
+
|
|
7
|
+
๋ค์ค/๋จ์ผ ์ ํ ์ํ ๊ด๋ฆฌ.
|
|
8
|
+
- options: `{ displayItems: Signal<TItem[]>; selectedKeys: WritableSignal<TKey[]>; selectMode: Signal<"single"|"multi"|undefined>; getItemSelectableFn: Signal<((item) => boolean|string)|undefined>; trackByFn: Signal<(item,index) => TKey> }` โ selectMode ๋ฏธ์ง์ ์ด๋ฉด ์ ํ ๋นํ์ฑ, getItemSelectableFn ์ด string ๋ฐํ ์ ๊ทธ ์ฌ์ ๋ก ๋ถ๊ฐ, trackByFn ์ผ๋ก ํค ๋น๊ต(`obj.equal` ๊น์ ๋น๊ต).
|
|
9
|
+
- ๋ฐํ: `hasSelectable`/`isAllSelected`(Signal), `getSelectable(item): true|string|undefined`, `getCanChangeFn(item)`, `select`/`deselect`/`toggle`/`toggleAll`/`isSelected`. single ์ 1๊ฐ๋ก ๊ต์ฒด, multi ๋ ๋์ .
|
|
10
|
+
|
|
11
|
+
## useSortingManager
|
|
12
|
+
|
|
13
|
+
ํค๋ ํด๋ฆญ ์ ๋ ฌ ์ํ + ์ ๋ ฌ ์คํ.
|
|
14
|
+
- options: `{ sorts: WritableSignal<SortingDef[]> }`.
|
|
15
|
+
- ๋ฐํ: `defMap: Signal<Map<key, { indexText?; desc }>>`(๋ค์ค ์ ๋ ฌ ์ ์๋ฒ ํ์), `toggle(key, multiple)`(๋จ์ผ/๋ค์ค ํ ๊ธ: ์์โ์ค๋ฆ์ฐจ์โ๋ด๋ฆผ์ฐจ์โํด์ ์ํ), `sort<T>(items): T[]`(null ์ ์, ๋ฌธ์์ด localeCompare, ์ซ์ ์ฐจ์ด ๊ธฐ์ค).
|
|
16
|
+
- **SortingDef** โ `{ key: string; desc: boolean }`. ์ ๋ ฌ 1๊ฑด.
|
|
17
|
+
|
|
18
|
+
## useExpandingManager<T>
|
|
19
|
+
|
|
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 }`. ํญ๋ชฉ์ ํธ๋ฆฌ ์์น ์ ์.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const sorting = useSortingManager({ sorts });
|
|
27
|
+
const selection = useSelectionManager({ displayItems, selectedKeys, selectMode, getItemSelectableFn, trackByFn });
|
|
28
|
+
```
|