diff --git a/.github/workflows/angular.yml b/.github/workflows/angular.yml
index a4036f8474..0c0f8d5b6c 100644
--- a/.github/workflows/angular.yml
+++ b/.github/workflows/angular.yml
@@ -12,9 +12,11 @@ on:
- 'dev'
jobs:
build-test-lint:
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
- uses: actions/cache@v2
with:
@@ -31,25 +33,13 @@ jobs:
working-directory: npm/ng-packs
- name: Run lint
- run: yarn ng lint
+ run: yarn affected:lint --base=remotes/origin/${{ github.base_ref }}
working-directory: npm/ng-packs
- - name: Run prepare workspace
- run: yarn prepare:workspace
+ - name: Run build
+ run: yarn affected:build --base=remotes/origin/${{ github.base_ref }}
working-directory: npm/ng-packs
- name: Run test
- run: yarn ci:test
- working-directory: npm/ng-packs
-
- - name: Build dev-app
- run: yarn build --prod
+ run: yarn affected:test --base=remotes/origin/${{ github.base_ref }}
working-directory: npm/ng-packs
-
- - name: Install packages of app template
- run: yarn install
- working-directory: templates/app/angular
-
- - name: Build app template
- run: yarn build --prod
- working-directory: templates/app/angular
diff --git a/.github/workflows/cancel-workflow.yml b/.github/workflows/cancel-workflow.yml
new file mode 100644
index 0000000000..78bbf94b3b
--- /dev/null
+++ b/.github/workflows/cancel-workflow.yml
@@ -0,0 +1,12 @@
+name: cancel-workflow
+on: [push]
+jobs:
+ cancel:
+ name: 'Cancel Previous Runs'
+ runs-on: ubuntu-latest
+ timeout-minutes: 3
+ steps:
+ - uses: styfle/cancel-workflow-action@0.6.0
+ with:
+ workflow_id: 10629,1299107,2792859,8268314
+ access_token: ${{ github.token }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index ae5d4fdacc..7aaad739e9 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -7,12 +7,22 @@ name: "CodeQL"
on:
push:
- branches: [dev, rel-1.0, rel-1.1, rel-2.0, rel-2.1, rel-2.2, rel-2.3, rel-2.4, rel-2.5, rel-2.6, rel-2.7, rel-2.8, rel-2.9, rel-3.0, rel-3.1, rel-3.2]
+ branches: [dev, rel-*]
+ paths:
+ - 'abp/**/*.js'
+ - 'abp/**/*.cs'
+ - 'abp/**/*.cshtml'
+ - 'abp/**/*.csproj'
+ - 'abp/**/*.razor'
pull_request:
# The branches below must be a subset of the branches above
branches: [dev]
- schedule:
- - cron: '0 8 * * 6'
+ paths:
+ - 'abp/**/*.js'
+ - 'abp/**/*.cs'
+ - 'abp/**/*.cshtml'
+ - 'abp/**/*.csproj'
+ - 'abp/**/*.razor'
jobs:
analyze:
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index 04da7d097d..dd7112efec 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "Dark Blue Theme",
"LightTheme": "Light Theme",
"ProudToWorkWith": "Proud to Work With",
- "OurConsumers": "Hundreds of enterprises and developers over 50 countries worldwide rely on ABP Commercial.",
+ "OurConsumers": "Thousands of enterprises and developers over 70 countries worldwide rely on ABP Commercial.",
"JoinOurConsumers": "Join them and build amazing products fast.",
"AdditionalServicesExplanation": "Do you need additional or custom services? We and our partners can provide;",
"CustomProjectDevelopment": "Custom Project Development",
@@ -358,6 +358,25 @@
"WeWillSendYouADownloadLink": "A link to download the e-book has been sent to {0}. Check your inbox / junk / spam boxes!",
"InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. To download your book, click here.",
- "FreeDDDEBook": "Free DDD E-Book"
+ "FreeDDDEBook": "Free DDD E-Book",
+ "StartFree": "Start free",
+ "FreeTrial": "Free Trial",
+ "AcceptsMarketingCommunications": " Yes, I`d like to receive ABP Commercial marketing communications.",
+ "PurposeOfUsage": "Purpose of usage",
+ "Industry": "Industry",
+ "Choose": "- Choose -",
+ "CompanyOrganizationName": "Company / Organization Name",
+ "CompanySize": "Company Size",
+ "Next": "Next",
+ "StartTrial": "Start My Free Trial",
+ "ContactUsIssues": "Contact us if you have any issues",
+ "TrialActivatedWarning": "Dear {0}, a user is entitled to have only 1 free trial period. You already used your trial period.",
+ "ActivationRequirement": "You are one step away from starting your free trial. We have sent an email to {0} to activate your account. Check your inbox/junk/spam boxes!",
+ "SaveAndDownload": "Save And Download",
+ "CompanyNameValidationMessage": "Company name is too long!",
+ "AddressValidationMessage": "Address is too long!",
+ "TaxNoValidationMessage": "TAX/VAT No is too long!",
+ "NotesValidationMessage": "Notes field is too long!",
+ "CheckYourBillingInfo": "You can create your invoice only once! Check your billing info before creating your invoice."
}
-}
+}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
index 8de4891e99..8a0e6f22c1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "Tummansininen teema",
"LightTheme": "Kevyt teema",
"ProudToWorkWith": "Ylpeä työskennellä",
- "OurConsumers": "Sadat yritykset ja kehittäjät yli 50 maassa ympäri maailmaa luottavat ABP Commercialiin.",
+ "OurConsumers": "Sadat yritykset ja kehittäjät yli 70 maassa ympäri maailmaa luottavat ABP Commercialiin.",
"JoinOurConsumers": "Liity heihin ja rakenna upeita tuotteita nopeasti.",
"AdditionalServicesExplanation": "Tarvitsetko lisä- tai mukautettuja palveluita? Me ja kumppanimme voimme tarjota; ",
"CustomProjectDevelopment": "Mukautettu projektikehitys",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
index e8f4165971..4db09019ed 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "Thème bleu foncé",
"LightTheme": "Thème clair",
"ProudToWorkWith": "Fier de travailler avec",
- "OurConsumers": "Des centaines d'entreprises et de développeurs dans plus de 50 pays dans le monde font confiance à ABP Commercial.",
+ "OurConsumers": "Des centaines d'entreprises et de développeurs dans plus de 70 pays dans le monde font confiance à ABP Commercial.",
"JoinOurConsumers": "Rejoignez-les et créez rapidement des produits incroyables.",
"AdditionalServicesExplanation": "Avez-vous besoin de services supplémentaires ou personnalisés? Nous et nos partenaires pouvons fournir; ",
"CustomProjectDevelopment": "Développement de projets personnalisés",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
index 4af2f31246..91158973d8 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "डार्क ब्लू थीम",
"LightTheme": "प्रकाश थीम",
"ProudToWorkWith": "गर्व के साथ काम करने के लिए",
- "OurConsumers": "दुनिया भर में 50 से अधिक देशों के सैकड़ों उद्यम और डेवलपर्स एबीपी कमर्शियल पर निर्भर हैं।",
+ "OurConsumers": "दुनिया भर में 70 से अधिक देशों के सैकड़ों उद्यम और डेवलपर्स एबीपी कमर्शियल पर निर्भर हैं।",
"JoinOurConsumers": "उनके साथ जुड़ें और तेजी से अद्भुत उत्पादों का निर्माण करें।",
"AdditionalServicesExplanation": "क्या आपको अतिरिक्त या कस्टम सेवाओं की आवश्यकता है? हम और हमारे साथी प्रदान कर सकते हैं; ",
"CustomProjectDevelopment": "कस्टम परियोजना विकास",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
index 722c10275f..ccb9f5ecd1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "Tema blu scuro",
"LightTheme": "Tema chiaro",
"ProudToWorkWith": "Orgoglioso di lavorare con",
- "OurConsumers": "Centinaia di aziende e sviluppatori in oltre 50 paesi in tutto il mondo si affidano a ABP Commercial.",
+ "OurConsumers": "Centinaia di aziende e sviluppatori in oltre 70 paesi in tutto il mondo si affidano a ABP Commercial.",
"JoinOurConsumers": "Unisciti a loro e crea prodotti sorprendenti velocemente.",
"AdditionalServicesExplanation": "Hai bisogno di servizi aggiuntivi o personalizzati? Noi e i nostri partner possiamo fornire; ",
"CustomProjectDevelopment": "Sviluppo di progetti personalizzati",
@@ -358,6 +358,25 @@
"WeWillSendYouADownloadLink": "Un link per scaricare il libro e-book è stato spedito a {0}. Controlla nella posta in arrivo / indesiderata / spam!",
"InvalidFormInputs": "Per favore, digita le informazioni valide specificate nel modulo",
"DDDBookEmailBody": "Grazie. Per scaricare il tuo libro, clicca qui.",
- "FreeDDDEBook": "E-Book Gratuito DDD"
+ "FreeDDDEBook": "E-Book Gratuito DDD",
+ "StartFree": "Inizia gratuitamente",
+ "FreeTrial": "Prova Gratuita",
+ "AcceptsMarketingCommunications": "Si desidero ricevere comunicazioni marketing riguardanti ABP Commercial",
+ "PurposeOfUsage": "Proposta di utilizzo",
+ "Industry": "Settore",
+ "Choose": "- Scegli -",
+ "CompanyOrganizationName": "Azienda / Nome organizzazione",
+ "CompanySize": "Dimensioni Azienda",
+ "Next": "Prossimo",
+ "StartTrial": "Inizia la mia prova gratuita",
+ "ContactUsIssues": "Contattaci per qualsiasi problema",
+ "TrialActivatedWarning": "Caro {0}, un utente ha diritto di avere 1 solo periodo di prova gratuito. Hai già utilizzato il tuo periodo di prova.",
+ "ActivationRequirement": "Ti manca un solo passo per iniziare il tuo periodo di prova gratuito. Abbiamo inviato un'email a {0} per attivare il tuo account. Controlla la tua casella di posta e non dimenticare la cartella spam!",
+ "SaveAndDownload": "Salva e Scarica",
+ "CompanyNameValidationMessage": "Il nome dell'azienda è troppo lungo!",
+ "AddressValidationMessage": "L'indirizzo è troppo lungo!",
+ "TaxNoValidationMessage": "TAX/VAT (IVA) è troppo lungo!",
+ "NotesValidationMessage": "Il campo note è troppo lungo!",
+ "CheckYourBillingInfo": "Puoi creare una fattura solo una volta! Controlla i tuoi dati di fatturazione prima di creare una fattura."
}
-}
\ No newline at end of file
+}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
index d5dcbfa751..a88d581d36 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "Tema Dark Blue",
"LightTheme": "Tema Light",
"ProudToWorkWith": "Mândru să lucrez cu",
- "OurConsumers": "Sute de întreprinderi şi dezvoltatori din peste 50 de ţări din jurul lumii se bazează pe ABP Commercial.",
+ "OurConsumers": "Sute de întreprinderi şi dezvoltatori din peste 70 de ţări din jurul lumii se bazează pe ABP Commercial.",
"JoinOurConsumers": "Alăturaţi-va lor şi construiţi produse uimitoare rapid.",
"AdditionalServicesExplanation": "Aveţi nevoie de servicii suplimentare sau personalizate? Noi şi partenerii noştri vi le putem oferi;",
"CustomProjectDevelopment": "Custom Project Development",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
index 7e2143a9af..4b160bdb70 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "Tmavomodrá téma",
"LightTheme": "Téma Light",
"ProudToWorkWith": "Hrdo spolupracujeme s",
- "OurConsumers": "Na ABP Commercial sa spoliehajú stovky podnikov a vývojárov vo viac ako 50 krajinách sveta.",
+ "OurConsumers": "Na ABP Commercial sa spoliehajú stovky podnikov a vývojárov vo viac ako 70 krajinách sveta.",
"JoinOurConsumers": "Pridajte sa k nim a jednoducho vytvorte úžasné produkty.",
"AdditionalServicesExplanation": "Potrebujete ďalšie alebo vlastné služby? My a naši partneri vám ich môžeme poskytnúť;",
"CustomProjectDevelopment": "Vývoj projektu na mieru",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
index 5f99be6ba8..ac5e247264 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
@@ -106,7 +106,7 @@
"DarkBlueTheme": "深蓝主题",
"LightTheme": "浅色主题",
"ProudToWorkWith": "荣幸与你合作",
- "OurConsumers": "全球50多个国家的数百家企业和开发商使用ABP商业版.",
+ "OurConsumers": "全球70多个国家的数百家企业和开发商使用ABP商业版.",
"JoinOurConsumers": "加它他们并快速构建令人惊叹的产品.",
"AdditionalServicesExplanation": "你是否需要额外或自定义的服务? 我们和我们的合作伙伴可以提供;",
"CustomProjectDevelopment": "自定义项目开发",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
index a676aa9124..80fed13066 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
@@ -104,7 +104,7 @@
"DarkBlueTheme": "深藍主題",
"LightTheme": "淺色主題",
"ProudToWorkWith": "榮幸與你合作",
- "OurConsumers": "全球50多個國家的數百家企業和開發商使用ABP商業版.",
+ "OurConsumers": "全球70多個國家的數百家企業和開發商使用ABP商業版.",
"JoinOurConsumers": "加它他們並快速構建令人驚嘆的產品.",
"AdditionalServicesExplanation": "你是否需要額外或自定義的服務? 我們和我們的合作夥伴可以提供;",
"CustomProjectDevelopment": "自定義項目開發",
diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md
index 6b906fe194..66fded1a29 100644
--- a/docs/en/Authorization.md
+++ b/docs/en/Authorization.md
@@ -256,7 +256,7 @@ myGroup.AddPermission("Book_Creation")
#### Depending on a Global Feature
-Use the `RequireFeatures` extension method on your permission definition to make the permission available only if a given feature is enabled:
+Use the `RequireGlobalFeatures` extension method on your permission definition to make the permission available only if a given feature is enabled:
````csharp
myGroup.AddPermission("Book_Creation")
diff --git a/docs/en/Blog-Posts/2021-07-28-lepton-x-release/POST.md b/docs/en/Blog-Posts/2021-07-28-lepton-x-release/POST.md
new file mode 100644
index 0000000000..bc586fdeed
--- /dev/null
+++ b/docs/en/Blog-Posts/2021-07-28-lepton-x-release/POST.md
@@ -0,0 +1,216 @@
+# LeptonX Alpha Release
+
+We are excited to announce that the **alpha version** of the LeptonX theme has been released! As stated in [this blog post](https://volosoft.com/blog/introducing-the-lepton-theme-next-generation), LeptonX comes in different shapes. For this release, we introduce only ABP based projects with the Angular UI. So, if you are already using the ABP Framework and Angular as the frontend choice, you can integrate these packages into your project today.
+
+The theme has been deployed with two versions: LeptonX-lite (free) and LeptonX (commercial).
+
+> **Note that this theme currently only works for the *Angular UI*. Please keep waiting for other UI options.**
+
+## Open-Source
+
+This section shows how to replace the basic theme (that comes with open source ABP Framework startup template) with the new LeptonX-lite theme.
+
+To add `LeptonX-lite` into your project,
+
+* Install `@abp/ng.theme.lepton-x` NPM package
+
+`npm install @abp/ng.theme.lepton-x@preview` or
+
+`yarn add @abp/ng.theme.lepton-x@preview`
+
+* Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one.
+
+Replace the following style
+
+```JSON
+{
+ "input": "node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "inject": true,
+ "bundleName": "bootstrap-ltr.min"
+},
+```
+
+with
+
+```json
+"node_modules/@volo/ngx-lepton-x.lite/styles/sidemenu-layout.min.css",
+"node_modules/bootstrap-icons/font/bootstrap-icons.css",
+```
+
+* Finally, remove `ThemeBasicModule` from `app.module.ts` and `shared.module.ts`, and import the related modules in `app.module.ts`
+
+```js
+import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x';
+import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts';
+
+@NgModule({
+ imports: [
+ // ...
+ ThemeLeptonXModule.forRoot(),
+ SideMenuLayoutModule.forRoot(),
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+Note: If you employ [Resource Owner Password Flow](https://docs.abp.io/en/abp/latest/UI/Angular/Authorization#resource-owner-password-flow) for authorization, you should import the following module as well:
+
+```js
+import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
+
+@NgModule({
+ // ...
+ imports: [
+ // ...
+ AccountLayoutModule.forRoot(),
+ // ...
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+To change the logos and brand color of the `LeptonX`, simply add the following CSS to the `styles.scss`
+
+```css
+:root {
+ --lpx-logo: url('/assets/images/logo.png');
+ --lpx-logo-icon: url('/assets/images/logo-icon.png');
+ --lpx-brand: #edae53;
+}
+```
+
+- `--lpx-logo` is used to place the logo in the menu.
+- `--lpx-logo-icon` is a square icon used when the menu is collapsed.
+- `--lpx-brand` is a color used throughout the application, especially on active elements.
+
+
+
+
+
+## ABP Commercial
+
+This section shows how to replace the lepton theme (that comes with the ABP Commercial startup template) with the new LeptonX theme.
+
+To add `LeptonX` into your existing projects,
+
+* Firstly, install `@volosoft/abp.ng.theme.lepton-x` NPM package
+
+`npm install @volosoft/abp.ng.theme.lepton-x@preview` or
+
+`yarn add @volosoft/abp.ng.theme.lepton-x@preview`
+
+* Then, edit `angular.json` as follows:
+
+Remove the following config from the `styles` array since LeptonX provides bootstrap as embedded in its CSS.
+
+```JSON
+{
+ "input": "node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "inject": true,
+ "bundleName": "bootstrap-ltr.min"
+},
+```
+
+Add the following ones into the `styles` array
+
+```JSON
+{
+ "input": "node_modules/@volosoft/ngx-lepton-x/styles/themes/dark.css",
+ "inject": false,
+ "bundleName": "lepton-x.dark"
+},
+{
+ "input": "node_modules/@volosoft/ngx-lepton-x/styles/themes/dim.css",
+ "inject": false,
+ "bundleName": "lepton-x.dim"
+},
+{
+ "input": "node_modules/@volosoft/ngx-lepton-x/styles/themes/light.css",
+ "inject": false,
+ "bundleName": "lepton-x.light"
+},
+"node_modules/@volosoft/ngx-lepton-x/styles/css/sidemenu-layout.min.css",
+"node_modules/bootstrap-icons/font/bootstrap-icons.css",
+```
+
+Three of them are related to the theming and will be loaded during runtime. That's why they are not injected into the `head` as a style. Hence, the `"inject": false`
+
+The fourth one depends on which layout you want to use. For now, there is only `sidemenu-layout` available. In the future, there will be many layouts to choose from.
+
+The last one is `bootstrap-icons` which are being used throughout the components.
+
+* At last, remove `ThemeLeptonModule` from `app.module.ts` and `shared.module.ts`, and import the following modules in `app.module.ts`
+
+```js
+import { ThemeLeptonXModule } from '@volosoft/abp.ng.theme.lepton-x';
+import { AbpSideMenuLayoutModule } from '@volosoft/abp.ng.theme.lepton-x/layouts';
+
+@NgModule({
+ // ...
+ imports: [
+ // ...
+ ThemeLeptonXModule.forRoot(),
+ AbpSideMenuLayoutModule.forRoot(), // depends on which layout you choose
+ // ...
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+Note: If you employ [Resource Owner Password Flow](https://docs.abp.io/en/abp/latest/UI/Angular/Authorization#resource-owner-password-flow) for authorization, you should import the following module as well:
+
+```js
+import { AccountLayoutModule } from '@volosoft/abp.ng.theme.lepton-x/account';
+
+@NgModule({
+ // ...
+ imports: [
+ // ...
+ AccountLayoutModule.forRoot({
+ layout: {
+ authLayoutImg: '/assets/images/login-bg.jpg',
+ },
+ }),
+ // ...
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+`authLayoutImg`: (Optional) If not given, a default image will be placed on the authentication pages.
+
+
+* At this point, `LeptonX` theme should be up and running within your application. However, you may need to overwrite some css variables based your needs for every theme available as follows:
+```scss
+:root {
+ .lpx-theme-dark {
+ --lpx-logo: url('/assets/images/logo/logo-light.svg');
+ --lpx-logo-icon: url('/assets/images/logo/logo-light-icon.svg');
+ --lpx-brand: #edae53;
+ }
+
+ .lpx-theme-dim {
+ --lpx-logo: url('/assets/images/logo/logo-light.svg');
+ --lpx-logo-icon: url('/assets/images/logo/logo-light-icon.svg');
+ --lpx-brand: #f15835;
+ }
+
+ .lpx-theme-light {
+ --lpx-logo: url('/assets/images/logo/logo-dark.svg');
+ --lpx-logo-icon: url('/assets/images/logo/logo-dark-icon.svg');
+ --lpx-brand: #69aada;
+ }
+}
+```
+
+When the user selects a theme, the corresponding CSS class is added to the `body`, so you can write specific CSS rules to each theme.
+
+## Conclusion
+
+In this blog post, I've explained how to use the alpha version of the new LeptonX theme for ABP-based solutions. Please, keep in mind that this is an alpha version, and we will continue to work on the LeptonX theme. The APIs are bound to change and breaking changes may be introduced in future versions.
+
+We would like you to try it out with the latest version of the ABP Framework and give us feedback at lepton@volosoft.com or open an issue on this repository: https://github.com/volosoft/lepton-theme
diff --git a/docs/en/Blog-Posts/2021-07-28-lepton-x-release/lepton-x-lite-dashboard.png b/docs/en/Blog-Posts/2021-07-28-lepton-x-release/lepton-x-lite-dashboard.png
new file mode 100644
index 0000000000..6c1ed170fc
Binary files /dev/null and b/docs/en/Blog-Posts/2021-07-28-lepton-x-release/lepton-x-lite-dashboard.png differ
diff --git a/docs/en/Blog-Posts/2021-07-28-lepton-x-release/lepton-x-lite-menu-collapsed.png b/docs/en/Blog-Posts/2021-07-28-lepton-x-release/lepton-x-lite-menu-collapsed.png
new file mode 100644
index 0000000000..36cc5014d3
Binary files /dev/null and b/docs/en/Blog-Posts/2021-07-28-lepton-x-release/lepton-x-lite-menu-collapsed.png differ
diff --git a/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md b/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md
index 915d4ef5c1..eea0eaae46 100644
--- a/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md
+++ b/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md
@@ -168,7 +168,7 @@ namespace SignalRTieredDemo.Web
{
````
-Also, we need to add [@abp/signalr](https://www.npmjs.com/package/@abp/signalr) npm package to package.json in ***.Web** project, then run **yarn** and **gulp** commands.
+Also, we need to add [@abp/signalr](https://www.npmjs.com/package/@abp/signalr) npm package to package.json in ***.Web** project, then run **abp install-libs** command.
`````json
{
diff --git a/docs/en/Community-Articles/2020-08-18-Using-DevExtreme-Components-With-The-ABP-Framework/Using-DevExtreme-Components-With-The-ABP-Framework.md b/docs/en/Community-Articles/2020-08-18-Using-DevExtreme-Components-With-The-ABP-Framework/Using-DevExtreme-Components-With-The-ABP-Framework.md
index 93ed01d05c..fdaaefbea1 100644
--- a/docs/en/Community-Articles/2020-08-18-Using-DevExtreme-Components-With-The-ABP-Framework/Using-DevExtreme-Components-With-The-ABP-Framework.md
+++ b/docs/en/Community-Articles/2020-08-18-Using-DevExtreme-Components-With-The-ABP-Framework/Using-DevExtreme-Components-With-The-ABP-Framework.md
@@ -77,9 +77,11 @@ module.exports = {
};
```
-Open your `DevExtremeSample.Web` project folder with a command line and run the `gulp` command. This command will copy the needed library files into the ``/wwwroot/libs/devextreme/` folder.
+Open your `DevExtremeSample.Web` project folder with a command line and run the `abp install-libs` command. This command will copy the needed library files into the `/wwwroot/libs/devextreme/` folder.
-
+````bash
+abp install-libs
+````
You can see `devextreme` folder inside the `wwwroot/libs`:
diff --git a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md
index 8aeff16612..a53fec2e48 100644
--- a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md
+++ b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md
@@ -91,7 +91,7 @@ You can install the latest version (3.1.13 will be old)
#### 3- Add resource Mapping
-We added SignalR to the `package.json` but it comes into your `node_modules` folder. We need to copy the related files to `wwwroot/libs` folder. To do this copy the content of the following file to your `abp.resourcemappings.js` file. It's in your root directory of Web folder. After you do this, go to your web directory and run `gulp` command. By doing this, it'll copy the related files into your `wwwroot/libs` folder.
+We added SignalR to the `package.json` but it comes into your `node_modules` folder. We need to copy the related files to `wwwroot/libs` folder. To do this copy the content of the following file to your `abp.resourcemappings.js` file. It's in your root directory of Web folder. After you do this, go to your web directory and run `abp install-libs` command. By doing this, it'll copy the related files into your `wwwroot/libs` folder.
[abp.resourcemappings.js](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-abp-resourcemapping-js)
diff --git a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md
index 15fbbc4678..d8fa243c3b 100644
--- a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md
+++ b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md
@@ -30,7 +30,7 @@ If you want to make it in your solution with today, follow the steps in this art
> There is one **drawback** with the new design (everything in software development is a trade-off). We need to remove the `AppUser` entity, because EF Core can't map two classes to single table without an inheritance relation. I will cover this later in this article and provide suggestions to deal with it.
-> If you are using **ABP Commercial**, ABP Suite code generation won't work correctly with the new design. In this case, we suggest to wait for the next version.
+> If you are using **ABP Commercial**, ABP Suite code generation won't work correctly before the version 4.4. Please upgrade to v4.4 if you are using a previous version.
## The Steps
diff --git a/docs/en/Concurrency-Check.md b/docs/en/Concurrency-Check.md
new file mode 100644
index 0000000000..e22afe82b8
--- /dev/null
+++ b/docs/en/Concurrency-Check.md
@@ -0,0 +1,3 @@
+## Concurrency Check
+
+TODO
\ No newline at end of file
diff --git a/docs/en/Data-Filtering.md b/docs/en/Data-Filtering.md
index 6df738cf18..dc237f6151 100644
--- a/docs/en/Data-Filtering.md
+++ b/docs/en/Data-Filtering.md
@@ -239,15 +239,25 @@ protected override Expression> CreateFilterExpression
+[ExposeServices(typeof(IMongoDbRepositoryFilterer))]
+public class BookMongoDbRepositoryFilterer : MongoDbRepositoryFilterer , ITransientDependency
{
- protected override void AddGlobalFilters(List> filters)
+ public BookMongoDbRepositoryFilterer(
+ IDataFilter dataFilter,
+ ICurrentTenant currentTenant) :
+ base(dataFilter, currentTenant)
{
+ }
+
+ public override void AddGlobalFilters(List> filters)
+ {
+ base.AddGlobalFilters(filters);
+
if (DataFilter.IsEnabled())
{
filters.Add(Builders.Filter.Eq(e => ((IIsActive)e).IsActive, true));
@@ -256,7 +266,7 @@ public class BookRepository : MongoDbRepository : MongoDbRepository
@@ -271,6 +281,8 @@ public abstract class MyMongoRepository : MongoD
protected override void AddGlobalFilters(List> filters)
{
+ base.AddGlobalFilters(filters);
+
if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity))
&& DataFilter.IsEnabled())
{
@@ -278,6 +290,15 @@ public abstract class MyMongoRepository : MongoD
}
}
}
-````
-> See "Set Default Repository Classes" section of the [MongoDb Integration document](MongoDB.md) to learn how to replace default repository base with your custom class.
\ No newline at end of file
+
+public class MyMongoDbModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ //.......
+ context.Services
+ .Replace(ServiceDescriptor.Transient(typeof(IMongoDbRepositoryFilterer<,>),typeof(MyMongoDbRepositoryFilterer<,>)));
+ }
+}
+````
\ No newline at end of file
diff --git a/docs/en/Data-Transfer-Objects.md b/docs/en/Data-Transfer-Objects.md
index bc81205b66..4d45570c1d 100644
--- a/docs/en/Data-Transfer-Objects.md
+++ b/docs/en/Data-Transfer-Objects.md
@@ -210,15 +210,15 @@ namespace AbpDemo
{
//Create the query
var query = _productRepository
- .OrderBy(input.Sorting)
- .Skip(input.SkipCount)
- .Take(input.MaxResultCount);
+ .OrderBy(input.Sorting);
//Get total count from the repository
var totalCount = await query.CountAsync();
//Get entities from the repository
- List products = await query.ToListAsync();
+ List products = await query
+ .Skip(input.SkipCount)
+ .Take(input.MaxResultCount).ToListAsync();
//Map entities to DTOs
List productDtos =
diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md
index 3894e29d20..f848789176 100644
--- a/docs/en/Modules/Docs.md
+++ b/docs/en/Modules/Docs.md
@@ -185,10 +185,11 @@ Open `package.json` and add `@abp/docs": "^2.9.0` as shown below:
}
```
- Then open the command line terminal in the `Acme.MyProject.Web` project folder and run the following command:
+Then open the command line terminal in the `Acme.MyProject.Web` project folder and run the following command:
- 1. `yarn`
- 2. `abp install-libs`
+````bash
+abp install-libs
+````
### 4- Database Integration
diff --git a/docs/en/Modules/Permission-Management.md b/docs/en/Modules/Permission-Management.md
index ba4b34d8ed..b97ddfca6c 100644
--- a/docs/en/Modules/Permission-Management.md
+++ b/docs/en/Modules/Permission-Management.md
@@ -28,7 +28,7 @@ In this dialog, you can grant permissions for the selected role. The tabs in the
## IPermissionManager
-`IPermissionManager` is the main service provided by this module. It is used to read and change the permission values. `IPermissionManager` is typically used by the *Feature Management Dialog*. However, you can inject it if you need to set a permission value.
+`IPermissionManager` is the main service provided by this module. It is used to read and change the permission values. `IPermissionManager` is typically used by the *Permission Management Dialog*. However, you can inject it if you need to set a permission value.
> If you just want to read/check permission values for the current user, use the `IAuthorizationService` or the `[Authorize]` attribute as explained in the [Authorization document](../Authorization.md).
@@ -91,9 +91,9 @@ public class CustomPermissionManagementProvider : PermissionManagementProvider
}
````
-`PermissionManagementProvider` base class makes the default implementation (using the `IPermissionGrantRepository`) for you. You can override base methods as you need. Every provider must have a unique name, which is `Custom` in this example (keep it short since it is saved to database for each feature value record).
+`PermissionManagementProvider` base class makes the default implementation (using the `IPermissionGrantRepository`) for you. You can override base methods as you need. Every provider must have a unique name, which is `Custom` in this example (keep it short since it is saved to database for each permission value record).
-Once you create your provider class, you should register it using the `FeatureManagementOptions` [options class](../Options.md):
+Once you create your provider class, you should register it using the `PermissionManagementOptions` [options class](../Options.md):
````csharp
Configure(options =>
diff --git a/docs/en/Modules/Setting-Management.md b/docs/en/Modules/Setting-Management.md
index bf4ab30031..4eedcc969d 100644
--- a/docs/en/Modules/Setting-Management.md
+++ b/docs/en/Modules/Setting-Management.md
@@ -99,7 +99,7 @@ public class CustomSettingProvider : SettingManagementProvider
}
````
-`SettingManagementProvider` base class makes the default implementation (using the `ISettingManagementStore`) for you. You can override base methods as you need. Every provider must have a unique name, which is `Custom` in this example (keep it short since it is saved to database for each feature value record).
+`SettingManagementProvider` base class makes the default implementation (using the `ISettingManagementStore`) for you. You can override base methods as you need. Every provider must have a unique name, which is `Custom` in this example (keep it short since it is saved to database for each setting value record).
Once you create your provider class, you should register it using the `SettingManagementOptions` [options class](../Options.md):
diff --git a/docs/en/Modules/Virtual-File-Explorer.md b/docs/en/Modules/Virtual-File-Explorer.md
index b0e25a2d65..1a22418937 100644
--- a/docs/en/Modules/Virtual-File-Explorer.md
+++ b/docs/en/Modules/Virtual-File-Explorer.md
@@ -60,8 +60,9 @@ Or you can also manually install nuget package to `Acme.MyProject.Web` project:
Then open the command line terminal in the `Acme.MyProject.Web` project folder and run the following command:
- 1. `yarn`
- 2. `abp install-libs`
+````bash
+abp install-libs
+````
That's all,Now run the application and Navigate to `/VirtualFileExplorer`. You will see virtual file explorer page:
diff --git a/docs/en/SignalR-Integration.md b/docs/en/SignalR-Integration.md
index c8a25215de..7ebf4f6539 100644
--- a/docs/en/SignalR-Integration.md
+++ b/docs/en/SignalR-Integration.md
@@ -70,7 +70,7 @@ This will add the `@abp/signalr` to the dependencies in the `package.json` of yo
}
````
-Run `abp install-libs` command in the root folder of your web project:
+Run the following [ABP CLI](CLI.md) command in the root folder of your web project:
````bash
abp install-libs
diff --git a/docs/en/Text-Templating-Scriban.md b/docs/en/Text-Templating-Scriban.md
index 51b6c50f88..324fed7b14 100644
--- a/docs/en/Text-Templating-Scriban.md
+++ b/docs/en/Text-Templating-Scriban.md
@@ -1,4 +1,4 @@
-# Razor Integration
+# Scriban Integration
## Installation
diff --git a/docs/en/Tutorials/Part-9.md b/docs/en/Tutorials/Part-9.md
index 2a3e43c736..e2df7c262e 100644
--- a/docs/en/Tutorials/Part-9.md
+++ b/docs/en/Tutorials/Part-9.md
@@ -1022,7 +1022,7 @@ Create a new Razor Component Page, `/Pages/Authors.razor`, in the `Acme.BookStor
````
-* This code is similar to the `Books.razor`, except it doesn't inherit from the `BlazorisePageBase`, but uses its own implementation.
+* This code is similar to the `Books.razor`, except it doesn't inherit from the `AbpCrudPageBase`, but uses its own implementation.
* Injects the `IAuthorAppService` to consume the server side HTTP APIs from the UI. We can directly inject application service interfaces and use just like regular method calls by the help of [Dynamic C# HTTP API Client Proxy System](../API/Dynamic-CSharp-API-Clients.md), which performs REST API calls for us. See the `Authors` class below to see the usage.
* Injects the `IAuthorizationService` to check [permissions](../Authorization.md).
* Injects the `IObjectMapper` for [object to object mapping](../Object-To-Object-Mapping.md).
diff --git a/docs/en/Tutorials/Todo/Index.md b/docs/en/Tutorials/Todo/Index.md
index 9f4a33a9c0..8eca93fead 100644
--- a/docs/en/Tutorials/Todo/Index.md
+++ b/docs/en/Tutorials/Todo/Index.md
@@ -618,7 +618,7 @@ Open the `Index.razor` file in the `Pages` folder of the *TodoApp.Blazor* projec
### Index.razor.css
-As the final touch, open the `Index.razor.css` file in the `Pages` folder of the *TodoApp.Web* project and replace with the following content:
+As the final touch, open the `Index.razor.css` file in the `Pages` folder of the *TodoApp.Blazor* project and replace with the following content:
````css
#TodoList{
diff --git a/docs/en/UI/Angular/Settings.md b/docs/en/UI/Angular/Settings.md
index 0dd29025e5..69794d5d5b 100644
--- a/docs/en/UI/Angular/Settings.md
+++ b/docs/en/UI/Angular/Settings.md
@@ -2,7 +2,7 @@
You can get settings on the client-side using the [config state service](./Config-State.md) if they are allowed by their setting definition on the server-side.
-> This document only explains how settings work in the Angular UI projects. See the [settings document](../../../Settings.md) to understand the ABP setting system.
+> This document only explains how settings work in the Angular UI projects. See the [settings document](../../Settings.md) to understand the ABP setting system.
## Before Use
diff --git a/docs/en/UI/AspNetCore/Basic-Theme.md b/docs/en/UI/AspNetCore/Basic-Theme.md
index 0a5b2c152f..e74799a423 100644
--- a/docs/en/UI/AspNetCore/Basic-Theme.md
+++ b/docs/en/UI/AspNetCore/Basic-Theme.md
@@ -85,7 +85,7 @@ See the [User Interface Customization Guide](Customization-User-Interface.md) to
You can run the following [ABP CLI](../../CLI.md) command in **Web** project directory to copy the source code to your solution:
-`abp add-package Volo.Abp.AspNetCore.Components.Server.BasicTheme --with-source-code --add-to-solution-file`
+`abp add-module Volo.BasicTheme --with-source-code --add-to-solution-file`
----
diff --git a/docs/en/UI/AspNetCore/Client-Side-Package-Management.md b/docs/en/UI/AspNetCore/Client-Side-Package-Management.md
index 259461adf3..eaccc39119 100644
--- a/docs/en/UI/AspNetCore/Client-Side-Package-Management.md
+++ b/docs/en/UI/AspNetCore/Client-Side-Package-Management.md
@@ -18,7 +18,7 @@ To solve the versioning problem, we created a **standard set of packages** those
The benefit of a **standard package** is:
* It depends on a **standard version** of a package. Depending on this package is **safe** because all modules depend on the same version.
-* It contains the necessary mapping configuration to copy library resources (js, css, img... files) from the **node_modules** folder to **wwwroot/libs** folder. See the *Mapping The Library Resources* section for more.
+* It contains the mappings copy library resources (js, css, img... files) from the **node_modules** folder to **wwwroot/libs** folder. See the *Mapping The Library Resources* section for more.
Depending on a standard package is easy. Just add it to your **package.json** file like you normally do. Example:
@@ -61,13 +61,7 @@ Using NPM packages and NPM/Yarn tool is the de facto standard for client side li
Next challenge is copying needed resources (js, css, img... files) from the `node_modules` into a folder inside the **wwwroot** folder to make it accessible to the clients/browsers.
-[ABP CLI](../../CLI.md) offers the command below to **copy resources** from **node_modules** to **wwwroot/libs** folder. You have to run it in the root folder of your web project:
-
-````bash
-abp install-libs
-````
-
-Each **standard package** (see the *@ABP NPM Packages* section) defines the mapping for its own files. So, most of the time, you only configure dependencies.
+ABP CLI's `abp install-libs` command **copies resources** from **node_modules** to **wwwroot/libs** folder. Each **standard package** (see the *@ABP NPM Packages* section) defines the mapping for its own files. So, most of the time, you only configure dependencies.
The **startup templates** are already configured to work all these out of the box. This section will explain the configuration options.
@@ -106,17 +100,15 @@ mappings: {
}
````
-#### Using ABP CLI To Copy Resources
+#### install-libs Command
-Once you properly configure the `abp.resourcemapping.js` file, you can run the [ABP CLI](../../CLI.md) command from the command line:
+Once you properly configure the `abp.resourcemapping.js` file, you can run the following ABP CLI command from the command line:
````bash
abp install-libs
````
-When you run this command, all packages will copy their own resources into the **wwwroot/libs** folder. Running `yarn` & `abp install-libs` are only necessary if you make a change in your dependencies in the **package.json** file.
-
-> When you run the `abp install-libs` command, dependencies of the application are resolved using the package.json file. [ABP CLI](../../CLI.md) automatically discovers and maps all resources from all dependencies (recursively).
+When you run this command, all packages will copy their own resources into the **wwwroot/libs** folder. Running `abp install-libs` is only necessary if you make a change in your dependencies in the **package.json** file.
#### See Also
diff --git a/docs/en/UI/Blazor/Customization-Overriding-Components.md b/docs/en/UI/Blazor/Customization-Overriding-Components.md
index 995213f9e7..e62e0a0ff4 100644
--- a/docs/en/UI/Blazor/Customization-Overriding-Components.md
+++ b/docs/en/UI/Blazor/Customization-Overriding-Components.md
@@ -20,11 +20,11 @@ First, create your logo and place under a folder in your web application. We use

-The next step is to create a razor component, like `MyBlazor.razor`, in your application:
+The next step is to create a razor component, like `MyBranding.razor`, in your application:

-The content of the `MyBlazor.razor` is shown below:
+The content of the `MyBranding.razor` is shown below:
````html
@using Volo.Abp.DependencyInjection
diff --git a/docs/zh-Hans/Data-Filtering.md b/docs/zh-Hans/Data-Filtering.md
index 45adcb6b05..74192cf426 100644
--- a/docs/zh-Hans/Data-Filtering.md
+++ b/docs/zh-Hans/Data-Filtering.md
@@ -188,15 +188,25 @@ protected override Expression> CreateFilterExpression
+[ExposeServices(typeof(IMongoDbRepositoryFilterer))]
+public class BookMongoDbRepositoryFilterer : MongoDbRepositoryFilterer , ITransientDependency
{
- protected override void AddGlobalFilters(List> filters)
+ public BookMongoDbRepositoryFilterer(
+ IDataFilter dataFilter,
+ ICurrentTenant currentTenant) :
+ base(dataFilter, currentTenant)
{
+ }
+
+ public override void AddGlobalFilters(List> filters)
+ {
+ base.AddGlobalFilters(filters);
+
if (DataFilter.IsEnabled())
{
filters.Add(Builders.Filter.Eq(e => ((IIsActive)e).IsActive, true));
@@ -205,7 +215,7 @@ public class BookRepository : MongoDbRepository : MongoDbRepository
@@ -220,6 +230,8 @@ public abstract class MyMongoRepository : MongoD
protected override void AddGlobalFilters(List> filters)
{
+ base.AddGlobalFilters(filters);
+
if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity))
&& DataFilter.IsEnabled())
{
@@ -227,6 +239,17 @@ public abstract class MyMongoRepository : MongoD
}
}
}
+
+
+public class MyMongoDbModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ //.......
+ context.Services
+ .Replace(ServiceDescriptor.Transient(typeof(IMongoDbRepositoryFilterer<,>),typeof(MyMongoDbRepositoryFilterer<,>)));
+ }
+}
````
> 参阅[MongoDb集成文档](MongoDB.md)的 "设置默认仓储" 部分了解如何使用自定义类替换默认仓储.
\ No newline at end of file
diff --git a/docs/zh-Hans/Data-Transfer-Objects.md b/docs/zh-Hans/Data-Transfer-Objects.md
index eb844e7ea7..5f8a1bc527 100644
--- a/docs/zh-Hans/Data-Transfer-Objects.md
+++ b/docs/zh-Hans/Data-Transfer-Objects.md
@@ -210,15 +210,15 @@ namespace AbpDemo
{
//Create the query
var query = _productRepository
- .OrderBy(input.Sorting)
- .Skip(input.SkipCount)
- .Take(input.MaxResultCount);
+ .OrderBy(input.Sorting);
//Get total count from the repository
var totalCount = await query.CountAsync();
//Get entities from the repository
- List products = await query.ToListAsync();
+ List products = await query
+ .Skip(input.SkipCount)
+ .Take(input.MaxResultCount);.ToListAsync();
//Map entities to DTOs
List productDtos =
diff --git a/docs/zh-Hans/Entities.md b/docs/zh-Hans/Entities.md
index 23ca3e73f0..85e1132d2b 100644
--- a/docs/zh-Hans/Entities.md
+++ b/docs/zh-Hans/Entities.md
@@ -211,7 +211,7 @@ public class OrderLine : Entity
> 如果你不想你的聚合根继承`AggregateRoot`类,你可以直接实现`IAggregateRoot`接口
-`Order`是一个具有`Guid`类型`Id`属性的 **聚合根**.它有一个`OrderLine`实体集合.`OrderLine`是一个具有组合键(`OrderLine`和 ` ProductId`)的实体.
+`Order`是一个具有`Guid`类型`Id`属性的 **聚合根**.它有一个`OrderLine`实体集合.`OrderLine`是一个具有组合键(`OrderId`和 ` ProductId`)的实体.
虽然这个示例可能无法实现聚合根的所有最佳实践,但它仍然遵循良好的实践:
diff --git a/docs/zh-Hans/Modules/Docs.md b/docs/zh-Hans/Modules/Docs.md
index 1d09552e50..7b651fd821 100644
--- a/docs/zh-Hans/Modules/Docs.md
+++ b/docs/zh-Hans/Modules/Docs.md
@@ -186,8 +186,9 @@ ABP框架的[文档](docs.abp.io)也是使用的此模块.
然后在 `Acme.MyProject.Web` 项目目录打开命令行终端运行以下命令:
- 1. `yarn`
- 2. `gulp`
+````bash
+abp install-libs
+````
### 4- 数据库集成
diff --git a/docs/zh-Hans/Modules/Virtual-File-Explorer.md b/docs/zh-Hans/Modules/Virtual-File-Explorer.md
index 024b3d23df..e70306f13c 100644
--- a/docs/zh-Hans/Modules/Virtual-File-Explorer.md
+++ b/docs/zh-Hans/Modules/Virtual-File-Explorer.md
@@ -60,8 +60,9 @@
然后在 `Acme.MyProject.Web` 项目目录打开命令行终端运行以下命令:
- 1. `yarn`
- 2. `gulp`
+````bash
+abp install-libs
+````
这就是全部,运行应用程序导航到 `/VirtualFileExplorer`. 你会看到虚拟文件浏览器页面:
diff --git a/docs/zh-Hans/SignalR-Integration.md b/docs/zh-Hans/SignalR-Integration.md
index bdf4a7a786..7adc75daa4 100644
--- a/docs/zh-Hans/SignalR-Integration.md
+++ b/docs/zh-Hans/SignalR-Integration.md
@@ -70,10 +70,10 @@ yarn add @abp/signalr
}
````
-在你的Web项目的根文件夹中运行 `gulp`:
+在你的Web项目的根文件夹中运行 `abp install-libs`:
````bash
-gulp
+abp install-libs
````
它会将SignalR JavaScript文件拷贝到你的项目:
diff --git a/docs/zh-Hans/Tutorials/Todo/Index.md b/docs/zh-Hans/Tutorials/Todo/Index.md
new file mode 100644
index 0000000000..d940957c18
--- /dev/null
+++ b/docs/zh-Hans/Tutorials/Todo/Index.md
@@ -0,0 +1,830 @@
+# 快速入门
+
+````json
+//[doc-params]
+{
+ "UI": ["MVC", "Blazor", "BlazorServer", "NG"],
+ "DB": ["EF", "Mongo"]
+}
+````
+
+这是一个由单个部分组成的快速入门教程, 旨在使用ABP框架构建一个简单的待办事项应用程序. 这是最终应用程序的屏幕截图:
+
+
+
+你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp)找到已完成的项目源代码.
+
+## 先决条件
+
+* 一个集成开发环境 (比如: [Visual Studio](https://visualstudio.microsoft.com/vs/)) 它需要支持 [.NET 5.0+](https://dotnet.microsoft.com/download/dotnet) 的开发.
+
+{{if DB=="Mongo"}}
+
+* [MongoDB Server 4.0+](https://docs.mongodb.com/manual/administration/install-community/)
+
+{{end}}
+
+{{if UI=="NG"}}
+
+* [Node v14.x](https://nodejs.org/)
+
+{{end}}
+
+## 创建新的解决方案
+
+我们将使用[ABP CLI](../../CLI.md) 创建带有ABP框架的新解决方案. 你可以在命令行终端中运行以下命令来安装它:
+
+````bash
+dotnet tool install -g Volo.Abp.Cli
+````
+
+然后创建一个空文件夹, 打开命令行终端并在终端中执行以下命令:
+
+````bash
+abp new TodoApp{{if UI=="Blazor"}} -u blazor{{else if UI=="BlazorServer"}} -u blazor-server{{else if UI=="NG"}} -u angular{{end}}{{if DB=="Mongo"}} -d mongodb{{end}}
+````
+
+{{if UI=="NG"}}
+
+这将创建一个名为*TodoApp*的新解决方案, 其中包含`angular`和`aspnet core`文件夹. 一旦解决方案就绪, 请在你最喜欢的 IDE 中打开 ASP.NET Core 解决方案.
+
+{{else}}
+
+这将创建一个名为*TodoApp*的新解决方案. 一旦解决方案就绪, 请在你最喜欢的 IDE 中打开它.
+
+{{end}}
+
+### 创建数据库
+
+如果你使用的是Visual Studio, 请右键单击`TodoApp.DbMigrator`项目, 选择*设置为启动项目*, 然后按*Ctrl+F5*运行它而不进行调试. 它将创建初始数据库并生成初始数据.
+
+{{if DB=="EF"}}
+
+> 一些IDE (例如Rider) 可能会在第一次运行时遇到问题, 因为 *DbMigrator* 添加初始迁移并重新编译项目. 在这种情况下, 在 `.DbMigrator` 项目文件夹中打开命令行终端并执行 `dotnet run` 命令.
+
+{{end}}
+
+### 运行应用程序
+
+{{if UI=="MVC" || UI=="BlazorServer"}}
+
+最好在开始开发之前运行一下应用程序. 确保 {{if UI=="BlazorServer"}}`TodoApp.Blazor`{{else}}`TodoApp.Web`{{end}} 是启动项目, 然后运行应用程序(Visual Studio中是Ctrl+F5)来查看初始UI:
+
+{{else if UI=="Blazor"}}
+
+最好在开始开发之前运行一下应用程序. 解决方案中有两个主要应用程序
+
+* `TodoApp.HttpApi.Host` 承载服务器端的 HTTP API.
+* `TodoApp.Blazor` 是客户端的Blazor WebAssembly应用程序.
+
+确保 `TodoApp.HttpApi.Host` 是启动项目, 然后运行应用程序(Visual Studio中的Ctrl+F5)打开[Swagger UI](https://swagger.io/tools/swagger-ui/)来查看服务器端的 HTTP API:
+
+
+
+你可以使用此 UI 探索和测试你的 HTTP API. 现在, 我们可以将 `TodoApp.Blazor` 设置为启动项目并运行它来打开实际的 Blazor 应用程序UI:
+
+{{else if UI=="NG"}}
+
+最好在开始开发之前运行一下应用程序. 解决方案中有两个主要应用程序;
+
+* `TodoApp.HttpApi.Host` (在.NET解决方案中)承载服务器端HTTP API.
+* `Angular` 文件夹包含 Angular 应用程序.
+
+确保 `TodoApp.HttpApi.Host` 是启动项目, 然后运行应用程序(Visual Studio中的Ctrl+F5)打开[Swagger UI](https://swagger.io/tools/swagger-ui/)来查看服务器端的 HTTP API:
+
+
+
+你可以使用此 UI 探索和测试你的 HTTP API. 如果该功能正常, 我们可以运行Angular 客户端应用程序.
+
+首先, 运行以下命令来还原NPM包:
+
+````bash
+npm install
+````
+
+安装所有软件包需要一些时间. 然后可以使用以下命令运行应用程序:
+
+````bash
+npm start
+````
+
+此命令需要时间, 但最终在你的默认浏览器中运行并打开应用程序:
+
+{{end}}
+
+
+
+你可以单击 *登录* 按钮, 以`admin`作为用户名和`1q2w3E*` 作为密码登录到应用程序.
+
+一切就绪. 我们可以开始编程!
+
+## 领域层
+
+此应用程序只有一个 [实体](../../Entities.md), 接下来我们开始创建它. 在 *TodoApp.Domain* 项目中创建一个新的 `TodoItem` 类:
+
+````csharp
+using System;
+using Volo.Abp.Domain.Entities;
+
+namespace TodoApp
+{
+ public class TodoItem : BasicAggregateRoot
+ {
+ public string Text { get; set; }
+ }
+}
+````
+
+`BasicAggregateRoot` 是创建根实体的最简单的基础类. `Guid` 是这里实体的主键 (`Id`).
+
+## 数据库集成
+
+{{if DB=="EF"}}
+
+下一步是设置 [Entity Framework Core](../../Entity-Framework-Core.md)配置
+
+### 映射配置
+
+打开在 *TodoApp.EntityFrameworkCore* 项目中 `EntityFrameworkCore` 文件夹中的 `TodoAppDbContext` 类, 并向该类添加新的 `DbSet` 属性:
+
+````csharp
+public DbSet TodoItems { get; set; }
+````
+
+然后在 `TodoAppDbContext` 类中定位到 `OnModelCreating` 方法, 并为 `TodoItem` 实体添加映射代码:
+
+````csharp
+protected override void OnModelCreating(ModelBuilder builder)
+{
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ builder.ConfigurePermissionManagement();
+ ...
+
+ /* Configure your own tables/entities inside here */
+ builder.Entity(b =>
+ {
+ b.ToTable("TodoItems");
+ });
+}
+````
+
+我们已经将 `TodoItem` 实体映射到数据库中的 `TodoItems` 表.
+
+### Code First 迁移
+
+解决方案快速模版已经配置为使用Entity Framework Core的 [Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations). 由于我们已经更改了数据库映射配置, 因此我们应该创建一个新的迁移并将更改应用于数据库.
+
+在 *TodoApp.EntityFrameworkCore* 项目目录中打开一个命令行终端并输入以下命令:
+
+````bash
+dotnet ef migrations add Added_TodoItem
+````
+
+这将向项目添加一个新的迁移类:
+
+
+
+你可以在同一命令行终端中使用以下命令将更改应用于数据库:
+
+````bash
+dotnet ef database update
+````
+
+> 如果你使用的是Visual Studio, 则可能希望在 *包管理器控制台 (PMC)* 中使用 `Add-Migration Added_TodoItem` 和 `Update-Database` 命令. 在这种情况下, 请确保 {{if UI=="MVC"}}`TodoApp.Web`{{else if UI=="BlazorServer"}}`TodoApp.Blazor`{{else if UI=="Blazor" || UI=="NG"}}`TodoApp.HttpApi.Host`{{end}} 是启动项目, 并且 `TodoApp.EntityFrameworkCore` 是PMC中的 *默认项目*.
+
+{{else if DB=="Mongo"}}
+
+下一步是设置 [MongoDB](../../MongoDB.md) 配置. 打开 *TodoApp.MongoDB* 项目中 `MongoDb` 文件夹的`TodoAppMongoDbContext` 类并做出以下更改;
+
+1. 向类添加新属性:
+
+````csharp
+public IMongoCollection TodoItems => Collection();
+````
+
+2. 在 `CreateModel` 方法中添加以下代码:
+
+````csharp
+modelBuilder.Entity(b =>
+{
+ b.CollectionName = "TodoItems";
+});
+````
+
+{{end}}
+
+现在, 我们可以使用ABP仓库保存和检索待办事项, 如我们在下一节所做的那样.
+
+## 应用层
+
+[应用程序服务](../../Application-Services.md) 用于执行应用程序的用例. 我们需要执行以下用例:
+
+* 获取待办事项列表
+* 创建新的待办事项
+* 删除现有的待办事项
+
+### 应用服务接口
+
+我们可以先从为应用程序服务定义接口开始. 在 *TodoApp.Application.Contracts* 项目中创建新的 `ITodoAppService` 接口, 如下所示:
+
+````csharp
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+
+namespace TodoApp
+{
+ public interface ITodoAppService : IApplicationService
+ {
+ Task> GetListAsync();
+ Task CreateAsync(string text);
+ Task DeleteAsync(Guid id);
+ }
+}
+````
+
+### 数据传输对象
+
+`GetListAsync` 和`CreateAsync` 方法返回 `TodoItemDto`. `应用程序服务` 通常获取并返回 DTO([数据传输对象](../../Data-Transfer-Objects.md)) 而不是实体. 因此, 我们应该在这里定义DTO类. 在 *TodoApp.Application.Contracts* 项目中创建新的 `TodoItemDto` 类:
+
+````csharp
+using System;
+
+namespace TodoApp
+{
+ public class TodoItemDto
+ {
+ public Guid Id { get; set; }
+ public string Text { get; set; }
+ }
+}
+````
+
+这是一个非常简单的DTO类, 它与我们的 `TodoItem` 实体相对应. 接下来, 我们准备实现 `ITodoAppService`接口.
+
+### 应用服务实现
+
+在 *TodoApp.Application* 项目中创建 `TodoAppService` 类, 如下所示:
+
+````csharp
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Domain.Repositories;
+
+namespace TodoApp
+{
+ public class TodoAppService : ApplicationService, ITodoAppService
+ {
+ private readonly IRepository _todoItemRepository;
+
+ public TodoAppService(IRepository todoItemRepository)
+ {
+ _todoItemRepository = todoItemRepository;
+ }
+
+ // TODO: Implement the methods here...
+ }
+}
+````
+
+该类继承自ABP框架的`ApplicationService`类, 并实现了之前定义的 `ITodoAppService`接口. ABP为实体提供默认的泛型 [仓储](../../Repositories.md). 我们可以使用它们来执行基本的数据库操作. 此类中 [注入](../../Dependency-Injection.md) 的 `IRepository`, 它就是 `TodoItem` 实体的默认存储库. 我们将使用它来实现之前描述的用例.
+
+#### 获取待办事项
+
+让我们先实现 `GetListAsync` 方法:
+
+````csharp
+public async Task> GetListAsync()
+{
+ var items = await _todoItemRepository.GetListAsync();
+ return items
+ .Select(item => new TodoItemDto
+ {
+ Id = item.Id,
+ Text = item.Text
+ }).ToList();
+}
+````
+
+我们只是从数据库中获取完整的`TodoItem`列表, 将它们映射到`TodoItemDto`对象并作为结果返回.
+
+#### 创建一个新的待办事项
+
+下一个我们可以实现方法是 `CreateAsync` , 如下所示:
+
+````csharp
+public async Task CreateAsync(string text)
+{
+ var todoItem = await _todoItemRepository.InsertAsync(
+ new TodoItem {Text = text}
+ );
+
+ return new TodoItemDto
+ {
+ Id = todoItem.Id,
+ Text = todoItem.Text
+ };
+}
+````
+
+仓储的 `InsertAsync` 方法将给定的`TodoItem`插入数据库, 并返回相同的`TodoItem` 对象. 它还设置了`Id`, 因此我们可以在返回对象上使用它. 我们只是通过从新的 `TodoItem` 实体创建和返回 `TodoItemDto`.
+
+#### 删除待办事项
+
+最后, 我们来实现 `DeleteAsync` 方法, 代码如下:
+
+````csharp
+public async Task DeleteAsync(Guid id)
+{
+ await _todoItemRepository.DeleteAsync(id);
+}
+````
+
+至此, 应用程序服务已准备好了让UI层来使用.
+
+## 用户界面层
+
+现在是在UI上显示待办事项的时候了! 在开始编写代码之前, 最好记住我们正在尝试构建的内容. 这里是示例程序的最终用户界面的截图:
+
+
+
+> **我们将在本教程中保持最简洁的UI端, 以使本教程简单且重点突出. 请参阅 [web应用程序开发教程](../Part-1.md) 来了解构建实际应用各个方面.**
+
+{{if UI=="MVC"}}
+
+### Index.cshtml.cs
+
+打开在 *TodoApp.Web* 项目的 `Pages` 文件夹中`Index.cshtml.cs`文件, 并用以下代码块替换它的默认内容:
+
+````csharp
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace TodoApp.Web.Pages
+{
+ public class IndexModel : TodoAppPageModel
+ {
+ public List TodoItems { get; set; }
+
+ private readonly ITodoAppService _todoAppService;
+
+ public IndexModel(ITodoAppService todoAppService)
+ {
+ _todoAppService = todoAppService;
+ }
+
+ public async Task OnGetAsync()
+ {
+ TodoItems = await _todoAppService.GetListAsync();
+ }
+ }
+}
+````
+
+此类使用 `ITodoAppService` 获取待办事项列表并将它赋值给 `TodoItems` 属性. 我们将用它来渲染razor页面上的待办事项目列表.
+
+### Index.cshtml
+
+打开 *TodoApp.Web* 项目中`Pages`文件夹下的`Index.cshtml`, 并替换为以下内容:
+
+````xml
+@page
+@model TodoApp.Web.Pages.IndexModel
+@section styles {
+
+}
+@section scripts {
+
+}
+
+
+
+
+ TODO LIST
+
+
+
+
+
+
+
+
+ @foreach (var todoItem in Model.TodoItems)
+ {
+