committed by
GitHub
48 changed files with 4353 additions and 1131 deletions
@ -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. |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", |
|||
"dest": "../../dist/catalog/config", |
|||
"lib": { |
|||
"entryFile": "src/public-api.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], |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
export * from './policy-names'; |
|||
export * from './route-names'; |
|||
@ -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', |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
export const enum eCatalogRouteNames { |
|||
Catalog = 'CatalogService::Menu:CatalogManagement', |
|||
Products = 'CatalogService::Menu:Products', |
|||
} |
|||
@ -0,0 +1 @@ |
|||
export * from './route.provider'; |
|||
@ -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', |
|||
}, |
|||
]); |
|||
}; |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
export * from './catalog-config.module'; |
|||
export * from './enums'; |
|||
export * from './providers'; |
|||
@ -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 |
|||
}); |
|||
}; |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json", |
|||
"dest": "../../dist/catalog", |
|||
"lib": { |
|||
"entryFile": "src/public-api.ts" |
|||
} |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
@ -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 {} |
|||
@ -0,0 +1,7 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CatalogRoutingModule } from './catalog-routing.module'; |
|||
|
|||
@NgModule({ |
|||
imports: [CatalogRoutingModule], |
|||
}) |
|||
export class CatalogModule {} |
|||
@ -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. |
|||
File diff suppressed because it is too large
@ -0,0 +1,2 @@ |
|||
import * as Products from './products'; |
|||
export { Products }; |
|||
@ -0,0 +1,3 @@ |
|||
export * from './models'; |
|||
export * from './product.service'; |
|||
export * from './public-product.service'; |
|||
@ -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; |
|||
} |
|||
@ -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) {} |
|||
} |
|||
@ -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) {} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
export * from './product'; |
|||
@ -0,0 +1,3 @@ |
|||
export * from './product-routing.module'; |
|||
export * from './product.component'; |
|||
export * from './product.module'; |
|||
@ -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,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> |
|||
@ -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(); |
|||
}); |
|||
} |
|||
} |
|||
@ -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 {} |
|||
@ -0,0 +1,4 @@ |
|||
export * from './catalog-routing.module'; |
|||
export * from './catalog.module'; |
|||
export * from './lib/proxy/products'; |
|||
export * from './pages'; |
|||
@ -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); |
|||
@ -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" |
|||
] |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
@ -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" |
|||
] |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,5 @@ |
|||
{ |
|||
"dependencies": { |
|||
"@ngxs/store": "^3.7.3" |
|||
} |
|||
} |
|||
@ -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?" |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -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…
Reference in new issue