diff --git a/.eslintignore b/.eslintignore
index 5e6019cab8..cec0ddf16e 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -38,3 +38,5 @@ node_modules/
# yarn v2
.yarn
+
+**/src/index.html
diff --git a/.eslintrc.js b/.eslintrc.js
index 4817296b7b..f766eb93d5 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -20,7 +20,6 @@ module.exports = {
],
rules: {
'prettier/prettier': ['error', prettierConfig],
- 'jsdoc/newline-after-description': 1,
'@angular-eslint/component-selector': [
'off',
{
@@ -171,8 +170,7 @@ module.exports = {
'@angular-eslint/no-input-rename': 'off',
'prefer-const': 'off',
'max-len': 'off',
- 'deprecation/deprecation': 'warn',
- 'jsdoc/newline-after-description': 'off'
+ 'deprecation/deprecation': 'warn'
}
},
{
diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml
index 527479dac2..066084e65e 100644
--- a/.github/workflows/deploy-site.yml
+++ b/.github/workflows/deploy-site.yml
@@ -16,7 +16,7 @@ jobs:
- name: build
run: |
- yarn run site:build:ssr
+ yarn run site:build
cp ./src/dist/browser/index.html ./src/dist/browser/404.html
cp ./Dockerfile.docs ./src/dist/browser/Dockerfile.docs
cp -r ./_nginx/ ./src/dist/browser/_nginx
diff --git a/.nvmrc b/.nvmrc
index 3e558c9b3c..d939939b25 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-18.12.0
+18.13.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ec1a6aa4e..e9b0da4b90 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,126 +1,54 @@
-## [16.4.2](https://github.com/ng-alain/delon/compare/16.4.1...16.4.2) (2023-10-26)
-
-
-### Features
-
-* **abc:qr:** will be removed in 18.0.0 ([#1667](https://github.com/ng-alain/delon/issues/1667)) ([5a7bdd4](https://github.com/ng-alain/delon/commit/5a7bdd42226960c8140397b1a1a377fb87ca725e))
-
-
-### Performance Improvements
-
-* **theme:modal:** perf code ([#1671](https://github.com/ng-alain/delon/issues/1671)) ([341ff56](https://github.com/ng-alain/delon/commit/341ff56dc67d65d5a545f124a51938366c7722dc))
-
-
-
-## [16.4.1](https://github.com/ng-alain/delon/compare/16.4.0...16.4.1) (2023-10-20)
-
-
-### Bug Fixes
-
-* temp downgrade `ng-zorro-antd` to `16.2.0` ([#1663](https://github.com/ng-alain/delon/issues/1663)) ([d3da2b7](https://github.com/ng-alain/delon/commit/d3da2b753c1ebed589ba51e9f184270508eb0ff9))
-
-
-
-# [16.4.0](https://github.com/ng-alain/delon/compare/16.3.0...16.4.0) (2023-10-19)
-
-
-### Bug Fixes
-
-* **abc:onboarding:** correct dark style ([#1650](https://github.com/ng-alain/delon/issues/1650)) ([7a21933](https://github.com/ng-alain/delon/commit/7a219338660bfbbe18f5ee35ccd1caaabf6e40a4))
-* **abc:st:** correct width misalignment in export excel ([#1655](https://github.com/ng-alain/delon/issues/1655)) ([76db16c](https://github.com/ng-alain/delon/commit/76db16c526057138e470244ccef1cd67e853ccc9))
-* **cli:** missing `fileReplacements` in Angular16 ([#1658](https://github.com/ng-alain/delon/issues/1658)) ([c5b46ee](https://github.com/ng-alain/delon/commit/c5b46ee50a3741dba0f0731f2f2326e9fd47b6cd))
-* **form:array:** fix invalid ui in `ui` schema ([#1657](https://github.com/ng-alain/delon/issues/1657)) ([6b3c711](https://github.com/ng-alain/delon/commit/6b3c711f2f56cbf93f2078b6d83a751b9bdd8bde))
-* **form:select:** correct trigger onSearch in reset when set value ([#1660](https://github.com/ng-alain/delon/issues/1660)) ([fa234cd](https://github.com/ng-alain/delon/commit/fa234cd2e7a127e4df79a82b6965a03220497143))
-* **form:** fix `visibleIf` to correctly trigger `reset` ([#1653](https://github.com/ng-alain/delon/issues/1653)) ([d80f8fb](https://github.com/ng-alain/delon/commit/d80f8fba87659be8099962817cbd17422a5ae249))
-* **form:** fix render UI can't be inherit ([#1661](https://github.com/ng-alain/delon/issues/1661)) ([ee96aaa](https://github.com/ng-alain/delon/commit/ee96aaac047dfa990aa0ffc2d94808939c3311c5))
-
-
-### Features
-
-* **abc:onboarding:** add `key` ([#1652](https://github.com/ng-alain/delon/issues/1652)) ([5edaa97](https://github.com/ng-alain/delon/commit/5edaa970f508c402d94843bb8260a5d72bdb5870))
-* **abc:theme:** add `.tag-wrap-list-spacing` class ([#1647](https://github.com/ng-alain/delon/issues/1647)) ([5da4ecb](https://github.com/ng-alain/delon/commit/5da4ecb766c9195609899dbaa543b5eefad82f01))
-* add provide function ([#1654](https://github.com/ng-alain/delon/issues/1654)) ([c8779f4](https://github.com/ng-alain/delon/commit/c8779f41234364bf8690dcf9c9aa5d90c48eadcd))
-
-
-
-# [16.3.0](https://github.com/ng-alain/delon/compare/16.2.1...16.3.0) (2023-09-01)
-
-
-### Bug Fixes
-
-* **abc:pdf:** fix ignore dependency `pdfjs-dist` ([#1641](https://github.com/ng-alain/delon/issues/1641)) ([b987bab](https://github.com/ng-alain/delon/commit/b987baba6035eb60872c4ee48198568df140869c))
-* **form:select:** fix ignore reset option data when set `onSearch` ([#1644](https://github.com/ng-alain/delon/issues/1644)) ([1f8def7](https://github.com/ng-alain/delon/commit/1f8def70856c091ed677cbd47aed7ca230a2aa79))
-* **theme:http:** fix missing `content` of `HttpOptions` ([#1640](https://github.com/ng-alain/delon/issues/1640)) ([28eeceb](https://github.com/ng-alain/delon/commit/28eecebd7ab71a1b9a8345c0af1ebe22fd3bc1a6))
-
-
-### Features
-
-* **abc:cell:** add `cell` component ([#1530](https://github.com/ng-alain/delon/issues/1530)) ([26023ca](https://github.com/ng-alain/delon/commit/26023cac7a91cae5383cfffd26d44fba6a95fb9f))
-* **abc:page-header:** add `titleSub` property ([#1643](https://github.com/ng-alain/delon/issues/1643)) ([79e229f](https://github.com/ng-alain/delon/commit/79e229f5c1b509dd463c48e4a82b361e5d923920))
-* **abc:st:** add `tooltip` in tag or badge ([#1634](https://github.com/ng-alain/delon/issues/1634)) ([0e9006e](https://github.com/ng-alain/delon/commit/0e9006e5b9fd30092b5a808f9b3d8012fd3a060c))
-* **abc:sv:** add `bordered` property ([#1628](https://github.com/ng-alain/delon/issues/1628)) ([ccfa5e1](https://github.com/ng-alain/delon/commit/ccfa5e1d6f5cf1d3f9bc5360bc2e373604ae22a2))
-* **cli:** add `bindToComponentInputs` of `ng add` ([#1630](https://github.com/ng-alain/delon/issues/1630)) ([9717d9d](https://github.com/ng-alain/delon/commit/9717d9dd4ee1d5ab1526616a99da7b70e8664bd2))
-* **theme:drawer:** add `closeAll`, `openDrawers` method ([#1627](https://github.com/ng-alain/delon/issues/1627)) ([bab3d0c](https://github.com/ng-alain/delon/commit/bab3d0c3c648d933784c4623b2714ac227219c5c))
-* **theme:modal:** add size support percentage ([#1626](https://github.com/ng-alain/delon/issues/1626)) ([8b52a08](https://github.com/ng-alain/delon/commit/8b52a08d82378a42e06c316757e19e5434e109dc))
-
-
-
-## [16.2.1](https://github.com/ng-alain/delon/compare/16.2.0...16.2.1) (2023-08-06)
-
-
-### Bug Fixes
-
-* **abc:reuse-tab:** fix missing export cache ([#1633](https://github.com/ng-alain/delon/issues/1633)) ([2c7def7](https://github.com/ng-alain/delon/commit/2c7def75a5b219a58319ab129407f4058010fc44))
-* **auth:cookie:** fix cookie expires ([#1636](https://github.com/ng-alain/delon/issues/1636)) ([eca7bcb](https://github.com/ng-alain/delon/commit/eca7bcb2e7ba43b3a4b3bb4ab3cd17a7d762a967))
-* **theme:table:** fix table image spacing ([#1629](https://github.com/ng-alain/delon/issues/1629)) ([994e2be](https://github.com/ng-alain/delon/commit/994e2be90354a55a538ed1b55c413b8ce8cde872))
-* **theme:title:** fix ignore empty title ([#1638](https://github.com/ng-alain/delon/issues/1638)) ([c7bf339](https://github.com/ng-alain/delon/commit/c7bf339ee417a3b238cdb7dc18cccd1fe99a6c88))
-
-
-
-# [16.2.0](https://github.com/ng-alain/delon/compare/16.1.1...16.2.0) (2023-07-21)
-
-
-### Bug Fixes
-
-* **abc:onboarding:** fix `ComponentFactoryResolver` ([#1624](https://github.com/ng-alain/delon/issues/1624)) ([ae065c2](https://github.com/ng-alain/delon/commit/ae065c21e9ba1ea0d56bae9ceb1e44b7bbb9b0fb))
-* **chat:timeline:** fix `y2` to be optional ([#1622](https://github.com/ng-alain/delon/issues/1622)) ([b565ddf](https://github.com/ng-alain/delon/commit/b565ddfdd7872a43f9fd3b3a1fd33d739f08074c))
-* **cli:** remove `skipTests` from generating module ([#1616](https://github.com/ng-alain/delon/issues/1616)) ([0da83f8](https://github.com/ng-alain/delon/commit/0da83f83b90ea5a367d35c6761554d7ebc07bfd0))
-* fix misalignment of `col` placeholders in `se`, `sv`, `sg` ([#1617](https://github.com/ng-alain/delon/issues/1617)) ([83b08c9](https://github.com/ng-alain/delon/commit/83b08c95ba803cf29e0f10bb354ae4f9170b2295))
-* **theme:modal:** removed `nzComponentParams` ([#1615](https://github.com/ng-alain/delon/issues/1615)) ([45863a1](https://github.com/ng-alain/delon/commit/45863a1d62e5751416321cb1d591faf820bb82d3))
-
-
-### Features
-
-* **abc:st:** add `onCell`, support colSpan and rowSpan merging ([#1613](https://github.com/ng-alain/delon/issues/1613)) ([9ab109e](https://github.com/ng-alain/delon/commit/9ab109e8f99fb1bd4e5b4e99b0b814bf34f0b4ac))
-* **abc:st:** button support function method of `icon`, `className` ([#1618](https://github.com/ng-alain/delon/issues/1618)) ([6bf27da](https://github.com/ng-alain/delon/commit/6bf27dac696818ff78b0ee955333e308597c968b))
-* **theme:layout-default:** add `fetching` property ([#1614](https://github.com/ng-alain/delon/issues/1614)) ([8446da6](https://github.com/ng-alain/delon/commit/8446da6fdd10d07f2e917d91830d95e1c81d2622))
-
-
-
-## [16.1.1](https://github.com/ng-alain/delon/compare/16.0.1...16.1.1) (2023-07-16)
-
-
-### Bug Fixes
-
-* **abc:reuse-tab:** fix cache ([#1611](https://github.com/ng-alain/delon/issues/1611)) ([3185ab8](https://github.com/ng-alain/delon/commit/3185ab8939da0b1eefd900a1a003223ad3eb8dba))
-* **cli:** remove `stylelint-config-prettier` ([#1606](https://github.com/ng-alain/delon/issues/1606)) ([2ecc28b](https://github.com/ng-alain/delon/commit/2ecc28b53773d9b5215ebd720be4ead55d78c705))
-* **theme:** fix ant-btn preserve white spaces when is link type ([#1605](https://github.com/ng-alain/delon/issues/1605)) ([0fdd15d](https://github.com/ng-alain/delon/commit/0fdd15dd0922bf6570d38fabd1afc1ca755b87a2))
-
-
-### Features
-
-* **abc:reuse-tab:** support custom cache data ([#1609](https://github.com/ng-alain/delon/issues/1609)) ([11599d9](https://github.com/ng-alain/delon/commit/11599d9566712c707146e4ac299ec6efc2d82b01))
-* **theme:modal:** support drag ([#1607](https://github.com/ng-alain/delon/issues/1607)) ([3cd73f7](https://github.com/ng-alain/delon/commit/3cd73f7f86a76a7ea450f839e9ad359f6afd0da4))
-
-
-## [16.0.1](https://github.com/ng-alain/delon/compare/16.0.0...16.0.1) (2023-06-08)
-
-* fix `ng-zorro-antd` dependency
-
-# [16.0.0](https://github.com/ng-alain/delon/compare/15.2.1...16.0.0) (2023-06-07)
-
-### Bug Fixes
-
-* **abc:st:** fix error row class in fixed column title cell ([#1598](https://github.com/ng-alain/delon/issues/1598)) ([d2bf211](https://github.com/ng-alain/delon/commit/d2bf211a35df8bcbee165b54bcda4b2dcf69c6f0))
-* **form:** fix inheriting references to other of ui ([#1600](https://github.com/ng-alain/delon/issues/1600)) ([a0150e7](https://github.com/ng-alain/delon/commit/a0150e7520376064469cfa5ae0e3394635620022))
+## 17.0.1 (2023-11-26)
+
+* fix(cli): fix node version (#1719) ([df40bb3](https://github.com/ng-alain/delon/commit/df40bb3)), closes [#1719](https://github.com/ng-alain/delon/issues/1719)
+
+
+
+## 17.0.0 (2023-11-26)
+
+* chore: add `typescript.referencesCodeLens.enabled` (#1679) ([4d2d25c](https://github.com/ng-alain/delon/commit/4d2d25c)), closes [#1679](https://github.com/ng-alain/delon/issues/1679)
+* chore: add data theme (#1684) ([d364ec1](https://github.com/ng-alain/delon/commit/d364ec1)), closes [#1684](https://github.com/ng-alain/delon/issues/1684)
+* chore: bump zorro 17.0.1 (#1712) ([4d9f353](https://github.com/ng-alain/delon/commit/4d9f353)), closes [#1712](https://github.com/ng-alain/delon/issues/1712)
+* chore: fix `provideMockConfig` (#1703) ([ae1cc30](https://github.com/ng-alain/delon/commit/ae1cc30)), closes [#1703](https://github.com/ng-alain/delon/issues/1703)
+* chore: fix interceptor (#1710) ([54f4ea3](https://github.com/ng-alain/delon/commit/54f4ea3)), closes [#1710](https://github.com/ng-alain/delon/issues/1710)
+* chore: fix ngDevMode (#1685) ([2803dc8](https://github.com/ng-alain/delon/commit/2803dc8)), closes [#1685](https://github.com/ng-alain/delon/issues/1685)
+* chore: perf mock interceptor (#1713) ([fa4dc94](https://github.com/ng-alain/delon/commit/fa4dc94)), closes [#1713](https://github.com/ng-alain/delon/issues/1713)
+* chore: remove Hotjar script (#1683) ([66e612d](https://github.com/ng-alain/delon/commit/66e612d)), closes [#1683](https://github.com/ng-alain/delon/issues/1683)
+* chore: support standalone of site (#1696) ([1dce440](https://github.com/ng-alain/delon/commit/1dce440)), closes [#1696](https://github.com/ng-alain/delon/issues/1696)
+* chore: type of widget registry items (#1715) ([7045cec](https://github.com/ng-alain/delon/commit/7045cec)), closes [#1715](https://github.com/ng-alain/delon/issues/1715)
+* chore(cli): fix `ng update` (#1714) ([a6c860e](https://github.com/ng-alain/delon/commit/a6c860e)), closes [#1714](https://github.com/ng-alain/delon/issues/1714)
+* chore(theme): add defaultLang (#1705) ([dbc122e](https://github.com/ng-alain/delon/commit/dbc122e)), closes [#1705](https://github.com/ng-alain/delon/issues/1705)
+* chore(theme): add icon (#1706) ([fcbb0a7](https://github.com/ng-alain/delon/commit/fcbb0a7)), closes [#1706](https://github.com/ng-alain/delon/issues/1706)
+* docs: unified NG-ALAIN text mark (#1677) ([491a342](https://github.com/ng-alain/delon/commit/491a342)), closes [#1677](https://github.com/ng-alain/delon/issues/1677)
+* docs: upgrade angualr 17 (#1717) ([0b423c5](https://github.com/ng-alain/delon/commit/0b423c5)), closes [#1717](https://github.com/ng-alain/delon/issues/1717)
+* perf: add `provideDelonMockConfig` (#1695) ([683ab23](https://github.com/ng-alain/delon/commit/683ab23)), closes [#1695](https://github.com/ng-alain/delon/issues/1695)
+* perf(*): support standalone (#1694) ([d6e75a0](https://github.com/ng-alain/delon/commit/d6e75a0)), closes [#1694](https://github.com/ng-alain/delon/issues/1694)
+* perf(*): use control flow (#1716) ([bee524f](https://github.com/ng-alain/delon/commit/bee524f)), closes [#1716](https://github.com/ng-alain/delon/issues/1716)
+* perf(theme): remove forRoot and forChild (#1688) ([d1ed91e](https://github.com/ng-alain/delon/commit/d1ed91e)), closes [#1688](https://github.com/ng-alain/delon/issues/1688)
+* chore(theme:preloader): support ssr (#1699) ([501566b](https://github.com/ng-alain/delon/commit/501566b)), closes [#1699](https://github.com/ng-alain/delon/issues/1699)
+* feat(abc:cell): add `provideCellWidgets` (#1700) ([7ea0daf](https://github.com/ng-alain/delon/commit/7ea0daf)), closes [#1700](https://github.com/ng-alain/delon/issues/1700)
+* feat(abc:reuse-tab): add provide (#1707) ([2f85357](https://github.com/ng-alain/delon/commit/2f85357)), closes [#1707](https://github.com/ng-alain/delon/issues/1707)
+* feat(abc:st): add `provideSTWidgets` (#1701) ([065316a](https://github.com/ng-alain/delon/commit/065316a)), closes [#1701](https://github.com/ng-alain/delon/issues/1701)
+* feat(theme:_httpclient): add `timestampSecond` (#1670) ([051b087](https://github.com/ng-alain/delon/commit/051b087)), closes [#1670](https://github.com/ng-alain/delon/issues/1670)
+* feat(theme:pipe:date): add global config (#1711) ([b3b93fa](https://github.com/ng-alain/delon/commit/b3b93fa)), closes [#1711](https://github.com/ng-alain/delon/issues/1711)
+* perf(cli:update): automatically add @_mock path (#1675) ([d014b54](https://github.com/ng-alain/delon/commit/d014b54)), closes [#1675](https://github.com/ng-alain/delon/issues/1675)
+* perf(theme:preloader): fix loading order issues (#1691) ([f09c324](https://github.com/ng-alain/delon/commit/f09c324)), closes [#1691](https://github.com/ng-alain/delon/issues/1691)
+* style(*): `clean` instead of `rational` of style (#1674) ([d9ea22f](https://github.com/ng-alain/delon/commit/d9ea22f)), closes [#1674](https://github.com/ng-alain/delon/issues/1674)
+* style(*): bump prettier to `3.1.0` (#1708) ([7f9e861](https://github.com/ng-alain/delon/commit/7f9e861)), closes [#1708](https://github.com/ng-alain/delon/issues/1708)
+* style(cli): fix prefer-self-closing-tags error (#1709) ([1abe2d5](https://github.com/ng-alain/delon/commit/1abe2d5)), closes [#1709](https://github.com/ng-alain/delon/issues/1709)
+* feat: add `provideAlainConfig` (#1689) ([b9e0fad](https://github.com/ng-alain/delon/commit/b9e0fad)), closes [#1689](https://github.com/ng-alain/delon/issues/1689)
+* feat(acl): remove `forRoot` (#1690) ([4472d48](https://github.com/ng-alain/delon/commit/4472d48)), closes [#1690](https://github.com/ng-alain/delon/issues/1690)
+* feat(auth): add provide (#1704) ([c0c731b](https://github.com/ng-alain/delon/commit/c0c731b)), closes [#1704](https://github.com/ng-alain/delon/issues/1704)
+* feat(cli): support multiple projects (#1664) ([e5476e2](https://github.com/ng-alain/delon/commit/e5476e2)), closes [#1664](https://github.com/ng-alain/delon/issues/1664)
+* feat(form): add `provideSFConfig` (#1702) ([2404802](https://github.com/ng-alain/delon/commit/2404802)), closes [#1702](https://github.com/ng-alain/delon/issues/1702)
+* feat(mock): add `mockInterceptor` (#1698) ([da051b2](https://github.com/ng-alain/delon/commit/da051b2)), closes [#1698](https://github.com/ng-alain/delon/issues/1698)
+* feat(mock): support asynchronous of response (#1686) ([d7980db](https://github.com/ng-alain/delon/commit/d7980db)), closes [#1686](https://github.com/ng-alain/delon/issues/1686)
+* feat(testing): add `delay` function (#1682) ([f83ea57](https://github.com/ng-alain/delon/commit/f83ea57)), closes [#1682](https://github.com/ng-alain/delon/issues/1682)
+* feat(theme): add `provideAlain` (#1697) ([4311426](https://github.com/ng-alain/delon/commit/4311426)), closes [#1697](https://github.com/ng-alain/delon/issues/1697)
+* fix(theme): corrected menu can't scrolling (#1692) ([2993297](https://github.com/ng-alain/delon/commit/2993297)), closes [#1692](https://github.com/ng-alain/delon/issues/1692)
+* build: remove `networkEnv` plugin instead of `nnrm` (#1680) ([b7dbc68](https://github.com/ng-alain/delon/commit/b7dbc68)), closes [#1680](https://github.com/ng-alain/delon/issues/1680)
+* build: support pnpm and update yarn to `4` (#1678) ([b904b9a](https://github.com/ng-alain/delon/commit/b904b9a)), closes [#1678](https://github.com/ng-alain/delon/issues/1678)
+* build: update angualr 17 (#1687) ([a8fc961](https://github.com/ng-alain/delon/commit/a8fc961)), closes [#1687](https://github.com/ng-alain/delon/issues/1687)
+* refactor(form): refining low-frequency widgets (#1668) ([8ab0e82](https://github.com/ng-alain/delon/commit/8ab0e82)), closes [#1668](https://github.com/ng-alain/delon/issues/1668)
+* ci: update node version (#1681) ([acae2c3](https://github.com/ng-alain/delon/commit/acae2c3)), closes [#1681](https://github.com/ng-alain/delon/issues/1681)
diff --git a/README.md b/README.md
index f7f56178bf..5710239440 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Delon
- Delon is a set of essential modules for [ng-alain](https://ng-alain.com).
+ Delon is a set of essential modules for [NG-ALAIN](https://ng-alain.com).
[![Build Status](https://dev.azure.com/ng-alain/delon/_apis/build/status/delon-CI?branchName=master)](https://dev.azure.com/ng-alain/delon/_build/latest?definitionId=1&branchName=master)
[![Codecov](https://img.shields.io/codecov/c/github/ng-alain/delon.svg?style=flat-square)](https://codecov.io/gh/ng-alain/delon)
diff --git a/_mock/user.ts b/_mock/user.ts
index 60f76717c5..5bc6eb138d 100644
--- a/_mock/user.ts
+++ b/_mock/user.ts
@@ -1,9 +1,7 @@
-import { MockStatusError, MockRequest } from '@delon/mock';
+import { MockStatusError, MockRequest, r } from '@delon/mock';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
// import * as Mock from 'mockjs';
-const r = (min: number, max: number): number => Math.floor(Math.random() * (max - min + 1) + min);
-
export const USERS = {
// 支持值为 Object 和 Array
'GET /users': (req: MockRequest) => {
diff --git a/_screenshot/data.webp b/_screenshot/data.webp
new file mode 100644
index 0000000000..5f8992d5a2
Binary files /dev/null and b/_screenshot/data.webp differ
diff --git a/angular.json b/angular.json
index 66810daee0..a961eabf28 100644
--- a/angular.json
+++ b/angular.json
@@ -21,13 +21,17 @@
"prefix": "app",
"architect": {
"build": {
- "builder": "@angular-devkit/build-angular:browser",
+ "builder": "@angular-devkit/build-angular:application",
"options": {
- "outputPath": "src/dist/browser",
+ "outputPath": "src/dist",
"index": "src/index.html",
- "main": "src/main.ts",
- "tsConfig": "src/tsconfig.json",
- "polyfills": "src/polyfills.ts",
+ "browser": "src/main.ts",
+ "tsConfig": "src/tsconfig.site.json",
+ "polyfills": [
+ "@webcomponents/custom-elements",
+ "@webcomponents/custom-elements/src/native-shim",
+ "zone.js"
+ ],
"assets": [
"src/assets",
"src/manifest.json",
@@ -78,7 +82,14 @@
"date-fns",
"extend",
"aos"
- ]
+ ],
+ "server": "src/main.server.ts",
+ "prerender": {
+ "routesFile": "scripts/site/route-paths.txt"
+ },
+ "ssr": {
+ "entry": "src/server.ts"
+ }
},
"configurations": {
"production": {
@@ -89,16 +100,12 @@
}
],
"outputHashing": "all",
- "serviceWorker": true,
- "ngswConfigPath": "ngsw-config.json"
+ "serviceWorker": "ngsw-config.json"
},
"development": {
- "buildOptimizer": false,
"optimization": false,
- "vendorChunk": true,
"extractLicenses": false,
- "sourceMap": true,
- "namedChunks": true
+ "sourceMap": true
}
},
"defaultConfiguration": "production"
@@ -107,58 +114,13 @@
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
- "browserTarget": "site:build:production"
+ "buildTarget": "site:build:production"
},
"development": {
- "browserTarget": "site:build:development"
+ "buildTarget": "site:build:development"
}
},
"defaultConfiguration": "development"
- },
- "server": {
- "builder": "@angular-devkit/build-angular:server",
- "options": {
- "outputPath": "src/dist/server",
- "main": "./src/server.ts",
- "tsConfig": "src/tsconfig.server.json"
- },
- "configurations": {
- "production": {
- "outputHashing": "media",
- "fileReplacements": [
- {
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
- }
- ],
- "sourceMap": false,
- "optimization": true
- }
- }
- },
- "serve-ssr": {
- "builder": "@nguniversal/builders:ssr-dev-server",
- "options": {
- "browserTarget": "site:build",
- "serverTarget": "site:server"
- },
- "configurations": {
- "production": {
- "browserTarget": "site:build:production",
- "serverTarget": "site:server:production"
- }
- }
- },
- "prerender": {
- "builder": "@nguniversal/builders:prerender",
- "options": {
- "browserTarget": "site:build:production",
- "serverTarget": "site:server:production",
- "routesFile": "scripts/site/route-paths.txt"
- },
- "configurations": {
- "production": {}
- }
}
}
},
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 6f9514cf73..81cd450d63 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -40,7 +40,7 @@ stages:
ACCESS_REPO: $(ACCESS_REPO)
ACCESS_TOKEN: $(ACCESS_TOKEN)
- script: |
- yarn run site:build:ssr
+ yarn run site:build
displayName: 'Build site'
- script: |
export DEPLOY_DOMAIN=https://preview-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-ng-alain-delon.surge.sh
diff --git a/docs/architecture.en-US.md b/docs/architecture.en-US.md
index f0962ab4c6..44afa16295 100644
--- a/docs/architecture.en-US.md
+++ b/docs/architecture.en-US.md
@@ -65,25 +65,22 @@ Schematic diagram of directory structure:
├── _mock # Mock Data rule
├── src
│ ├── app
-│ │ ├── core # Core module
+│ │ ├── core # Core
│ │ │ ├── i18n
│ │ │ ├── net
│ │ │ │ └── default.interceptor.ts # Default HTTP interceptor
│ │ │ ├── services
│ │ │ │ └── startup.service.ts # Initialize project configuration
-│ │ │ └── core.module.ts # Core module file
+│ │ │ └── index.ts # Core index.ts
│ │ ├── layout # Core layout
│ │ ├── routes
│ │ │ ├── ** # Business directory
-│ │ │ ├── routes.module.ts # Service routing module
-│ │ │ └── routes-routing.module.ts # Service routes registration
+│ │ │ └── routes.ts # Service routes registration
│ │ ├── shared # Shared module
-│ │ │ ├── shared-delon.module.ts # @Delon/* import of secondary shared modules
-│ │ │ ├── shared-zorro.module.ts # NG-ZORRO import of secondary shared modules
-│ │ │ └── shared.module.ts # Shared module file
+│ │ │ ├── shared-imports.ts # A collection of frequently shared components
+│ │ │ └── index.ts # Shared index.ts
│ │ ├── app.component.ts # Root component
-│ │ └── app.module.ts # Root module
-│ │ └── global-config.module.ts # @delon & ng-zorro global config
+│ │ └── app.config.ts # Global config
│ ├── assets # Local static resource
│ ├── environments # Environment variable configuration
│ ├── styles # Style directory
@@ -96,9 +93,9 @@ The following is a description and use of each directory and file.
The Mock data rules directory, if you create a project via [Command Line Tools](/cli), you can specify the `--mock` parameter to determine if the Mock function is required.
-**src/app/core/core.module.ts**
+**src/app/core/index.ts**
-The core module will only be imported once. Therefore, core service classes (eg, messages, data access, etc.) that are required for the entire ** business module should exist here.
+Some core business services (for example: messaging, data access, etc.)
**src/app/core/i18n**
@@ -108,7 +105,7 @@ The core module will only be imported once. Therefore, core service classes (eg,
The default interceptor, where you can handle request parameters, request exceptions, business exceptions, and so on.
-**src/app/core/services/startup.service.ts**
+**src/app/core/startup/startup.service.ts**
Useful when you need to execute some remote data (eg application information, user information, etc.) before Angular launches.
@@ -122,13 +119,13 @@ Layout file code, refer to the page structure section.
Business module, all your business code will be here.
-**src/app/shared/shared.module.ts**
+**src/app/shared/index.ts**
-The shared module means that some third-party modules, custom components, and custom instructions that you need to use for the entire business module should exist here. In addition, for @delon & NG-ZORRO, two shared secondary module imports, `shared-delon.module.ts` and` shared-zorro.module.ts`.
+A collection of some frequently shared components, The means that some third-party modules, custom components, and custom instructions that you need to use for the entire business module should exist here. In addition, for @delon & NG-ZORRO, two shared secondary module imports, `shared-delon.module.ts` and` shared-zorro.module.ts`.
-**src/app/global-config.module.ts**
+**src/app/app.config.ts**
-Global configuration for @delon & NG-ZORRO.
+Global configuration for project.
**src/environments**
diff --git a/docs/architecture.zh-CN.md b/docs/architecture.zh-CN.md
index 82dff43793..bba6f58e38 100644
--- a/docs/architecture.zh-CN.md
+++ b/docs/architecture.zh-CN.md
@@ -34,25 +34,22 @@ NG-ALAIN 目标是提供更多通用性业务模块,让开发者更加专注
├── angular.json # Angular 项目配置文件
├── src
│ ├── app
-│ │ ├── core # 核心模块
+│ │ ├── core # 核心
│ │ │ ├── i18n
│ │ │ ├── net
│ │ │ │ └── default.interceptor.ts # 默认HTTP拦截器
│ │ │ ├── services
│ │ │ │ └── startup.service.ts # 初始化项目配置
-│ │ │ └── core.module.ts # 核心模块文件
+│ │ │ └── index.ts # 核心导出
│ │ ├── layout # 通用布局
│ │ ├── routes
│ │ │ ├── ** # 业务目录
-│ │ │ ├── routes.module.ts # 业务路由模块
-│ │ │ └── routes-routing.module.ts # 业务路由注册口
-│ │ ├── shared # 共享模块
-│ │ │ ├── shared-delon.module.ts # @Delon/* 次级共享模块导入
-│ │ │ ├── shared-zorro.module.ts # NG-ZORRO 次级共享模块导入
-│ │ │ └── shared.module.ts # 共享模块文件
+│ │ │ └── routes.ts # 业务路由
+│ │ ├── shared # 共享
+│ │ │ ├── shared-imports.ts # 一些高频率共享组件的集合
+│ │ │ └── index.ts # 共享导出
│ │ ├── app.component.ts # 根组件
-│ │ └── app.module.ts # 根模块
-│ │ └── global-config.module.ts # @delon & ng-zorro 全局配置项
+│ │ └── app.config.ts # 全局配置项
│ ├── assets # 本地静态资源
│ ├── environments # 环境变量配置
│ ├── styles # 样式目录
@@ -65,12 +62,12 @@ NG-ALAIN 目标是提供更多通用性业务模块,让开发者更加专注
|----|----|
| **angular.json** | Angular 工作区及项目的配置文件,参考[Angular文档](https://angular.cn/guide/workspace-config) |
| **_mock** | Mock 数据规则目录,若你通过 [命令行工具](/cli) 创建项目时可以指定 `--mock` 参数决定是否需要 Mock 功能 |
-| **src/app/core/core.module.ts** | 核心模块,只会导入一次。因此,针对整个**业务模块都需要**使用的纯服务类(例如:消息、数据访问等) |
+| **src/app/core/index.ts** | 一些核心业务服务(例如:消息、数据访问等) |
| **src/app/core/i18n** | [国际化](/docs/i18n)数据加载及处理相关类,若你通过 [命令行工具](/cli) 创建项目时可以指定 `-di` 参数决定是否需要国际化支持 |
| **src/app/core/net** | 默认拦截器,你可以在这里统一处理请求参数、请求异常、业务异常等动作 |
-| **src/app/core/services/startup.service.ts** | 当你需要在 Angular 启动前执行一些远程数据(例如:应用信息、用户信息等)时非常有用 |
+| **src/app/core/startup/startup.service.ts** | 当你需要在 Angular 启动前执行一些远程数据(例如:应用信息、用户信息等)时非常有用 |
| **src/app/layout** | 布局目录,包含基础布局、空白布局、用户登录布局 |
| **src/app/routes** | 业务模块,你的所有业务代码都将在这里 |
-| **src/app/shared/shared.module.ts** | 共享模块,指当你需要针对整个**业务模块都需要**使用的一些第三方模块、自定义组件、自定义指令,都应该存在这里。除此之外,针对 @delon & NG-ZORRO 分别构建了 `shared-delon.module.ts`、`shared-zorro.module.ts` 两种次级共享模块的导入。 |
-| **src/app/global-config.module.ts** | 针对 @delon & NG-ZORRO 的全局配置项 |
+| **src/app/shared/index.ts** | 一些高频率共享组件的集合,指当你需要针对整个**业务模块都需要**使用的一些第三方模块、自定义组件、自定义指令,都应该存在这里。除此之外,针对 @delon & NG-ZORRO 分别构建了 `shared-delon.module.ts`、`shared-zorro.module.ts` 两种次级共享模块的导入。 |
+| **src/app/app.config.ts** | 项目全局配置项 |
| **src/environments** | 应用环境变量,包含以下值:`SERVER_URL` 所有HTTP请求的前缀;`production` 是否生产环境;`useHash` 路由是否useHash模式 |
diff --git a/docs/changelog.en-US.md b/docs/changelog.en-US.md
index 1e1502077e..bed499a456 100644
--- a/docs/changelog.en-US.md
+++ b/docs/changelog.en-US.md
@@ -14,127 +14,40 @@ NG-ALAIN strictly follows [Semantic Versioning 2.0.0](http://semver.org/lang/zh-
---
-## [16.4.2](https://github.com/ng-alain/delon/compare/16.4.1...16.4.2) (2023-10-26)
+##
17.0.1 (2023-11-26)
-### Performance Improvements
+* fix(cli): fix node 20 version (#1719) ([df40bb3](https://github.com/ng-alain/delon/commit/df40bb3)), closes [#1719](https://github.com/ng-alain/delon/issues/1719)
-* **theme:modal:** perf code ([#1671](https://github.com/ng-alain/delon/issues/1671)) ([341ff56](https://github.com/ng-alain/delon/commit/341ff56dc67d65d5a545f124a51938366c7722dc))
-* **abc:qr:** will be removed in 18.0.0 ([#1667](https://github.com/ng-alain/delon/issues/1667)) ([5a7bdd4](https://github.com/ng-alain/delon/commit/5a7bdd42226960c8140397b1a1a377fb87ca725e))
+## 17.0.0 (2023-11-26)
+### Breaking Changes
-## [16.4.1](https://github.com/ng-alain/delon/compare/16.4.0...16.4.1) (2023-10-20)
-
-### Bug Fixes
-
-* temp downgrade `ng-zorro-antd` to `16.2.0` ([#1663](https://github.com/ng-alain/delon/issues/1663)) ([d3da2b7](https://github.com/ng-alain/delon/commit/d3da2b753c1ebed589ba51e9f184270508eb0ff9))
-
-
-# [16.4.0](https://github.com/ng-alain/delon/compare/16.3.0...16.4.0) (2023-10-19)
-
-### Bug Fixes
-
-* **abc:onboarding:** correct dark style ([#1650](https://github.com/ng-alain/delon/issues/1650)) ([7a21933](https://github.com/ng-alain/delon/commit/7a219338660bfbbe18f5ee35ccd1caaabf6e40a4))
-* **abc:st:** correct width misalignment in export excel ([#1655](https://github.com/ng-alain/delon/issues/1655)) ([76db16c](https://github.com/ng-alain/delon/commit/76db16c526057138e470244ccef1cd67e853ccc9))
-* **cli:** missing `fileReplacements` in Angular16 ([#1658](https://github.com/ng-alain/delon/issues/1658)) ([c5b46ee](https://github.com/ng-alain/delon/commit/c5b46ee50a3741dba0f0731f2f2326e9fd47b6cd))
-* **form:array:** fix invalid ui in `ui` schema ([#1657](https://github.com/ng-alain/delon/issues/1657)) ([6b3c711](https://github.com/ng-alain/delon/commit/6b3c711f2f56cbf93f2078b6d83a751b9bdd8bde))
-* **form:select:** correct trigger onSearch in reset when set value ([#1660](https://github.com/ng-alain/delon/issues/1660)) ([fa234cd](https://github.com/ng-alain/delon/commit/fa234cd2e7a127e4df79a82b6965a03220497143))
-* **form:** fix `visibleIf` to correctly trigger `reset` ([#1653](https://github.com/ng-alain/delon/issues/1653)) ([d80f8fb](https://github.com/ng-alain/delon/commit/d80f8fba87659be8099962817cbd17422a5ae249))
-* **form:** fix render UI can't be inherit ([#1661](https://github.com/ng-alain/delon/issues/1661)) ([ee96aaa](https://github.com/ng-alain/delon/commit/ee96aaac047dfa990aa0ffc2d94808939c3311c5))
-* **fix(form:widget:object):** fix missing optional of card type ([#1661](https://github.com/ng-alain/delon/issues/1661)) ([ee96aaa](https://github.com/ng-alain/delon/commit/ee96aaac047dfa990aa0ffc2d94808939c3311c5))
-
-### Features
-
-* **abc:onboarding:** add `key` ([#1652](https://github.com/ng-alain/delon/issues/1652)) ([5edaa97](https://github.com/ng-alain/delon/commit/5edaa970f508c402d94843bb8260a5d72bdb5870))
-* **abc:theme:** add `.tag-wrap-list-spacing` class ([#1647](https://github.com/ng-alain/delon/issues/1647)) ([5da4ecb](https://github.com/ng-alain/delon/commit/5da4ecb766c9195609899dbaa543b5eefad82f01))
-* **cli:** add provide function ([#1654](https://github.com/ng-alain/delon/issues/1654)) ([c8779f4](https://github.com/ng-alain/delon/commit/c8779f41234364bf8690dcf9c9aa5d90c48eadcd))
-
-
-# [16.3.0](https://github.com/ng-alain/delon/compare/16.2.1...16.3.0) (2023-09-01)
-
-### SCAFFOLDING
-
-* enabled `bindToComponentInputs` [#2409](https://github.com/ng-alain/ng-alain/pull/2409/files).
-
-### Bug Fixes
-
-* **abc:pdf:** fix ignore dependency `pdfjs-dist` (If you [use local path](https://ng-alain.com/components/pdf) to load the libary, you need to install the dependency yourself. `pdfjs-dist` depends on `canvas`, which may be slow to install dependencies due to environmental factors) ([#1641](https://github.com/ng-alain/delon/issues/1641)) ([#1641](https://github.com/ng-alain/delon/issues/1641)) ([b987bab](https://github.com/ng-alain/delon/commit/b987baba6035eb60872c4ee48198568df140869c))
-* **form:select:** fix ignore reset option data when set `onSearch` ([#1644](https://github.com/ng-alain/delon/issues/1644)) ([1f8def7](https://github.com/ng-alain/delon/commit/1f8def70856c091ed677cbd47aed7ca230a2aa79))
-* **theme:http:** fix missing `content` of `HttpOptions` ([#1640](https://github.com/ng-alain/delon/issues/1640)) ([28eeceb](https://github.com/ng-alain/delon/commit/28eecebd7ab71a1b9a8345c0af1ebe22fd3bc1a6))
-
-### Features
-
-* **abc:cell:** add `cell` component ([#1530](https://github.com/ng-alain/delon/issues/1530)) ([26023ca](https://github.com/ng-alain/delon/commit/26023cac7a91cae5383cfffd26d44fba6a95fb9f))
-* **abc:page-header:** add `titleSub` property ([#1643](https://github.com/ng-alain/delon/issues/1643)) ([79e229f](https://github.com/ng-alain/delon/commit/79e229f5c1b509dd463c48e4a82b361e5d923920))
-* **abc:st:** add `tooltip` in tag or badge ([#1634](https://github.com/ng-alain/delon/issues/1634)) ([0e9006e](https://github.com/ng-alain/delon/commit/0e9006e5b9fd30092b5a808f9b3d8012fd3a060c))
-* **abc:sv:** add `bordered` property ([#1628](https://github.com/ng-alain/delon/issues/1628)) ([ccfa5e1](https://github.com/ng-alain/delon/commit/ccfa5e1d6f5cf1d3f9bc5360bc2e373604ae22a2))
-* **cli:** add `bindToComponentInputs` of `ng add` ([#1630](https://github.com/ng-alain/delon/issues/1630)) ([9717d9d](https://github.com/ng-alain/delon/commit/9717d9dd4ee1d5ab1526616a99da7b70e8664bd2))
-* **theme:drawer:** add `closeAll`, `openDrawers` method ([#1627](https://github.com/ng-alain/delon/issues/1627)) ([bab3d0c](https://github.com/ng-alain/delon/commit/bab3d0c3c648d933784c4623b2714ac227219c5c))
-* **theme:modal:** add size support percentage ([#1626](https://github.com/ng-alain/delon/issues/1626)) ([8b52a08](https://github.com/ng-alain/delon/commit/8b52a08d82378a42e06c316757e19e5434e109dc))
-
-
-## [16.2.1](https://github.com/ng-alain/delon/compare/16.2.0...16.2.1) (2023-08-06)
-
-### Bug Fixes
-
-* **abc:reuse-tab:** fix missing export cache ([#1633](https://github.com/ng-alain/delon/issues/1633)) ([2c7def7](https://github.com/ng-alain/delon/commit/2c7def75a5b219a58319ab129407f4058010fc44))
-* **auth:cookie:** fix cookie expires ([#1636](https://github.com/ng-alain/delon/issues/1636)) ([eca7bcb](https://github.com/ng-alain/delon/commit/eca7bcb2e7ba43b3a4b3bb4ab3cd17a7d762a967))
-* **theme:table:** fix table image spacing ([#1629](https://github.com/ng-alain/delon/issues/1629)) ([994e2be](https://github.com/ng-alain/delon/commit/994e2be90354a55a538ed1b55c413b8ce8cde872))
-* **theme:title:** fix ignore empty title ([#1638](https://github.com/ng-alain/delon/issues/1638)) ([c7bf339](https://github.com/ng-alain/delon/commit/c7bf339ee417a3b238cdb7dc18cccd1fe99a6c88))
-
-
-# [16.2.0](https://github.com/ng-alain/delon/compare/16.1.1...16.2.0) (2023-07-21)
-
-### SCAFFOLDING
-
-* Breaking changes router guard [#2407](https://github.com/ng-alain/ng-alain/pull/2407/files).
-* Code style [#2405](https://github.com/ng-alain/ng-alain/pull/2405/files#diff-a3f38f2cae79a3819f93ff1a9d4cd281cbe8f95696e14a29864f08796d3dc568).
-
-### Bug Fixes
-
-* **abc:onboarding:** fix `ComponentFactoryResolver` ([#1624](https://github.com/ng-alain/delon/issues/1624)) ([ae065c2](https://github.com/ng-alain/delon/commit/ae065c21e9ba1ea0d56bae9ceb1e44b7bbb9b0fb))
-* **chat:timeline:** fix `y2` to be optional ([#1622](https://github.com/ng-alain/delon/issues/1622)) ([b565ddf](https://github.com/ng-alain/delon/commit/b565ddfdd7872a43f9fd3b3a1fd33d739f08074c))
-* **cli:** remove `skipTests` from generating module ([#1616](https://github.com/ng-alain/delon/issues/1616)) ([0da83f8](https://github.com/ng-alain/delon/commit/0da83f83b90ea5a367d35c6761554d7ebc07bfd0))
-* fix misalignment of `col` placeholders in `se`, `sv`, `sg` ([#1617](https://github.com/ng-alain/delon/issues/1617)) ([83b08c9](https://github.com/ng-alain/delon/commit/83b08c95ba803cf29e0f10bb354ae4f9170b2295))
-* **theme:modal:** removed `nzComponentParams` ([#1615](https://github.com/ng-alain/delon/issues/1615)) ([45863a1](https://github.com/ng-alain/delon/commit/45863a1d62e5751416321cb1d591faf820bb82d3))
-
-### Features
-
-* **abc:st:** add `onCell`, support colSpan and rowSpan merging ([#1613](https://github.com/ng-alain/delon/issues/1613)) ([9ab109e](https://github.com/ng-alain/delon/commit/9ab109e8f99fb1bd4e5b4e99b0b814bf34f0b4ac))
-* **abc:st:** button support function method of `icon`, `className` ([#1618](https://github.com/ng-alain/delon/issues/1618)) ([6bf27da](https://github.com/ng-alain/delon/commit/6bf27dac696818ff78b0ee955333e308597c968b))
-* **theme:layout-default:** add `fetching` property ([#1614](https://github.com/ng-alain/delon/issues/1614)) ([8446da6](https://github.com/ng-alain/delon/commit/8446da6fdd10d07f2e917d91830d95e1c81d2622))
-
-### BREAKING CHANGE
-
-* **acl:** refactor `ACLGuard` to `aclCanMatch`, `aclCanActivate`, `aclCanActivateChild`
-* **auth:simple** refactor `SimpleGuard` to `authSimpleCanMatch`, `authSimpleCanActivate`, `authSimpleCanActivateChild`
-* **auth:jtw** refactor `JWTGuard` to `authJWTCanMatch`, `authJWTCanActivate`, `authJWTCanActivateChild`
-* **i18n** refactor `AlainI18NGuard` to `alainI18nCanMatch`, `alainI18nCanActivate`, `alainI18nCanActivateChild`
-
-
-# [16.1.1](https://github.com/ng-alain/delon/compare/16.0.1...16.1.0) (2023-07-16)
-
-### Bug Fixes
-
-* **cli:** remove `stylelint-config-prettier` ([#1606](https://github.com/ng-alain/delon/issues/1606)) ([2ecc28b](https://github.com/ng-alain/delon/commit/2ecc28b53773d9b5215ebd720be4ead55d78c705))
-* **theme:** fix ant-btn preserve white spaces when is link type ([#1605](https://github.com/ng-alain/delon/issues/1605)) ([0fdd15d](https://github.com/ng-alain/delon/commit/0fdd15dd0922bf6570d38fabd1afc1ca755b87a2))
+* refactor(form): refining low-frequency widgets (#1668) ([8ab0e82](https://github.com/ng-alain/delon/commit/8ab0e82)), closes [#1668](https://github.com/ng-alain/delon/issues/1668)
+* build: remove `networkEnv` plugin instead of [nnrm](https://github.com/YunYouJun/nnrm/blob/main/README.md) (#1680) ([b7dbc68](https://github.com/ng-alain/delon/commit/b7dbc68)), closes [#1680](https://github.com/ng-alain/delon/issues/1680)
+* feat(acl): remove `forRoot` (#1690) ([4472d48](https://github.com/ng-alain/delon/commit/4472d48)), closes [#1690](https://github.com/ng-alain/delon/issues/1690)
### Features
-* **abc:reuse-tab:** support custom cache data ([#1609](https://github.com/ng-alain/delon/issues/1609)) ([11599d9](https://github.com/ng-alain/delon/commit/11599d9566712c707146e4ac299ec6efc2d82b01))
-* **theme:modal:** support drag ([#1607](https://github.com/ng-alain/delon/issues/1607)) ([3cd73f7](https://github.com/ng-alain/delon/commit/3cd73f7f86a76a7ea450f839e9ad359f6afd0da4))
-
-
-## [16.0.1](https://github.com/ng-alain/delon/compare/16.0.0...16.0.1) (2023-06-08)
-
-* fix `ng-zorro-antd` dependency
-
-# [16.0.0](https://github.com/ng-alain/delon/compare/15.2.1...16.0.0) (2023-06-07)
+* feat(cli): support use `ng add ng-alain` in multiple projects (#1664) ([e5476e2](https://github.com/ng-alain/delon/commit/e5476e2)), closes [#1664](https://github.com/ng-alain/delon/issues/1664)
+* feat(theme): add `provideAlain` (#1697) ([4311426](https://github.com/ng-alain/delon/commit/4311426)), closes [#1697](https://github.com/ng-alain/delon/issues/1697)
+* feat(abc:cell): add `provideCellWidgets` (#1700) ([7ea0daf](https://github.com/ng-alain/delon/commit/7ea0daf)), closes [#1700](https://github.com/ng-alain/delon/issues/1700)
+* feat(abc:reuse-tab): add `provideReuseTabConfig` (#1707) ([2f85357](https://github.com/ng-alain/delon/commit/2f85357)), closes [#1707](https://github.com/ng-alain/delon/issues/1707)
+* feat(abc:st): add `provideSTWidgets` (#1701) ([065316a](https://github.com/ng-alain/delon/commit/065316a)), closes [#1701](https://github.com/ng-alain/delon/issues/1701)
+* feat(theme:_httpclient): add `timestampSecond` (#1670) ([051b087](https://github.com/ng-alain/delon/commit/051b087)), closes [#1670](https://github.com/ng-alain/delon/issues/1670)
+* feat(theme:pipe:date): add global config (#1711) ([b3b93fa](https://github.com/ng-alain/delon/commit/b3b93fa)), closes [#1711](https://github.com/ng-alain/delon/issues/1711)
+* feat: add `provideAlainConfig` (#1689) ([b9e0fad](https://github.com/ng-alain/delon/commit/b9e0fad)), closes [#1689](https://github.com/ng-alain/delon/issues/1689)
+* feat(auth): add `provideAuth` (#1704) ([c0c731b](https://github.com/ng-alain/delon/commit/c0c731b)), closes [#1704](https://github.com/ng-alain/delon/issues/1704)
+* feat(form): add `provideSFConfig` (#1702) ([2404802](https://github.com/ng-alain/delon/commit/2404802)), closes [#1702](https://github.com/ng-alain/delon/issues/1702)
+* feat(mock): add `mockInterceptor` (#1698) ([da051b2](https://github.com/ng-alain/delon/commit/da051b2)), closes [#1698](https://github.com/ng-alain/delon/issues/1698)
+* feat(mock): support asynchronous (`Promise`, `Observable`) of response (#1686) ([d7980db](https://github.com/ng-alain/delon/commit/d7980db)), closes [#1686](https://github.com/ng-alain/delon/issues/1686)
+* feat(mock): add `provideDelonMockConfig` (#1695) ([683ab23](https://github.com/ng-alain/delon/commit/683ab23)), closes [#1695](https://github.com/ng-alain/delon/issues/1695)
+* feat(testing): add `delay` function (#1682) ([f83ea57](https://github.com/ng-alain/delon/commit/f83ea57)), closes [#1682](https://github.com/ng-alain/delon/issues/1682)
+* build: support pnpm and update yarn to `4` (#1678) ([b904b9a](https://github.com/ng-alain/delon/commit/b904b9a)), closes [#1678](https://github.com/ng-alain/delon/issues/1678)
### Bug Fixes
-* **abc:st:** fix error row class in fixed column title cell ([#1598](https://github.com/ng-alain/delon/issues/1598)) ([d2bf211](https://github.com/ng-alain/delon/commit/d2bf211a35df8bcbee165b54bcda4b2dcf69c6f0))
-* **form:** fix inheriting references to other of ui ([#1600](https://github.com/ng-alain/delon/issues/1600)) ([a0150e7](https://github.com/ng-alain/delon/commit/a0150e7520376064469cfa5ae0e3394635620022))
-
+* fix(theme:preloader): fix loading order issues (#1691) ([f09c324](https://github.com/ng-alain/delon/commit/f09c324)), closes [#1691](https://github.com/ng-alain/delon/issues/1691)
+* fix(cli:update): automatically add @_mock path (#1675) ([d014b54](https://github.com/ng-alain/delon/commit/d014b54)), closes [#1675](https://github.com/ng-alain/delon/issues/1675)
## Old Versions
diff --git a/docs/changelog.zh-CN.md b/docs/changelog.zh-CN.md
index e8acd37533..7da191d855 100644
--- a/docs/changelog.zh-CN.md
+++ b/docs/changelog.zh-CN.md
@@ -14,127 +14,41 @@ NG-ALAIN 严格遵循 [Semantic Versioning 2.0.0](http://semver.org/lang/zh-CN/)
---
-## [16.4.2](https://github.com/ng-alain/delon/compare/16.4.1...16.4.2) (2023-10-26)
+##
17.0.1 (2023-11-26)
-### Performance Improvements
+* fix(cli): 修复不支持 node 20 版本 (#1719) ([df40bb3](https://github.com/ng-alain/delon/commit/df40bb3)), closes [#1719](https://github.com/ng-alain/delon/issues/1719)
-* **theme:modal:** perf code ([#1671](https://github.com/ng-alain/delon/issues/1671)) ([341ff56](https://github.com/ng-alain/delon/commit/341ff56dc67d65d5a545f124a51938366c7722dc))
-* **abc:qr:** will be removed in 18.0.0 ([#1667](https://github.com/ng-alain/delon/issues/1667)) ([5a7bdd4](https://github.com/ng-alain/delon/commit/5a7bdd42226960c8140397b1a1a377fb87ca725e))
+## 17.0.0 (2023-11-26)
-## [16.4.1](https://github.com/ng-alain/delon/compare/16.4.0...16.4.1) (2023-10-20)
+### Breaking Changes
-### Bug Fixes
-
-* temp downgrade `ng-zorro-antd` to `16.2.0` ([#1663](https://github.com/ng-alain/delon/issues/1663)) ([d3da2b7](https://github.com/ng-alain/delon/commit/d3da2b753c1ebed589ba51e9f184270508eb0ff9))
-
-
-# [16.4.0](https://github.com/ng-alain/delon/compare/16.3.0...16.4.0) (2023-10-19)
-
-### Bug Fixes
-
-* **abc:onboarding:** 纠正暗黑风格 ([#1650](https://github.com/ng-alain/delon/issues/1650)) ([7a21933](https://github.com/ng-alain/delon/commit/7a219338660bfbbe18f5ee35ccd1caaabf6e40a4))
-* **abc:st:** 纠正导出 Excel 中的宽度未对齐问题 ([#1655](https://github.com/ng-alain/delon/issues/1655)) ([76db16c](https://github.com/ng-alain/delon/commit/76db16c526057138e470244ccef1cd67e853ccc9))
-* **cli:** 修复 Angular 16 下 `ng new ng-alain` 缺失 `fileReplacements` ([#1658](https://github.com/ng-alain/delon/issues/1658)) ([c5b46ee](https://github.com/ng-alain/delon/commit/c5b46ee50a3741dba0f0731f2f2326e9fd47b6cd))
-* **form:array:** 修复 `ui` 属性无法合并 ui ([#1657](https://github.com/ng-alain/delon/issues/1657)) ([6b3c711](https://github.com/ng-alain/delon/commit/6b3c711f2f56cbf93f2078b6d83a751b9bdd8bde))
-* **form:select:** 纠正有默认值时初始化时无法触发 `onSearch` ([#1660](https://github.com/ng-alain/delon/issues/1660)) ([fa234cd](https://github.com/ng-alain/delon/commit/fa234cd2e7a127e4df79a82b6965a03220497143))
-* **form:** 修复设置 `visibleIf` 触发时也会触发 `reset` 方法 ([#1653](https://github.com/ng-alain/delon/issues/1653)) ([d80f8fb](https://github.com/ng-alain/delon/commit/d80f8fba87659be8099962817cbd17422a5ae249))
-* **form:** 修复渲染UI不应被继承([#1661](https://github.com/ng-alain/delon/issues/1661)) ([ee96aaa](https://github.com/ng-alain/delon/commit/ee96aaac047dfa990aa0ffc2d94808939c3311c5))
-* **fix(form:widget:object):** 修复 `card` 样式缺失 `optional` ([#1661](https://github.com/ng-alain/delon/issues/1661)) ([ee96aaa](https://github.com/ng-alain/delon/commit/ee96aaac047dfa990aa0ffc2d94808939c3311c5))
-
-### Features
-
-* **abc:onboarding:** 新增 `key` 用于自动判断是否发生版本变化 ([#1652](https://github.com/ng-alain/delon/issues/1652)) ([5edaa97](https://github.com/ng-alain/delon/commit/5edaa970f508c402d94843bb8260a5d72bdb5870))
-* **abc:theme:** 纠正 `ng-tag` 列表换行间距问题 ([#1647](https://github.com/ng-alain/delon/issues/1647)) ([5da4ecb](https://github.com/ng-alain/delon/commit/5da4ecb766c9195609899dbaa543b5eefad82f01))
-* **cli:** add provide function ([#1654](https://github.com/ng-alain/delon/issues/1654)) ([c8779f4](https://github.com/ng-alain/delon/commit/c8779f41234364bf8690dcf9c9aa5d90c48eadcd))
-
-
-# [16.3.0](https://github.com/ng-alain/delon/compare/16.2.1...16.3.0) (2023-09-01)
-
-### SCAFFOLDING
-
-* 启用 `bindToComponentInputs` [#2409](https://github.com/ng-alain/ng-alain/pull/2409/files).
-
-### Bug Fixes
-
-* **abc:pdf:** 忽略依赖 `pdfjs-dist`(若使用[本地](https://ng-alain.com/components/pdf)加载模式,需要自行安装该依赖,`pdfjs-dist` 依赖了 `canvas` 可能会因为环境因素安装依赖很慢) ([#1641](https://github.com/ng-alain/delon/issues/1641)) ([b987bab](https://github.com/ng-alain/delon/commit/b987baba6035eb60872c4ee48198568df140869c))
-* **form:select:** 当设置 `onSearch` 时重置数据时会忽略更新预选数据 ([#1644](https://github.com/ng-alain/delon/issues/1644)) ([1f8def7](https://github.com/ng-alain/delon/commit/1f8def70856c091ed677cbd47aed7ca230a2aa79))
-* **theme:http:** 纠正 `HttpOptions` 缺少 `content` ([#1640](https://github.com/ng-alain/delon/issues/1640)) ([28eeceb](https://github.com/ng-alain/delon/commit/28eecebd7ab71a1b9a8345c0af1ebe22fd3bc1a6))
+* refactor(form): 重构低频率小部件为可选导入 (#1668) ([8ab0e82](https://github.com/ng-alain/delon/commit/8ab0e82)), closes [#1668](https://github.com/ng-alain/delon/issues/1668)
+* build: 移除 `networkEnv` 插件,使用 [nnrm](https://github.com/YunYouJun/nnrm/blob/main/README.zh-CN.md) 替代 (#1680) ([b7dbc68](https://github.com/ng-alain/delon/commit/b7dbc68)), closes [#1680](https://github.com/ng-alain/delon/issues/1680)
+* feat(acl): 移除 `forRoot` (#1690) ([4472d48](https://github.com/ng-alain/delon/commit/4472d48)), closes [#1690](https://github.com/ng-alain/delon/issues/1690)
### Features
-* **abc:cell:** 新增 `cell` 单元格数据组件 ([#1530](https://github.com/ng-alain/delon/issues/1530)) ([26023ca](https://github.com/ng-alain/delon/commit/26023cac7a91cae5383cfffd26d44fba6a95fb9f))
-* **abc:page-header:** 新增 `titleSub` 子标题属性 ([#1643](https://github.com/ng-alain/delon/issues/1643)) ([79e229f](https://github.com/ng-alain/delon/commit/79e229f5c1b509dd463c48e4a82b361e5d923920))
-* **abc:st:** 标签或徽标支持 `tooltip` ([#1634](https://github.com/ng-alain/delon/issues/1634)) ([0e9006e](https://github.com/ng-alain/delon/commit/0e9006e5b9fd30092b5a808f9b3d8012fd3a060c))
-* **abc:sv:** 新增 `bordered` 是否显示边框 ([#1628](https://github.com/ng-alain/delon/issues/1628)) ([ccfa5e1](https://github.com/ng-alain/delon/commit/ccfa5e1d6f5cf1d3f9bc5360bc2e373604ae22a2))
-* **cli:** `ng add` 开启 `bindToComponentInputs` ([#1630](https://github.com/ng-alain/delon/issues/1630)) ([9717d9d](https://github.com/ng-alain/delon/commit/9717d9dd4ee1d5ab1526616a99da7b70e8664bd2))
-* **theme:drawer:** 新增 `closeAll`, `openDrawers` 方法 ([#1627](https://github.com/ng-alain/delon/issues/1627)) ([bab3d0c](https://github.com/ng-alain/delon/commit/bab3d0c3c648d933784c4623b2714ac227219c5c))
-* **theme:modal:** 支持百分比大小 ([#1626](https://github.com/ng-alain/delon/issues/1626)) ([8b52a08](https://github.com/ng-alain/delon/commit/8b52a08d82378a42e06c316757e19e5434e109dc))
-
-
-## [16.2.1](https://github.com/ng-alain/delon/compare/16.2.0...16.2.1) (2023-08-06)
+* feat(cli): 支持多重项目下使用 `ng add ng-alain` (#1664) ([e5476e2](https://github.com/ng-alain/delon/commit/e5476e2)), closes [#1664](https://github.com/ng-alain/delon/issues/1664)
+* feat(theme): 新增 `provideAlain` (#1697) ([4311426](https://github.com/ng-alain/delon/commit/4311426)), closes [#1697](https://github.com/ng-alain/delon/issues/1697)
+* feat(abc:cell): 新增 `provideCellWidgets` (#1700) ([7ea0daf](https://github.com/ng-alain/delon/commit/7ea0daf)), closes [#1700](https://github.com/ng-alain/delon/issues/1700)
+* feat(abc:reuse-tab): 新增 `provideReuseTabConfig` (#1707) ([2f85357](https://github.com/ng-alain/delon/commit/2f85357)), closes [#1707](https://github.com/ng-alain/delon/issues/1707)
+* feat(abc:st): 新增 `provideSTWidgets` (#1701) ([065316a](https://github.com/ng-alain/delon/commit/065316a)), closes [#1701](https://github.com/ng-alain/delon/issues/1701)
+* feat(theme:_httpclient): 新增 `timestampSecond` 支持 10 位时间戳 (#1670) ([051b087](https://github.com/ng-alain/delon/commit/051b087)), closes [#1670](https://github.com/ng-alain/delon/issues/1670)
+* feat(theme:pipe:date): 支持全局配置格式化字符串 (#1711) ([b3b93fa](https://github.com/ng-alain/delon/commit/b3b93fa)), closes [#1711](https://github.com/ng-alain/delon/issues/1711)
+* feat: 新增 `provideAlainConfig` (#1689) ([b9e0fad](https://github.com/ng-alain/delon/commit/b9e0fad)), closes [#1689](https://github.com/ng-alain/delon/issues/1689)
+* feat(auth): 新增 `provideAuth` (#1704) ([c0c731b](https://github.com/ng-alain/delon/commit/c0c731b)), closes [#1704](https://github.com/ng-alain/delon/issues/1704)
+* feat(form): 新增 `provideSFConfig` (#1702) ([2404802](https://github.com/ng-alain/delon/commit/2404802)), closes [#1702](https://github.com/ng-alain/delon/issues/1702)
+* feat(mock): 新增 `mockInterceptor` (#1698) ([da051b2](https://github.com/ng-alain/delon/commit/da051b2)), closes [#1698](https://github.com/ng-alain/delon/issues/1698)
+* feat(mock): 支持异步返回,例如 `Promise`、`Observable` (#1686) ([d7980db](https://github.com/ng-alain/delon/commit/d7980db)), closes [#1686](https://github.com/ng-alain/delon/issues/1686)
+* feat(mock): 新增 `provideDelonMockConfig` (#1695) ([683ab23](https://github.com/ng-alain/delon/commit/683ab23)), closes [#1695](https://github.com/ng-alain/delon/issues/1695)
+* feat(testing): 新增 `delay` function (#1682) ([f83ea57](https://github.com/ng-alain/delon/commit/f83ea57)), closes [#1682](https://github.com/ng-alain/delon/issues/1682)
+* build: support pnpm and update yarn to `4` (#1678) ([b904b9a](https://github.com/ng-alain/delon/commit/b904b9a)), closes [#1678](https://github.com/ng-alain/delon/issues/1678)
### Bug Fixes
-* **abc:reuse-tab:** 修复缺少导出缓存相关 ([#1633](https://github.com/ng-alain/delon/issues/1633)) ([2c7def7](https://github.com/ng-alain/delon/commit/2c7def75a5b219a58319ab129407f4058010fc44))
-* **auth:cookie:** 修复过期值应与 expires 同步 ([#1636](https://github.com/ng-alain/delon/issues/1636)) ([eca7bcb](https://github.com/ng-alain/delon/commit/eca7bcb2e7ba43b3a4b3bb4ab3cd17a7d762a967))
-* **theme:table:** 修复单图像的间距问题 ([#1629](https://github.com/ng-alain/delon/issues/1629)) ([994e2be](https://github.com/ng-alain/delon/commit/994e2be90354a55a538ed1b55c413b8ce8cde872))
-* **theme:title:** 修复应忽略空标题 ([#1638](https://github.com/ng-alain/delon/issues/1638)) ([c7bf339](https://github.com/ng-alain/delon/commit/c7bf339ee417a3b238cdb7dc18cccd1fe99a6c88))
-
-
-# [16.2.0](https://github.com/ng-alain/delon/compare/16.1.1...16.2.0) (2023-07-21)
-
-### SCAFFOLDING
-
-* 路由守卫的破坏性变更 [#2407](https://github.com/ng-alain/ng-alain/pull/2407/files).
-* 代码风格变更 [#2405](https://github.com/ng-alain/ng-alain/pull/2405/files#diff-a3f38f2cae79a3819f93ff1a9d4cd281cbe8f95696e14a29864f08796d3dc568).
-
-### Bug Fixes
-
-* **abc:onboarding:** 修复使用过期方法 `ComponentFactoryResolver` ([#1624](https://github.com/ng-alain/delon/issues/1624)) ([ae065c2](https://github.com/ng-alain/delon/commit/ae065c21e9ba1ea0d56bae9ceb1e44b7bbb9b0fb))
-* **chat:timeline:** 修复 `y2` 指标数据为可选 ([#1622](https://github.com/ng-alain/delon/issues/1622)) ([b565ddf](https://github.com/ng-alain/delon/commit/b565ddfdd7872a43f9fd3b3a1fd33d739f08074c))
-* **cli:** 移除生成模块时包含无效参数 `skipTests` ([#1616](https://github.com/ng-alain/delon/issues/1616)) ([0da83f8](https://github.com/ng-alain/delon/commit/0da83f83b90ea5a367d35c6761554d7ebc07bfd0))
-* 修复 `col` 占位符不对齐问题,涉及 `se`, `sv`, `sg` 组件 ([#1617](https://github.com/ng-alain/delon/issues/1617)) ([83b08c9](https://github.com/ng-alain/delon/commit/83b08c95ba803cf29e0f10bb354ae4f9170b2295))
-* **theme:modal:** 修复过期参数 `nzComponentParams` ([#1615](https://github.com/ng-alain/delon/issues/1615)) ([45863a1](https://github.com/ng-alain/delon/commit/45863a1d62e5751416321cb1d591faf820bb82d3))
-
-### Features
-
-* **abc:st:** 新增 `onCell` 方法支持合并列或行 ([#1613](https://github.com/ng-alain/delon/issues/1613)) ([9ab109e](https://github.com/ng-alain/delon/commit/9ab109e8f99fb1bd4e5b4e99b0b814bf34f0b4ac))
-* **abc:st:** 新增 `icon`, `className` 方法支持动态调整 ([#1618](https://github.com/ng-alain/delon/issues/1618)) ([6bf27da](https://github.com/ng-alain/delon/commit/6bf27dac696818ff78b0ee955333e308597c968b))
-* **theme:layout-default:** 新增 `fetchingStrictly`, `fetching` 属性用于自主受控顶部加载动画状态 ([#1614](https://github.com/ng-alain/delon/issues/1614)) ([8446da6](https://github.com/ng-alain/delon/commit/8446da6fdd10d07f2e917d91830d95e1c81d2622))
-
-### BREAKING CHANGE
-
-* **acl:** 重构 `ACLGuard` 为 `aclCanMatch`, `aclCanActivate`, `aclCanActivateChild`
-* **auth:simple** 重构 `SimpleGuard` 为 `authSimpleCanMatch`, `authSimpleCanActivate`, `authSimpleCanActivateChild`
-* **auth:jtw** 重构 `JWTGuard` 为 `authJWTCanMatch`, `authJWTCanActivate`, `authJWTCanActivateChild`
-* **i18n** 重构 `AlainI18NGuard` 为 `alainI18nCanMatch`, `alainI18nCanActivate`, `alainI18nCanActivateChild`
-
-
-# [16.1.1](https://github.com/ng-alain/delon/compare/16.0.1...16.1.0) (2023-07-16)
-
-### Bug Fixes
-
-* **cli:** 移除过期库 `stylelint-config-prettier` ([#1606](https://github.com/ng-alain/delon/issues/1606)) ([2ecc28b](https://github.com/ng-alain/delon/commit/2ecc28b53773d9b5215ebd720be4ead55d78c705))
-* **theme:** 修复忽略两个 `nzType="link"` 按错时间距 ([#1605](https://github.com/ng-alain/delon/issues/1605)) ([0fdd15d](https://github.com/ng-alain/delon/commit/0fdd15dd0922bf6570d38fabd1afc1ca755b87a2))
-
-### Features
-
-* **abc:reuse-tab:** 新增可自定义缓存存储 ([#1609](https://github.com/ng-alain/delon/issues/1609)) ([11599d9](https://github.com/ng-alain/delon/commit/11599d9566712c707146e4ac299ec6efc2d82b01))
-* **theme:modal:** 新增支持拖拽参数 `drag` ([#1607](https://github.com/ng-alain/delon/issues/1607)) ([3cd73f7](https://github.com/ng-alain/delon/commit/3cd73f7f86a76a7ea450f839e9ad359f6afd0da4))
-
-
-## [16.0.1](https://github.com/ng-alain/delon/compare/16.0.0...16.0.1) (2023-06-08)
-
-* 修复 `ng-zorro-antd` 错位版本依赖
-
-# [16.0.0](https://github.com/ng-alain/delon/compare/15.2.1...16.0.0) (2023-06-07)
-
-### Bug Fixes
-
-* **abc:st:** 修复固定列样式错误 ([#1598](https://github.com/ng-alain/delon/issues/1598)) ([d2bf211](https://github.com/ng-alain/delon/commit/d2bf211a35df8bcbee165b54bcda4b2dcf69c6f0))
-* **form:** 修复ui由于继承关系导致重复引用 ([#1600](https://github.com/ng-alain/delon/issues/1600)) ([a0150e7](https://github.com/ng-alain/delon/commit/a0150e7520376064469cfa5ae0e3394635620022))
-
+* fix(theme:preloader): 修复启动动画存在懒加载时空白问题 (#1691) ([f09c324](https://github.com/ng-alain/delon/commit/f09c324)), closes [#1691](https://github.com/ng-alain/delon/issues/1691)
+* fix(cli:update): 修复自动追加 `@_mock` 路径 (#1675) ([d014b54](https://github.com/ng-alain/delon/commit/d014b54)), closes [#1675](https://github.com/ng-alain/delon/issues/1675)
## 历史版本
diff --git a/docs/faq.en-US.md b/docs/faq.en-US.md
index 78d418aada..005899ed1c 100644
--- a/docs/faq.en-US.md
+++ b/docs/faq.en-US.md
@@ -10,10 +10,6 @@ Please check the FAQ below before asking questions.
## Basic
-### Can't Bind to since it isn't a known property of
-
-When you have multiple lazy modules, you want each submodule to use the component library (for example: `NgZorroAntdModule`, `NgxTinymceModule`) should be exported in `ShareModule`, please refer to [module registration guidelines](/docs/Module).
-
### Expression Changed After It Has Been Checked Error
Common mistakes under Angular, [this article](https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4) will help you understand why.
diff --git a/docs/faq.zh-CN.md b/docs/faq.zh-CN.md
index bb59cc8b3f..b141560c4f 100644
--- a/docs/faq.zh-CN.md
+++ b/docs/faq.zh-CN.md
@@ -10,10 +10,6 @@ type: Other
## 基础
-### Can't Bind to since it isn't a known property of
-
-当你有多个懒模块时,希望每个子模块都需要使用组件库时(例如:`NgZorroAntdModule`、`NgxTinymceModule`)应在 `ShareModule` 中 export,请参考[模块注册指导原则](/docs/module)。
-
### Expression Changed After It Has Been Checked Error 错误
Angular 下常见错误,[这篇文章](https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4) 会帮助你理解原因。
diff --git a/docs/getting-started.en-US.md b/docs/getting-started.en-US.md
index 3bf09c6d25..623aaf0a25 100644
--- a/docs/getting-started.en-US.md
+++ b/docs/getting-started.en-US.md
@@ -39,6 +39,18 @@ npm start
# Or use HMR mode by: npm run hmr
```
+**Multiple projects**
+
+```bash
+yarn global add @angular/cli
+ng new my-workspace --no-create-application --package-manager yarn
+cd my-workspace
+ng g application mgr --style less --routing
+ng add ng-alain
+yarn mgr:start
+# Or use HMR mode by: yarn run mgr:hmr
+```
+
> Please refer to [Schematics](/cli) for more details.
### Clone the Git Repository
@@ -103,9 +115,9 @@ This will automatically open [http://localhost:4200](http://localhost:4200). If
- Server-side Rendering
- [Electron](https://electron.atom.io/)
-| [
![IE / Edge](https://img.alicdn.com/tfs/TB1G5ewZuL2gK0jSZPhXXahvXXa-48-48.png)
](https://godban.github.io/browsers-support-badges//)
IE / Edge | [
![Firefox](https://img.alicdn.com/tfs/TB1Dx73o79l0K4jSZFKXXXFjpXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Firefox | [
![Chrome](https://img.alicdn.com/tfs/TB1mY9FZrr1gK0jSZFDXXb9yVXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Chrome | [
![Safari](https://img.alicdn.com/tfs/TB1Vas5o79l0K4jSZFKXXXFjpXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Safari | [
![Opera](https://img.alicdn.com/tfs/TB12EmNZET1gK0jSZFrXXcNCXXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Opera | [
![Electron](https://img.alicdn.com/tfs/TB1TMW8paNj0u4jSZFyXXXgMVXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Electron |
-| --- | --- | --- | --- | --- | --- |
-| Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
+| [
![Edge](https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png)
](http://godban.github.io/browsers-support-badges/)Edge | [
![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png)
](http://godban.github.io/browsers-support-badges/)Firefox | [
![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png)
](http://godban.github.io/browsers-support-badges/)Chrome | [
![Safari](https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png)
](http://godban.github.io/browsers-support-badges/)Safari | [
![Opera](https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png)
](http://godban.github.io/browsers-support-badges/)Opera | [
![Electron](https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png)
](http://godban.github.io/browsers-support-badges/)Electron |
+| --------- | --------- | --------- | --------- | --------- | --------- |
+| last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions
## Contributing
diff --git a/docs/getting-started.zh-CN.md b/docs/getting-started.zh-CN.md
index dde9de1294..9a554383cd 100644
--- a/docs/getting-started.zh-CN.md
+++ b/docs/getting-started.zh-CN.md
@@ -43,6 +43,11 @@ NG-ALAIN 必须先创建一个全新的 Angular 项目,可以通过终端窗
```bash
ng new my-project --style less --routing
+cd my-project
+# 或多重项目
+ng new my-workspace --no-create-application
+cd my-workspace
+ng g application mgr --style less --routing
```
> 如果你想了解 `--style`、`--routing` 参数,请参考 [ng new](https://angular.io/cli/new#options) 文档。
@@ -50,10 +55,11 @@ ng new my-project --style less --routing
接下来只需要将 NG-ALAIN 添加到 `my-project` 项目中即可,在 `my-project` 目录下通过终端窗口中运行:
```bash
-cd my-project
ng add ng-alain
```
+> 若多重项目时,需要提供具体的项目名称。
+
NG-ALAIN 会询问是否需要一些额外的插件,一开始完全可以一路回车,这些插件都是可插拔,后期可以自行添加与移除。
> 以上只会生成干净的项目,可以直接用于生产环境中。你可能在[预览](https://ng-alain.gitee.io/)上看到许多示例页,它们全都可以在 [Github](https://github.com/ng-alain/ng-alain) 查看到源代码,当然也可以通过 Git 克隆代码的形式获得:
@@ -82,9 +88,9 @@ npm start
- 支持服务端渲染
- [Electron](https://electron.atom.io/)
-| [
![IE / Edge](https://img.alicdn.com/tfs/TB1G5ewZuL2gK0jSZPhXXahvXXa-48-48.png)
](https://godban.github.io/browsers-support-badges//)
IE / Edge | [
![Firefox](https://img.alicdn.com/tfs/TB1Dx73o79l0K4jSZFKXXXFjpXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Firefox | [
![Chrome](https://img.alicdn.com/tfs/TB1mY9FZrr1gK0jSZFDXXb9yVXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Chrome | [
![Safari](https://img.alicdn.com/tfs/TB1Vas5o79l0K4jSZFKXXXFjpXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Safari | [
![Opera](https://img.alicdn.com/tfs/TB12EmNZET1gK0jSZFrXXcNCXXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Opera | [
![Electron](https://img.alicdn.com/tfs/TB1TMW8paNj0u4jSZFyXXXgMVXa-48-48.png)
](https://godban.github.io/browsers-support-badges/)
Electron |
-| --- | --- | --- | --- | --- | --- |
-| Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
+| [
![Edge](https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png)
](http://godban.github.io/browsers-support-badges/)Edge | [
![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png)
](http://godban.github.io/browsers-support-badges/)Firefox | [
![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png)
](http://godban.github.io/browsers-support-badges/)Chrome | [
![Safari](https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png)
](http://godban.github.io/browsers-support-badges/)Safari | [
![Opera](https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png)
](http://godban.github.io/browsers-support-badges/)Opera | [
![Electron](https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png)
](http://godban.github.io/browsers-support-badges/)Electron |
+| --------- | --------- | --------- | --------- | --------- | --------- |
+| last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions
## 如何贡献
diff --git a/docs/global-config.en-US.md b/docs/global-config.en-US.md
index 2dee1385b1..c0b30d6fce 100644
--- a/docs/global-config.en-US.md
+++ b/docs/global-config.en-US.md
@@ -10,22 +10,31 @@ We add support of **global configuration** to many components. You can define th
## How to Use?
-If you want to provide default configurations to some components, you should provide an object that implements the interface **AlainConfig** with the injection token **ALAIN_CONFIG**, in the root module (in another word, to the root injector). Like this:
+If you want to provide default configurations to some components, please use `provideAlain` function. object providing implements interface `AlainProvideOptions` For example:
```typescript
// global-config.module.ts
-import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
+import { AlainConfig, AlainProvideLang } from '@delon/util/config';
+import { ICONS } from '../style-icons';
+import { ICONS_AUTO } from '../style-icons-auto';
+
+const defaultLang: AlainProvideLang = {
+ abbr: 'zh-CN',
+ ng: ngLang,
+ zorro: zorroLang,
+ date: dateLang,
+ delon: delonLang
+};
const alainConfig: AlainConfig = {
st: { ps: 3 },
};
-@NgModule({
+export const appConfig: ApplicationConfig = {
providers: [
- { provide: ALAIN_CONFIG, useValue: alainConfig },
- ],
-})
-export class GlobalConfigModule {}
+ provideAlain({ config: alainConfig, defaultLang, icons: [...ICONS_AUTO, ...ICONS] })
+ ]
+};
```
These global configuration would be injected into a service named `AlainConfigService` and gets stored.
diff --git a/docs/global-config.zh-CN.md b/docs/global-config.zh-CN.md
index 626eea5689..1cd350ee32 100644
--- a/docs/global-config.zh-CN.md
+++ b/docs/global-config.zh-CN.md
@@ -10,22 +10,31 @@ type: Dev
## 如何使用
-想要为某些组件提供默认配置项,请在根注入器中根据注入令牌 `ALAIN_CONFIG` 提供一个符合 `AlainConfig` 接口的对象,例如:
+想要为某些组件提供默认配置项,可以使用 `provideAlain` 函数,转入一个符合 `AlainProvideOptions` 接口的对象,例如:
```typescript
// global-config.module.ts
-import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
+import { AlainConfig, AlainProvideLang } from '@delon/util/config';
+import { ICONS } from '../style-icons';
+import { ICONS_AUTO } from '../style-icons-auto';
+
+const defaultLang: AlainProvideLang = {
+ abbr: 'zh-CN',
+ ng: ngLang,
+ zorro: zorroLang,
+ date: dateLang,
+ delon: delonLang
+};
const alainConfig: AlainConfig = {
st: { ps: 3 },
};
-@NgModule({
+export const appConfig: ApplicationConfig = {
providers: [
- { provide: ALAIN_CONFIG, useValue: alainConfig },
- ],
-})
-export class GlobalConfigModule {}
+ provideAlain({ config: alainConfig, defaultLang, icons: [...ICONS_AUTO, ...ICONS] })
+ ]
+};
```
这些全局配置项将会被注入 `AlainConfigService` 当中并保存。
diff --git a/docs/how-to-start.en-US.md b/docs/how-to-start.en-US.md
index a84bd382ea..f84666e775 100644
--- a/docs/how-to-start.en-US.md
+++ b/docs/how-to-start.en-US.md
@@ -31,13 +31,14 @@ When running an app via `ng serve`, a complete Angular startup process would loo
### 1) APP_INITIALIZER
-From a mid and back-office perspective, NG-ALAIN always believes that a network request is required to get some application information (eg menu data, user data, etc.) before Angular starts.[startup.service.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/startup/startup.service.ts);It returns a `Promise` object, which always needs to be called: `resolve()` to ensure that Angular starts normally.
+Angular provides a DI (dependency injection) token `APP_INITIALIZER` that allows the application to perform some data that will affect the rendering results when it starts, such as: language data, menu data, user information data, dictionary data, etc., and must return an `Observable` Asynchronous, asynchronous means that you can do a lot of interesting things, such as data coming from a remote location. `APP_INITIALIZER` will only be executed once, you only need to register it in the `ApplicationConfig` module.
-> Network requests may encounter a 403 error because the scaffolding uses the user authentication module by default and always assumes that all requests must be a valid user authorization. For more documentation see:
-> - [Interact with server](/docs/server)
-> - [Auth User Authentication](/auth)
+The NG-ALAIN scaffolding provides a sample code on how to load basic data before starting rendering after starting Angular [startup.service.ts](https://github.com/ng-alain/ng-alain/blob/ master/src/app/core/startup/startup.service.ts).
-After obtaining the application information, you need to assign some values to the built-in services of the scaffolding, including:
+1. Provide unified registration `provideStartup` function, which only needs to be registered in `app.config.ts`
+2. Provide the `load()` function and ensure that **regardless of whether the request is successful or not** must return an `Observable
` for Angular to render normally, otherwise Angular will not be able to start.
+
+> Note: NG-ALAIN provides authorization services. If the requested data interface cannot be authorized, you can add `ALLOW_ANONYMOUS` to mark it.
**Application Information**
@@ -99,18 +100,21 @@ It is recommended to load the internationalization package first before starting
### 2) Business routing
-Scaffolding top-level routing begins with [routes-routing.module.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/routes/routes-routing.module.ts) Its structure is as follows:
+Scaffolding top-level routing begins with [routes.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/routes/routes.ts) Its structure is as follows:
```ts
const routes: Routes = [
{
path: '',
- component: LayoutDefaultComponent,
+ component: LayoutBasicComponent,
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
- { path: 'dashboard', component: DashboardComponent, data: { title: 'Dashboard' } },
+ {
+ path: 'dashboard',
+ loadChildren: () => import('./dashboard/routes').then(m => m.routes)
+ },
// business submodule
- // { path: 'trade', loadChildren: './trade/trade.module#TradeModule' }
+ // { path: 'trade', loadChildren: () => import('./trade/routes').then(m => m.routes) },
]
},
// Blank layout
@@ -120,37 +124,29 @@ const routes: Routes = [
children: [
]
},
- // passport
- {
- path: 'passport',
- component: LayoutPassportComponent,
- children: [
- { path: 'login', component: UserLoginComponent },
- { path: 'register', component: UserRegisterComponent },
- { path: 'register-result', component: UserRegisterResultComponent }
- ]
- },
- // Single page does not wrap Layout
- { path: 'callback/:type', component: CallbackComponent },
- { path: '403', component: Exception403Component },
- { path: '404', component: Exception404Component },
- { path: '500', component: Exception500Component },
+ { path: '', loadChildren: () => import('./passport/routes').then(m => m.routes) },
+ { path: 'exception', loadChildren: () => import('./exception/routes').then(m => m.routes) },
+ // All missed routes will jump to the `exception/404` page
{ path: '**', redirectTo: 'dashboard' }
];
```
-Above we used the `LayoutDefaultComponent` base layout in the business module. User authorization uses `LayoutPassportComponent` user authorization layout and the full screen layout.
+> The above mentioned `LayoutBasicComponent` basic layout is used in the business module, user authorization uses `LayoutPassportComponent` user authorization layout and `LayoutBlankComponent` blank layout. The above three layouts can be used in [layout](https://github.com/ ng-alain/ng-alain/tree/master/src/app/layout) directory.
-It is recommended that all submodules be loaded using a lazy module, such as the `TradeModule` order module, which organizes the code structure more efficiently.
+> NG-ALAIN also provides some [commercial themes](https://e.ng-alain.com/) to chooses.
-### Under what circumstances do you not use lazy loading?
-
-Angular startup from the top-level component. When a lazy module is encountered, it will initiate a script request. At this time, the dashboard or login page will be blank due to network requests, which is not good for the experience.
+For example, when a user accesses the `/dashboard` route, they will first go through `LayoutBasicComponent` -> `DashboardComponent`, and eventually form a huge component tree to represent a specific page. NG-ALAIN scaffolding helps you complete most of the work, and a newbie only needs to care about how to implement the `DashboardComponent` business component.
### Routing permission control
The routing URL may be affected by the browser's own historical memory, so that users may access the unprivileged route. If you want a better experience, you need to configure the `canActivate` option on the route. When the user has no permission, it will utomatically jump to the relevant page. see the [ACL Routing Guard](/acl/guard) section for details.
+### Intercept network requests
+
+Network requests are a very frequent task. If you want to use network request actions elegantly within business components, it is essential to centrally handle server-side URL prefixes, exception handling, token refresh and other operations. NG-ALAIN scaffolding Provide a [net](https://github.com/ng-alain/ng-alain/tree/master/src/app/core/net) file. It uses the token `HttpInterceptorFn` to act as an interceptor.
+
+For details, please refer to [default.interceptor.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/net/default.interceptor. ts) file.
+
## IDE
A developer must first sharpen his tools if he is to do his work well, NG-ALAIN recommended to use the [Visual Studio Code](https://code.visualstudio.com/) IDE, because ng-alain adds some extra features to VSCode to better help you. Development.
diff --git a/docs/how-to-start.zh-CN.md b/docs/how-to-start.zh-CN.md
index 4b78a8279a..b1fbf66cff 100644
--- a/docs/how-to-start.zh-CN.md
+++ b/docs/how-to-start.zh-CN.md
@@ -31,48 +31,16 @@ NG-ALAIN 技术栈基于 Typescript、Angular、图表G2 和 NG-ZORRO,在开
### 初始化项目数据
-Angular 提供一个DI(依赖注入)令牌 `APP_INITIALIZER` 让应用启动时可以做一些会影响渲染结果的数据,比如:语言数据、菜单数据、用户信息数据、字典数据等,并且必须返回一个 `Promise` 异步函数,异步意味者可以做很多有趣的事,比如数据来自远程。`APP_INITIALIZER` 只会执行一次,只需要在 `AppModule` 模块注册它就行了。
+Angular 提供一个DI(依赖注入)令牌 `APP_INITIALIZER` 让应用启动时可以做一些会影响渲染结果的数据,比如:语言数据、菜单数据、用户信息数据、字典数据等,并且必须返回一个 `Observable` 异步,异步意味者可以做很多有趣的事,比如数据来自远程。`APP_INITIALIZER` 只会执行一次,只需要在 `ApplicationConfig` 模块注册它就行了。
-```ts
-export function StartupServiceFactory(startupService: StartupService): () => Promise {
- return () => startupService.load();
-}
-
-@NgModule({
- declarations: [AppComponent],
- imports: [BrowserModule]
- providers: [{
- StartupService,
- {
- provide: APP_INITIALIZER,
- useFactory: StartupServiceFactory,
- deps: [StartupService],
- multi: true,
- },
- }],
- bootstrap: [AppComponent],
-})
-export class AppModule {}
-```
+NG-ALAIN 脚手架提供了一个如何在启动 Angular 后先加载基础数据以后才会开始渲染的样板代码 [startup.service.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/startup/startup.service.ts)。
-而 `StartupService` 如下:
+1. 提供统一注册 `provideStartup` 函数,只需要在 `app.config.ts` 注册就能生效
+2. 提供 `load()` 函数,并确保**无论请求是否成功**都必须返回一个 `Observable` 以供Angular正常渲染,否则会导致Angular无法启动
-```ts
-@Injectable()
-export class StartupService {
- constructor(private httpClient: HttpClient) {}
-
- load(): Promise {
- return new Promise((resolve) => {
- this.httpClient.get(``).subscribe(() => {
- resolve();
- });
- });
- }
-}
-```
+> 注:NG-ALAIN 提供授权服务,若在请求数据接口无法授权时,可加 `ALLOW_ANONYMOUS` 来标记
-哪怕 Http 请求失败,这里也必须执行 `resolve()`,否则应用就无法启动。而 NG-ALAIN 提供的 [startup.service.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/startup/startup.service.ts) 内容更加丰富一点,对于完整的中后台而言,大多数项目中以下这些信息都可以必备的:
+ NG-ALAIN 提供的 [startup.service.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/startup/startup.service.ts) 内容更加丰富一点,对于完整的中后台而言,大多数项目中以下这些信息都可以必备的:
| 数据类型 | 描述 |
|------|----|
@@ -86,7 +54,7 @@ export class StartupService {
### 业务路由
-当 Angular 项目正式启动后会进入渲染动作,根据当前的路由地址来决定一个页面如何渲染,从最顶层路由 [routes-routing.module.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/routes/routes-routing.module.ts) 开始一层层寻找,其结构如下:
+当 Angular 项目正式启动后会进入渲染动作,根据当前的路由地址来决定一个页面如何渲染,从最顶层路由 [routes.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/routes/routes.ts) 开始一层层寻找,其结构如下:
```ts
const routes: Routes = [
@@ -95,9 +63,12 @@ const routes: Routes = [
component: LayoutBasicComponent,
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
- { path: 'dashboard', component: DashboardComponent, data: { title: '仪表盘' } },
+ {
+ path: 'dashboard',
+ loadChildren: () => import('./dashboard/routes').then(m => m.routes)
+ },
// 业务子模块
- // { path: 'trade', loadChildren: './trade/trade.module#TradeModule' }
+ // { path: 'trade', loadChildren: () => import('./trade/routes').then(m => m.routes) },
]
},
// 空白布局
@@ -107,17 +78,8 @@ const routes: Routes = [
children: [
]
},
- // passport
- {
- path: 'passport',
- component: LayoutPassportComponent,
- children: [
- { path: 'login', component: UserLoginComponent },
- ]
- },
- // 单页不包裹Layout
- { path: 'passport/callback/:type', component: CallbackComponent },
- { path: 'exception', loadChildren: () => import('./exception/exception.module').then((m) => m.ExceptionModule) },
+ { path: '', loadChildren: () => import('./passport/routes').then(m => m.routes) },
+ { path: 'exception', loadChildren: () => import('./exception/routes').then(m => m.routes) },
// 未命中路由全部跳转至 `exception/404` 页面上
{ path: '**', redirectTo: 'exception/404' },
];
@@ -125,11 +87,9 @@ const routes: Routes = [
> 上述在业务模块中使用了 `LayoutBasicComponent` 基础布局、用户授权使用了 `LayoutPassportComponent` 用户授权布局以及 `LayoutBlankComponent` 空白布局,以上三种布局都可以在 [layout](https://github.com/ng-alain/ng-alain/tree/master/src/app/layout) 目录下找得到。
-例如当用户访问 `/dashboard` 路由时,会先经过 `LayoutBasicComponent` -> `DashboardComponent`,最终换形成一个庞大的组件树来表示一个具体的页面。NG-ALAIN 脚手架帮助你完成大多数工作,而一个新入门的人更多只需要关心 `DashboardComponent` 业务组件该如何实现。
-
-**什么情况下不使用懒加载?**
+> NG-ALAIN 也提供一些[商用主题](https://e.ng-alain.com/)可供选择。
-Angular 启动是从顶层组件开始向下渲染,当遇到懒模块时会先发起脚本请求,此时会因为网络请求导致仪表盘或登录页短暂的空白,这对体验并不好。
+例如当用户访问 `/dashboard` 路由时,会先经过 `LayoutBasicComponent` -> `DashboardComponent`,最终换形成一个庞大的组件树来表示一个具体的页面。NG-ALAIN 脚手架帮助你完成大多数工作,而一个新入门的人更多只需要关心 `DashboardComponent` 业务组件该如何实现。
### 用户认证与授权
@@ -180,10 +140,9 @@ const routes: Routes = [
### 拦截网络请求
-网络请求是一项非常频繁的工作,如果想优雅的在业务组件内使用网络请求动作的话,那么将服务端URL前缀、异常处理、Token 刷新等操作集中处理是必不可少的,NG-ALAIN 脚手架提供一个 [default.interceptor.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/net/default.interceptor.ts) 文件。它会利用令牌 `HTTP_INTERCEPTORS` 起到一种拦截器的效果。
-
-有关以上集中处理的动作细节,请参考 [default.interceptor.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/net/default.interceptor.ts) 文件。
+网络请求是一项非常频繁的工作,如果想优雅的在业务组件内使用网络请求动作的话,那么将服务端URL前缀、异常处理、Token 刷新等操作集中处理是必不可少的,NG-ALAIN 脚手架提供一个 [net](https://github.com/ng-alain/ng-alain/tree/master/src/app/core/net) 文件。它会利用令牌 `HttpInterceptorFn` 起到一种拦截器的效果。
+有关更多细节,请参考 [default.interceptor.ts](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/net/default.interceptor.ts) 文件。
## IDE
diff --git a/docs/i18n.en-US.md b/docs/i18n.en-US.md
index e6f0220fb2..649fc86e47 100644
--- a/docs/i18n.en-US.md
+++ b/docs/i18n.en-US.md
@@ -28,10 +28,9 @@ registerLocaleData(zh);
```ts
import { en_US, provideNzI18n } from 'ng-zorro-antd/i18n';
-@NgModule({
+export const appConfig: ApplicationConfig = {
providers: [provideNzI18n(en_US)]
-})
-export class App1Module {}
+};
```
Of course, you can also use runtime changes:
@@ -75,19 +74,16 @@ switchLanguage() {
## ALAIN_I18N_TOKEN
-`@delon/*` class library has many data interface properties with the _i18n_ typeface (for example: `page-header`, `st` column description, `Menu` menu data, etc.) when you want the data for these components. When the interface can dynamically switch automatically according to the Key value in the current language, you also need to define a self-implementation service interface for `ALAIN_I18N_TOKEN` (for example: [I18NService](https://github.com/ng-alain/ng-alain/blob) /master/src/app/core/i18n/i18n.service.ts)) and register under the root module.
+`@delon/*` class library has many data interface properties with the _i18n_ typeface (for example: `page-header`, `st` column description, `Menu` menu data, etc.) when you want the data for these components. When the interface can dynamically switch automatically according to the Key value in the current language, you also need to define a self-implementation service interface for `ALAIN_I18N_TOKEN` (for example: [I18NService](https://github.com/ng-alain/ng-alain/blob) /master/src/app/core/i18n/i18n.service.ts)) and register under the `app.config.ts` file.
```ts
-import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { I18NService } from '@core';
-@NgModule({
- ...
+export const appConfig: ApplicationConfig = {
providers: [
- { provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false }
+ provideAlain({ config: alainConfig, defaultLang, i18nClass: I18NService }),
]
-})
-export class AppModule {}
+};
```
### i18n pipe
@@ -140,59 +136,54 @@ In order to make language uniformity, NG-ALAIN provides a simple unified configu
#### Chinese Version
```ts
-// #region i18n
import { default as ngLang } from '@angular/common/locales/zh';
import { provideNzI18n, zh_CN as zorroLang } from 'ng-zorro-antd/i18n';
import { DELON_LOCALE, zh_CN as delonLang } from '@delon/theme';
-const LANG = {
+import { zhCN as dateLang } from 'date-fns/locale';
+import { I18NService } from '@core';
+
+const defaultLang: AlainProvideLang = {
abbr: 'zh',
ng: ngLang,
zorro: zorroLang,
+ date: dateLang,
delon: delonLang,
};
-// register angular
-import { registerLocaleData } from '@angular/common';
-registerLocaleData(LANG.ng, LANG.abbr);
-const LANG_PROVIDES = [
- { provide: LOCALE_ID, useValue: LANG.abbr },
- provideNzI18n(LANG.zorro),
- { provide: DELON_LOCALE, useValue: LANG.delon },
-];
-// #endregion
-@NgModule({
- providers: [...LANG_PROVIDES],
-})
-export class AppModule {}
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideAlain({ config: alainConfig, defaultLang, i18nClass: I18NService }),
+ ]
+};
```
#### English version
```ts
-// #region i18n
import { default as ngLang } from '@angular/common/locales/en';
import { provideNzI18n, en_US as zorroLang } from 'ng-zorro-antd/i18n';
import { DELON_LOCALE, en_US as delonLang } from '@delon/theme';
+import { en_US as dateLang } from 'date-fns/locale';
const LANG = {
abbr: 'en',
ng: ngLang,
zorro: zorroLang,
delon: delonLang,
};
-// register angular
-import { registerLocaleData } from '@angular/common';
-registerLocaleData(LANG.ng, LANG.abbr);
-const LANG_PROVIDES = [
- { provide: LOCALE_ID, useValue: LANG.abbr },
- provideNzI18n(LANG.zorro),
- { provide: DELON_LOCALE, useValue: LANG.delon },
-];
-// #endregion
-@NgModule({
- providers: [...LANG_PROVIDES],
-})
-export class AppModule {}
+const defaultLang: AlainProvideLang = {
+ abbr: 'en',
+ ng: ngLang,
+ zorro: zorroLang,
+ date: dateLang,
+ delon: delonLang,
+};
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideAlain({ config: alainConfig, defaultLang, i18nClass: I18NService }),
+ ]
+};
```
### Command Line
diff --git a/docs/i18n.zh-CN.md b/docs/i18n.zh-CN.md
index 561e3259f9..d5abe45a42 100644
--- a/docs/i18n.zh-CN.md
+++ b/docs/i18n.zh-CN.md
@@ -28,10 +28,9 @@ NG-ZORRO 国际化默认是中文版,例如默认为英文版本:
```ts
import { en_US, provideNzI18n } from 'ng-zorro-antd/i18n';
-@NgModule({
+export const appConfig: ApplicationConfig = {
providers: [provideNzI18n(en_US)]
-})
-export class App1Module {}
+};
```
当然,也可以使用运行时更改:
@@ -75,19 +74,16 @@ switchLanguage() {
## ALAIN_I18N_TOKEN
-`@delon/*` 类库有许多带有 _i18n_ 字样的数据接口属性(例如:`page-header`、`st` 列描述、`Menu` 菜单数据等等),当你希望这些组件的数据接口能动态根据 Key 值按当前语言自动切换时,你还需要对 `ALAIN_I18N_TOKEN` 定义一个自实现服务接口(例如:[I18NService](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/i18n/i18n.service.ts)),并在根模块下注册。
+`@delon/*` 类库有许多带有 _i18n_ 字样的数据接口属性(例如:`page-header`、`st` 列描述、`Menu` 菜单数据等等),当你希望这些组件的数据接口能动态根据 Key 值按当前语言自动切换时,你还需要对 `ALAIN_I18N_TOKEN` 定义一个自实现服务接口(例如:[I18NService](https://github.com/ng-alain/ng-alain/blob/master/src/app/core/i18n/i18n.service.ts)),并在 `app.config.ts` 下注册。
```ts
-import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { I18NService } from '@core';
-@NgModule({
- ...
+export const appConfig: ApplicationConfig = {
providers: [
- { provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false }
+ provideAlain({ config: alainConfig, defaultLang, i18nClass: I18NService }),
]
-})
-export class AppModule {}
+};
```
### i18n管道
@@ -140,59 +136,54 @@ export class I18nTestComponent {
#### 中文版
```ts
-// #region i18n
import { default as ngLang } from '@angular/common/locales/zh';
import { provideNzI18n, zh_CN as zorroLang } from 'ng-zorro-antd/i18n';
import { DELON_LOCALE, zh_CN as delonLang } from '@delon/theme';
-const LANG = {
+import { zhCN as dateLang } from 'date-fns/locale';
+import { I18NService } from '@core';
+
+const defaultLang: AlainProvideLang = {
abbr: 'zh',
ng: ngLang,
zorro: zorroLang,
+ date: dateLang,
delon: delonLang,
};
-// register angular
-import { registerLocaleData } from '@angular/common';
-registerLocaleData(LANG.ng, LANG.abbr);
-const LANG_PROVIDES = [
- { provide: LOCALE_ID, useValue: LANG.abbr },
- provideNzI18n(LANG.zorro),
- { provide: DELON_LOCALE, useValue: LANG.delon },
-];
-// #endregion
-@NgModule({
- providers: [...LANG_PROVIDES],
-})
-export class AppModule {}
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideAlain({ config: alainConfig, defaultLang, i18nClass: I18NService }),
+ ]
+};
```
#### 英文版
```ts
-// #region i18n
import { default as ngLang } from '@angular/common/locales/en';
import { provideNzI18n, en_US as zorroLang } from 'ng-zorro-antd/i18n';
import { DELON_LOCALE, en_US as delonLang } from '@delon/theme';
+import { en_US as dateLang } from 'date-fns/locale';
const LANG = {
abbr: 'en',
ng: ngLang,
zorro: zorroLang,
delon: delonLang,
};
-// register angular
-import { registerLocaleData } from '@angular/common';
-registerLocaleData(LANG.ng, LANG.abbr);
-const LANG_PROVIDES = [
- { provide: LOCALE_ID, useValue: LANG.abbr },
- provideNzI18n(LANG.zorro),
- { provide: DELON_LOCALE, useValue: LANG.delon },
-];
-// #endregion
-@NgModule({
- providers: [...LANG_PROVIDES],
-})
-export class AppModule {}
+const defaultLang: AlainProvideLang = {
+ abbr: 'en',
+ ng: ngLang,
+ zorro: zorroLang,
+ date: dateLang,
+ delon: delonLang,
+};
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideAlain({ config: alainConfig, defaultLang, i18nClass: I18NService }),
+ ]
+};
```
### 命令行
diff --git a/docs/module.en-US.md b/docs/module.en-US.md
index 5faa7bbe9d..0e8c327795 100644
--- a/docs/module.en-US.md
+++ b/docs/module.en-US.md
@@ -36,7 +36,6 @@ NG-ZORRO, @delon/abc, @delon/chart, etc. have changed from all import to on-dema
+ Angular Module: `BrowserModule`, `BrowserAnimationsModule`, `HttpClientModule`
+ `AlainThemeModule` Theme system
-+ `DelonMockModule` Mock data
+ `AlainAuthModule` User authentication module
+ `AlainACLModule` Privilege module
+ Internationalization module
diff --git a/docs/module.zh-CN.md b/docs/module.zh-CN.md
index aa3a3562b8..9c2f01dbcb 100644
--- a/docs/module.zh-CN.md
+++ b/docs/module.zh-CN.md
@@ -36,7 +36,6 @@ NG-ZORRO、@delon/abc、@delon/chart 等从版本11开始由一次性导入改
+ Angular 模块:`BrowserModule`、`BrowserAnimationsModule`、`HttpClientModule`
+ `AlainThemeModule` 主题系统
-+ `DelonMockModule` Mock数据
+ `AlainAuthModule` 用户认证模块
+ `AlainACLModule` 权限模块
+ 国际化模块
diff --git a/docs/new-component.en-US.md b/docs/new-component.en-US.md
index 9ef4eff165..061e81e036 100644
--- a/docs/new-component.en-US.md
+++ b/docs/new-component.en-US.md
@@ -47,7 +47,9 @@ import { Component, Input } from '@angular/core';
template: `
![]()
-
{{ desc }}
+ @if (desc) {
+
{{ desc }}
+ }
`,
styleUrls: [ './index.less' ]
diff --git a/docs/new-component.zh-CN.md b/docs/new-component.zh-CN.md
index ca2b899a21..5c77b94da6 100644
--- a/docs/new-component.zh-CN.md
+++ b/docs/new-component.zh-CN.md
@@ -47,7 +47,9 @@ import { Component, Input } from '@angular/core';
template: `
![]()
-
{{ desc }}
+ @if (desc) {
+
{{ desc }}
+ }
`,
styleUrls: [ './index.less' ]
diff --git a/docs/ssr.md b/docs/ssr.md
index 74a1ef962a..5b1c4f3391 100644
--- a/docs/ssr.md
+++ b/docs/ssr.md
@@ -77,7 +77,7 @@ export class AuthStorageStore implements IStore {
```diff
const alainProvides = [
- { provide: ALAIN_CONFIG, useValue: alainConfig },
+ provideAlainConfig(alainConfig)
+ { provide: DA_STORE_TOKEN, useClass: AuthStorageStore },
];
```
diff --git a/docs/upgrade-v16.en-US.md b/docs/upgrade-v16.en-US.md
deleted file mode 100644
index 4037d2b3df..0000000000
--- a/docs/upgrade-v16.en-US.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-order: 1000
-type: Basic
-title: Upgrade to version 16.0
-hot: true
----
-
-> This guide applies to the current version ng-alain >= `15`;
-> If you encounter problems during the upgrade process, feel free to comment here.
-> If you find any errors in this guide, please point out
-> Or you have encountered a new problem and solved it, welcome to comment here.
-
-## Before upgrade
-
-1. Make sure `Node.js` >= `16.10.0`.
-2. Create a new branch, or use other methods to back up the current project.
-3. Delete the `package-lock.json` or `yarn.lock` file.
-
-### 1.Upgrade dependencies
-
-- Upgrade Angular to 15.x version, Run `ng update @angular/core@16 @angular/cli@16 @angular-eslint/schematics@16 ng-zorro-antd@16 ng-alain@16`.
-- _Run `ng update @angular/cdk@16`, if you have used `@angular/cdk`._
-- **If any warning messages appear in the console, follow the prompts to modify the corresponding code.**
-
-> NG-ALAIN scaffolding upgrade all change files, please refer to: [#2394](https://github.com/ng-alain/ng-alain/pull/2394/files).
diff --git a/docs/upgrade-v16.zh-CN.md b/docs/upgrade-v16.zh-CN.md
deleted file mode 100644
index 9103fed256..0000000000
--- a/docs/upgrade-v16.zh-CN.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-order: 1000
-type: Basic
-title: 升级到 16.0 版本
-hot: true
----
-
-> 本指南适用于当前版本 ng-alain >= `15` ;
-> 如果在升级过程中遇到问题,欢迎提出。提问前请阅读 [如何向开源社区提问题](https://github.com/seajs/seajs/issues/545)
-> 如果发现本指南存在遗漏/错误,请指出!
-> 或者你遇到了新的问题并解决了,欢迎补充!
-
-## 开始之前
-
-1. 首先确保你 `Node.js` >= `16.10.0`
-2. 创建新的分支,或者使用其他方式备份当前项目
-3. 删除项目下 `package-lock.json` 或 `yarn.lock` 文件
-
-## 升级步骤
-
-### 升级相关依赖
-
-- 将项目升级到 Angular 15 运行 `ng update @angular/core@16 @angular/cli@16 @angular-eslint/schematics@16 ng-zorro-antd@16 ng-alain@16`。
-- _如果你有单独使用 `@angular/cdk` 请执行 `ng update @angular/cdk@16`_
-- **如果控制台出现警告消息请按提示修改对应代码**
-
-> NG-ALAIN脚手架升级全部变更文件,请参考:[#2394](https://github.com/ng-alain/ng-alain/pull/2394/files)。
diff --git a/docs/upgrade-v17.en-US.md b/docs/upgrade-v17.en-US.md
new file mode 100644
index 0000000000..5b2c28a9cb
--- /dev/null
+++ b/docs/upgrade-v17.en-US.md
@@ -0,0 +1,52 @@
+---
+order: 1000
+type: Basic
+title: Upgrade to version 17.0
+hot: true
+---
+
+> This guide applies to the current version ng-alain >= `16`;
+> If you encounter problems during the upgrade process, feel free to comment here.
+> If you find any errors in this guide, please point out
+> Or you have encountered a new problem and solved it, welcome to comment here.
+
+
+## Before upgrade
+
+1. Make sure `Node.js` >= `18.13.0`.
+2. Create a new branch, or use other methods to back up the current project.
+3. Delete the `package-lock.json` or `yarn.lock` file.
+
+### 1.Upgrade dependencies
+
+- Upgrade Angular to 16.x version, Run `ng update @angular/core@17 @angular/cli@17 @angular-eslint/schematics@17 ng-zorro-antd@17 ng-alain@17`.
+- _Run `ng update @angular/cdk@17`, if you have used `@angular/cdk`._
+- **If any warning messages appear in the console, follow the prompts to modify the corresponding code.**
+
+> NG-ALAIN scaffolding upgrade all change files, please refer to: [#2394](https://github.com/ng-alain/ng-alain/pull/2394/files).
+
+## Optional
+
+The optional part of the work is centered around Standalone. Currently, NG-ALAIN will reserve some DEMO pages using the NgModule writing method. [#2442](https://github.com/ng-alain/ng-alain/pull/2442/files) contains all changes in this PR.
+
+### Upgrade to Standalone
+
+- Use `bootstrapApplication` instead of `platformBrowserDynamic`
+- Use `app.config.ts` instead of `global-config.module.ts`, `app.module.ts`
+
+The `layout`, `dashboard`, `passport` have been rewritten using standalone and can be modified according to [#2442](https://github.com/ng-alain/ng-alain/pull/2442/files) changes.
+
+### DI configuration
+
+- NG-ALAIN removes all DI configuration modes such as `Module. forRoot`. Of course, for compatibility, the `NgModule` writing method is still retained.
+- All DI configurations are maintained by `provide*`, see `app.config.ts` for more details
+- If you use a third party but does not provide a similar `provide` writing method, you need to transition through `importProvidersFrom`
+
+### HTTP interceptor
+
+- Angular 17 has strict requirements for the order of interceptors to be visible. This upgrade has all been modified to the `HttpInterceptorFn` writing method (see `provideHttpClient` for details)
+- If you upgrade from NG-ALAIN 16, `withInterceptorsFromDi()` will be imported by default to be compatible with the `HTTP_INTERCEPTORS` writing method, but it is recommended to upgrade to the new writing method as much as possible, please refer to [#2442](https://github.com/ng-alain/ng-alain/pull/2442/files)
+
+### About `@delon/form`
+
+- Convert all widgets with low frequency into optional imports. All widgets will be automatically imported during this upgrade to ensure compatibility.
diff --git a/docs/upgrade-v17.zh-CN.md b/docs/upgrade-v17.zh-CN.md
new file mode 100644
index 0000000000..3a049cca09
--- /dev/null
+++ b/docs/upgrade-v17.zh-CN.md
@@ -0,0 +1,53 @@
+---
+order: 1000
+type: Basic
+title: 升级到 17.0 版本
+hot: true
+---
+
+> 本指南适用于当前版本 ng-alain >= `16` ;
+> 如果在升级过程中遇到问题,欢迎提出。提问前请阅读 [如何向开源社区提问题](https://github.com/seajs/seajs/issues/545)
+> 如果发现本指南存在遗漏/错误,请指出!
+> 或者你遇到了新的问题并解决了,欢迎补充!
+
+## 开始之前
+
+1. 首先确保你 `Node.js` >= `18.13.0`
+2. 创建新的分支,或者使用其他方式备份当前项目
+3. 删除项目下 `package-lock.json` 或 `yarn.lock` 文件
+
+## 升级步骤
+
+### 升级相关依赖
+
+- 将项目升级到 Angular 16 运行 `ng update @angular/core@17 @angular/cli@17 @angular-eslint/schematics@17 ng-zorro-antd@17 ng-alain@17`。
+- _如果你有单独使用 `@angular/cdk` 请执行 `ng update @angular/cdk@17`_
+- **如果控制台出现警告消息请按提示修改对应代码**
+
+> NG-ALAIN脚手架升级全部变更文件,请参考:[#2394](https://github.com/ng-alain/ng-alain/pull/2394/files)。
+
+## 可选部分
+
+可选部分的主要工作都是围绕 Standalone 展开,目前 NG-ALAIN 会保留部分DEMO页使用 NgModule 写法。[#2442](https://github.com/ng-alain/ng-alain/pull/2442/files) 包含着这部分变动的所有内容。
+
+### 升级为 Standalone
+
+- 使用 `bootstrapApplication` 替代 `platformBrowserDynamic`
+- 使用 `app.config.ts` 替代 `global-config.module.ts`, `app.module.ts`
+
+其中 `layout`, `dashboard`, `passport` 目录采用 standalone 写法,可根据 [#2442](https://github.com/ng-alain/ng-alain/pull/2442/files) 变动自行修改。
+
+### DI配置
+
+- NG-ALAIN 移除掉所有 `Module. forRoot` 之类的 DI 配置模式,当然为了兼容,依然保留 `NgModule` 写法
+- 所有DI配置都是 `provide*` 来维护,更多细节见 `app.config.ts`
+- 如果您使用第三方但不提供类似 `provide` 写法时,只需要借助 `importProvidersFrom` 过渡
+
+### HTTP拦截器
+
+- Angular 17 对拦截器顺序可见有严格的要求,本次升级已经全部修改为 `HttpInterceptorFn` 写法(细节见 `provideHttpClient`)
+- 若从 NG-ALAIN 16 升级默认为会导入 `withInterceptorsFromDi()` 用于兼容 `HTTP_INTERCEPTORS` 写法,但建议尽可能升级新的写法,可参考 [#2442](https://github.com/ng-alain/ng-alain/pull/2442/files)
+
+### 关于 `@delon/form`
+
+- 将小部件频率较低的全部转化为可选导入,本次升级时会自动导入所有小部件来保证兼容
diff --git a/package.json b/package.json
index e2a21a1b1b..c44c55a8de 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "delon",
- "version": "16.4.2",
+ "version": "17.0.1",
"description": "Delon is a set of essential modules for NG-ALAIN.",
"keywords": [
"delon",
@@ -21,7 +21,7 @@
},
"homepage": "https://ng-alain.com",
"engines": {
- "node": "^18.10.0"
+ "node": "^18.13.0"
},
"scripts": {
"ng-high-memory": "node --max_old_space_size=8000 ./node_modules/@angular/cli/bin/ng",
@@ -40,7 +40,6 @@
"analyze:view": "source-map-explorer src/dist/browser/*.js",
"site:gen": "node scripts/site/main init && ng-alain-plugin-theme -t=themeCss && ng-alain-plugin-theme -t=colorLess",
"site:build": "npm run site:gen && ng b site && npm run site:ngsw && npm run site:minify && npm run site:sitemap && npm run site:helper",
- "site:build:ssr": "npm run site:gen && npm run ssr:prerender && npm run site:ngsw && npm run site:minify && npm run site:sitemap && npm run site:helper",
"site:helper": "bash scripts/ci/helper.sh",
"site:minify": "node scripts/build/minify.js",
"site:sitemap": "node scripts/build/sitemap.js",
@@ -49,26 +48,25 @@
"pre-publish": "node scripts/publish/publish.js && node scripts/publish/publish-scaffold.js",
"publish:next": "bash scripts/publish/publish.sh -next",
"publish": "bash scripts/publish/publish.sh",
- "sync-scaffold-version": "node scripts/publish/sync-scaffold-version.js",
- "ssr": "npm run ng-high-memory run site:serve-ssr",
- "ssr:serve": "node src/dist/server/main.js",
- "ssr:prerender": "npm run ng-high-memory run site:prerender"
+ "sync-scaffold-version": "node scripts/publish/sync-scaffold-version.js"
},
"dependencies": {
- "@angular/animations": "^16.2.0",
- "@angular/common": "^16.2.0",
- "@angular/compiler": "^16.2.0",
- "@angular/core": "^16.2.0",
- "@angular/forms": "^16.2.0",
- "@angular/platform-browser": "^16.2.0",
- "@angular/platform-browser-dynamic": "^16.2.0",
- "@angular/router": "^16.2.0",
+ "@angular/animations": "^17.0.0",
+ "@angular/common": "^17.0.0",
+ "@angular/compiler": "^17.0.0",
+ "@angular/core": "^17.0.0",
+ "@angular/forms": "^17.0.0",
+ "@angular/platform-browser": "^17.0.0",
+ "@angular/platform-browser-dynamic": "^17.0.0",
+ "@angular/router": "^17.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
- "zone.js": "~0.13.0",
- "@angular/service-worker": "^16.2.0",
- "@angular/platform-server": "^16.2.0",
- "@angular/elements": "^16.2.0",
+ "zone.js": "~0.14.2",
+ "@angular/service-worker": "^17.0.0",
+ "@angular/platform-server": "^17.0.0",
+ "@angular/ssr": "^17.0.0",
+ "express": "^4.18.2",
+ "@angular/elements": "^17.0.0",
"@antv/data-set": "^0.11.8",
"@antv/g2": "^5.1.6",
"echarts": "^5.4.3",
@@ -78,55 +76,53 @@
"ajv-formats": "^2.1.1",
"extend": "^3.0.2",
"file-saver": "^2.0.5",
- "ng-github-button": "^16.0.0",
- "ng-zorro-antd": "^16.2.2",
- "ngx-color": "~9.0.0",
- "ngx-countdown": "^16.0.0",
- "ngx-highlight-js": "^16.1.0",
- "ngx-tinymce": "^16.0.0",
+ "ng-github-button": "^17.0.0",
+ "ng-zorro-antd": "^17.0.1",
+ "@angular/cdk": "^17.0.0",
+ "ngx-countdown": "^17.0.0",
+ "ngx-highlight-js": "^17.0.0",
+ "ngx-tinymce": "^17.0.0",
"qrious": "^4.0.2",
"@webcomponents/custom-elements": "^1.6.0",
"aos": "^3.0.0-beta.6",
- "@ng-util/monaco-editor": "^16.0.0",
- "@nguniversal/express-engine": "^16.2.0",
- "express": "^4.18.2",
+ "@ng-util/monaco-editor": "^17.0.0",
"isutf8": "^4.0.0",
- "@github/hotkey": "^2.0.1"
+ "@github/hotkey": "^2.3.0",
+ "ng-antd-color-picker": "^0.0.2"
},
"devDependencies": {
- "@angular-devkit/build-angular": "^16.2.0",
- "@angular/cli": "~16.2.0",
- "@angular/compiler-cli": "^16.2.0",
- "@types/jasmine": "~4.3.0",
- "jasmine-core": "~4.6.0",
+ "@angular-devkit/build-angular": "^17.0.0",
+ "@angular/cli": "^17.0.0",
+ "@angular/compiler-cli": "^17.0.0",
+ "@types/jasmine": "~5.1.0",
+ "jasmine-core": "~5.1.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
- "typescript": "~5.1.3",
- "codelyzer": "^6.0.2",
+ "typescript": "~5.2.2",
+ "jasmine": "^5.1.0",
"jasmine-spec-reporter": "^7.0.0",
- "protractor": "~7.0.0",
"ts-node": "~10.9.1",
- "@angular/language-service": "^16.2.0",
- "@types/jasminewd2": "~2.0.10",
+ "@angular/language-service": "^17.0.0",
+ "@types/jasminewd2": "~2.0.13",
"karma-junit-reporter": "^2.0.1",
"karma-spec-reporter": "0.0.36",
"karma-viewport": "^1.0.9",
- "@types/aos": "^3.0.4",
- "@types/file-saver": "^2.0.5",
- "@types/deep-extend": "^0.6.0",
- "@types/extend": "^3.0.1",
- "@types/mockjs": "^1.0.7",
+ "@types/aos": "^3.0.7",
+ "@types/file-saver": "^2.0.7",
+ "@types/deep-extend": "^0.6.2",
+ "@types/extend": "^3.0.4",
+ "@types/mockjs": "^1.0.10",
"@types/parse5": "^7.0.0",
"karma-summary-reporter": "^3.1.1",
"karma-parallel": "^0.3.1",
"chalk": "^5.3.0",
"codecov": "^3.8.3",
- "conventional-changelog-cli": "^4.0.0",
+ "conventional-changelog-cli": "^4.1.0",
"fs-extra": "^11.1.1",
- "@types/fs-extra": "^11.0.1",
+ "@types/fs-extra": "^11.0.4",
"husky": "^8.0.3",
"jsonml.js": "^0.1.0",
"klaw-sync": "^6.0.0",
@@ -136,12 +132,12 @@
"mark-twain": "^2.0.3",
"mockjs": "^1.1.0",
"mustache": "^4.2.0",
- "ng-packagr": "^16.2.1",
+ "ng-packagr": "^17.0.0",
"parse5": "^7.1.2",
- "prettier": "^3.0.2",
+ "prettier": "^3.1.0",
"readline-sync": "^1.4.10",
"stream": "0.0.2",
- "stylelint": "^15.10.3",
+ "stylelint": "^15.11.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-declaration-block-no-ignored-properties": "^2.7.0",
"stylelint-config-clean-order": "^5.2.0",
@@ -151,32 +147,30 @@
"plyr": "^3.7.8",
"screenfull": "^6.0.2",
"less-bundle-promise": "^1.0.11",
- "ng-alain-codelyzer": "^0.0.1",
"ng-alain-sts": "^0.0.2",
- "ng-alain-plugin-theme": "^15.0.1",
+ "ng-alain-plugin-theme": "^16.0.0",
"tsconfig-paths": "^4.2.0",
- "@nguniversal/builders": "^16.2.0",
"@types/express": "^4.17.17",
+ "@types/node": "^18.18.0",
"html-minifier-terser": "^7.2.0",
"terser": "^5.19.2",
- "@commitlint/cli": "^17.7.1",
- "@commitlint/config-angular": "^17.7.0",
- "@angular-eslint/builder": "~16.1.1",
- "@angular-eslint/eslint-plugin": "~16.1.1",
- "@angular-eslint/eslint-plugin-template": "~16.1.1",
- "@angular-eslint/schematics": "~16.1.1",
- "@angular-eslint/template-parser": "~16.1.1",
- "@typescript-eslint/eslint-plugin": "~6.4.1",
- "@typescript-eslint/parser": "~6.4.1",
- "eslint": "^8.48.0",
+ "@commitlint/cli": "^17.8.1",
+ "@commitlint/config-angular": "^17.8.1",
+ "@angular-eslint/builder": "^17.0.0",
+ "@angular-eslint/eslint-plugin": "^17.0.0",
+ "@angular-eslint/eslint-plugin-template": "^17.0.0",
+ "@angular-eslint/schematics": "^17.0.0",
+ "@angular-eslint/template-parser": "^17.0.0",
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
+ "@typescript-eslint/parser": "^6.10.0",
+ "eslint": "^8.53.0",
"eslint-config-prettier": "~9.0.0",
- "eslint-plugin-import": "~2.28.1",
- "eslint-plugin-jsdoc": "~46.5.0",
+ "eslint-plugin-import": "~2.29.0",
+ "eslint-plugin-jsdoc": "~46.5.1",
"eslint-plugin-prefer-arrow": "~1.2.3",
- "eslint-plugin-prettier": "~5.0.0",
- "eslint-plugin-deprecation": "~1.5.0",
+ "eslint-plugin-prettier": "~5.0.1",
+ "eslint-plugin-deprecation": "~2.0.0",
"lint-staged": "^14.0.1",
- "raw-loader": "^4.0.2",
"swagger-typescript-api": "^12.0.4",
"sitemap": "^7.1.1"
},
diff --git a/packages/abc/auto-focus/auto-focus.directive.spec.ts b/packages/abc/auto-focus/auto-focus.directive.spec.ts
index 9c898ed0ef..814282c85c 100644
--- a/packages/abc/auto-focus/auto-focus.directive.spec.ts
+++ b/packages/abc/auto-focus/auto-focus.directive.spec.ts
@@ -42,9 +42,11 @@ describe('abc: auto-focus', () => {
@Component({
template: `
-
-
-
+ @if (showInput) {
+
+
+
+ }
`
})
class TestComponent {
diff --git a/packages/abc/auto-focus/demo/simple.md b/packages/abc/auto-focus/demo/simple.md
index 422015c499..97ef3a8ba3 100644
--- a/packages/abc/auto-focus/demo/simple.md
+++ b/packages/abc/auto-focus/demo/simple.md
@@ -20,9 +20,11 @@ import { Component } from '@angular/core';
selector: 'app-demo',
template: `
-
-
-
+ @if (showInput) {
+
+
+
+ }
`,
})
export class DemoComponent {
diff --git a/packages/abc/avatar-list/avatar-list.component.html b/packages/abc/avatar-list/avatar-list.component.html
index 0e724cbbeb..f39eacc01e 100644
--- a/packages/abc/avatar-list/avatar-list.component.html
+++ b/packages/abc/avatar-list/avatar-list.component.html
@@ -1,17 +1,23 @@
- -
-
-
-
- - 0" [ngClass]="cls">
-
-
+ @for (i of items; track $index) {
+ -
+ @if (i.tips) {
+
+ } @else {
+
+ }
+
+ }
+ @if (exceedCount > 0) {
+ -
+
+
+ }
diff --git a/packages/abc/cell/cell-host.directive.ts b/packages/abc/cell/cell-host.directive.ts
index 1b2069cc23..3b4d140c9d 100644
--- a/packages/abc/cell/cell-host.directive.ts
+++ b/packages/abc/cell/cell-host.directive.ts
@@ -6,7 +6,8 @@ import { CellService } from './cell.service';
import { CellWidgetData } from './cell.types';
@Directive({
- selector: '[cell-widget-host]'
+ selector: '[cell-widget-host]',
+ standalone: true
})
export class CellHostDirective implements OnInit {
@Input() data!: CellWidgetData;
diff --git a/packages/abc/cell/cell.component.ts b/packages/abc/cell/cell.component.ts
index 6f99e839f8..3c2e6293d8 100644
--- a/packages/abc/cell/cell.component.ts
+++ b/packages/abc/cell/cell.component.ts
@@ -1,3 +1,4 @@
+import { NgTemplateOutlet } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@@ -13,6 +14,7 @@ import {
SimpleChange,
ViewEncapsulation
} from '@angular/core';
+import { FormsModule } from '@angular/forms';
import type { SafeValue } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
@@ -20,9 +22,16 @@ import { Subscription } from 'rxjs';
import { updateHostClass } from '@delon/util/browser';
import { BooleanInput, InputBoolean } from '@delon/util/decorator';
import { WINDOW } from '@delon/util/token';
+import { NzBadgeModule } from 'ng-zorro-antd/badge';
+import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
+import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzImage, NzImageService } from 'ng-zorro-antd/image';
+import { NzRadioModule } from 'ng-zorro-antd/radio';
+import { NzTagModule } from 'ng-zorro-antd/tag';
+import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
+import { CellHostDirective } from './cell-host.directive';
import { CellService } from './cell.service';
import type { CellDefaultText, CellOptions, CellTextResult, CellValue, CellWidgetData } from './cell.types';
@@ -30,69 +39,90 @@ import type { CellDefaultText, CellOptions, CellTextResult, CellValue, CellWidge
selector: 'cell, [cell]',
template: `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ _unit }}
-
-
+ @switch (safeOpt.type) {
+ @case ('checkbox') {
+
+ }
+ @case ('radio') {
+
+ }
+ @case ('link') {
+
+ }
+ @case ('tag') {
+
+
+
+ }
+ @case ('badge') {
+
+ }
+ @case ('widget') {
+
+ }
+ @case ('img') {
+ @for (i of $any(_text); track $index) {
+
+ }
+ }
+ @default {
+ @if (isText) {
+
+ } @else {
+
+ }
+ @if (_unit) {
+ {{ _unit }}
+ }
+ }
+ }
- {{ safeOpt.default?.text }}
-
-
+ @if (showDefault) {
+ {{ safeOpt.default?.text }}
+ } @else {
+ @if (safeOpt.tooltip) {
+
+
+
+ } @else {
-
-
+ }
+ }
-
+ @if (loading) {
+
+ } @else {
+
+ }
`,
exportAs: 'cell',
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
- encapsulation: ViewEncapsulation.None
+ encapsulation: ViewEncapsulation.None,
+ standalone: true,
+ imports: [
+ FormsModule,
+ NgTemplateOutlet,
+ NzCheckboxModule,
+ NzRadioModule,
+ NzIconModule,
+ NzTagModule,
+ NzBadgeModule,
+ NzToolTipModule,
+ CellHostDirective
+ ]
})
export class CellComponent implements OnChanges, OnDestroy {
static ngAcceptInputType_loading: BooleanInput;
@@ -151,7 +181,7 @@ export class CellComponent implements OnChanges, OnDestroy {
private setClass(): void {
const { el, renderer } = this;
- const { renderType, size } = this.safeOpt;
+ const { renderType, size, type } = this.safeOpt;
updateHostClass(el.nativeElement, renderer, {
[`cell`]: true,
[`cell__${renderType}`]: renderType != null,
@@ -160,7 +190,7 @@ export class CellComponent implements OnChanges, OnDestroy {
[`cell__has-default`]: this.showDefault,
[`cell__disabled`]: this.disabled
});
- el.nativeElement.dataset.type = this.safeOpt.type;
+ el.nativeElement.setAttribute('data-type', `${type}`);
}
ngOnChanges(changes: { [p in keyof CellComponent]?: SimpleChange }): void {
diff --git a/packages/abc/cell/cell.module.ts b/packages/abc/cell/cell.module.ts
index 67f835083d..7d4590c983 100644
--- a/packages/abc/cell/cell.module.ts
+++ b/packages/abc/cell/cell.module.ts
@@ -25,9 +25,10 @@ const COMPS = [CellComponent];
NzTagModule,
NzToolTipModule,
NzIconModule,
- NzImageModule
+ NzImageModule,
+ ...COMPS,
+ CellHostDirective
],
- declarations: [...COMPS, CellHostDirective],
exports: COMPS
})
export class CellModule {}
diff --git a/packages/abc/cell/cell.spec.ts b/packages/abc/cell/cell.spec.ts
index 53aba8f159..c61a163a0b 100644
--- a/packages/abc/cell/cell.spec.ts
+++ b/packages/abc/cell/cell.spec.ts
@@ -16,6 +16,7 @@ import { CellComponent } from './cell.component';
import { CellModule } from './cell.module';
import { CellService } from './cell.service';
import { CellFuValue, CellOptions, CellWidgetData } from './cell.types';
+import { provideCellWidgets } from './provide';
const DATE = new Date(2022, 0, 1, 1, 2, 3);
@@ -292,6 +293,19 @@ describe('abc: cell', () => {
});
});
+ describe('[widget]', () => {
+ it('via provideCellWidgets', () => {
+ TestBed.configureTestingModule({
+ imports: [CellModule, NoopAnimationsModule],
+ declarations: [TestComponent, TestWidget],
+ providers: [provideCellWidgets({ KEY: TestWidget.KEY, type: TestWidget })]
+ });
+ ({ fixture, dl, context } = createTestContext(TestComponent));
+ page = new PageObject();
+ page.update('1', { widget: { key: TestWidget.KEY, data: 'new data' } }).check('1-new data');
+ });
+ });
+
class PageObject {
update(value: unknown, options?: CellOptions): this {
context.value = value;
diff --git a/packages/abc/cell/demo/simple.md b/packages/abc/cell/demo/simple.md
index c634c4ddeb..85f00a4fb9 100644
--- a/packages/abc/cell/demo/simple.md
+++ b/packages/abc/cell/demo/simple.md
@@ -26,7 +26,9 @@ import { CellBadge, CellFuValue, CellOptions, CellRenderType } from '@delon/abc/
selector: 'app-demo',
template: `
-
{{ i | json }} => |
+ @for (i of baseList; track $index) {
+
{{ i | json }} => |
+ }
date-fn => |
mega => |
mask => |
@@ -107,10 +109,12 @@ import { CellBadge, CellFuValue, CellOptions, CellRenderType } from '@delon/abc/
default =>
|
-
- {{ i }} =>
- |
-
+ @for (i of typeList; track $index) {
+
+ {{ i }} =>
+ |
+
+ }
size =>
| ,
| ,
@@ -128,7 +132,9 @@ import { CellBadge, CellFuValue, CellOptions, CellRenderType } from '@delon/abc/
Async =>
|
-
Again
+ @if (!asyncLoading) {
+
Again
+ }
Unit => |
Text Unit => |
diff --git a/packages/abc/cell/index.en-US.md b/packages/abc/cell/index.en-US.md
index 47063de66d..d5efedd24a 100644
--- a/packages/abc/cell/index.en-US.md
+++ b/packages/abc/cell/index.en-US.md
@@ -62,7 +62,7 @@ Cell formatting is supported for multiple data types, and supports widget mode.
- `enum` Enum
- `widget` Custom widget
-**Custom widget**
+## Custom widget
Just implement the `CellWidgetInstance` interface, for example:
@@ -95,28 +95,14 @@ export class CellTestWidget implements CellWidgetInstance {
`data` is a fixed parameter, including `value`, `options` configuration items.
-Secondly, you also need to call `CellService.registerWidget` to register the widget; usually a new module will be built separately, for example:
+Finally, register the widget through `provideCellWidgets` under `app.config.ts`, for example:
```ts
-import { NgModule } from '@angular/core';
-
-import { CellService } from '@delon/abc/cell';
-
-import { CellTestWidget } from './test';
-import { SharedModule } from '../shared.module';
-
-export const CELL_WIDGET_COMPONENTS = [CellTestWidget];
-
-@NgModule({
- declarations: CELL_WIDGET_COMPONENTS,
- imports: [SharedModule],
- exports: CELL_WIDGET_COMPONENTS
-})
-export class CellWidgetModule {
- constructor(srv: CellService) {
- srv.registerWidget(CellTestWidget.KEY, CellTestWidget);
- }
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideCellWidgets(
+ { KEY: CellTestWidget.KEY, type: CellTestWidget }
+ ),
+ ]
}
```
-
-Finally, just register `CellWidgetModule` under the root module.
diff --git a/packages/abc/cell/index.ts b/packages/abc/cell/index.ts
index 397ff56e11..e16b303798 100644
--- a/packages/abc/cell/index.ts
+++ b/packages/abc/cell/index.ts
@@ -3,3 +3,4 @@ export * from './cell-host.directive';
export * from './cell.module';
export * from './cell.service';
export * from './cell.types';
+export * from './provide';
diff --git a/packages/abc/cell/index.zh-CN.md b/packages/abc/cell/index.zh-CN.md
index 5767686247..49bf73a562 100644
--- a/packages/abc/cell/index.zh-CN.md
+++ b/packages/abc/cell/index.zh-CN.md
@@ -62,7 +62,7 @@ module: import { CellModule } from '@delon/abc/cell';
- `enum` 枚举转换
- `widget` 自定义小部件
-**自定义小部件**
+## 自定义小部件
实现 `CellWidgetInstance` 接口即可,例如:
@@ -95,28 +95,14 @@ export class CellTestWidget implements CellWidgetInstance {
其中 `data` 为固定参数,包含 `value`、`options` 配置项。
-其次,还需要调用 `CellService.registerWidget` 注册小部件;通常会单独构建一个新的模块,例如:
+最后在 `app.config.ts` 下通过 `provideCellWidgets` 注册小部件,例如:
```ts
-import { NgModule } from '@angular/core';
-
-import { CellService } from '@delon/abc/cell';
-
-import { CellTestWidget } from './test';
-import { SharedModule } from '../shared.module';
-
-export const CELL_WIDGET_COMPONENTS = [CellTestWidget];
-
-@NgModule({
- declarations: CELL_WIDGET_COMPONENTS,
- imports: [SharedModule],
- exports: CELL_WIDGET_COMPONENTS
-})
-export class CellWidgetModule {
- constructor(srv: CellService) {
- srv.registerWidget(CellTestWidget.KEY, CellTestWidget);
- }
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideCellWidgets(
+ { KEY: CellTestWidget.KEY, type: CellTestWidget }
+ ),
+ ]
}
```
-
-最后,将 `CellWidgetModule` 注册到根模块下即可。
diff --git a/packages/abc/cell/provide.ts b/packages/abc/cell/provide.ts
new file mode 100644
index 0000000000..1fc429c6c5
--- /dev/null
+++ b/packages/abc/cell/provide.ts
@@ -0,0 +1,26 @@
+import { ENVIRONMENT_INITIALIZER, EnvironmentProviders, inject, makeEnvironmentProviders } from '@angular/core';
+
+import type { NzSafeAny } from 'ng-zorro-antd/core/types';
+
+import { CellService } from './cell.service';
+
+export interface CellWidgetProvideConfig {
+ KEY: string;
+ type: NzSafeAny;
+}
+
+/**
+ * Just only using Standalone widgets
+ */
+export function provideCellWidgets(...widgets: CellWidgetProvideConfig[]): EnvironmentProviders {
+ return makeEnvironmentProviders([
+ {
+ provide: ENVIRONMENT_INITIALIZER,
+ multi: true,
+ useValue: () => {
+ const srv = inject(CellService);
+ widgets.forEach(widget => srv.registerWidget(widget.KEY, widget.type));
+ }
+ }
+ ]);
+}
diff --git a/packages/abc/count-down/count-down.component.ts b/packages/abc/count-down/count-down.component.ts
index 233ac2bc9a..fcac7c55aa 100644
--- a/packages/abc/count-down/count-down.component.ts
+++ b/packages/abc/count-down/count-down.component.ts
@@ -14,7 +14,9 @@ import { CountdownComponent, CountdownConfig, CountdownEvent } from 'ngx-countdo
@Component({
selector: 'count-down',
exportAs: 'countDown',
- template: `
`,
+ template: `@if (config) {
+
+ }`,
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
diff --git a/packages/abc/count-down/count-down.spec.ts b/packages/abc/count-down/count-down.spec.ts
index d746d318e8..491e1d5082 100644
--- a/packages/abc/count-down/count-down.spec.ts
+++ b/packages/abc/count-down/count-down.spec.ts
@@ -50,12 +50,16 @@ describe('abc: count-down', () => {
@Component({
template: `
-
-
-
-
-
-
+ @if (config) {
+
+
+
+ }
+ @if (target) {
+
+
+
+ }
`
})
class TestComponent {
diff --git a/packages/abc/date-picker/range-shortcut.component.ts b/packages/abc/date-picker/range-shortcut.component.ts
index 8b997df8cf..414131d656 100644
--- a/packages/abc/date-picker/range-shortcut.component.ts
+++ b/packages/abc/date-picker/range-shortcut.component.ts
@@ -6,12 +6,9 @@ import { AlainDateRangePickerShortcutItem } from '@delon/util/config';
selector: '',
template: `
-
+ @for (i of list; track $index) {
+
+ }
`
})
diff --git a/packages/abc/date-picker/range.directive.ts b/packages/abc/date-picker/range.directive.ts
index c82c3e1e3a..f1458ddbd4 100644
--- a/packages/abc/date-picker/range.directive.ts
+++ b/packages/abc/date-picker/range.directive.ts
@@ -72,10 +72,12 @@ export class RangePickerDirective implements OnDestroy, AfterViewInit {
@Host() @Optional() private nativeComp: NzRangePickerComponent,
private vcr: ViewContainerRef
) {
- assert(
- !!nativeComp,
- `It should be attached to nz-range-picker component, for example: '
'`
- );
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ assert(
+ !!nativeComp,
+ `It should be attached to nz-range-picker component, for example: '
'`
+ );
+ }
const cog = configSrv.merge('dataRange', {
nzFormat: 'yyyy-MM-dd',
nzAllowClear: true,
diff --git a/packages/abc/down-file/demo/simple.md b/packages/abc/down-file/demo/simple.md
index f8dd3807e8..3ba952a35b 100644
--- a/packages/abc/down-file/demo/simple.md
+++ b/packages/abc/down-file/demo/simple.md
@@ -19,17 +19,18 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-demo',
template: `
-
+ @for (i of fileTypes; track $index) {
+
+ }
`,
})
export class DemoComponent {
diff --git a/packages/abc/down-file/down-file.spec.ts b/packages/abc/down-file/down-file.spec.ts
index 9df116ac8e..2349f68ecd 100644
--- a/packages/abc/down-file/down-file.spec.ts
+++ b/packages/abc/down-file/down-file.spec.ts
@@ -204,21 +204,22 @@ describe('abc: down-file', () => {
@Component({
template: `
-
+ @for (i of fileTypes; track $index) {
+
+ }
`
})
class TestComponent {
diff --git a/packages/abc/ellipsis/ellipsis.component.html b/packages/abc/ellipsis/ellipsis.component.html
index dfdc9fa0b5..90c453c456 100644
--- a/packages/abc/ellipsis/ellipsis.component.html
+++ b/packages/abc/ellipsis/ellipsis.component.html
@@ -1,35 +1,42 @@
-
+ @if (tooltip) {
+
+
+
+
+ } @else {
-
-
+ }
-
-
-
-
+@switch (type) {
+ @case ('default') {
+
+ }
+ @case ('length') {
+
{{ text }}
-
-
-
+ }
+ @case ('line-clamp') {
+
-
-
-
-
-
{{ linsWord }}
-
-
-
{{ text }}
+ }
+ @case ('line') {
+
+
+
+
{{ linsWord }}
+
+
+ {{ text }}
+
-
-
+ }
+}
diff --git a/packages/abc/exception/exception.component.html b/packages/abc/exception/exception.component.html
index 711fe8a2e4..9896894978 100644
--- a/packages/abc/exception/exception.component.html
+++ b/packages/abc/exception/exception.component.html
@@ -8,8 +8,10 @@
-
+ @if (!hasCon) {
+
+ }
diff --git a/packages/abc/footer-toolbar/footer-toolbar.component.html b/packages/abc/footer-toolbar/footer-toolbar.component.html
index 8ebe9798f4..a3c8accd89 100644
--- a/packages/abc/footer-toolbar/footer-toolbar.component.html
+++ b/packages/abc/footer-toolbar/footer-toolbar.component.html
@@ -2,6 +2,8 @@
{{ extra }}
diff --git a/packages/abc/global-footer/global-footer.component.html b/packages/abc/global-footer/global-footer.component.html
index b7cd71f70d..2e7e0fbb83 100644
--- a/packages/abc/global-footer/global-footer.component.html
+++ b/packages/abc/global-footer/global-footer.component.html
@@ -1,9 +1,15 @@
- 0 || items.length > 0" class="global-footer__links">
-
-
-
+@if (links.length > 0 || items.length > 0) {
+
+}
diff --git a/packages/abc/hotkey/hotkey.directive.ts b/packages/abc/hotkey/hotkey.directive.ts
index 1ca9981d46..914f4d78d4 100644
--- a/packages/abc/hotkey/hotkey.directive.ts
+++ b/packages/abc/hotkey/hotkey.directive.ts
@@ -3,7 +3,7 @@ import { Directive, ElementRef, Input, NgZone, OnDestroy } from '@angular/core';
import { install, uninstall } from '@github/hotkey';
-@Directive({ selector: '[hotkey]' })
+@Directive({ selector: '[hotkey]', standalone: true })
export class HotkeyDirective implements OnDestroy {
/**
* Specify [hotkey format](https://github.com/github/hotkey#hotkey-string-format)
diff --git a/packages/abc/hotkey/hotkey.module.ts b/packages/abc/hotkey/hotkey.module.ts
index f63cfc3b1e..2aa068362e 100644
--- a/packages/abc/hotkey/hotkey.module.ts
+++ b/packages/abc/hotkey/hotkey.module.ts
@@ -5,7 +5,7 @@ import { HotkeyDirective } from './hotkey.directive';
const DIRECTIVES = [HotkeyDirective];
@NgModule({
- declarations: DIRECTIVES,
+ imports: DIRECTIVES,
exports: DIRECTIVES
})
export class HotkeyModule {}
diff --git a/packages/abc/let/demo/async.md b/packages/abc/let/demo/async.md
index a8d7f57fb4..21ddb9bc2f 100644
--- a/packages/abc/let/demo/async.md
+++ b/packages/abc/let/demo/async.md
@@ -23,13 +23,13 @@ import { NzSafeAny } from 'ng-zorro-antd/core/types';
@Component({
selector: 'app-demo',
template: `
-
+ @if (timer$ !== null) {
Timer value: {{ time }}
Timer value: {{ time }}
Timer value: {{ time }}
-
+ }
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
diff --git a/packages/abc/let/let.directive.ts b/packages/abc/let/let.directive.ts
index a9037f179b..24e72a0794 100644
--- a/packages/abc/let/let.directive.ts
+++ b/packages/abc/let/let.directive.ts
@@ -14,7 +14,7 @@ export class LetContext {
}
}
-@Directive({ selector: '[let]' })
+@Directive({ selector: '[let]', standalone: true })
export class LetDirective {
@Input({ required: true }) let!: T;
diff --git a/packages/abc/let/let.module.ts b/packages/abc/let/let.module.ts
index 2aa1707e90..b9199e5f04 100644
--- a/packages/abc/let/let.module.ts
+++ b/packages/abc/let/let.module.ts
@@ -5,7 +5,7 @@ import { LetDirective } from './let.directive';
const DIRECTIVES = [LetDirective];
@NgModule({
- declarations: DIRECTIVES,
+ imports: DIRECTIVES,
exports: DIRECTIVES
})
export class LetModule {}
diff --git a/packages/abc/loading/demo/custom.md b/packages/abc/loading/demo/custom.md
index bdba2b00dc..0a1171c027 100644
--- a/packages/abc/loading/demo/custom.md
+++ b/packages/abc/loading/demo/custom.md
@@ -20,7 +20,10 @@ import { LoadingCustom, LoadingService } from '@delon/abc/loading';
@Component({
selector: 'app-demo',
- template: ` `,
+ template: `
+ @for (i of customs; track $index) {
+
+ }`,
})
export class DemoComponent {
customs: LoadingCustom[] = [
diff --git a/packages/abc/loading/loading.component.html b/packages/abc/loading/loading.component.html
index 10a7170a14..2ac6e2a728 100644
--- a/packages/abc/loading/loading.component.html
+++ b/packages/abc/loading/loading.component.html
@@ -1,8 +1,18 @@
-
-{{ options.text }}
+@if (options.type! !== 'text') {
+
+ @switch (options.type) {
+ @case ('spin') {
+
+ }
+ @case ('icon') {
+
+ }
+ @default {
+
+ }
+ }
+
+}
+@if (options.text) {
+ {{ options.text }}
+}
diff --git a/packages/abc/lodop/demo/design.md b/packages/abc/lodop/demo/design.md
index 4137ac9e76..5c146ab46c 100644
--- a/packages/abc/lodop/demo/design.md
+++ b/packages/abc/lodop/demo/design.md
@@ -21,37 +21,41 @@ import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-demo',
template: `
-
- 请先下载Lodop插件。
-
-
+ @if (error) {
+
+ 请先下载Lodop插件。
+
+ }
+ @if (lodop && !error) {
+
+ }
`,
})
export class DemoComponent {
diff --git a/packages/abc/lodop/demo/print.md b/packages/abc/lodop/demo/print.md
index 195a4c0f19..99baeb073a 100644
--- a/packages/abc/lodop/demo/print.md
+++ b/packages/abc/lodop/demo/print.md
@@ -21,62 +21,69 @@ import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-demo',
template: `
-
-
- 请先下载Lodop插件, 安装后点击重试。
-
-
-
+ @if (error) {
+
+
+ 请先下载Lodop插件, 安装后点击重试。
+
+
+ } @else {
+
+ }
`,
})
export class DemoComponent {
diff --git a/packages/abc/notice-icon/notice-icon-tab.component.html b/packages/abc/notice-icon/notice-icon-tab.component.html
index d81f604bdb..c748288e18 100644
--- a/packages/abc/notice-icon/notice-icon-tab.component.html
+++ b/packages/abc/notice-icon/notice-icon-tab.component.html
@@ -1,11 +1,17 @@
-
-
![not found]()
-
-
- {{ data.emptyText || locale.emptyText }}
-
-
-
+@if (data.list?.length === 0) {
+
+ @if (data.emptyImage) {
+
![not found]()
+ }
+
+
+ {{ data.emptyText || locale.emptyText }}
+
+
+
+} @else {
+
+}
@@ -15,17 +21,23 @@
{{ item.title }}
-
+ @if (item.extra) {
+
+ }
-
-
- {{ item.description }}
-
-
- {{ item.datetime }}
+ @if (item.description) {
+
+
+ {{ item.description }}
+
+
+ }
+ @if (item.datetime) {
+ {{ item.datetime }}
+ }
diff --git a/packages/abc/notice-icon/notice-icon.component.html b/packages/abc/notice-icon/notice-icon.component.html
index 9a4fa89c07..f4d5bcf94b 100644
--- a/packages/abc/notice-icon/notice-icon.component.html
+++ b/packages/abc/notice-icon/notice-icon.component.html
@@ -3,27 +3,29 @@
-
+@if (data!.length <= 0) {
-
- 0"
- nz-dropdown
- [nzVisible]="popoverVisible"
- (nzVisibleChange)="onVisibleChange($event)"
- nzTrigger="click"
- nzPlacement="bottomRight"
- [nzOverlayClassName]="overlayCls"
- [nzDropdownMenu]="noticeMenu"
->
-
-
-
-
-
-
-
-
-
-
-
+} @else {
+
+
+
+
+
+
+ @for (i of data; track $index) {
+
+
+
+ }
+
+
+
+}
diff --git a/packages/abc/observers/observer-size.ts b/packages/abc/observers/observer-size.ts
index a094874bfd..3d81d96a9f 100644
--- a/packages/abc/observers/observer-size.ts
+++ b/packages/abc/observers/observer-size.ts
@@ -80,7 +80,8 @@ export class SizeObserver implements OnDestroy {
@Directive({
selector: '[observeSize]',
- exportAs: 'observeSize'
+ exportAs: 'observeSize',
+ standalone: true
})
export class ObserverSize implements AfterViewInit, OnDestroy {
private _sub$: Subscription | null = null;
@@ -117,6 +118,6 @@ export class ObserverSize implements AfterViewInit, OnDestroy {
@NgModule({
exports: [ObserverSize],
- declarations: [ObserverSize]
+ imports: [ObserverSize]
})
export class ObserversModule {}
diff --git a/packages/abc/onboarding/onboarding.component.html b/packages/abc/onboarding/onboarding.component.html
index 96717c30d4..be3aab5b2c 100644
--- a/packages/abc/onboarding/onboarding.component.html
+++ b/packages/abc/onboarding/onboarding.component.html
@@ -1,62 +1,54 @@
-
-
-
-
-
-
-
-
+ @if (footer) {
+
+ }
diff --git a/packages/chart/chart-echarts/echarts.component.ts b/packages/chart/chart-echarts/echarts.component.ts
index eaad848828..e0fa424aee 100644
--- a/packages/chart/chart-echarts/echarts.component.ts
+++ b/packages/chart/chart-echarts/echarts.component.ts
@@ -34,7 +34,9 @@ import {
selector: 'chart-echarts, [chart-echarts]',
exportAs: 'chartECharts',
template: `
-
+ @if (!loaded) {
+
+ }
`,
host: {
diff --git a/packages/chart/custom/custom.component.ts b/packages/chart/custom/custom.component.ts
index 99345d131f..d3c54fa3dd 100644
--- a/packages/chart/custom/custom.component.ts
+++ b/packages/chart/custom/custom.component.ts
@@ -16,8 +16,10 @@ import { InputNumber, NumberInput } from '@delon/util/decorator';
selector: 'g2,g2-custom',
exportAs: 'g2Custom',
template: `
-
-
+ @if (!loaded) {
+
+ }
+
`,
host: {
'[style.height.px]': 'height'
diff --git a/packages/chart/docs/demo/resizable.md b/packages/chart/docs/demo/resizable.md
index 15600195cc..a5dffbd4a4 100644
--- a/packages/chart/docs/demo/resizable.md
+++ b/packages/chart/docs/demo/resizable.md
@@ -14,10 +14,11 @@ type: example
Use [nz-resizable](https://ng.ant.design/experimental/resizable/en) to build a resizable container.
```ts
-import { Component, ViewChild } from '@angular/core';
-import { G2BarClickItem, G2BarComponent, G2BarData } from '@delon/chart/bar';
+import { Component, ViewChild, inject } from '@angular/core';
+
+import { G2BarClickItem, G2BarComponent, G2BarData, G2BarModule } from '@delon/chart/bar';
import { NzMessageService } from 'ng-zorro-antd/message';
-import { NzResizeEvent } from 'ng-zorro-antd/resizable';
+import { NzResizableModule, NzResizeEvent } from 'ng-zorro-antd/resizable';
@Component({
selector: 'app-demo',
@@ -30,21 +31,23 @@ import { NzResizeEvent } from 'ng-zorro-antd/resizable';
(nzResize)="onResize($event)"
style="background: #eee;border: 1px solid #ddd; padding: 16px;"
>
-
-
+
+
`,
+ standalone: true,
+ imports: [NzResizableModule, G2BarModule]
})
export class DemoComponent {
+ private msg = inject(NzMessageService);
@ViewChild('bar') private readonly barComp!: G2BarComponent;
width = 400;
height = 200;
private id = -1;
- constructor(private msg: NzMessageService) {}
salesData: G2BarData[] = new Array(12).fill({}).map((_i, idx) => ({
x: `${idx + 1}月`,
y: Math.floor(Math.random() * 1000) + 200,
- color: idx > 5 ? '#f50' : undefined,
+ color: idx > 5 ? '#f50' : undefined
}));
handleClick(data: G2BarClickItem): void {
diff --git a/packages/chart/docs/getting-started.en-US.md b/packages/chart/docs/getting-started.en-US.md
index 12329bd056..51538d8651 100644
--- a/packages/chart/docs/getting-started.en-US.md
+++ b/packages/chart/docs/getting-started.en-US.md
@@ -29,7 +29,7 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
- { provide: ALAIN_CONFIG, useValue: alainConfig }
+ provideAlainConfig(alainConfig)
]
};
}
@@ -105,9 +105,9 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
- { provide: ALAIN_CONFIG, useValue: alainConfig }
+ provideAlainConfig(alainConfig)
]
};
}
}
-```
\ No newline at end of file
+```
diff --git a/packages/chart/docs/getting-started.zh-CN.md b/packages/chart/docs/getting-started.zh-CN.md
index ba34699d4c..9ee80c98a4 100644
--- a/packages/chart/docs/getting-started.zh-CN.md
+++ b/packages/chart/docs/getting-started.zh-CN.md
@@ -41,7 +41,7 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
- { provide: ALAIN_CONFIG, useValue: alainConfig }
+ provideAlainConfig(alainConfig)
]
};
}
@@ -117,7 +117,7 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
- { provide: ALAIN_CONFIG, useValue: alainConfig }
+ provideAlainConfig(alainConfig)
]
};
}
diff --git a/packages/chart/gauge/gauge.component.ts b/packages/chart/gauge/gauge.component.ts
index 558eb08d5c..4dd49c78e3 100644
--- a/packages/chart/gauge/gauge.component.ts
+++ b/packages/chart/gauge/gauge.component.ts
@@ -9,7 +9,9 @@ import type { NzSafeAny } from 'ng-zorro-antd/core/types';
@Component({
selector: 'g2-gauge',
exportAs: 'g2Gauge',
- template: ``,
+ template: `@if (!loaded) {
+
+ }`,
host: {
'[class.g2-gauge]': 'true'
},
diff --git a/packages/chart/number-info/number-info.component.html b/packages/chart/number-info/number-info.component.html
index d0054ca5fa..08db60486c 100644
--- a/packages/chart/number-info/number-info.component.html
+++ b/packages/chart/number-info/number-info.component.html
@@ -1,16 +1,26 @@
-
- {{ title }}
-
-
- {{ subTitle }}
-
+@if (title) {
+
+ {{ title }}
+
+}
+@if (subTitle) {
+
+ {{ subTitle }}
+
+}
{{ total }}
- {{ suffix }}
-
-
- {{ subTotal }}
-
+ @if (suffix) {
+ {{ suffix }}
+ }
+ @if (status || subTotal) {
+
+ {{ subTotal }}
+ @if (status) {
+
+ }
+
+ }
diff --git a/packages/chart/pie/pie.component.html b/packages/chart/pie/pie.component.html
index b877d452d7..b0e7dfb50d 100644
--- a/packages/chart/pie/pie.component.html
+++ b/packages/chart/pie/pie.component.html
@@ -1,25 +1,37 @@
-
+@if (!loaded) {
+
+}
-
-
-
-
-
-
-
-
-
-
+ @if (subTitle || total) {
+
+ @if (subTitle) {
+
+
+
+
+
+ }
+ @if (total) {
+
+ }
-
+ }
-
- -
-
- {{ item.x }}
-
- {{ item.percent }}%
-
-
-
+@if (hasLegend && legendData?.length) {
+
+ @for (item of legendData; track $index) {
+ -
+
+ {{ item.x }}
+
+ {{ item.percent }}%
+
+
+ }
+
+}
diff --git a/packages/chart/radar/radar.component.html b/packages/chart/radar/radar.component.html
index 492c5d8db8..3a056bb0af 100644
--- a/packages/chart/radar/radar.component.html
+++ b/packages/chart/radar/radar.component.html
@@ -1,18 +1,18 @@
-
+@if (!loaded) {
+
+}
{{ title }}
-
-
-
- {{ i.name }}
-
{{ i.value }}
+@if (hasLegend) {
+
+ @for (i of legendData; track $index) {
+
+
+ {{ i.name }}
+
{{ i.value }}
+
+ }
-
+}
diff --git a/packages/chart/single-bar/demo/basic.md b/packages/chart/single-bar/demo/basic.md
index fc826dca91..10ec47b015 100644
--- a/packages/chart/single-bar/demo/basic.md
+++ b/packages/chart/single-bar/demo/basic.md
@@ -23,15 +23,17 @@ import { Component, ViewEncapsulation } from '@angular/core';
-
- {{ idx + 1 }} |
-
-
- |
-
-
- |
-
+ @for (i of list; track $index) {
+
+ {{ $index + 1 }} |
+
+
+ |
+
+
+ |
+
+ }
`,
diff --git a/packages/chart/tag-cloud/tag-cloud.component.ts b/packages/chart/tag-cloud/tag-cloud.component.ts
index c45db08d73..ac2a2b55a0 100644
--- a/packages/chart/tag-cloud/tag-cloud.component.ts
+++ b/packages/chart/tag-cloud/tag-cloud.component.ts
@@ -21,7 +21,9 @@ export interface G2TagCloudClickItem {
@Component({
selector: 'g2-tag-cloud',
exportAs: 'g2TagCloud',
- template: `
`,
+ template: `@if (!loaded) {
+
+ }`,
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
diff --git a/packages/chart/timeline/demo/max-axis.md b/packages/chart/timeline/demo/max-axis.md
index ae56e21237..9a4b80aec8 100644
--- a/packages/chart/timeline/demo/max-axis.md
+++ b/packages/chart/timeline/demo/max-axis.md
@@ -16,7 +16,9 @@ import { G2TimelineData, G2TimelineMap } from '@delon/chart/timeline';
selector: 'app-demo',
template: `
-
+ @for (i of axisList; track $index) {
+
+ }
`
})
diff --git a/packages/chart/timeline/timeline.component.ts b/packages/chart/timeline/timeline.component.ts
index 1c94b85abe..d6f3328a87 100644
--- a/packages/chart/timeline/timeline.component.ts
+++ b/packages/chart/timeline/timeline.component.ts
@@ -67,7 +67,9 @@ export interface G2TimelineClickItem {
{{ title }}
-
+ @if (!loaded) {
+
+ }
`,
preserveWhitespaces: false,
diff --git a/packages/chart/trend/trend.component.ts b/packages/chart/trend/trend.component.ts
index 2bce55077a..13c85f6a7b 100644
--- a/packages/chart/trend/trend.component.ts
+++ b/packages/chart/trend/trend.component.ts
@@ -7,7 +7,9 @@ import { BooleanInput, InputBoolean } from '@delon/util/decorator';
exportAs: 'trend',
template: `
-
+ @if (flag) {
+
+ }
`,
host: {
'[class.trend]': 'true',
diff --git a/packages/chart/water-wave/water-wave.component.html b/packages/chart/water-wave/water-wave.component.html
index d52f3d709a..43b53b1b64 100644
--- a/packages/chart/water-wave/water-wave.component.html
+++ b/packages/chart/water-wave/water-wave.component.html
@@ -2,8 +2,10 @@
-
- {{ title }}
-
+ @if (title) {
+
+ {{ title }}
+
+ }
{{ percent }}%
diff --git a/packages/form/docs/customize.en-US.md b/packages/form/docs/customize.en-US.md
index a93e13f1fe..c864a75238 100644
--- a/packages/form/docs/customize.en-US.md
+++ b/packages/form/docs/customize.en-US.md
@@ -6,7 +6,7 @@ type: Documents
## Foreword
-`@delon/form` try our best to meet the needs of different environments, in addition to the built-in basic component widgets, you can further expand the requirements in two ways:
+`@delon/form` try our best to meet the needs of different environments, in addition to the built-in basic widgets (Some require manual registration), you can further expand the requirements in two ways:
## Custom widget in sf
@@ -18,22 +18,17 @@ Making a set of widgets for project can lead to faster development work.
### How to making widget
-**Third-party library**
-
-By default `@delon/form` implements some common third-party library widgets, which are called third-party component widgets. This widget exists in [widgets-third](https://github.com/ng-alain /delon/tree/master/packages/form/widgets-third) directory; you can use directly.
-
-| Name | Description | Document | Source |
-| ---- | ----------- | -------- | ------ |
-| `markdown` | Markdown Editor | [Document](/form/markdown) | [Source](https://github.com/ng-alain/delon/tree/master/packages/form/widgets-third/markdown) |
-| `tinymce` | Tinymce Editor | [Document](/form/tinymce) | [Source](https://github.com/ng-alain/delon/tree/master/packages/form/widgets-third/tinymce) |
-
**Create widgets**
A widget is a component. You only need to inherit `ControlWidget` to create a widget. For example:
```ts
-import { Component, OnInit } from '@angular/core';
-import { ControlWidget } from '@delon/form';
+import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
+import { ControlWidget, DelonFormModule, SFWidgetProvideConfig } from '@delon/form';
+
+export function withTestWidget(): SFWidgetProvideConfig {
+ return { KEY: 'test', type: TestWidget };
+}
@Component({
selector: 'sf-tinymce',
@@ -47,11 +42,17 @@ import { ControlWidget } from '@delon/form';
[loading]="loading">
- `
+ `,
+ preserveWhitespaces: false,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ standalone: true,
+ imports: [DelonFormModule]
})
-export class TinymceWidget extends ControlWidget implements OnInit {
- static readonly KEY = 'tinymce';
+class TestWidget extends ControlWidget implements OnInit {
+ /* KEY value for registering widgets */
+ static readonly KEY = 'test';
+ // It is recommended to use `ngOnInit` to obtain the parameters required by the component.
config: any;
loadingTip: string;
@@ -60,6 +61,7 @@ export class TinymceWidget extends ControlWidget implements OnInit {
this.config = this.ui.config || {};
}
+ // reset can better solve the problem of new data required during the form reset process
reset(value: string) {
}
@@ -81,34 +83,32 @@ The widget is manually trigger changed detection during the rendering process. I
### Register
-Define the widget component in the root module (includes: `declarations`), import `WidgetRegistry` in the module and register the custom widget.
+Recommended to define a widget called `withXWidth` and return `SFWidgetProvideConfig` type, for example:
```ts
-@NgModule({
- declarations: [ TinymceWidget ],
- imports: [
- DelonFormModule.forRoot()
- ]
-})
-export class AppModule {
- constructor(widgetRegistry: WidgetRegistry) {
- widgetRegistry.register(TinymceWidget.KEY, TinymceWidget);
- }
+export function withTestWidget(): SFWidgetProvideConfig {
+ return { KEY: 'test', type: TestWidget };
}
```
-Of course, for more friendly maintenance, recommended to define a Json schema module in the Shared directory. Please refer to [ng-alain implementation](https://github.com/ng-alain/ng-alain/blob/master/ Src/app/shared/json-schema/json-schema.module.ts).
+Finally, register via `provideSFConfig`:
+
+```ts
+provideSFConfig({ widgets: [ withTestWidget() ] })
+```
+
+For more friendly maintenance, recommended to define a project-specific collection in the `shared` directory. If you are interested, please refer to [NG-ALAIN implementation](https://github.com/ng-alain/ng-alain/blob/master/src/app/shared/json-schema/) or refer to [@delon/form/widgets/autocomplete](https://github.com/ng-alain/delon/tree/master/packages/form/widgets/autocomplete).
### Usage
Just like other widgets, just specify the `widget` value, for example:
```json
-"intro": {
+"test": {
"type": "string",
"ui": {
- "widget": "tinymce",
- "loadingTip": "loading..."
+ "widget": "test",
+ "data": "widget parameters"
}
}
```
diff --git a/packages/form/docs/customize.zh-CN.md b/packages/form/docs/customize.zh-CN.md
index 774b03ea0d..e36c38586c 100644
--- a/packages/form/docs/customize.zh-CN.md
+++ b/packages/form/docs/customize.zh-CN.md
@@ -6,7 +6,7 @@ type: Documents
## 写在前面
-`@delon/form` 尽可能满足不同需求,除现有内置的十几种基础组件小部件外,可以通过以下两种方式进一步扩展需求:
+`@delon/form` 尽可能满足不同需求,除现有内置的十几种基础小部件(部分需要手动注册)外,可以通过以下两种方式进一步扩展需求:
## 自定义小部件
@@ -18,24 +18,17 @@ type: Documents
### 编写小部件
-**常见小部件库**
-
-默认情况下 @delon/form 实现了一些常见需求,但需要额外类库支持的,称它为第三方组件小部件,这一部分小部件存在于[widgets-third](https://github.com/ng-alain/delon/tree/master/packages/form/widgets-third)目录里;你可以直接复制使用。
-
-这些组件包括:
-
-| 名称 | 描述 | 文档 | 源代码 |
-| --- | ---- | ---- | ---- |
-| `markdown` | Markdown 编辑器 | [文档](/form/markdown) | [源代码](https://github.com/ng-alain/delon/tree/master/packages/form/widgets-third/markdown) |
-| `tinymce` | Tinymce 富文本框 | [文档](/form/tinymce) | [源代码](https://github.com/ng-alain/delon/tree/master/packages/form/widgets-third/tinymce) |
-
**自己创建小部件**
-小部件就是一个组件,你只需要继承 `ControlWidget` 就相当于构建一个小部件,其结构如下:
+小部件就是一个组件,你只需要继承 `ControlWidget` 就相当于构建一个小部件,例如:
```ts
-import { Component, OnInit } from '@angular/core';
-import { ControlWidget } from '@delon/form';
+import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
+import { ControlWidget, DelonFormModule, SFWidgetProvideConfig } from '@delon/form';
+
+export function withTestWidget(): SFWidgetProvideConfig {
+ return { KEY: 'test', type: TestWidget };
+}
@Component({
selector: 'sf-tinymce',
@@ -49,11 +42,15 @@ import { ControlWidget } from '@delon/form';
[loading]="loading">
- `
+ `,
+ preserveWhitespaces: false,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ standalone: true,
+ imports: [DelonFormModule]
})
-export class TinymceWidget extends ControlWidget implements OnInit {
+class TestWidget extends ControlWidget implements OnInit {
/* 用于注册小部件 KEY 值 */
- static readonly KEY = 'tinymce';
+ static readonly KEY = 'test';
// 组件所需要的参数,建议使用 `ngOnInit` 获取
config: any;
@@ -86,34 +83,32 @@ export class TinymceWidget extends ControlWidget implements OnInit {
### 注册小部件
-在根模块中定义(`declarations`)注册小部件组件,同时在模块中导入 `WidgetRegistry` 并注册自定义小部件。
+建议在小部件内定义一个名为 `withXWidth` 并返回 `SFWidgetProvideConfig`,例如:
```ts
-@NgModule({
- declarations: [ TinymceWidget ],
- imports: [
- DelonFormModule.forRoot()
- ]
-})
-export class AppModule {
- constructor(widgetRegistry: WidgetRegistry) {
- widgetRegistry.register(TinymceWidget.KEY, TinymceWidget);
- }
+export function withTestWidget(): SFWidgetProvideConfig {
+ return { KEY: 'test', type: TestWidget };
}
```
-当然为了更友好的维护,建议在Shared目录下定义一个专属 Json schema 模块,有兴趣可参考 [ng-alain实现](https://github.com/ng-alain/ng-alain/blob/master/src/app/shared/json-schema/json-schema.module.ts)。
+最后,通过 `provideSFConfig` 来注册:
+
+```ts
+provideSFConfig({ widgets: [ withTestWidget() ] })
+```
+
+当然为了更友好的维护,建议在Shared目录下定义项目专属的集合,有兴趣可参考 [ng-alain实现](https://github.com/ng-alain/ng-alain/blob/master/src/app/shared/json-schema/)或参考[@delon/form/widgets/autocomplete](https://github.com/ng-alain/delon/tree/master/packages/form/widgets/autocomplete)。
### 使用自定义小部件
同其他小部件一样,只需要指定 `widget` 值,例如:
```json
-"intro": {
+"test": {
"type": "string",
"ui": {
- "widget": "tinymce",
- "loadingTip": "loading..."
+ "widget": "test",
+ "data": "widget parameters"
}
}
```
diff --git a/packages/form/public_api.ts b/packages/form/public_api.ts
index a606da1581..cba1843545 100644
--- a/packages/form/public_api.ts
+++ b/packages/form/public_api.ts
@@ -1 +1 @@
-export * from './src/form';
+export * from './src/index';
diff --git a/packages/form/spec/base.spec.ts b/packages/form/spec/base.spec.ts
index 17e3b67dd2..dfafacfc45 100644
--- a/packages/form/spec/base.spec.ts
+++ b/packages/form/spec/base.spec.ts
@@ -9,6 +9,7 @@ import { AlainThemeModule } from '@delon/theme';
import { deepCopy, deepGet } from '@delon/util/other';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
+import { SFWidgetProvideConfig, provideSFConfig } from '../src';
import { SF_SEQ } from '../src/const';
import { SFButton } from '../src/interface';
import { FormProperty } from '../src/model/form.property';
@@ -47,9 +48,7 @@ export function builder(options?: {
} {
options = { detectChanges: true, ...options };
TestBed.configureTestingModule({
- imports: [NoopAnimationsModule, AlainThemeModule.forRoot(), DelonFormModule.forRoot()].concat(
- options.imports || []
- ),
+ imports: [NoopAnimationsModule, AlainThemeModule, DelonFormModule.forRoot()].concat(options.imports || []),
declarations: [TestFormComponent]
});
if (options.template) {
@@ -75,11 +74,18 @@ export function builder(options?: {
};
}
-export function configureSFTestSuite(): void {
+export function configureSFTestSuite(options?: { imports?: NzSafeAny[]; widgets?: SFWidgetProvideConfig[] }): void {
beforeEach(() => {
TestBed.configureTestingModule({
- imports: [NoopAnimationsModule, AlainThemeModule.forRoot(), DelonFormModule.forRoot(), HttpClientTestingModule],
- declarations: [TestFormComponent]
+ imports: [
+ NoopAnimationsModule,
+ AlainThemeModule,
+ DelonFormModule,
+ HttpClientTestingModule,
+ ...(options?.imports ?? [])
+ ],
+ declarations: [TestFormComponent],
+ providers: [provideSFConfig({ widgets: options?.widgets })]
});
});
}
diff --git a/packages/form/spec/form.spec.ts b/packages/form/spec/form.spec.ts
index 7660fd6652..487784485c 100644
--- a/packages/form/spec/form.spec.ts
+++ b/packages/form/spec/form.spec.ts
@@ -27,12 +27,9 @@ describe('form: component', () => {
function genModule(options: { acl?: boolean; i18n?: boolean } = {}): void {
options = { acl: false, i18n: false, ...options };
- const imports = [NoopAnimationsModule, DelonFormModule.forRoot(), AlainThemeModule.forRoot()];
- if (options.i18n) {
- imports.push(AlainThemeModule.forRoot());
- }
+ const imports: NzSafeAny[] = [NoopAnimationsModule, DelonFormModule.forRoot(), AlainThemeModule];
if (options.acl) {
- imports.push(DelonACLModule.forRoot());
+ imports.push(DelonACLModule);
}
TestBed.configureTestingModule({
imports,
diff --git a/packages/form/src/form.ts b/packages/form/src/index.ts
similarity index 95%
rename from packages/form/src/form.ts
rename to packages/form/src/index.ts
index 2c1378475e..73d5189514 100644
--- a/packages/form/src/form.ts
+++ b/packages/form/src/index.ts
@@ -16,6 +16,7 @@ export * from './model/index';
export * from './widget';
export * from './widgets/index';
export * from './widget.factory';
+export * from './provide';
// other
export * from './validator.factory';
diff --git a/packages/form/src/module.ts b/packages/form/src/module.ts
index b72cad44af..e67ba6a9cf 100644
--- a/packages/form/src/module.ts
+++ b/packages/form/src/module.ts
@@ -3,10 +3,8 @@ import { CommonModule } from '@angular/common';
import { ModuleWithProviders, NgModule, NgZone } from '@angular/core';
import { FormsModule } from '@angular/forms';
-import { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzCardModule } from 'ng-zorro-antd/card';
-import { NzCascaderModule } from 'ng-zorro-antd/cascader';
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
import { NzFormModule } from 'ng-zorro-antd/form';
@@ -14,28 +12,18 @@ import { NzGridModule } from 'ng-zorro-antd/grid';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzInputModule } from 'ng-zorro-antd/input';
import { NzInputNumberModule } from 'ng-zorro-antd/input-number';
-import { NzMentionModule } from 'ng-zorro-antd/mention';
import { NzModalModule } from 'ng-zorro-antd/modal';
import { NzRadioModule } from 'ng-zorro-antd/radio';
-import { NzRateModule } from 'ng-zorro-antd/rate';
import { NzSelectModule } from 'ng-zorro-antd/select';
-import { NzSliderModule } from 'ng-zorro-antd/slider';
import { NzSwitchModule } from 'ng-zorro-antd/switch';
-import { NzTagModule } from 'ng-zorro-antd/tag';
-import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
-import { NzTransferModule } from 'ng-zorro-antd/transfer';
-import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select';
-import { NzUploadModule } from 'ng-zorro-antd/upload';
import { DelonLocaleModule } from '@delon/theme';
import { AlainConfigService } from '@delon/util/config';
const ZORROS = [
- NzAutocompleteModule,
NzButtonModule,
NzCardModule,
- NzCascaderModule,
NzCheckboxModule,
NzDatePickerModule,
NzFormModule,
@@ -43,19 +31,11 @@ const ZORROS = [
NzIconModule,
NzInputModule,
NzInputNumberModule,
- NzMentionModule,
NzModalModule,
NzRadioModule,
- NzRateModule,
NzSelectModule,
- NzSliderModule,
NzSwitchModule,
- NzTagModule,
- NzTimePickerModule,
- NzToolTipModule,
- NzTransferModule,
- NzTreeSelectModule,
- NzUploadModule
+ NzToolTipModule
];
import { SFFixedDirective } from './sf-fixed.directive';
@@ -71,28 +51,18 @@ const COMPONENTS = [SFComponent, SFItemComponent, SFItemWrapComponent, SFTemplat
import { WidgetRegistry } from './widget.factory';
import { ArrayWidget } from './widgets/array/array.widget';
-import { AutoCompleteWidget } from './widgets/autocomplete/autocomplete.widget';
import { BooleanWidget } from './widgets/boolean/boolean.widget';
-import { CascaderWidget } from './widgets/cascader/cascader.widget';
import { CheckboxWidget } from './widgets/checkbox/checkbox.widget';
import { CustomWidget } from './widgets/custom/custom.widget';
import { DateWidget } from './widgets/date/date.widget';
-import { MentionWidget } from './widgets/mention/mention.widget';
import { NumberWidget } from './widgets/number/number.widget';
import { NzWidgetRegistry } from './widgets/nz-widget.registry';
import { ObjectWidget } from './widgets/object/object.widget';
import { RadioWidget } from './widgets/radio/radio.widget';
-import { RateWidget } from './widgets/rate/rate.widget';
import { SelectWidget } from './widgets/select/select.widget';
-import { SliderWidget } from './widgets/slider/slider.widget';
import { StringWidget } from './widgets/string/string.widget';
-import { TagWidget } from './widgets/tag/tag.widget';
import { TextWidget } from './widgets/text/text.widget';
import { TextareaWidget } from './widgets/textarea/textarea.widget';
-import { TimeWidget } from './widgets/time/time.widget';
-import { TransferWidget } from './widgets/transfer/transfer.widget';
-import { TreeSelectWidget } from './widgets/tree-select/tree-select.widget';
-import { UploadWidget } from './widgets/upload/upload.widget';
const WIDGETS = [
ObjectWidget,
@@ -100,21 +70,11 @@ const WIDGETS = [
StringWidget,
NumberWidget,
DateWidget,
- TimeWidget,
RadioWidget,
CheckboxWidget,
BooleanWidget,
TextareaWidget,
SelectWidget,
- TreeSelectWidget,
- TagWidget,
- UploadWidget,
- TransferWidget,
- SliderWidget,
- RateWidget,
- AutoCompleteWidget,
- CascaderWidget,
- MentionWidget,
CustomWidget,
TextWidget
];
diff --git a/packages/form/src/provide.ts b/packages/form/src/provide.ts
new file mode 100644
index 0000000000..4de812db29
--- /dev/null
+++ b/packages/form/src/provide.ts
@@ -0,0 +1,45 @@
+import {
+ ENVIRONMENT_INITIALIZER,
+ EnvironmentProviders,
+ NgZone,
+ Provider,
+ inject,
+ makeEnvironmentProviders
+} from '@angular/core';
+
+import { AlainConfigService } from '@delon/util/config';
+import type { NzSafeAny } from 'ng-zorro-antd/core/types';
+
+import { AjvSchemaValidatorFactory, SchemaValidatorFactory } from './validator.factory';
+import { WidgetRegistry } from './widget.factory';
+import { NzWidgetRegistry } from './widgets/nz-widget.registry';
+
+export interface SFWidgetProvideConfig {
+ KEY: string;
+ type: NzSafeAny;
+}
+
+/**
+ * Just only using Standalone widgets
+ */
+export function provideSFConfig(options?: { widgets?: SFWidgetProvideConfig[] }): EnvironmentProviders {
+ const provides: Array
= [
+ {
+ provide: SchemaValidatorFactory,
+ useClass: AjvSchemaValidatorFactory,
+ deps: [AlainConfigService, NgZone]
+ },
+ { provide: WidgetRegistry, useClass: NzWidgetRegistry }
+ ];
+ if (options?.widgets) {
+ provides.push({
+ provide: ENVIRONMENT_INITIALIZER,
+ multi: true,
+ useValue: () => {
+ const srv = inject(WidgetRegistry);
+ options?.widgets?.forEach(widget => srv.register(widget.KEY, widget.type));
+ }
+ });
+ }
+ return makeEnvironmentProviders(provides);
+}
diff --git a/packages/form/src/sf-item-wrap.component.html b/packages/form/src/sf-item-wrap.component.html
index c14725ee17..207f71feec 100644
--- a/packages/form/src/sf-item-wrap.component.html
+++ b/packages/form/src/sf-item-wrap.component.html
@@ -8,39 +8,50 @@
[class.ant-form-item-is-validating]="ui.feedback === 'validating'"
[class.ant-form-item-has-feedback]="ui.feedback"
>
-
-
-
+ @if (_showTitle) {
+
+ @if (t) {
+
+ }
+
+ }