Browse Source

Merge pull request #34 from abpframework/feat/angular-project-for-demo

Feat/angular project for demo
pull/37/head
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
75e302ea09
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      apps/angular/angular.json
  2. 21
      apps/angular/package.json
  3. 24
      apps/angular/projects/catalog/README.md
  4. 7
      apps/angular/projects/catalog/config/ng-package.json
  5. 12
      apps/angular/projects/catalog/config/src/catalog-config.module.ts
  6. 2
      apps/angular/projects/catalog/config/src/enums/index.ts
  7. 8
      apps/angular/projects/catalog/config/src/enums/policy-names.ts
  8. 4
      apps/angular/projects/catalog/config/src/enums/route-names.ts
  9. 1
      apps/angular/projects/catalog/config/src/providers/index.ts
  10. 31
      apps/angular/projects/catalog/config/src/providers/route.provider.ts
  11. 3
      apps/angular/projects/catalog/config/src/public-api.ts
  12. 44
      apps/angular/projects/catalog/karma.conf.js
  13. 7
      apps/angular/projects/catalog/ng-package.json
  14. 14
      apps/angular/projects/catalog/package.json
  15. 16
      apps/angular/projects/catalog/src/catalog-routing.module.ts
  16. 7
      apps/angular/projects/catalog/src/catalog.module.ts
  17. 17
      apps/angular/projects/catalog/src/lib/proxy/README.md
  18. 2221
      apps/angular/projects/catalog/src/lib/proxy/generate-proxy.json
  19. 2
      apps/angular/projects/catalog/src/lib/proxy/index.ts
  20. 3
      apps/angular/projects/catalog/src/lib/proxy/products/index.ts
  21. 24
      apps/angular/projects/catalog/src/lib/proxy/products/models.ts
  22. 58
      apps/angular/projects/catalog/src/lib/proxy/products/product.service.ts
  23. 27
      apps/angular/projects/catalog/src/lib/proxy/products/public-product.service.ts
  24. 1
      apps/angular/projects/catalog/src/pages/index.ts
  25. 3
      apps/angular/projects/catalog/src/pages/product/index.ts
  26. 22
      apps/angular/projects/catalog/src/pages/product/product-routing.module.ts
  27. 0
      apps/angular/projects/catalog/src/pages/product/product.component.css
  28. 167
      apps/angular/projects/catalog/src/pages/product/product.component.html
  29. 106
      apps/angular/projects/catalog/src/pages/product/product.component.ts
  30. 21
      apps/angular/projects/catalog/src/pages/product/product.module.ts
  31. 4
      apps/angular/projects/catalog/src/public-api.ts
  32. 28
      apps/angular/projects/catalog/src/test.ts
  33. 20
      apps/angular/projects/catalog/tsconfig.lib.json
  34. 10
      apps/angular/projects/catalog/tsconfig.lib.prod.json
  35. 17
      apps/angular/projects/catalog/tsconfig.spec.json
  36. 4
      apps/angular/src/app/app-routing.module.ts
  37. 12
      apps/angular/src/app/app.module.ts
  38. 13
      apps/angular/src/environments/environment.ts
  39. 10
      apps/angular/tsconfig.json
  40. 2391
      apps/angular/yarn.lock
  41. 5
      package.json
  42. 2
      services/administration/src/EShopOnAbp.AdministrationService.Application.Contracts/AdministrationServiceApplicationContractsModule.cs
  43. 2
      services/administration/src/EShopOnAbp.AdministrationService.Application.Contracts/EShopOnAbp.AdministrationService.Application.Contracts.csproj
  44. 12
      services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/Localization/CatalogService/en.json
  45. 19
      services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/Localization/CatalogService/tr.json
  46. 4
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json
  47. 2
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServerDataSeeder.cs
  48. 15
      yarn.lock

41
apps/angular/angular.json

@ -51,15 +51,13 @@
"bundleName": "ngx-datatable-material"
},
{
"input": "node_modules/bootstrap/dist/css/bootstrap.rtl.min.css",
"input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css",
"inject": false,
"bundleName": "bootstrap-rtl.min"
},
{
"input": "node_modules/bootstrap/dist/css/bootstrap.min.css",
"inject": true,
"bundleName": "bootstrap-ltr.min"
},
"node_modules/@volo/ngx-lepton-x.lite/styles/sidemenu-layout.min.css",
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
"src/styles.scss"
],
"scripts": [],
@ -158,6 +156,37 @@
}
}
}
},
"catalog": {
"projectType": "library",
"root": "projects/catalog",
"sourceRoot": "projects/catalog/src",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"project": "projects/catalog/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "projects/catalog/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "projects/catalog/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/catalog/src/test.ts",
"tsConfig": "projects/catalog/tsconfig.spec.json",
"karmaConfig": "projects/catalog/karma.conf.js"
}
}
}
}
},
"defaultProject": "EShopOnAbp",

21
apps/angular/package.json

@ -12,14 +12,15 @@
},
"private": true,
"dependencies": {
"@abp/ng.account": "~5.0.0-rc.1",
"@abp/ng.components": "~5.0.0-rc.1",
"@abp/ng.core": "~5.0.0-rc.1",
"@abp/ng.identity": "~5.0.0-rc.1",
"@abp/ng.setting-management": "~5.0.0-rc.1",
"@abp/ng.tenant-management": "~5.0.0-rc.1",
"@abp/ng.theme.basic": "~5.0.0-rc.1",
"@abp/ng.theme.shared": "~5.0.0-rc.1",
"@abp/ng.account": "4.4.4",
"@abp/ng.components": "4.4.4",
"@abp/ng.core": "4.4.4",
"@abp/ng.identity": "4.4.4",
"@abp/ng.setting-management": "4.4.4",
"@abp/ng.tenant-management": "4.4.4",
"@abp/ng.theme.basic": "4.4.4",
"@abp/ng.theme.lepton-x": "^1.0.0-alpha.2",
"@abp/ng.theme.shared": "4.4.4",
"@angular/animations": "~12.2.8",
"@angular/common": "~12.2.8",
"@angular/compiler": "~12.2.8",
@ -34,7 +35,7 @@
"zone.js": "~0.11.4"
},
"devDependencies": {
"@abp/ng.schematics": "~5.0.0-rc.1",
"@abp/ng.schematics": "4.4.4",
"@angular-devkit/build-angular": "~12.2.8",
"@angular/cli": "~12.2.8",
"@angular/compiler-cli": "~12.2.8",
@ -56,4 +57,4 @@
"tslint": "~6.1.0",
"typescript": "~4.3.5"
}
}
}

24
apps/angular/projects/catalog/README.md

@ -0,0 +1,24 @@
# Catalog
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.
## Code scaffolding
Run `ng generate component component-name --project catalog` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project catalog`.
> Note: Don't forget to add `--project catalog` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build catalog` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build catalog`, go to the dist folder `cd dist/catalog` and run `npm publish`.
## Running unit tests
Run `ng test catalog` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

7
apps/angular/projects/catalog/config/ng-package.json

@ -0,0 +1,7 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/catalog/config",
"lib": {
"entryFile": "src/public-api.ts"
}
}

12
apps/angular/projects/catalog/config/src/catalog-config.module.ts

@ -0,0 +1,12 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { CATALOG_ROUTE_PROVIDERS } from './providers/route.provider';
@NgModule()
export class CatalogConfigModule {
static forRoot(): ModuleWithProviders<CatalogConfigModule> {
return {
ngModule: CatalogConfigModule,
providers: [CATALOG_ROUTE_PROVIDERS],
};
}
}

2
apps/angular/projects/catalog/config/src/enums/index.ts

@ -0,0 +1,2 @@
export * from './policy-names';
export * from './route-names';

8
apps/angular/projects/catalog/config/src/enums/policy-names.ts

@ -0,0 +1,8 @@
export const enum eCatalogPolicyNames {
Catalog = 'CatalogService.Products',
ProductManagement = 'CatalogService.Products',
ProductManagementCreate = 'CatalogService.Products.Create',
ProductManagementUpdate = 'CatalogService.Products.Update',
ProductManagementDelete = 'CatalogService.Products.Delete',
}

4
apps/angular/projects/catalog/config/src/enums/route-names.ts

@ -0,0 +1,4 @@
export const enum eCatalogRouteNames {
Catalog = 'CatalogService::Menu:CatalogManagement',
Products = 'CatalogService::Menu:Products',
}

1
apps/angular/projects/catalog/config/src/providers/index.ts

@ -0,0 +1 @@
export * from './route.provider';

31
apps/angular/projects/catalog/config/src/providers/route.provider.ts

@ -0,0 +1,31 @@
import { eLayoutType, RoutesService } from '@abp/ng.core';
import { APP_INITIALIZER } from '@angular/core';
import { eCatalogPolicyNames } from '../enums/policy-names';
import { eCatalogRouteNames } from '../enums/route-names';
export const CATALOG_ROUTE_PROVIDERS = [
{ provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true },
];
export function configureRoutes(routesService: RoutesService) {
return () => {
routesService.add([
{
path: '/catalog',
name: eCatalogRouteNames.Catalog,
layout: eLayoutType.application,
parentName: null,
iconClass: 'bi bi-collection-fill',
requiredPolicy: eCatalogPolicyNames.Catalog,
},
{
path: '/catalog/products',
name: eCatalogRouteNames.Products,
parentName: eCatalogRouteNames.Catalog,
order: 1,
requiredPolicy: eCatalogPolicyNames.ProductManagement,
iconClass: 'bi bi-tag-fill',
},
]);
};
}

3
apps/angular/projects/catalog/config/src/public-api.ts

@ -0,0 +1,3 @@
export * from './catalog-config.module';
export * from './enums';
export * from './providers';

44
apps/angular/projects/catalog/karma.conf.js

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, '../../coverage/catalog'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

7
apps/angular/projects/catalog/ng-package.json

@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/catalog",
"lib": {
"entryFile": "src/public-api.ts"
}
}

14
apps/angular/projects/catalog/package.json

@ -0,0 +1,14 @@
{
"name": "@eshoponabp/catalog",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^12.2.0",
"@angular/core": "^12.2.0",
"@abp/ng.theme.shared": "~5.0.0-rc.2",
"@abp/ng.core": "~5.0.0-rc.2",
"@ngx-validate/core": "~0.1.1"
},
"dependencies": {
"tslib": "^2.3.0"
}
}

16
apps/angular/projects/catalog/src/catalog-routing.module.ts

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: '', redirectTo: 'products', pathMatch: 'full' },
{
path: 'products',
loadChildren: () => import('./pages/product/product.module').then(m => m.ProductModule),
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class CatalogRoutingModule {}

7
apps/angular/projects/catalog/src/catalog.module.ts

@ -0,0 +1,7 @@
import { NgModule } from '@angular/core';
import { CatalogRoutingModule } from './catalog-routing.module';
@NgModule({
imports: [CatalogRoutingModule],
})
export class CatalogModule {}

17
apps/angular/projects/catalog/src/lib/proxy/README.md

@ -0,0 +1,17 @@
# Proxy Generation Output
This directory includes the output of the latest proxy generation.
The files and folders in it will be overwritten when proxy generation is run again.
Therefore, please do not place your own content in this folder.
In addition, `generate-proxy.json` works like a lock file.
It includes information used by the proxy generator, so please do not delete or modify it.
Finally, the name of the files and folders should not be changed for two reasons:
- Proxy generator will keep creating them at those paths and you will have multiple copies of the same content.
- ABP Suite generates files which include imports from this folder.
> **Important Notice:** If you are building a module and are planning to publish to npm,
> some of the generated proxies are likely to be exported from public-api.ts file. In such a case,
> please make sure you export files directly and not from barrel exports. In other words,
> do not include index.ts exports in your public-api.ts exports.

2221
apps/angular/projects/catalog/src/lib/proxy/generate-proxy.json

File diff suppressed because it is too large

2
apps/angular/projects/catalog/src/lib/proxy/index.ts

@ -0,0 +1,2 @@
import * as Products from './products';
export { Products };

3
apps/angular/projects/catalog/src/lib/proxy/products/index.ts

@ -0,0 +1,3 @@
export * from './models';
export * from './product.service';
export * from './public-product.service';

24
apps/angular/projects/catalog/src/lib/proxy/products/models.ts

@ -0,0 +1,24 @@
import type { AuditedEntityDto } from '@abp/ng.core';
export interface CreateProductDto {
code: string;
name: string;
imageName?: string;
price: number;
stockCount: number;
}
export interface ProductDto extends AuditedEntityDto<string> {
code?: string;
name?: string;
imageName?: string;
price: number;
stockCount: number;
}
export interface UpdateProductDto {
name: string;
imageName?: string;
price: number;
stockCount: number;
}

58
apps/angular/projects/catalog/src/lib/proxy/products/product.service.ts

@ -0,0 +1,58 @@
import type { CreateProductDto, ProductDto, UpdateProductDto } from './models';
import { RestService } from '@abp/ng.core';
import type { ListResultDto, PagedAndSortedResultRequestDto, PagedResultDto } from '@abp/ng.core';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class ProductService {
apiName = 'Catalog';
create = (input: CreateProductDto) =>
this.restService.request<any, ProductDto>({
method: 'POST',
url: '/api/catalog/product',
body: input,
},
{ apiName: this.apiName });
delete = (id: string) =>
this.restService.request<any, void>({
method: 'DELETE',
url: `/api/catalog/product/${id}`,
},
{ apiName: this.apiName });
get = (id: string) =>
this.restService.request<any, ProductDto>({
method: 'GET',
url: `/api/catalog/product/${id}`,
},
{ apiName: this.apiName });
getList = () =>
this.restService.request<any, ListResultDto<ProductDto>>({
method: 'GET',
url: '/api/catalog/product',
},
{ apiName: this.apiName });
getListPaged = (input: PagedAndSortedResultRequestDto) =>
this.restService.request<any, PagedResultDto<ProductDto>>({
method: 'GET',
url: '/api/catalog/product/paged',
params: { sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount },
},
{ apiName: this.apiName });
update = (id: string, input: UpdateProductDto) =>
this.restService.request<any, ProductDto>({
method: 'PUT',
url: `/api/catalog/product/${id}`,
body: input,
},
{ apiName: this.apiName });
constructor(private restService: RestService) {}
}

27
apps/angular/projects/catalog/src/lib/proxy/products/public-product.service.ts

@ -0,0 +1,27 @@
import type { ProductDto } from './models';
import { RestService } from '@abp/ng.core';
import type { ListResultDto } from '@abp/ng.core';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class PublicProductService {
apiName = 'Catalog';
get = (id: string) =>
this.restService.request<any, ProductDto>({
method: 'GET',
url: `/api/catalog/public-product/${id}`,
},
{ apiName: this.apiName });
getList = () =>
this.restService.request<any, ListResultDto<ProductDto>>({
method: 'GET',
url: '/api/catalog/public-product',
},
{ apiName: this.apiName });
constructor(private restService: RestService) {}
}

1
apps/angular/projects/catalog/src/pages/index.ts

@ -0,0 +1 @@
export * from './product';

3
apps/angular/projects/catalog/src/pages/product/index.ts

@ -0,0 +1,3 @@
export * from './product-routing.module';
export * from './product.component';
export * from './product.module';

22
apps/angular/projects/catalog/src/pages/product/product-routing.module.ts

@ -0,0 +1,22 @@
import { AuthGuard, PermissionGuard } from '@abp/ng.core';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { eCatalogPolicyNames } from '@eshoponabp/catalog/config';
import { ProductComponent } from './product.component';
const routes: Routes = [
{
path: '',
component: ProductComponent,
canActivate: [AuthGuard, PermissionGuard],
data: {
requiredPolicy: eCatalogPolicyNames.ProductManagement,
},
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ProductRoutingModule {}

0
apps/angular/projects/catalog/src/pages/product/product.component.css

167
apps/angular/projects/catalog/src/pages/product/product.component.html

@ -0,0 +1,167 @@
<div class="card">
<div class="card-header">
<div class="row">
<div class="col col-md-6">
<h5 class="card-title">{{ 'CatalogService::Products' | abpLocalization }}</h5>
</div>
<div class="text-right col col-md-6">
<button class="btn btn-primary" (click)="onCreate()" *abpPermission="permissions.create">
{{ 'CatalogService::NewProduct' | abpLocalization }}
</button>
</div>
</div>
</div>
<div class="card-body">
<ngx-datatable [rows]="items" [count]="count" [list]="list" default>
<ngx-datatable-column
[name]="'AbpUi::Actions' | abpLocalization"
[sortable]="false"
*abpPermission="permissions.update + ' || ' + permissions.delete"
>
<ng-template let-row="row" ngx-datatable-cell-template>
<div ngbDropdown container="body" class="d-inline-block">
<button
class="btn btn-primary btn-sm dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
ngbDropdownToggle
>
<i class="mr-1 fa fa-cog"></i>{{ 'AbpUi::Actions' | abpLocalization }}
</button>
<div ngbDropdownMenu>
<button
class="dropdown-item"
(click)="onEdit(row)"
*abpPermission="permissions.update"
>
{{ 'AbpUi::Edit' | abpLocalization }}
</button>
<button
class="dropdown-item"
(click)="onDelete(row)"
*abpPermission="permissions.delete"
>
{{ 'AbpUi::Delete' | abpLocalization }}
</button>
</div>
</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column
[name]="'CatalogService::DisplayName:Code' | abpLocalization"
prop="code"
></ngx-datatable-column>
<ngx-datatable-column
[name]="'CatalogService::DisplayName:Name' | abpLocalization"
prop="name"
></ngx-datatable-column>
<ngx-datatable-column
[name]="'CatalogService::DisplayName:ImageName' | abpLocalization"
prop="imageName"
></ngx-datatable-column>
<ngx-datatable-column
[name]="'CatalogService::DisplayName:Price' | abpLocalization"
prop="price"
></ngx-datatable-column>
<ngx-datatable-column
[name]="'CatalogService::DisplayName:StockCount' | abpLocalization"
prop="stockCount"
></ngx-datatable-column>
</ngx-datatable>
</div>
</div>
<abp-modal [(visible)]="isModalVisible" [busy]="modalBusy">
<ng-template #abpHeader>
<h3>
{{ (selected?.id ? 'AbpUi::Edit' : 'CatalogService::NewProduct') | abpLocalization }}
</h3>
</ng-template>
<ng-template #abpBody>
<ng-template #loaderRef
><div class="text-center"><i class="fa fa-pulse fa-spinner"></i></div
></ng-template>
<form *ngIf="form; else loaderRef" [formGroup]="form" (ngSubmit)="save()">
<div class="mb-3">
<label class="form-label" for="code">
{{ 'CatalogService::DisplayName:Code' | abpLocalization }} *
</label>
<input
type="text"
class="form-control"
id="code"
formControlName="code"
[readonly]="selected?.id"
[placeholder]="'CatalogService::DisplayName:Code' | abpLocalization"
/>
</div>
<div class="mb-3">
<label class="form-label" for="name">
{{ 'CatalogService::DisplayName:Name' | abpLocalization }} *
</label>
<input
type="text"
class="form-control"
id="name"
formControlName="name"
[placeholder]="'CatalogService::DisplayName:Name' | abpLocalization"
/>
</div>
<div class="mb-3">
<label class="form-label" for="imageName">
{{ 'CatalogService::DisplayName:ImageName' | abpLocalization }} *
</label>
<input
type="text"
class="form-control"
id="imageName"
formControlName="imageName"
[placeholder]="'CatalogService::DisplayName:ImageName' | abpLocalization"
/>
</div>
<div class="mb-3">
<label class="form-label" for="price">
{{ 'CatalogService::DisplayName:Price' | abpLocalization }} *
</label>
<input
type="number"
class="form-control"
id="price"
formControlName="price"
[placeholder]="'CatalogService::DisplayName:Price' | abpLocalization"
/>
</div>
<div class="mb-3">
<label class="form-label" for="stockCount">
{{ 'CatalogService::DisplayName:StockCount' | abpLocalization }} *
</label>
<input
type="number"
class="form-control"
id="stockCount"
formControlName="stockCount"
[placeholder]="'CatalogService::DisplayName:StockCount' | abpLocalization"
/>
</div>
</form>
<ng-template #loaderRef
><div class="text-center"><i class="fa fa-pulse fa-spinner"></i></div
></ng-template>
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" abpClose>
{{ 'AbpUi::Cancel' | abpLocalization }}
</button>
<abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="save()">{{
'AbpUi::Save' | abpLocalization
}}</abp-button>
</ng-template>
</abp-modal>

106
apps/angular/projects/catalog/src/pages/product/product.component.ts

@ -0,0 +1,106 @@
import { ListService } from '@abp/ng.core';
import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { eCatalogPolicyNames } from '@eshoponabp/catalog/config';
import { finalize } from 'rxjs/operators';
import { ProductDto } from '../../lib/proxy/products/models';
import { ProductService } from '../../lib/proxy/products/product.service';
@Component({
selector: 'lib-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css'],
providers: [ListService],
})
export class ProductComponent implements OnInit {
permissions = {
create: eCatalogPolicyNames.ProductManagementCreate,
update: eCatalogPolicyNames.ProductManagementUpdate,
delete: eCatalogPolicyNames.ProductManagementDelete,
};
items: ProductDto[] = [];
count = 0;
selected: ProductDto;
isModalVisible: boolean;
modalBusy = false;
form: FormGroup;
constructor(
public readonly list: ListService,
private readonly service: ProductService,
private confirmationService: ConfirmationService,
private fb: FormBuilder
) {
this.list.maxResultCount = 10;
}
ngOnInit(): void {
const productStreamCreator = query => this.service.getListPaged(query);
this.list.hookToQuery(productStreamCreator).subscribe(response => {
this.items = response.items;
this.count = response.totalCount;
});
}
buildForm() {
this.form = this.fb.group({
name: [this.selected.name, { validators: [Validators.required] }],
code: [this.selected.code, { validators: [Validators.required] }],
imageName: [this.selected.imageName, { validators: [Validators.required] }],
price: [this.selected.price, { validators: [Validators.required] }],
stockCount: [this.selected.stockCount, { validators: [Validators.required] }],
});
}
onEdit(product: ProductDto) {
this.selected = product;
this.openModal();
}
onCreate() {
this.selected = {} as ProductDto;
this.openModal();
}
openModal() {
this.isModalVisible = true;
this.buildForm();
}
onDelete(product: ProductDto) {
this.confirmationService
.warn('CatalogService::ProductDeletionConfirmationMessage', 'AbpUi::AreYouSure', {
messageLocalizationParams: [product.name],
})
.subscribe((status: Confirmation.Status) => {
if (status === Confirmation.Status.confirm) {
this.service.delete(product.id).subscribe(() => this.list.get());
}
});
}
save() {
if (!this.form.valid || this.modalBusy) return;
this.modalBusy = true;
const { id } = this.selected;
(id
? this.service.update(id, {
...this.selected,
...this.form.value,
})
: this.service.create({ ...this.form.value })
)
.pipe(finalize(() => (this.modalBusy = false)))
.subscribe(() => {
this.isModalVisible = false;
this.list.get();
});
}
}

21
apps/angular/projects/catalog/src/pages/product/product.module.ts

@ -0,0 +1,21 @@
import { CoreModule } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxValidateCoreModule } from '@ngx-validate/core';
import { ProductRoutingModule } from './product-routing.module';
import { ProductComponent } from './product.component';
@NgModule({
declarations: [ProductComponent],
imports: [
CommonModule,
ProductRoutingModule,
ThemeSharedModule,
CoreModule,
NgbDropdownModule,
NgxValidateCoreModule,
],
})
export class ProductModule {}

4
apps/angular/projects/catalog/src/public-api.ts

@ -0,0 +1,4 @@
export * from './catalog-routing.module';
export * from './catalog.module';
export * from './lib/proxy/products';
export * from './pages';

28
apps/angular/projects/catalog/src/test.ts

@ -0,0 +1,28 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(),
{ teardown: { destroyAfterEach: true }},
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

20
apps/angular/projects/catalog/tsconfig.lib.json

@ -0,0 +1,20 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"target": "es2015",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}

10
apps/angular/projects/catalog/tsconfig.lib.prod.json

@ -0,0 +1,10 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"compilationMode": "partial"
}
}

17
apps/angular/projects/catalog/tsconfig.spec.json

@ -0,0 +1,17 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

4
apps/angular/src/app/app-routing.module.ts

@ -25,6 +25,10 @@ const routes: Routes = [
loadChildren: () =>
import('@abp/ng.setting-management').then(m => m.SettingManagementModule.forLazy()),
},
{
path: 'catalog',
loadChildren: () => import('@eshoponabp/catalog').then(m => m.CatalogModule),
},
];
@NgModule({

12
apps/angular/src/app/app.module.ts

@ -4,11 +4,15 @@ import { registerLocale } from '@abp/ng.core/locale';
import { IdentityConfigModule } from '@abp/ng.identity/config';
import { SettingManagementConfigModule } from '@abp/ng.setting-management/config';
import { TenantManagementConfigModule } from '@abp/ng.tenant-management/config';
import { ThemeBasicModule } from '@abp/ng.theme.basic';
import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x';
import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { CatalogConfigModule } from '@eshoponabp/catalog/config';
import { NgxsModule } from '@ngxs/store';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@ -28,7 +32,11 @@ import { APP_ROUTE_PROVIDER } from './route.provider';
IdentityConfigModule.forRoot(),
TenantManagementConfigModule.forRoot(),
SettingManagementConfigModule.forRoot(),
ThemeBasicModule.forRoot(),
ThemeLeptonXModule.forRoot(),
SideMenuLayoutModule.forRoot(),
AccountLayoutModule.forRoot(),
CatalogConfigModule.forRoot(),
NgxsModule.forRoot(),
],
declarations: [AppComponent],
providers: [APP_ROUTE_PROVIDER],

13
apps/angular/src/environments/environment.ts

@ -12,15 +12,18 @@ export const environment = {
issuer: 'https://localhost:44330',
redirectUri: baseUrl,
clientId: 'Web',
responseType: 'code',
scope:
'offline_access openid profile email phone IdentityService AdministrationService',
requireHttps: true,
//responseType: 'code',
scope: 'offline_access openid profile email phone IdentityService AdministrationService',
//requireHttps: true,
},
apis: {
default: {
url: 'https://localhost:44372',
rootNamespace: 'EShopOnAbp',
}
},
Catalog: {
url: 'https://localhost:44354',
rootNamespace: 'EShopOnAbp.CatalogService',
},
},
} as Environment;

10
apps/angular/tsconfig.json

@ -14,8 +14,14 @@
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"paths": {
"@proxy": ["src/app/proxy/index.ts"],
"@proxy/*": ["src/app/proxy/*"]
"@eshoponabp/catalog/config": [
"node_modules/@eshoponabp/catalog/config",
"projects/catalog/config/src/public-api.ts"
],
"@eshoponabp/catalog": [
"node_modules/@eshoponabp/catalog",
"projects/catalog/src/public-api.ts",
],
}
},
"angularCompilerOptions": {

2391
apps/angular/yarn.lock

File diff suppressed because it is too large

5
package.json

@ -0,0 +1,5 @@
{
"dependencies": {
"@ngxs/store": "^3.7.3"
}
}

2
services/administration/src/EShopOnAbp.AdministrationService.Application.Contracts/AdministrationServiceApplicationContractsModule.cs

@ -2,10 +2,12 @@
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SettingManagement;
using EShopOnAbp.CatalogService;
namespace EShopOnAbp.AdministrationService
{
[DependsOn(
typeof(CatalogServiceApplicationContractsModule),
typeof(AdministrationServiceDomainSharedModule),
typeof(AbpPermissionManagementApplicationContractsModule),
typeof(AbpFeatureManagementApplicationContractsModule),

2
services/administration/src/EShopOnAbp.AdministrationService.Application.Contracts/EShopOnAbp.AdministrationService.Application.Contracts.csproj

@ -7,12 +7,14 @@
<ItemGroup>
<ProjectReference Include="..\EShopOnAbp.AdministrationService.Domain.Shared\EShopOnAbp.AdministrationService.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\catalog\src\EShopOnAbp.CatalogService.Application.Contracts\EShopOnAbp.CatalogService.Application.Contracts.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.PermissionManagement.Application.Contracts" Version="5.0.0-rc.1" />
<PackageReference Include="Volo.Abp.FeatureManagement.Application.Contracts" Version="5.0.0-rc.1" />
<PackageReference Include="Volo.Abp.SettingManagement.Application.Contracts" Version="5.0.0-rc.1" />
</ItemGroup>
</Project>

12
services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/Localization/CatalogService/en.json

@ -6,6 +6,16 @@
"Permission:Products": "Products",
"Permission:Products.Edit": "Edit",
"Permission:Products.Delete": "Delete",
"Permission:Products.Create": "Create"
"Permission:Products.Create": "Create",
"Menu:CatalogManagement": "Catalog Management",
"Menu:Products": "Products",
"NewProduct": "New Product",
"Products": "Products",
"DisplayName:Name": "Name",
"DisplayName:Code": "Code",
"DisplayName:ImageName": "Image Name",
"DisplayName:Price": "Price",
"DisplayName:StockCount": "StockCount",
"ProductDeletionConfirmationMessage": "Are you sure you want to delete this {0} product?"
}
}

19
services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/Localization/CatalogService/tr.json

@ -1,6 +1,21 @@
{
"culture": "tr",
"texts": {
"CatalogService:000001": "{productCode} kodlu bir ürün zaten var!"
"CatalogService:000001": "{productCode} kodlu bir ürün zaten var!",
"Permission:GroupName": "Katalog",
"Permission:Products": "Ürünler",
"Permission:Products.Edit": "Düzenleme",
"Permission:Products.Delete": "Silme",
"Permission:Products.Create": "Oluşturma",
"Menu:CatalogManagement": "Katalog Yönetimi",
"Menu:Products": "Ürünler",
"NewProduct": "Yeni Ürün",
"Products": "Ürünler",
"DisplayName:Name": "İsim",
"DisplayName:Code": "Kod",
"DisplayName:ImageName": "Resim Adı",
"DisplayName:Price": "Fiyat",
"DisplayName:StockCount": "Stok Adedi",
"ProductDeletionConfirmationMessage": "{0} ürününü silmek istediğinizden emin misiniz?"
}
}
}

4
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json

@ -1,7 +1,7 @@
{
"App": {
"SelfUrl": "https://localhost:44354",
"CorsOrigins": "https://localhost:44372,https://localhost:44373,https://localhost:44335"
"CorsOrigins": "https://localhost:44372,https://localhost:44373,https://localhost:44335,http://localhost:4200"
},
"AuthServer": {
"Authority": "https://localhost:44330",
@ -41,4 +41,4 @@
"ElasticSearch": {
"Url": "http://localhost:9200"
}
}
}

2
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServerDataSeeder.cs

@ -238,7 +238,7 @@ namespace EShopOnAbp.IdentityService.DbMigrations
"IdentityService",
"AdministrationService"
}),
grantTypes: new[] { "authorization_code", "LinkLogin" },
grantTypes: new[] { "authorization_code", "LinkLogin", "password" },
secret: "1q2w3e*".Sha256(),
requirePkce: true,
requireClientSecret: false,

15
yarn.lock

@ -0,0 +1,15 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@ngxs/store@^3.7.3":
version "3.7.3"
resolved "https://registry.yarnpkg.com/@ngxs/store/-/store-3.7.3.tgz#74e2878d527fc12dace343ce43fd79fa1a2645af"
integrity sha512-JjATXC7FsxxQu2SaayP/iLe4O+5/RkRov3/J7WkaQmV6/JWFNkkdOwbEa6pDbh/po0JO7DHHMk3huIUNpDu67g==
dependencies:
tslib "^1.9.0"
tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
Loading…
Cancel
Save