From ed2373d6d9c808cae84b9b7fd2f6f72497c23a1d Mon Sep 17 00:00:00 2001 From: Florent Poittevin <florent.poittevin@unige.ch> Date: Tue, 25 Jun 2019 15:56:39 +0200 Subject: [PATCH] Increase genericity principle for sub resource --- package-lock.json | 170 ++++++++++++++++++ package.json | 1 + .../components/form/form.component.ts | 3 +- .../views/detail/detail.view.ts | 4 +- .../views/edit/edit.view.ts | 4 +- .../abstract-form/abstract-form.component.ts | 3 +- src/app/shared/crud.action.ts | 84 ++++++++- src/app/shared/crud.state.ts | 73 +++++++- src/app/shared/enums/model-attribut.enum.ts | 3 + .../models/sub-resource-update.model.ts | 9 + src/app/shared/organizational-unit.action.ts | 66 ++++++- src/app/shared/organizational-unit.state.ts | 99 +++++----- src/app/shared/services/api.service.ts | 60 ++----- src/app/shared/utils/crud-action.util.ts | 73 ++++++-- src/app/shared/utils/string.util.ts | 11 ++ .../abstract-detail/abstract-detail.view.ts | 3 +- .../views/abstract-list/abstract-list.view.ts | 3 +- 17 files changed, 537 insertions(+), 132 deletions(-) create mode 100644 src/app/shared/enums/model-attribut.enum.ts create mode 100644 src/app/shared/models/sub-resource-update.model.ts diff --git a/package-lock.json b/package-lock.json index 855d5327d..e72bbc7c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2301,6 +2301,15 @@ "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", @@ -2357,6 +2366,31 @@ } } }, + "change-case": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", + "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", + "requires": { + "camel-case": "^3.0.0", + "constant-case": "^2.0.0", + "dot-case": "^2.1.0", + "header-case": "^1.0.0", + "is-lower-case": "^1.1.0", + "is-upper-case": "^1.1.0", + "lower-case": "^1.1.1", + "lower-case-first": "^1.0.0", + "no-case": "^2.3.2", + "param-case": "^2.1.0", + "pascal-case": "^2.0.0", + "path-case": "^2.1.0", + "sentence-case": "^2.1.0", + "snake-case": "^2.1.0", + "swap-case": "^1.1.0", + "title-case": "^2.1.0", + "upper-case": "^1.1.1", + "upper-case-first": "^1.1.0" + } + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -2734,6 +2768,15 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, + "constant-case": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", + "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", + "requires": { + "snake-case": "^2.1.0", + "upper-case": "^1.1.1" + } + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -4080,6 +4123,14 @@ "domelementtype": "1" } }, + "dot-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", + "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", + "requires": { + "no-case": "^2.2.0" + } + }, "dot-prop": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", @@ -6307,6 +6358,15 @@ "minimalistic-assert": "^1.0.1" } }, + "header-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", + "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.3" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -6945,6 +7005,14 @@ "is-extglob": "^2.1.1" } }, + "is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "requires": { + "lower-case": "^1.1.0" + } + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -7049,6 +7117,14 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "requires": { + "upper-case": "^1.1.0" + } + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -7841,6 +7917,19 @@ "signal-exit": "^3.0.0" } }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "lower-case-first": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", + "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", + "requires": { + "lower-case": "^1.1.2" + } + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -8380,6 +8469,14 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, "node-fetch-npm": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz", @@ -9113,6 +9210,14 @@ "readable-stream": "^2.1.5" } }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "requires": { + "no-case": "^2.2.0" + } + }, "parse-asn1": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", @@ -9201,6 +9306,15 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "requires": { + "camel-case": "^3.0.0", + "upper-case-first": "^1.1.0" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -9234,6 +9348,14 @@ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, + "path-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", + "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", + "requires": { + "no-case": "^2.2.0" + } + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -10368,6 +10490,15 @@ } } }, + "sentence-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", + "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", + "requires": { + "no-case": "^2.2.0", + "upper-case-first": "^1.1.2" + } + }, "serialize-javascript": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", @@ -10541,6 +10672,14 @@ "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", "dev": true }, + "snake-case": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", + "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", + "requires": { + "no-case": "^2.2.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -11612,6 +11751,15 @@ "has-flag": "^3.0.0" } }, + "swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "requires": { + "lower-case": "^1.1.1", + "upper-case": "^1.1.1" + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", @@ -11869,6 +12017,15 @@ "setimmediate": "^1.0.4" } }, + "title-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", + "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.0.3" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -12229,6 +12386,19 @@ "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "requires": { + "upper-case": "^1.1.1" + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", diff --git a/package.json b/package.json index e8d9b1398..33a2143ee 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@ngxs/logger-plugin": "3.4.3", "@ngxs/router-plugin": "3.4.3", "@ngxs/store": "3.4.3", + "change-case": "^3.1.0", "core-js": "2.5.4", "decimal.js": "10.2.0", "flexboxgrid-sass": "8.0.5", diff --git a/src/app/organizational-unit/components/form/form.component.ts b/src/app/organizational-unit/components/form/form.component.ts index dbb4c2e03..686253bda 100644 --- a/src/app/organizational-unit/components/form/form.component.ts +++ b/src/app/organizational-unit/components/form/form.component.ts @@ -2,6 +2,7 @@ import {ChangeDetectionStrategy, Component, Input} from "@angular/core"; import {FormBuilder, Validators} from "@angular/forms"; import {OrganizationalUnitsModel, PreservationPoliciesModel, SubmissionPoliciesModel} from "@app/generated-api"; import {AbstractFormComponent} from "@app/shared/components/abstract-form/abstract-form.component"; +import {ModelAttributEnum} from "@app/shared/enums/model-attribut.enum"; import {DateUtil} from "@app/shared/utils/date.util"; import _ from "lodash"; @@ -53,7 +54,7 @@ export class FormComponent extends AbstractFormComponent<OrganizationalUnitsMode closingDate: [organizationalUnit.closingDate], isEmpty: [organizationalUnit.isEmpty], open: [organizationalUnit.open], - submissionPolicies: [_.map(this.selectedSubmissionPolicies, "resId")], + submissionPolicies: [_.map(this.selectedSubmissionPolicies, ModelAttributEnum.resId)], }); } diff --git a/src/app/organizational-unit/views/detail/detail.view.ts b/src/app/organizational-unit/views/detail/detail.view.ts index 2f1d915be..c4f38c224 100644 --- a/src/app/organizational-unit/views/detail/detail.view.ts +++ b/src/app/organizational-unit/views/detail/detail.view.ts @@ -20,7 +20,7 @@ import {Observable} from "rxjs"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class DetailView extends AbstractDetailView<OrganizationalUnitsModel, OrganizationalUnitStateModel> { - @Select((state) => (state[StateEnum.organizationalUnit] as OrganizationalUnitStateModel).listSubmissionPolicies) selectedSubmissionPolicies$: Observable<SubmissionPoliciesModel[]>; + @Select((state) => (state[StateEnum.organizationalUnit] as OrganizationalUnitStateModel).selectedSubmissionPolicies) selectedSubmissionPolicies$: Observable<SubmissionPoliciesModel[]>; @Select((state) => ((state[StateEnum.shared] as SharedStateModel).submissionPolicy as SubmissionPolicyStateModel).list) listSubmissionPolicies$: Observable<SubmissionPoliciesModel[]>; @Select((state) => ((state[StateEnum.shared] as SharedStateModel).preservationPolicy as PreservationPolicyStateModel).list) listPreservationPolicies$: Observable<PreservationPoliciesModel[]>; @@ -35,6 +35,6 @@ export class DetailView extends AbstractDetailView<OrganizationalUnitsModel, Org } getSubResourceWithParentId(id: string): void { - this.store.dispatch(new OrgUnitAction.GetAllSubmissionPolicy(id)); + this.store.dispatch(new OrgUnitAction.GetAllSubResourceSubmissionPolicies(id)); } } diff --git a/src/app/organizational-unit/views/edit/edit.view.ts b/src/app/organizational-unit/views/edit/edit.view.ts index 89e937ca3..932455418 100644 --- a/src/app/organizational-unit/views/edit/edit.view.ts +++ b/src/app/organizational-unit/views/edit/edit.view.ts @@ -19,7 +19,7 @@ import {Observable} from "rxjs"; }) export class EditView extends AbstractEditView<OrganizationalUnitsModel, OrganizationalUnitStateModel> { @Select((state) => (state[StateEnum.organizationalUnit] as OrganizationalUnitStateModel).isLoadingSubmissionPolicies) isLoadingSubmissionPolicies$: Observable<boolean>; - @Select((state) => (state[StateEnum.organizationalUnit] as OrganizationalUnitStateModel).listSubmissionPolicies) selectedSubmissionPolicies$: Observable<SubmissionPoliciesModel[]>; + @Select((state) => (state[StateEnum.organizationalUnit] as OrganizationalUnitStateModel).selectedSubmissionPolicies) selectedSubmissionPolicies$: Observable<SubmissionPoliciesModel[]>; @Select((state) => ((state[StateEnum.shared] as SharedStateModel).submissionPolicy as SubmissionPolicyStateModel).list) listSubmissionPolicies$: Observable<SubmissionPoliciesModel[]>; @Select((state) => ((state[StateEnum.shared] as SharedStateModel).preservationPolicy as PreservationPolicyStateModel).list) listPreservationPolicies$: Observable<PreservationPoliciesModel[]>; @@ -29,6 +29,6 @@ export class EditView extends AbstractEditView<OrganizationalUnitsModel, Organiz } getSubresourceWithParentId(id: string): void { - this.store.dispatch(new OrgUnitAction.GetAllSubmissionPolicy(id)); + this.store.dispatch(new OrgUnitAction.GetAllSubResourceSubmissionPolicies(id)); } } diff --git a/src/app/shared/components/abstract-form/abstract-form.component.ts b/src/app/shared/components/abstract-form/abstract-form.component.ts index a043f7159..4073ffff4 100644 --- a/src/app/shared/components/abstract-form/abstract-form.component.ts +++ b/src/app/shared/components/abstract-form/abstract-form.component.ts @@ -1,6 +1,7 @@ import {EventEmitter, Input, OnInit, Output} from "@angular/core"; import {AbstractControl, FormGroup, Validators} from "@angular/forms"; import {BaseDirective} from "@app/shared/directives/base.directive"; +import {ModelAttributEnum} from "@app/shared/enums/model-attribut.enum"; export abstract class AbstractFormComponent<T> extends BaseDirective implements OnInit { public form: FormGroup; @@ -52,7 +53,7 @@ export abstract class AbstractFormComponent<T> extends BaseDirective implements private addResId(model: T) { const isUpdate = this.model !== null && this.model !== undefined; if (isUpdate) { - model["resId"] = this.model["resId"]; + model[ModelAttributEnum.resId] = this.model[ModelAttributEnum.resId]; } } diff --git a/src/app/shared/crud.action.ts b/src/app/shared/crud.action.ts index 6dbf2b8be..d892663da 100644 --- a/src/app/shared/crud.action.ts +++ b/src/app/shared/crud.action.ts @@ -131,24 +131,96 @@ export namespace CrudAction { } export class GetAllSubResource { - protected static abstractType = "[{0}] Get All Subresource {1}"; - public static readonly className = "GetAllSubResource"; + protected static abstractType = "[{0}] Get All SubResource {1}"; + public static readonly className = "GetAllSubResource{0}"; constructor(public parentId: string, public queryParameters?: QueryParametersModel) { } } export class GetAllSubResourceSuccess<T> { - protected static abstractType = "[{0}] Get All Subresource {1} Success"; - public static readonly className = "GetAllSubResourceSuccess"; + protected static abstractType = "[{0}] Get All SubResource {1} Success"; + public static readonly className = "GetAllSubResource{0}Success"; constructor(public list: CollectionTypedModel<T>) { } } export class GetAllSubResourceFail { - protected static abstractType = "[{0}] Get All Subresource {1} Fail"; - public static readonly className = "GetAllSubResourceFail"; + protected static abstractType = "[{0}] Get All SubResource {1} Fail"; + public static readonly className = "GetAllSubResource{0}Fail"; + + constructor() { + } + } + + export class CreateSubResource { + protected static abstractType = "[{0}] Create SubResource {1}"; + public static readonly className = "CreateSubResource{0}"; + + constructor(public parentId: string, public listResId: string[]) { + } + } + + export class CreateSubResourceSuccess { + protected static abstractType = "[{0}] Create SubResource {1} Success"; + public static readonly className = "CreateSubResource{0}Success"; + + constructor() { + } + } + + export class CreateSubResourceFail { + protected static abstractType = "[{0}] Create SubResource {1} Fail"; + public static readonly className = "CreateSubResource{0}Fail"; + + constructor() { + } + } + + export class DeleteSubResource { + protected static abstractType = "[{0}] Delete SubResource {1}"; + public static readonly className = "DeleteSubResource{0}"; + + constructor(public parentId: string, public listResId: string[]) { + } + } + + export class DeleteSubResourceSuccess { + protected static abstractType = "[{0}] Delete SubResource {1} Success"; + public static readonly className = "DeleteSubResource{0}Success"; + + constructor() { + } + } + + export class DeleteSubResourceFail { + protected static abstractType = "[{0}] Delete SubResource {1} Fail"; + public static readonly className = "DeleteSubResource{0}Fail"; + + constructor() { + } + } + + export class UpdateSubResource { + protected static abstractType = "[{0}] Update SubResource {1}"; + public static readonly className = "UpdateSubResource{0}"; + + constructor(public parentId: string, public oldResId: string[], public newResId: string[]) { + } + } + + export class UpdateSubResourceSuccess { + protected static abstractType = "[{0}] Update SubResource {1} Success"; + public static readonly className = "UpdateSubResource{0}Success"; + + constructor() { + } + } + + export class UpdateSubResourceFail { + protected static abstractType = "[{0}] Update SubResource {1} Fail"; + public static readonly className = "UpdateSubResource{0}Fail"; constructor() { } diff --git a/src/app/shared/crud.state.ts b/src/app/shared/crud.state.ts index 099b96004..e0672424b 100644 --- a/src/app/shared/crud.state.ts +++ b/src/app/shared/crud.state.ts @@ -2,10 +2,12 @@ import {BaseStateModel} from "@app/base.state"; import {CrudAction} from "@app/shared/crud.action"; import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum"; import {ResourceApiEnum, SubResourceApiEnum} from "@app/shared/enums/api.enum"; +import {ModelAttributEnum} from "@app/shared/enums/model-attribut.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 {CrudActionUtil} from "@app/shared/utils/crud-action.util"; @@ -15,6 +17,7 @@ import {ObjectUtil} from "@app/shared/utils/object.util"; import {TRANSLATE} from "@app/shared/utils/translate.util"; import {Navigate} from "@ngxs/router-plugin"; import {StateContext} from "@ngxs/store"; +import _ from "lodash"; import {Observable} from "rxjs"; import {catchError} from "rxjs/internal/operators/catchError"; import {tap} from "rxjs/operators"; @@ -27,7 +30,7 @@ export interface CrudStateModel<T> extends BaseStateModel { } export abstract class CrudState<T> { - private readonly state: StateEnum; + protected readonly state: StateEnum; private readonly urlResource: ResourceApiEnum; private readonly subResource: ApiResourceNameEnum[]; @@ -156,7 +159,7 @@ export abstract class CrudState<T> { isLoading: true, }); - return this.apiService.patchById<T>(this.urlResource, action.model["resId"], action.model) + return this.apiService.patchById<T>(this.urlResource, action.model[ModelAttributEnum.resId], action.model) .pipe( tap(() => { ctx.dispatch(CrudActionUtil.updateSuccess(this.state)); @@ -220,15 +223,41 @@ export abstract class CrudState<T> { getAllSubResource<U>(ctx: StateContext<CrudStateModel<T>>, action: CrudAction.GetAllSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<CollectionTypedModel<U>> { const queryParameters = CrudHelperUtil.getQueryParametersToApply(action.queryParameters, ctx); const url = this.evaluateSubResourceUrl(subResource, parentId); - debugger; - return null; return this.apiService.get<U>(url, queryParameters) .pipe( tap((collection: CollectionTypedModel<U>) => { - // ctx.dispatch(CrudAction.GetAllSubResourceSuccess.getInstance<U>(this.state, subResource, collection)); + ctx.dispatch(CrudActionUtil.getAllSubResourceSuccess<U>(this.state, subResource, collection)); }), catchError(error => { - // ctx.dispatch(CrudAction.GetAllSubResourceFail.getInstance(this.state, subResource)); + ctx.dispatch(CrudActionUtil.getAllSubResourceFail(this.state, subResource)); + throw error; + }), + ); + } + + createSubResource(ctx: StateContext<CrudStateModel<T>>, action: CrudAction.CreateSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<string[]> { + const url = this.evaluateSubResourceUrl(subResource, parentId); + return this.apiService.post<string[]>(url, action.listResId) + .pipe( + tap(() => { + ctx.dispatch(CrudActionUtil.createSubResourceSuccess(this.state, subResource)); + }), + catchError(error => { + ctx.dispatch(CrudActionUtil.createSubResourceFail(this.state, subResource)); + throw error; + }), + ); + } + + deleteSubResource(ctx: StateContext<CrudStateModel<T>>, action: CrudAction.DeleteSubResource, subResource: SubResourceApiEnum, parentId: string): Observable<string[]> { + const url = this.evaluateSubResourceUrl(subResource, parentId); + return this.apiService.delete<string[]>(url, action.listResId) + .pipe( + tap(() => { + ctx.dispatch(CrudActionUtil.deleteSubResourceSuccess(this.state, subResource)); + }), + catchError(error => { + ctx.dispatch(CrudActionUtil.deleteSubResourceFail(this.state, subResource)); throw error; }), ); @@ -237,4 +266,36 @@ export abstract class CrudState<T> { private evaluateSubResourceUrl(subResource: ApiResourceNameEnum, parentId: string): string { return this.urlResource + urlSeparator + parentId + urlSeparator + subResource; } + + updateSubResource(ctx: StateContext<CrudStateModel<T>>, action: CrudAction.UpdateSubResource, subResource: SubResourceApiEnum, parentId: string): void { + const subResourceUpdate: SubResourceUpdateModel = this.determineSubResourceChange(action.oldResId, action.newResId); + const createAndUpdateActions = this.computeUpdatesActionsToDispatch(subResourceUpdate, subResource, parentId); + ctx.dispatch(createAndUpdateActions); + } + + private computeUpdatesActionsToDispatch(subResourceUpdate: SubResourceUpdateModel, subResource: SubResourceApiEnum, parentId: string): CrudAction.CreateSubResource[] | CrudAction.DeleteSubResource[] { + const actions = []; + if (subResourceUpdate.resourceToRemoved.length > 0) { + const deleteAction = CrudActionUtil.deleteSubResource(this.state, subResource, parentId, subResourceUpdate.resourceToRemoved); + actions.push(deleteAction); + } + if (subResourceUpdate.resourceToAdd.length > 0) { + const createAction = CrudActionUtil.createSubResource(this.state, subResource, parentId, subResourceUpdate.resourceToAdd); + actions.push(createAction); + } + return actions; + } + + private determineSubResourceChange(oldSubmissionPolicies, newSubmissionPolicies): SubResourceUpdateModel { + const subResourceUpdate: SubResourceUpdateModel = new SubResourceUpdateModel(); + const diff: string[] = _.xor(oldSubmissionPolicies, newSubmissionPolicies); + diff.forEach(d => { + if (_.includes(oldSubmissionPolicies, d)) { + subResourceUpdate.resourceToRemoved.push(d); + } else { + subResourceUpdate.resourceToAdd.push(d); + } + }); + return subResourceUpdate; + } } diff --git a/src/app/shared/enums/model-attribut.enum.ts b/src/app/shared/enums/model-attribut.enum.ts new file mode 100644 index 000000000..eebbe28bc --- /dev/null +++ b/src/app/shared/enums/model-attribut.enum.ts @@ -0,0 +1,3 @@ +export enum ModelAttributEnum { + resId = "resId", +} diff --git a/src/app/shared/models/sub-resource-update.model.ts b/src/app/shared/models/sub-resource-update.model.ts new file mode 100644 index 000000000..9b8496ed1 --- /dev/null +++ b/src/app/shared/models/sub-resource-update.model.ts @@ -0,0 +1,9 @@ +export class SubResourceUpdateModel { + resourceToAdd: string[]; + resourceToRemoved: string[]; + + constructor() { + this.resourceToAdd = []; + this.resourceToRemoved = []; + } +} diff --git a/src/app/shared/organizational-unit.action.ts b/src/app/shared/organizational-unit.action.ts index 3497d4767..1cb38c37c 100644 --- a/src/app/shared/organizational-unit.action.ts +++ b/src/app/shared/organizational-unit.action.ts @@ -137,7 +137,7 @@ export namespace OrgUnitAction { } } - export class GetAllSubmissionPolicy extends CrudAction.GetAllSubResource { + export class GetAllSubResourceSubmissionPolicies extends CrudAction.GetAllSubResource { static readonly type = StringUtil.format(CrudAction.GetAllSubResource.abstractType, state, ApiResourceNameEnum.SUB_POLICY); constructor(public parentId, public queryParameters?: QueryParametersModel) { @@ -145,16 +145,72 @@ export namespace OrgUnitAction { } } - export class GetAllSubmissionPolicySuccess extends CrudAction.GetAllSubResourceSuccess<SubmissionPoliciesModel> { - static readonly type = StringUtil.format(CrudAction.GetAllSubResourceSuccess.abstractType, state); + export class GetAllSubResourceSubmissionPoliciesSuccess extends CrudAction.GetAllSubResourceSuccess<SubmissionPoliciesModel> { + static readonly type = StringUtil.format(CrudAction.GetAllSubResourceSuccess.abstractType, state, ApiResourceNameEnum.SUB_POLICY); constructor(public list: CollectionTypedModel<SubmissionPoliciesModel>) { super(list); } } - export class GetAllSubmissionPolicyFail extends CrudAction.GetAllSubResourceFail { - static readonly type = StringUtil.format(CrudAction.GetAllSubResourceFail.abstractType, state); + export class GetAllSubResourceSubmissionPoliciesFail extends CrudAction.GetAllSubResourceFail { + static readonly type = StringUtil.format(CrudAction.GetAllSubResourceFail.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor() { + super(); + } + } + + export class UpdateSubResourceSubmissionPolicies extends CrudAction.UpdateSubResource { + static readonly type = StringUtil.format(CrudAction.UpdateSubResource.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor(public parentId, public oldResId: string[], newResId: string[]) { + super(parentId, oldResId, newResId); + } + } + + export class CreateSubResourceSubmissionPolicies extends CrudAction.CreateSubResource { + static readonly type = StringUtil.format(CrudAction.CreateSubResource.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor(public parentId, public listResId: string[]) { + super(parentId, listResId); + } + } + + export class CreateSubResourceSubmissionPoliciesSuccess extends CrudAction.CreateSubResourceSuccess { + static readonly type = StringUtil.format(CrudAction.CreateSubResourceSuccess.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor() { + super(); + } + } + + export class CreateSubResourceSubmissionPoliciesFail extends CrudAction.CreateSubResourceFail { + static readonly type = StringUtil.format(CrudAction.CreateSubResourceFail.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor() { + super(); + } + } + + export class DeleteSubResourceSubmissionPolicies extends CrudAction.DeleteSubResource { + static readonly type = StringUtil.format(CrudAction.DeleteSubResource.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor(public parentId, public listResId: string[]) { + super(parentId, listResId); + } + } + + export class DeleteSubResourceSubmissionPoliciesSuccess extends CrudAction.DeleteSubResourceSuccess { + static readonly type = StringUtil.format(CrudAction.DeleteSubResourceSuccess.abstractType, state, ApiResourceNameEnum.SUB_POLICY); + + constructor() { + super(); + } + } + + export class DeleteSubResourceSubmissionPoliciesFail extends CrudAction.DeleteSubResourceFail { + static readonly type = StringUtil.format(CrudAction.DeleteSubResourceFail.abstractType, state, ApiResourceNameEnum.SUB_POLICY); constructor() { super(); diff --git a/src/app/shared/organizational-unit.state.ts b/src/app/shared/organizational-unit.state.ts index 83024a606..f77e032a6 100644 --- a/src/app/shared/organizational-unit.state.ts +++ b/src/app/shared/organizational-unit.state.ts @@ -2,19 +2,22 @@ import {OrganizationalUnitsModel, SubmissionPoliciesModel} from "@app/generated- import {CrudState, CrudStateModel} from "@app/shared/crud.state"; import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum"; import {AdminResourceApiEnum, ResourceApiEnum} from "@app/shared/enums/api.enum"; +import {ModelAttributEnum} from "@app/shared/enums/model-attribut.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 {OrgUnitAction} from "@app/shared/organizational-unit.action"; import {ApiService} from "@app/shared/services/api.service"; +import {CrudActionUtil} from "@app/shared/utils/crud-action.util"; import {NotificationService} from "@app/shared/services/notification.service"; import {Action, State, StateContext} from "@ngxs/store"; import _ from "lodash"; import {Observable} from "rxjs"; +import {tap} from "rxjs/internal/operators/tap"; export interface OrganizationalUnitStateModel extends CrudStateModel<OrganizationalUnitsModel> { - listSubmissionPolicies: SubmissionPoliciesModel[]; + selectedSubmissionPolicies: SubmissionPoliciesModel[]; isLoadingSubmissionPolicies: boolean; } @@ -27,7 +30,7 @@ export interface OrganizationalUnitStateModel extends CrudStateModel<Organizatio list: [], current: null, queryParameters: new QueryParametersModel(), - listSubmissionPolicies: [], + selectedSubmissionPolicies: [], }, }) export class OrganizationalUnitState extends CrudState<OrganizationalUnitsModel> { @@ -105,34 +108,14 @@ export class OrganizationalUnitState extends CrudState<OrganizationalUnitsModel> @Action(OrgUnitAction.Update, {cancelUncompleted: true}) update(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.Update): Observable<OrganizationalUnitsModel> { - const oldSubmissionPolicies = _.map(ctx.getState().listSubmissionPolicies, "resId"); - const newSubmissionPolicies = action.model["submissionPolicies"]; - //TODO manage subresource as list of items ! - this.determineSubresourceChange(oldSubmissionPolicies, newSubmissionPolicies); - - - return super.update(ctx, action); - // .pipe( - // tap(m => { - // ctx.dispatch(CrudActionUtil.get(this.state)); - // }), - // ); - } - - determineSubresourceChange(oldSubmissionPolicies, newSubmissionPolicies) { - const diff: string[] = _.xor(oldSubmissionPolicies, newSubmissionPolicies); - const newResource: string[] = []; - const removedResource: string[] = []; - diff.forEach(d => { - if (_.includes(oldSubmissionPolicies, d)) { - removedResource.push(d); - } else { - newResource.push(d); - } - }); - - console.warn("removed", removedResource); - console.warn("created", newResource); + return super.update(ctx, action) + .pipe( + tap(m => { + const oldSubmissionPolicies = _.map(ctx.getState().selectedSubmissionPolicies, ModelAttributEnum.resId); + const newSubmissionPolicies = action.model["submissionPolicies"]; + ctx.dispatch(CrudActionUtil.updateSubResource(this.state, ApiResourceNameEnum.SUB_POLICY, action.model.resId, oldSubmissionPolicies, newSubmissionPolicies)); + }), + ); } @Action(OrgUnitAction.UpdateSuccess) @@ -160,26 +143,50 @@ export class OrganizationalUnitState extends CrudState<OrganizationalUnitsModel> super.deleteFail(ctx, action); } - @Action(OrgUnitAction.GetAllSubmissionPolicy, {cancelUncompleted: true}) - getAllSubmissionPolicy(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.GetAllSubmissionPolicy): Observable<CollectionTypedModel<SubmissionPoliciesModel>> { + @Action(OrgUnitAction.UpdateSubResourceSubmissionPolicies, {cancelUncompleted: true}) + updateSubmissionPolicy(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.UpdateSubResourceSubmissionPolicies): void { + ctx.patchState({ + isLoadingSubmissionPolicies: true, + }); + super.updateSubResource(ctx, action, ApiResourceNameEnum.SUB_POLICY, action.parentId); + } + + @Action(OrgUnitAction.GetAllSubResourceSubmissionPolicies, {cancelUncompleted: true}) + getAllSubmissionPolicy(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.GetAllSubResourceSubmissionPolicies): Observable<CollectionTypedModel<SubmissionPoliciesModel>> { ctx.patchState({ isLoadingSubmissionPolicies: true, }); return super.getAllSubResource<SubmissionPoliciesModel>(ctx, action, ApiResourceNameEnum.SUB_POLICY, action.parentId); } - // @Action(OrgUnit.GetAllSubmissionPolicySuccess) - // getAllSubmissionPolicySuccess(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnit.GetAllSubmissionPolicySuccess): void { - // ctx.patchState({ - // listSubmissionPolicies: action.list._data, - // isLoadingSubmissionPolicies: false, - // }); - // } - // - // @Action(OrgUnit.GetAllSubmissionPolicyFail) - // getAllSubmissionPolicyFail(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnit.GetAllSubmissionPolicyFail): void { - // ctx.patchState({ - // isLoadingSubmissionPolicies: false, - // }); - // } + @Action(OrgUnitAction.GetAllSubResourceSubmissionPoliciesSuccess) + getAllSubmissionPolicySuccess(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.GetAllSubResourceSubmissionPoliciesSuccess): void { + ctx.patchState({ + selectedSubmissionPolicies: action.list._data, + isLoadingSubmissionPolicies: false, + }); + } + + @Action(OrgUnitAction.GetAllSubResourceSubmissionPoliciesFail) + getAllSubmissionPolicyFail(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.GetAllSubResourceSubmissionPoliciesFail): void { + ctx.patchState({ + isLoadingSubmissionPolicies: false, + }); + } + + @Action(OrgUnitAction.CreateSubResourceSubmissionPolicies, {cancelUncompleted: true}) + createSubmissionPolicy(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.CreateSubResourceSubmissionPolicies): Observable<string[]> { + ctx.patchState({ + isLoadingSubmissionPolicies: true, + }); + return super.createSubResource(ctx, action, ApiResourceNameEnum.SUB_POLICY, action.parentId); + } + + @Action(OrgUnitAction.DeleteSubResourceSubmissionPolicies, {cancelUncompleted: true}) + deleteSubmissionPolicy(ctx: StateContext<OrganizationalUnitStateModel>, action: OrgUnitAction.DeleteSubResourceSubmissionPolicies): Observable<string[]> { + ctx.patchState({ + isLoadingSubmissionPolicies: true, + }); + return super.deleteSubResource(ctx, action, ApiResourceNameEnum.SUB_POLICY, action.parentId); + } } diff --git a/src/app/shared/services/api.service.ts b/src/app/shared/services/api.service.ts index 9e99f75a3..933958c06 100644 --- a/src/app/shared/services/api.service.ts +++ b/src/app/shared/services/api.service.ts @@ -168,49 +168,23 @@ export class ApiService { ); } - // public getSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, queryParameters: QueryParametersModel, customParameters?: { [key: string]: string; }, observe?: "body", reportProgress?: boolean): Observable<CollectionTypedModel<T>>; - // public getSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, queryParameters: QueryParametersModel, customParameters?: { [key: string]: string; }, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<CollectionTypedModel<T>>>; - // public getSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, queryParameters: QueryParametersModel, customParameters?: { [key: string]: string; }, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<CollectionTypedModel<T>>>; - // public getSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, queryParameters?: QueryParametersModel, customParameters?: { [key: string]: string; }, observe: any = "body", reportProgress: boolean = false): Observable<any> { - // const pathEvaluated = this.evaluatePathParentId(subResource, parentId); - // return this.get<T>(pathEvaluated as string, queryParameters, customParameters, observe, reportProgress); - // } - // - // public getSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe?: "body", reportProgress?: boolean): Observable<T>; - // public getSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; - // public getSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; - // public getSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe: any = "body", reportProgress: boolean = false): Observable<any> { - // const pathEvaluated = this.evaluatePathParentId(subResource, parentId); - // return this.getById<T>(pathEvaluated as string, resId, observe, reportProgress); - // } - // - // public deleteSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe?: "body", reportProgress?: boolean): Observable<T>; - // public deleteSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; - // public deleteSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; - // public deleteSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, observe: any = "body", reportProgress: boolean = false): Observable<any> { - // const pathEvaluated = this.evaluatePathParentId(subResource, parentId); - // return this.deleteById<T>(pathEvaluated as string, resId, observe, reportProgress); - // } - // - // public patchSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, body?: T, observe?: "body", reportProgress?: boolean): Observable<T>; - // public patchSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, body?: T, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; - // public patchSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, body?: T, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; - // public patchSubResourceById<T>(subResource: ApiResourceNameEnum, parentId: string, resId: string, body?: T, observe: any = "body", reportProgress: boolean = false): Observable<any> { - // const pathEvaluated = this.evaluatePathParentId(subResource, parentId); - // return this.patchById<T>(pathEvaluated as string, resId, body, observe, reportProgress); - // } - // - // public postSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, body?: T, observe?: "body", reportProgress?: boolean): Observable<T>; - // public postSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, body?: T, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; - // public postSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, body?: T, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; - // public postSubResource<T>(subResource: ApiResourceNameEnum, parentId: string, body?: T, observe: any = "body", reportProgress: boolean = false): Observable<any> { - // const pathEvaluated = this.evaluatePathParentId(subResource, parentId); - // return this.post<T>(pathEvaluated as string, body, observe, reportProgress); - // } - // - // private evaluatePathParentId(subResource: ApiResourceNameEnum, parentId: string): string { - // return StringUtil.formatKeyValue(subResource, new KeyValueModel(ApiKeyword.PARENT_ID, parentId)); - // } + public delete<T>(path: string, body?: T, observe?: "body", reportProgress?: boolean): Observable<T>; + public delete<T>(path: string, body?: T, observe?: "response", reportProgress?: boolean): Observable<HttpResponse<T>>; + public delete<T>(path: string, body?: T, observe?: "events", reportProgress?: boolean): Observable<HttpEvent<T>>; + public delete<T>(path: string, body?: T, observe: any = "body", reportProgress: boolean = false): Observable<any> { + let headers = this.getHeaders(); + headers = this.addContentType(headers); + + return this.httpClient.delete<T>(`${this.configuration.basePath}/${path}`, + { + withCredentials: this.configuration.withCredentials, + headers, + observe, + reportProgress, + body, + } as any, + ); + } private getQueryParameters(queryParameters: QueryParametersModel, customParameters: { [p: string]: string }) { let queryParametersHttp = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()}); diff --git a/src/app/shared/utils/crud-action.util.ts b/src/app/shared/utils/crud-action.util.ts index e81808452..df2d06143 100644 --- a/src/app/shared/utils/crud-action.util.ts +++ b/src/app/shared/utils/crud-action.util.ts @@ -1,5 +1,6 @@ import {DepositAction} from "@app/deposit/deposit.action"; import {CrudAction} from "@app/shared/crud.action"; +import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum"; import {StateEnum} from "@app/shared/enums/state.enum"; import {LanguageAction} from "@app/shared/language.action"; import {LicenseAction} from "@app/shared/license.action"; @@ -43,10 +44,12 @@ export class CrudActionUtil { try { return new (namespace)[className](...param); } catch (e) { - throw Error(`Unable to instance ${state}Action.${className}.`); + throw Error(`Unable to instance ${state}Action.${className}. If it's a sub resource, please check that the name of the action is similar to name present in ApiResourceName (converted in PascalCase)`); } } + // TODO Find a way to not redeclare parameters (risk of mistake). If this methods go to CrudAction we get circular dependancy because of action namespace use (see getNamespace) + static changeQueryParameters(state: StateEnum, queryParameters: QueryParametersModel): CrudAction.ChangeQueryParameters { return CrudActionUtil.getInstanceInternal(state, CrudAction.ChangeQueryParameters.className, queryParameters); } @@ -111,21 +114,55 @@ export class CrudActionUtil { return CrudActionUtil.getInstanceInternal(state, CrudAction.DeleteFail.className); } - // static getAllSubresourceSuccess<T>(state: StateEnum, urlSubresource: SubResourceApiEnum, list: CollectionTypedModel<T>): GetAllSubresourceSuccess<any> { - // return CrudActionUtil.getInstanceInternal(state, CrudAction.GetAllSubresourceSuccess.className); - // if (state === StateEnum.organizationalUnit) { - // if (urlSubresource === AdminSubResourceApiEnum.organizationalUnitsSubmissionPolicy) { - // return new OrgUnitGetAllSubmissionPolicySuccess(list); - // } - // } - // } - // - // static getAllSubresourceFail(state: StateEnum, urlSubresource: SubResourceApiEnum): GetAllSubresourceFail { - // return CrudActionUtil.getInstanceInternal(state, CrudAction.GetAllSubresourceFail.className); - // if (state === StateEnum.organizationalUnit) { - // if (urlSubresource === AdminSubResourceApiEnum.organizationalUnitsSubmissionPolicy) { - // return new OrgUnitGetAllSubmissionPolicyFail(); - // } - // } - // } + static getAllSubResource(state: StateEnum, subResource: ApiResourceNameEnum, parentId: string, queryParameters?: QueryParametersModel): CrudAction.GetAllSubResource { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.GetAllSubResource.className, CrudActionUtil.formatSubResourceName(subResource)), parentId, queryParameters); + } + + static getAllSubResourceSuccess<T>(state: StateEnum, subResource: ApiResourceNameEnum, list: CollectionTypedModel<T>): CrudAction.GetAllSubResourceSuccess<any> { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.GetAllSubResourceSuccess.className, CrudActionUtil.formatSubResourceName(subResource)), list); + } + + static getAllSubResourceFail(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.GetAllSubResourceFail { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.GetAllSubResourceFail.className, CrudActionUtil.formatSubResourceName(subResource)), subResource); + } + + static createSubResource(state: StateEnum, subResource: ApiResourceNameEnum, parentId: string, listResId: string[]): CrudAction.CreateSubResource { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.CreateSubResource.className, CrudActionUtil.formatSubResourceName(subResource)), parentId, listResId); + } + + static createSubResourceSuccess(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.CreateSubResourceSuccess { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.CreateSubResourceSuccess.className, CrudActionUtil.formatSubResourceName(subResource))); + } + + static createSubResourceFail(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.CreateSubResourceFail { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.CreateSubResourceFail.className, CrudActionUtil.formatSubResourceName(subResource)), subResource); + } + + static deleteSubResource(state: StateEnum, subResource: ApiResourceNameEnum, parentId: string, listResId: string[]): CrudAction.DeleteSubResource { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.DeleteSubResource.className, CrudActionUtil.formatSubResourceName(subResource)), parentId, listResId); + } + + static deleteSubResourceSuccess(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.DeleteSubResourceSuccess { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.DeleteSubResourceSuccess.className, CrudActionUtil.formatSubResourceName(subResource))); + } + + static deleteSubResourceFail(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.DeleteSubResourceFail { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.DeleteSubResourceFail.className, CrudActionUtil.formatSubResourceName(subResource)), subResource); + } + + static updateSubResource(state: StateEnum, subResource: ApiResourceNameEnum, parentId: string, oldResId: string[], newResId: string[]): CrudAction.DeleteSubResource { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.UpdateSubResource.className, CrudActionUtil.formatSubResourceName(subResource)), parentId, oldResId, newResId); + } + + static updateSubResourceSuccess(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.DeleteSubResourceSuccess { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.UpdateSubResourceSuccess.className, CrudActionUtil.formatSubResourceName(subResource))); + } + + static updateSubResourceFail(state: StateEnum, subResource: ApiResourceNameEnum): CrudAction.DeleteSubResourceFail { + return CrudActionUtil.getInstanceInternal(state, StringUtil.format(CrudAction.UpdateSubResourceFail.className, CrudActionUtil.formatSubResourceName(subResource)), subResource); + } + + private static formatSubResourceName(subResource: ApiResourceNameEnum): string { + return StringUtil.convertSpinalCaseToPascalCase(subResource as string); + } } diff --git a/src/app/shared/utils/string.util.ts b/src/app/shared/utils/string.util.ts index a4160b0dd..cff43961e 100644 --- a/src/app/shared/utils/string.util.ts +++ b/src/app/shared/utils/string.util.ts @@ -1,4 +1,5 @@ import {KeyValueModel} from "@app/shared/models/key-value.model"; +import * as changeCase from "change-case"; export class StringUtil { static readonly stringEmpty = ""; @@ -16,4 +17,14 @@ export class StringUtil { }); return str; } + + static convertSpinalCaseToPascalCase(origin: string): string { + origin = origin.replace("-", " "); + return changeCase.pascalCase(origin); + } + + static convertSpinalCaseToCamelCase(origin: string): string { + origin = origin.replace("-", " "); + return changeCase.camelCase(origin); + } } diff --git a/src/app/shared/views/abstract-detail/abstract-detail.view.ts b/src/app/shared/views/abstract-detail/abstract-detail.view.ts index e89102efe..862190e98 100644 --- a/src/app/shared/views/abstract-detail/abstract-detail.view.ts +++ b/src/app/shared/views/abstract-detail/abstract-detail.view.ts @@ -6,6 +6,7 @@ import {CrudAction} from "@app/shared/crud.action"; import {CrudStateModel} from "@app/shared/crud.state"; import {AbstractDeleteDialog} from "@app/shared/dialogs/abstract-delete/abstract-delete.dialog"; import {BaseDirective} from "@app/shared/directives/base.directive"; +import {ModelAttributEnum} from "@app/shared/enums/model-attribut.enum"; import {StateEnum} from "@app/shared/enums/state.enum"; import {DeleteDialogModel} from "@app/shared/models/delete-dialog.model"; import {CrudActionUtil} from "@app/shared/utils/crud-action.util"; @@ -60,7 +61,7 @@ export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends const datas = {} as DeleteDialogModel; this.addToSubscription(this.current$.pipe(take(1)).subscribe((model: T) => { datas.name = model[this.KEY_PARAM_NAME]; - datas.resId = model["resId"]; + datas.resId = model[ModelAttributEnum.resId]; })); const dialogRef = this.dialog.open(CrudDialogUtil.delete(this.state) as ComponentType<AbstractDeleteDialog<T, U>>, { width: "250px", diff --git a/src/app/shared/views/abstract-list/abstract-list.view.ts b/src/app/shared/views/abstract-list/abstract-list.view.ts index 714c9f988..2e56c4b0f 100644 --- a/src/app/shared/views/abstract-list/abstract-list.view.ts +++ b/src/app/shared/views/abstract-list/abstract-list.view.ts @@ -1,6 +1,7 @@ import {OnInit} from "@angular/core"; import {CrudStateModel} from "@app/shared/crud.state"; import {BaseDirective} from "@app/shared/directives/base.directive"; +import {ModelAttributEnum} from "@app/shared/enums/model-attribut.enum"; import {StateEnum} from "@app/shared/enums/state.enum"; import {DataTableColumnsModel} from "@app/shared/models/data-table-columns.model"; import {QueryParametersModel} from "@app/shared/models/query-parameters.model"; @@ -44,7 +45,7 @@ export abstract class AbstractListView<T, U extends CrudStateModel<T>> extends B } showDetail(model: T) { - this.store.dispatch(new Navigate([CrudRouteUtil.getDetailRoute(this.state), model["resId"]])); + this.store.dispatch(new Navigate([CrudRouteUtil.getDetailRoute(this.state), model[ModelAttributEnum.resId]])); } onQueryParametersEvent($event: QueryParametersModel) { -- GitLab