Commit 200f1554 authored by Florent Poittevin's avatar Florent Poittevin
Browse files

Crud Sub resource WIP

parent a366c184
......@@ -42,7 +42,7 @@ export class FileContainer extends BaseDirective {
this.store.dispatch(new DepositAction.ResumeDataFile(this.parentResId, $event));
}
refresh() {
refresh(): void {
this.store.dispatch(new DepositAction.GetAllSubResourceData(this.parentResId));
}
}
......@@ -3,9 +3,7 @@ import {DepositsModel} from "@app/generated-api";
import {CrudAction} from "@app/shared/crud.action";
import {CrudNameSpace} from "@app/shared/crud.namespace";
import {TypeCrudAction} from "@app/shared/decorators/type-crud-action.decorator";
import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum";
import {StateEnum} from "@app/shared/enums/state.enum";
import {StringUtil} from "@app/shared/utils/string.util";
const state = StateEnum.deposit;
......@@ -107,52 +105,25 @@ export namespace DepositAction {
}
}
export class GetAllSubResourceData extends CrudAction.GetAllSubResource {
static readonly type: string = StringUtil.format(CrudAction.GetAllSubResource.type, state, ApiResourceNameEnum.DATAFILE);
}
export class GetAllSubResourceDataSuccess extends CrudAction.GetAllSubResourceSuccess<DepositDataFileModel> {
static readonly type: string = StringUtil.format(CrudAction.GetAllSubResourceSuccess.type, state, ApiResourceNameEnum.DATAFILE);
}
export class GetAllSubResourceDataFail extends CrudAction.GetAllSubResourceFail {
static readonly type: string = StringUtil.format(CrudAction.GetAllSubResourceFail.type, state, ApiResourceNameEnum.DATAFILE);
}
export class UpdateSubResourceData extends CrudAction.UpdateSubResource {
static readonly type: string = StringUtil.format(CrudAction.UpdateSubResource.type, state, ApiResourceNameEnum.DATAFILE);
}
export class UpdateSubResourceDataSuccess extends CrudAction.UpdateSubResourceSuccess {
static readonly type: string = StringUtil.format(CrudAction.UpdateSubResourceSuccess.type, state, ApiResourceNameEnum.DATAFILE);
}
export class GetAllSubResourceData { // extends CrudAction.GetAllSubResource {
static readonly type: string = "DEPOSIT : GetAllSubResourceData"; //StringUtil.format(CrudAction.GetAllSubResource.type, state, ApiResourceNameEnum.DATAFILE);
export class UpdateSubResourceDataFail extends CrudAction.UpdateSubResourceFail {
static readonly type: string = StringUtil.format(CrudAction.UpdateSubResourceFail.type, state, ApiResourceNameEnum.DATAFILE);
constructor(public parentId: string) {
}
}
export class CreateSubResourceData<DepositDataFile> extends CrudAction.CreateCompoSubResource<DepositDataFile> {
static readonly type: string = StringUtil.format(CrudAction.CreateCompoSubResource.type, state, ApiResourceNameEnum.DATAFILE);
}
export class GetAllSubResourceDataSuccess { // extends CrudAction.GetAllSubResourceSuccess<DepositDataFileModel> {
static readonly type: string = "DEPOSIT : GetAllSubResourceDataSuccess"; // StringUtil.format(CrudAction.GetAllSubResourceSuccess.type, state, ApiResourceNameEnum.DATAFILE);
export class CreateSubResourceDataSuccess extends CrudAction.CreateSubResourceSuccess {
static readonly type: string = StringUtil.format(CrudAction.CreateSubResourceSuccess.type, state, ApiResourceNameEnum.DATAFILE);
}
export class CreateSubResourceDataFail extends CrudAction.CreateSubResourceFail {
static readonly type: string = StringUtil.format(CrudAction.CreateSubResourceFail.type, state, ApiResourceNameEnum.DATAFILE);
}
export class DeleteSubResourceData extends CrudAction.DeleteSubResource {
static readonly type: string = StringUtil.format(CrudAction.DeleteSubResource.type, state, ApiResourceNameEnum.DATAFILE);
constructor(public parentId: string, public model: DepositDataFileModel) {
}
}
export class DeleteSubResourceDataSuccess extends CrudAction.DeleteSubResourceSuccess {
static readonly type: string = StringUtil.format(CrudAction.DeleteSubResourceSuccess.type, state, ApiResourceNameEnum.DATAFILE);
}
export class GetAllSubResourceDataFail { // extends CrudAction.GetAllSubResourceFail {
static readonly type: string = "DEPOSIT : GetAllSubResourceDataFail"; // StringUtil.format(CrudAction.GetAllSubResourceFail.type, state, ApiResourceNameEnum.DATAFILE);
export class DeleteSubResourceDataFail extends CrudAction.DeleteSubResourceFail {
static readonly type: string = StringUtil.format(CrudAction.DeleteSubResourceFail.type, state, ApiResourceNameEnum.DATAFILE);
constructor(public parentId: string) {
}
}
}
......
......@@ -3,11 +3,13 @@ import {DepositAction, depositActionNameSpace} from "@app/deposit/deposit.action
import {DepositDataFileModel} from "@app/deposit/models/deposit-data-file.model";
import {UploadFileStatusModel} from "@app/deposit/models/upload-file-status.model";
import {DepositsModel} from "@app/generated-api";
import {CrudTwoTiersAction} from "@app/shared/crud-two-tiers.action";
import {CrudNameSpace} from "@app/shared/crud.namespace";
import {CrudState, CrudStateModel} from "@app/shared/crud.state";
import {ApiActionEnum} from "@app/shared/enums/api-action.enum";
import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum";
import {PreIngestResourceApiEnum, ResourceApiEnum} from "@app/shared/enums/api.enum";
import {PreIngestResourceApiEnum, ResourceApiEnum, SubResourceApiEnum} from "@app/shared/enums/api.enum";
import {urlSeparator} from "@app/shared/enums/routes.enum";
import {StateEnum} from "@app/shared/enums/state.enum";
import {LanguageAction} from "@app/shared/language.action";
import {LicenseAction} from "@app/shared/license.action";
......@@ -17,8 +19,10 @@ import {PreservationPolicyAction} from "@app/shared/preservation-policy.action";
import {ApiService} from "@app/core/http/api.service";
import {SubmissionPolicyAction} from "@app/shared/submission-policy.action";
import {NotificationService} from "@app/core/notification.service";
import {CrudHelperUtil} from "@app/shared/utils/crud-helper.util";
import {Action, State, StateContext, Store} from "@ngxs/store";
import {Observable} from "rxjs";
import {catchError} from "rxjs/internal/operators/catchError";
import {tap} from "rxjs/internal/operators/tap";
import {map} from "rxjs/operators";
......@@ -86,13 +90,34 @@ export class DepositState extends CrudState<DepositsModel> {
ctx.patchState({
isLoadingDataFile: true,
});
return super.getAllSubResource<DepositDataFileModel>(ctx, action, ApiResourceNameEnum.DATAFILE, action.parentId);
return this.getAllSubResource<DepositDataFileModel>(ctx, action, ApiResourceNameEnum.DATAFILE, action.parentId);
}
// TO MOVE IN CrudCompositeState
getAllSubResource<U>(ctx: StateContext<DepositStateModel>, action: CrudTwoTiersAction.GetAllSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<CollectionTypedModel<U>> {
const queryParameters = CrudHelperUtil.getQueryParametersToApply(action.queryParameters, ctx);
const url = this.evaluateSubResourceUrl(subResource, parentId);
return this.apiService.get<U>(url, queryParameters)
.pipe(
tap((collection: U) => {
ctx.dispatch(new DepositAction.GetAllSubResourceDataSuccess(parentId, collection));
}),
catchError(error => {
ctx.dispatch(new DepositAction.GetAllSubResourceDataFail(parentId));
throw error;
}),
);
}
// TO MOVE IN CrudCompositeState
private evaluateSubResourceUrl(subResource: ApiResourceNameEnum, parentId: string): string {
return this.urlResource + urlSeparator + parentId + urlSeparator + subResource;
}
@Action(DepositAction.GetAllSubResourceDataSuccess)
getAllDataFileSuccess(ctx: StateContext<DepositStateModel>, action: DepositAction.GetAllSubResourceDataSuccess): void {
ctx.patchState({
listDataFile: action.list._data,
// listDataFile: action.model,
isLoadingDataFile: false,
});
}
......
......@@ -3,6 +3,7 @@ import {MatDialog} from "@angular/material";
import {ActivatedRoute} from "@angular/router";
import {OrganizationalUnitsModel, PreservationPoliciesModel, SubmissionPoliciesModel} from "@app/generated-api";
import {StateEnum} from "@app/shared/enums/state.enum";
import {OrgUnitSubmissionPolicyAction} from "@app/shared/organizational-unit-submission-policy.action";
import {OrgUnitAction, orgUnitActionNameSpace} from "@app/shared/organizational-unit.action";
import {OrganizationalUnitStateModel} from "@app/shared/organizational-unit.state";
import {PreservationPolicyStateModel} from "@app/shared/preservation-policy.state";
......@@ -36,7 +37,7 @@ export class DetailView extends AbstractDetailView<OrganizationalUnitsModel, Org
}
getSubResourceWithParentId(id: string): void {
this.store.dispatch(new OrgUnitAction.GetAllSubResourceSubmissionPolicies(id));
this.store.dispatch(new OrgUnitSubmissionPolicyAction.GetAllSubResource(id));
}
ngOnInit(): void {
......
......@@ -2,6 +2,7 @@ import {ChangeDetectionStrategy, Component, OnInit} from "@angular/core";
import {ActivatedRoute} from "@angular/router";
import {OrganizationalUnitsModel, PreservationPoliciesModel, SubmissionPoliciesModel} from "@app/generated-api";
import {StateEnum} from "@app/shared/enums/state.enum";
import {OrgUnitSubmissionPolicyAction} from "@app/shared/organizational-unit-submission-policy.action";
import {OrgUnitAction, orgUnitActionNameSpace} from "@app/shared/organizational-unit.action";
import {OrganizationalUnitStateModel} from "@app/shared/organizational-unit.state";
import {PreservationPolicyStateModel} from "@app/shared/preservation-policy.state";
......@@ -29,7 +30,7 @@ export class EditView extends AbstractEditView<OrganizationalUnitsModel, Organiz
}
getSubResourceWithParentId(id: string): void {
this.store.dispatch(new OrgUnitAction.GetAllSubResourceSubmissionPolicies(id));
this.store.dispatch(new OrgUnitSubmissionPolicyAction.GetAllSubResource(id));
}
ngOnInit(): void {
......
import {CrudTwoTiersNameSpace} from "@app/shared/crud.namespace";
import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
export namespace CrudTwoTiersAction {
export class GetAllSubResource {
static readonly type: string = "[{0}] Get All SubResource";
constructor(public parentId: string, public queryParameters?: QueryParametersModel) {
}
}
export class GetAllSubResourceSuccess<T> {
static readonly type: string = "[{0}] Get All SubResource Success";
constructor(public list: CollectionTypedModel<T>) {
}
}
export class GetAllSubResourceFail {
static readonly type: string = "[{0}] Get All SubResource Fail";
}
export class CreateCompoSubResource<T> {
static readonly type: string = "[{0}] Create Compo SubResource";
constructor(public parentId: string, public model: T) {
}
}
export class CreateSubResource {
static readonly type: string = "[{0}] Create SubResource";
constructor(public parentId: string, public listResId: string[]) {
}
}
export class CreateSubResourceSuccess {
static readonly type: string = "[{0}] Create SubResource Success";
}
export class CreateSubResourceFail {
static readonly type: string = "[{0}] Create SubResource Fail";
}
export class DeleteSubResource {
static readonly type: string = "[{0}] Delete SubResource";
constructor(public parentId: string, public listResId: string[]) {
}
}
export class DeleteSubResourceSuccess {
static readonly type: string = "[{0}] Delete SubResource Success";
}
export class DeleteSubResourceFail {
static readonly type: string = "[{0}] Delete SubResource Fail";
}
export class UpdateSubResource {
static readonly type: string = "[{0}] Update SubResource";
constructor(public parentId: string, public oldResId: string[], public newResId: string[]) {
}
}
export class UpdateSubResourceSuccess {
static readonly type: string = "[{0}] Update SubResource Success";
constructor(public parentId: string) {
}
}
export class UpdateSubResourceFail {
static readonly type: string = "[{0}] Update SubResource Fail";
constructor(public parentId: string) {
}
}
}
export const crudTwoTiersActionNameSpace: CrudTwoTiersNameSpace = CrudTwoTiersAction;
import {BaseStateModel} from "@app/base.state";
import {CrudTwoTiersAction} from "@app/shared/crud-two-tiers.action";
import {CrudActionClass, CrudTwoTiersNameSpace} from "@app/shared/crud.namespace";
import {CrudState} from "@app/shared/crud.state";
import {RegisterCrudAction} from "@app/shared/decorators/crud.decorator";
import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum";
import {ResourceApiEnum, SubResourceApiEnum} from "@app/shared/enums/api.enum";
import {urlSeparator} from "@app/shared/enums/routes.enum";
import {StateEnum} from "@app/shared/enums/state.enum";
import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
import {SubResourceUpdateModel} from "@app/shared/models/sub-resource-update.model";
import {ApiService} from "@app/shared/services/api.service";
import {NotificationService} from "@app/shared/services/notification.service";
import {CrudHelperUtil} from "@app/shared/utils/crud-helper.util";
import {CrudTwoTiersActionHelper} from "@app/shared/utils/crud-two-tiers-action.helper";
import {CrudUtil} from "@app/shared/utils/crud.util";
import {SolidifyMetadataUtil} from "@app/shared/utils/solidify-metadata.util";
import {ActionOptions, ensureStoreMetadata, StateContext, Store} from "@ngxs/store";
import _ from "lodash";
import {Observable} from "rxjs";
import {catchError} from "rxjs/internal/operators/catchError";
import {tap} from "rxjs/operators";
export interface CrudTwoTiersStateModel<T> extends BaseStateModel {
total: number;
list: T[];
current: T;
queryParameters: QueryParametersModel;
}
export abstract class CrudTwoTiersState<T> {
protected readonly state: StateEnum;
protected readonly crudTwoTiersNameSpace: CrudTwoTiersNameSpace;
protected readonly urlResource: ResourceApiEnum;
private readonly subResource: ApiResourceNameEnum[];
protected constructor(protected apiService: ApiService,
protected store: Store,
protected notificationService: NotificationService) {
this.urlResource = this.defineUrlResource();
this.state = this.defineState();
this.crudTwoTiersNameSpace = this.defineCrudNameSpace();
this.subResource = this.defineSubResource();
CrudUtil.initState(CrudTwoTiersState, this.constructor, this.crudTwoTiersNameSpace);
}
abstract defineUrlResource(): ResourceApiEnum;
abstract defineState(): StateEnum;
abstract defineCrudNameSpace(): CrudTwoTiersNameSpace;
abstract defineSubResource(): ApiResourceNameEnum[];
@RegisterCrudAction((crudTwoTiersNameSpace: CrudTwoTiersNameSpace) => crudTwoTiersNameSpace.GetAllSubResource)
getAllSubResource<U>(ctx: StateContext<CrudTwoTiersStateModel<T>>, action: CrudTwoTiersAction.GetAllSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<CollectionTypedModel<U>> {
const queryParameters = CrudHelperUtil.getQueryParametersToApply(action.queryParameters, ctx);
const url = this.evaluateSubResourceUrl(subResource, parentId);
return this.apiService.get<U>(url, queryParameters)
.pipe(
tap((collection: CollectionTypedModel<U>) => {
ctx.dispatch(CrudTwoTiersActionHelper.getAllSubResourceSuccess<U>(this.crudTwoTiersNameSpace, collection));
}),
catchError(error => {
ctx.dispatch(CrudTwoTiersActionHelper.getAllSubResourceFail(this.crudTwoTiersNameSpace));
throw error;
}),
);
}
@RegisterCrudAction((crudTwoTiersNameSpace: CrudTwoTiersNameSpace) => crudTwoTiersNameSpace.CreateSubResource)
createSubResource(ctx: StateContext<CrudTwoTiersStateModel<T>>, action: CrudTwoTiersAction.CreateSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<string[]> {
if (action.listResId.length === 0) {
return;
}
const url = this.evaluateSubResourceUrl(subResource, parentId);
return this.apiService.post<string[]>(url, action.listResId)
.pipe(
tap(() => {
ctx.dispatch(CrudTwoTiersActionHelper.createSubResourceSuccess(this.crudTwoTiersNameSpace));
}),
catchError(error => {
ctx.dispatch(CrudTwoTiersActionHelper.createSubResourceFail(this.crudTwoTiersNameSpace));
throw error;
}),
);
}
@RegisterCrudAction((crudTwoTiersNameSpace: CrudTwoTiersNameSpace) => crudTwoTiersNameSpace.DeleteSubResource)
deleteSubResource(ctx: StateContext<CrudTwoTiersStateModel<T>>, action: CrudTwoTiersAction.DeleteSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<string[]> {
if (action.listResId.length === 0) {
return;
}
const url = this.evaluateSubResourceUrl(subResource, parentId);
return this.apiService.delete<string[]>(url, action.listResId)
.pipe(
tap(() => {
ctx.dispatch(CrudTwoTiersActionHelper.deleteSubResourceSuccess(this.crudTwoTiersNameSpace));
}),
catchError(error => {
ctx.dispatch(CrudTwoTiersActionHelper.deleteSubResourceFail(this.crudTwoTiersNameSpace));
throw error;
}),
);
}
private evaluateSubResourceUrl(subResource: ApiResourceNameEnum, parentId: string): string {
return this.urlResource + urlSeparator + parentId + urlSeparator + subResource;
}
@RegisterCrudAction((crudTwoTiersNameSpace: CrudTwoTiersNameSpace) => crudTwoTiersNameSpace.UpdateSubResource)
updateSubResource(ctx: StateContext<CrudTwoTiersStateModel<T>>, action: CrudTwoTiersAction.UpdateSubResource, parentId: string): void {
const subResourceUpdate: SubResourceUpdateModel = this.determineSubResourceChange(action.oldResId, action.newResId);
const createAndUpdateActions = this.computeUpdatesActionsToDispatch(subResourceUpdate, parentId);
ctx.dispatch(createAndUpdateActions);
}
private computeUpdatesActionsToDispatch(subResourceUpdate: SubResourceUpdateModel, parentId: string): CrudTwoTiersAction.CreateSubResource[] | CrudTwoTiersAction.DeleteSubResource[] {
const actions = [];
const deleteAction = CrudTwoTiersActionHelper.deleteSubResource(this.crudTwoTiersNameSpace, parentId, subResourceUpdate.resourceToRemoved);
actions.push(deleteAction);
const createAction = CrudTwoTiersActionHelper.createSubResource(this.crudTwoTiersNameSpace, parentId, subResourceUpdate.resourceToAdd);
actions.push(createAction);
return actions;
}
private determineSubResourceChange(oldList: string[], newList: string[]): SubResourceUpdateModel {
const subResourceUpdate: SubResourceUpdateModel = new SubResourceUpdateModel();
const diff: string[] = _.xor(oldList, newList);
diff.forEach(d => {
if (_.includes(oldList, d)) {
subResourceUpdate.resourceToRemoved.push(d);
} else {
subResourceUpdate.resourceToAdd.push(d);
}
});
return subResourceUpdate;
}
}
import {DepositAction} from "@app/deposit/deposit.action";
import {CrudNameSpace} from "@app/shared/crud.namespace";
import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
......@@ -6,22 +5,18 @@ import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
export namespace CrudAction {
export class LoadResource {
static readonly type: string = "[{0}] Load resource";
static readonly className: string = LoadResource.name;
}
export class LoadResourceSuccess {
static readonly type: string = "[{0}] Load resource Success";
static readonly className: string = LoadResourceSuccess.name;
}
export class LoadResourceFail {
static readonly type: string = "[{0}] Load resource Fail";
static readonly className: string = LoadResourceFail.name;
}
export class ChangeQueryParameters {
static readonly type: string = "[{0}] Change Query Parameters";
static readonly className: string = ChangeQueryParameters.name;
constructor(public queryParameters: QueryParametersModel) {
}
......@@ -29,7 +24,6 @@ export namespace CrudAction {
export class GetAll {
static readonly type: string = "[{0}] Get All";
static readonly className: string = GetAll.name;
constructor(public queryParameters?: QueryParametersModel) {
}
......@@ -37,7 +31,6 @@ export namespace CrudAction {
export class GetAllSuccess<T> {
static readonly type: string = "[{0}] Get All Success";
static readonly className: string = GetAllSuccess.name;
constructor(public list: CollectionTypedModel<T>) {
}
......@@ -45,12 +38,10 @@ export namespace CrudAction {
export class GetAllFail {
static readonly type: string = "[{0}] Get All Fail";
static readonly className: string = GetAllFail.name;
}
export class GetById {
static readonly type: string = "[{0}] Get By Id";
static readonly className: string = GetById.name;
constructor(public id: string) {
}
......@@ -58,7 +49,6 @@ export namespace CrudAction {
export class GetByIdSuccess<T> {
static readonly type: string = "[{0}] Get By Id Success";
static readonly className: string = GetByIdSuccess.name;
constructor(public model: T) {
}
......@@ -66,12 +56,10 @@ export namespace CrudAction {
export class GetByIdFail {
static readonly type: string = "[{0}] Get By Id Fail";
static readonly className: string = GetByIdFail.name;
}
export class Create<T> {
static readonly type: string = "[{0}] Create";
static readonly className: string = Create.name;
constructor(public model: T) {
}
......@@ -79,17 +67,14 @@ export namespace CrudAction {
export class CreateSuccess {
static readonly type: string = "[{0}] Create Success";
static readonly className: string = CreateSuccess.name;
}
export class CreateFail {
static readonly type: string = "[{0}] Create Fail";
static readonly className: string = CreateFail.name;
}
export class Update<T> {
static readonly type: string = "[{0}] Update";
static readonly className: string = Update.name;
constructor(public model: T) {
}
......@@ -97,17 +82,14 @@ export namespace CrudAction {
export class UpdateSuccess {
static readonly type: string = "[{0}] Update Success";
static readonly className: string = UpdateSuccess.name;
}
export class UpdateFail {
static readonly type: string = "[{0}] Update Fail";
static readonly className: string = UpdateFail.name;
}
export class Delete {
static readonly type: string = "[{0}] Delete";
static readonly className: string = Delete.name;
constructor(public resId: string) {
}
......@@ -115,101 +97,10 @@ export namespace CrudAction {
export class DeleteSuccess {
static readonly type: string = "[{0}] Delete Success";
static readonly className: string = DeleteSuccess.name;
}
export class DeleteFail {
static readonly type: string = "[{0}] Delete Fail";
static readonly className: string = DeleteFail.name;
}
export class GetAllSubResource {
static readonly type: string = "[{0}] Get All SubResource {1}";
static readonly className: string = "GetAllSubResource{0}";
constructor(public parentId: string, public queryParameters?: QueryParametersModel) {
}
}
export class GetAllSubResourceSuccess<T> {
static readonly type: string = "[{0}] Get All SubResource {1} Success";
static readonly className: string = "GetAllSubResource{0}Success";
constructor(public list: CollectionTypedModel<T>) {
}
}
export class GetAllSubResourceFail {
static readonly type: string = "[{0}] Get All SubResource {1} Fail";
static readonly className: string = "GetAllSubResource{0}Fail";
}
export class CreateCompoSubResource<T> {
static readonly type: string = "[{0}] Create Compo SubResource {1}";
static readonly className: string = "CreateCompoSubResource{0}";
constructor(public parentId: string, public model: T) {
}
}
export class CreateSubResource {
static readonly type: string = "[{0}] Create SubResource {1}";
static readonly className: string = "CreateSubResource{0}";
constructor(public parentId: string, public listResId: string[]) {
}
}
export class CreateSubResourceSuccess {
static readonly type: string = "[{0}] Create SubResource {1} Success";
static readonly className: string = "CreateSubResource{0}Success";
}
export class CreateSubResourceFail {
static readonly type: string = "[{0}] Create SubResource {1} Fail";
static readonly className: string = "CreateSubResource{0}Fail";
}
export class DeleteSubResource {
static readonly type: string = "[{0}] Delete SubResource {1}";
static readonly className: string = "DeleteSubResource{0}";
constructor(public parentId: string, public listResId: string[]) {
}
}