From 3c0534cbf4c9a9ce30696712fc993b70ef0ce288 Mon Sep 17 00:00:00 2001 From: Florent POITTEVIN <poittevin.florent@gmail.com> Date: Thu, 25 Feb 2021 12:24:29 +0100 Subject: [PATCH] feat: 292 improve multilanguage field in summary --- .../admin-structure-form.presentational.html | 4 +- .../deposit-container.presentational.html | 35 + .../deposit-container.presentational.scss | 25 + .../deposit-container.presentational.ts | 76 ++ .../deposit-form.presentational.html | 44 +- .../deposit-form.presentational.ts | 20 +- .../deposit-summary.presentational.html | 141 ++-- .../deposit-summary.presentational.scss | 58 +- .../deposit-summary.presentational.ts | 652 ++++++++++-------- .../deposit-detail/deposit-detail.routable.ts | 19 +- src/app/features/deposit/deposit.module.ts | 2 + src/app/models/index.ts | 14 +- .../structure/shared-structure.state.ts | 8 +- src/app/shared/utils/aou-object.util.ts | 29 + 14 files changed, 731 insertions(+), 396 deletions(-) create mode 100644 src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.html create mode 100644 src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.scss create mode 100644 src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.ts create mode 100644 src/app/shared/utils/aou-object.util.ts diff --git a/src/app/features/admin/structure/components/presentationals/admin-structure-form/admin-structure-form.presentational.html b/src/app/features/admin/structure/components/presentationals/admin-structure-form/admin-structure-form.presentational.html index acc74249b..b440003f4 100644 --- a/src/app/features/admin/structure/components/presentationals/admin-structure-form/admin-structure-form.presentational.html +++ b/src/app/features/admin/structure/components/presentationals/admin-structure-form/admin-structure-form.presentational.html @@ -2,8 +2,8 @@ (ngSubmit)="onSubmit()" > <solidify-detail-presentation [iconName]="iconNameEnum.structures" - [centerTemplate]="centerTemplate" - [rightTemplate]="rightTemplate" + [centerTemplate]="centerTemplate" + [rightTemplate]="rightTemplate" ></solidify-detail-presentation> <ng-template #centerTemplate> diff --git a/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.html b/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.html new file mode 100644 index 000000000..9d1cef94a --- /dev/null +++ b/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.html @@ -0,0 +1,35 @@ +<h2>{{titleToTranslate | translate}}</h2> +<ng-template [ngIf]="current | isNotNullNorUndefined"> + <div *ngIf="current.lang | isNonEmptyString" + class="current-language" + [class.is-clickable]="listLanguages.length > 0" + matRipple + [matRippleDisabled]="listLanguages.length === 0" + [matMenuTriggerFor]="menu" + >{{current.lang}}</div> + + <mat-menu #menu="matMenu"> + <button *ngFor="let lang of listLanguages" + mat-menu-item + (click)="switchToLanguage(lang)" + > + <span>{{lang}}</span> + </button> + </mat-menu> + + <div class="text"> + + <a *ngIf="withUrl; else normal" + [href]="current.url" + target="_blank" + solidifyTooltipOnEllipsis + > + {{current.text}} + </a> + + <ng-template #normal> + {{current.text}} + </ng-template> + </div> + +</ng-template> diff --git a/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.scss b/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.scss new file mode 100644 index 000000000..78a28a669 --- /dev/null +++ b/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.scss @@ -0,0 +1,25 @@ +@import "../../../../../../../node_modules/solidify-frontend/lib/components/presentationals/abstract-form/abstract-form.presentational"; + +:host { + display: block; + position: relative; + + .current-language { + position: absolute; + top: 0; + right: 0; + background: $primary-color; + color: $white; + width: fit-content; + padding: 2px 10px; + border-radius: 0 6px 0 0; + + &.is-clickable { + cursor: pointer; + } + + &:not(.is-clickable) { + pointer-events: none + } + } +} diff --git a/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.ts b/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.ts new file mode 100644 index 000000000..9106815f3 --- /dev/null +++ b/src/app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational.ts @@ -0,0 +1,76 @@ +import { + ChangeDetectionStrategy, + Component, + Input, + OnChanges, + OnInit, +} from "@angular/core"; +import { + DepositSummaryLinkInfo, + DepositSummaryValueLanguage, +} from "@app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational"; +import {DepositFormText} from "@app/features/deposit/models/deposit-form-definition.model"; +import {AppState} from "@app/stores/app.state"; +import {Enums} from "@enums"; +import {environment} from "@environments/environment"; +import {Store} from "@ngxs/store"; +import { + AbstractPresentational, + isEmptyArray, + isNullOrUndefined, + MemoizedUtil, +} from "solidify-frontend"; + +@Component({ + selector: "aou-deposit-container", + templateUrl: "./deposit-container.presentational.html", + styleUrls: ["deposit-container.presentational.scss"], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DepositContainerPresentational extends AbstractPresentational implements OnChanges, OnInit { + private _depositFormText: (DepositFormText | DepositSummaryLinkInfo | DepositSummaryValueLanguage)[]; + + @Input() + withUrl: boolean = false; + + @Input() + set depositFormText(value: (DepositFormText | DepositSummaryLinkInfo | DepositSummaryValueLanguage)[]) { + this._depositFormText = value; + + if (isNullOrUndefined(value) || isEmptyArray(value)) { + return; + } + + const currentLanguage = Enums.Language.LanguageIso639V2ToV1(MemoizedUtil.selectSnapshot(this._store, AppState, state => state.appLanguage)); + let indexCurrentLanguage = value.findIndex(t => t.lang === currentLanguage); + if (indexCurrentLanguage === -1) { + const defaultLanguage = Enums.Language.LanguageIso639V2ToV1(environment.defaultLanguage); + indexCurrentLanguage = value.findIndex(t => t.lang === defaultLanguage); + if (indexCurrentLanguage === -1) { + indexCurrentLanguage = 0; + } + } + + this.current = value[indexCurrentLanguage]; + this.listLanguages = value.filter(t => t !== this.current).map(t => t.lang); + } + + get depositFormText(): (DepositFormText | DepositSummaryLinkInfo | DepositSummaryValueLanguage)[] { + return this._depositFormText; + } + + @Input() + titleToTranslate: string; + + listLanguages: string[] = []; + current: DepositFormText | DepositSummaryLinkInfo | DepositSummaryValueLanguage; + + constructor(private _store: Store) { + super(); + } + + switchToLanguage(language: string): void { + this.current = this.depositFormText.find(t => t.lang === language); + this.listLanguages = this.depositFormText.filter(t => t !== this.current).map(t => t.lang); + } +} diff --git a/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.html b/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.html index ac7f1194c..bc4824e51 100644 --- a/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.html +++ b/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.html @@ -37,28 +37,28 @@ ></aou-deposit-form-fourth-step-description> </ng-template> - <ng-template [ngIf]="model | isNotNullNorUndefined"> - <aou-deposit-summary #depositSummaryPresentational - [depositId]="model?.resId" - [class.hide]="step !== depositStepEnum.SUMMARY" - ></aou-deposit-summary> - <ul class="form-error"> - <li *ngIf="numberFilesInError > 0"> - <a class="link" - (click)="navigateToStep(depositStepEnum.FILES)" - > - {{labelTranslateEnum.filesAreInErrorAndPreventSubmission | translate}} - </a> - </li> - <li *ngIf="numberFilesNotReady > 0 && numberFilesNotReady > numberFilesInError"> - <a class="link" - (click)="navigateToStep(depositStepEnum.FILES)" - > - {{labelTranslateEnum.filesAreNotReadyAndPreventSubmission | translate}} - </a> - </li> - </ul> - </ng-template> + <ng-template [ngIf]="(model | isNotNullNorUndefined) && step === depositStepEnum.SUMMARY"> + <aou-deposit-summary #depositSummaryPresentational + [depositId]="model?.resId" + [depositFormModel]="convertedFormToDepositFormModelForSummary" + ></aou-deposit-summary> + <ul class="form-error"> + <li *ngIf="numberFilesInError > 0"> + <a class="link" + (click)="navigateToStep(depositStepEnum.FILES)" + > + {{labelTranslateEnum.filesAreInErrorAndPreventSubmission | translate}} + </a> + </li> + <li *ngIf="numberFilesNotReady > 0 && numberFilesNotReady > numberFilesInError"> + <a class="link" + (click)="navigateToStep(depositStepEnum.FILES)" + > + {{labelTranslateEnum.filesAreNotReadyAndPreventSubmission | translate}} + </a> + </li> + </ul> + </ng-template> <div class="button-wrapper"> <button *ngIf="stepper.currentStepIndex > 0" diff --git a/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts b/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts index fea6e8d88..3700a3bcd 100644 --- a/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts +++ b/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts @@ -37,7 +37,6 @@ import {DepositFormDescriptionLinkPresentational} from "@app/features/deposit/co import {DepositFormDescriptionPublicationIdentifierPresentational} from "@app/features/deposit/components/presentationals/deposit-form-description-publication-identifier/deposit-form-description-publication-identifier.presentational"; import {DepositFormDescriptionTextLanguageListPresentational} from "@app/features/deposit/components/presentationals/deposit-form-description-text-language-list/deposit-form-description-text-language-list.presentational"; import {DepositFormFourthStepDescriptionPresentational} from "@app/features/deposit/components/presentationals/deposit-form-fourth-step-description/deposit-form-fourth-step-description.presentational"; -import {DepositSummaryPresentational} from "@app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational"; import { DepositFormAbstractContributor, DepositFormAcademicStructure, @@ -83,6 +82,7 @@ import { RoutesEnum, } from "@shared/enums/routes.enum"; import {Step} from "@shared/models/step.model"; +import {AouObjectUtil} from "@shared/utils/aou-object.util"; import { BehaviorSubject, Observable, @@ -121,7 +121,7 @@ import { provide: STEPPER_GLOBAL_OPTIONS, useValue: {displayDefaultIndicatorType: false}, }], }) -export class DepositFormPresentational extends AbstractPresentational implements OnInit, AfterViewInit { +export class DepositFormPresentational extends AbstractPresentational implements OnInit { formDefinitionMain: FormComponentFormDefinitionMain = new FormComponentFormDefinitionMain(); formDefinitionFirstStepType: FormComponentFormDefinitionFirstStepType = new FormComponentFormDefinitionFirstStepType(); formDefinitionThirdStepContributors: FormComponentFormDefinitionThirdStepContributors = new FormComponentFormDefinitionThirdStepContributors(); @@ -148,6 +148,7 @@ export class DepositFormPresentational extends AbstractPresentational implements formGroupSecondStepFiles: FormGroup; formGroupThirdStepContributors: FormGroup; formGroupFourthStepDescription: FormGroup; + convertedFormToDepositFormModelForSummary: DepositFormModel; isEditable: boolean = true; linear: boolean = false; @@ -211,9 +212,6 @@ export class DepositFormPresentational extends AbstractPresentational implements @ViewChild("depositDescriptionPresentational") readonly depositDescriptionPresentational: DepositFormFourthStepDescriptionPresentational; - @ViewChild("depositSummaryPresentational") - readonly depositSummaryPresentational: DepositSummaryPresentational; - @ViewChild("stepper") readonly stepper: SharedStepperPresentational; @@ -271,13 +269,8 @@ export class DepositFormPresentational extends AbstractPresentational implements } this._addLogical(); this._addStepErrorWatcher(); - } - - ngAfterViewInit(): void { - super.ngAfterViewInit(); - - if (this.step === Enums.Deposit.StepEnum.SUMMARY && isNotNullNorUndefined(this.depositSummaryPresentational)) { - this.depositSummaryPresentational.depositFormModel = this.convertFormToDepositFormModel(); + if (this.step === Enums.Deposit.StepEnum.SUMMARY) { + this.convertedFormToDepositFormModelForSummary = AouObjectUtil.cleanEmptyAttributes(this.convertFormToDepositFormModel()); } } @@ -642,8 +635,7 @@ export class DepositFormPresentational extends AbstractPresentational implements } if (stepValue === Enums.Deposit.StepEnum.DESCRIPTION && targetRoutingAfterSave > 0) { - this.depositSummaryPresentational.depositFormModel = this.convertFormToDepositFormModel(); - this.depositSummaryPresentational.detectExternalChanges(); + this.convertedFormToDepositFormModelForSummary = AouObjectUtil.cleanEmptyAttributes(this.convertFormToDepositFormModel()); } this.update(stepValue, targetRoutingAfterSave); diff --git a/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.html b/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.html index 0248f57a4..3d0aeae35 100644 --- a/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.html +++ b/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.html @@ -1,14 +1,55 @@ -<ng-container *ngTemplateOutlet="listInfos; context: {list: listInfoMains}"></ng-container> +<ng-template [ngIf]="depositFormModel | isNotNullNorUndefined"> -<solidify-panel-expandable [titleToTranslate]="labelTranslateEnum.filesAndDistributionConditions | translate" - [isOpen]="true" -> - <aou-deposit-document-file *ngIf="depositId | isNotNullNorUndefined" - [canEdit]="false" - [depositId]="depositId" - class="document-file" - ></aou-deposit-document-file> -</solidify-panel-expandable> + <div class="container main-infos"> + <div *ngIf="getMostPreciseType as typeInfo" + class="corner-info type" + > + <ng-container *ngTemplateOutlet="retrieveModelForTranslate; context: {info: typeInfo}"></ng-container> + </div> + + <div *ngIf="depositFormModel?.description?.language as lang" + class="corner-info general-lang" + > + {{lang}} + </div> + + <h1>{{depositFormModel?.type?.title}}</h1> + + <h3 *ngIf="authors | isNonEmptyString">{{authors}}</h3> + + <aou-deposit-container *ngIf="abstracts | isNotNullNorUndefined" + class="container with-padding-top" + [titleToTranslate]="labelTranslateEnum.abstract" + [depositFormText]="abstracts" + ></aou-deposit-container> + + <div *ngIf="keywords | isNonEmptyString" + class="line" + > + <span class="label">{{labelTranslateEnum.keywords | translate}}: </span> + <span class="value">{{keywords}}</span> + </div> + + </div> + + <div *ngIf="listInfoMains" + class="container" + > + <ng-container *ngTemplateOutlet="listInfos; context: {list: listInfoMains}"></ng-container> + </div> + + <solidify-panel-expandable [titleToTranslate]="labelTranslateEnum.filesAndDistributionConditions | translate" + [isOpen]="true" + class="container document-file-wrapper" + > + <aou-deposit-document-file *ngIf="depositId | isNotNullNorUndefined" + [canEdit]="false" + [depositId]="depositId" + class="document-file" + ></aou-deposit-document-file> + </solidify-panel-expandable> + +</ng-template> <!--TEMPLATE BELOW--> @@ -24,7 +65,7 @@ <dl *ngIf="info.value | isNonEmptyString"> <ng-container *ngTemplateOutlet="label; context: {info: info}"></ng-container> <dd class="value" - [class.is-textarea]="info.isTextarea" + [class.wrap]="info.wrap" solidifyTooltipOnEllipsis >{{info.value}}</dd> </dl> @@ -40,12 +81,7 @@ <ng-template [ngIf]="(info.state | isNotNullNorUndefined) && (info.action | isNotNullNorUndefined) && (info.labelKey | isNotNullNorUndefined)" [ngIfElse]="normalTranslate" > - <aou-shared-resource-name-container [id]="info.value" - [labelKey]="info.labelKey" - [state]="info.state" - [action]="info.action" - [backTranslate]="info.isBackTranslate" - ></aou-shared-resource-name-container> + <ng-container *ngTemplateOutlet="retrieveModelForTranslate; context: {info: info}"></ng-container> </ng-template> <ng-template #normalTranslate> @@ -64,9 +100,8 @@ target="_blank" solidifyTooltipOnEllipsis > - {{info.link.name}} + {{info.link.text}} </a> - <ng-container *ngTemplateOutlet="languageSpan; context: {language: info.link.language}"></ng-container> </dd> </dl> </ng-container> @@ -87,47 +122,30 @@ </ng-container> <ng-container *ngSwitchCase="typeInfoEnum.listLanguage"> - <dl *ngIf="info.valuesLanguage | isNonEmptyArray"> - <ng-container *ngTemplateOutlet="label; context: {info: info}"></ng-container> - <dd class="value"> - <ul class="list-values"> - <li *ngFor="let v of info.valuesLanguage" - solidifyTooltipOnEllipsis - > - {{v.text}} - <ng-container *ngTemplateOutlet="languageSpan; context: {language: v.language}"></ng-container> - </li> - </ul> - </dd> - </dl> + <aou-deposit-container *ngIf="info.valuesLanguage | isNonEmptyArray" + class="container with-padding-top" + [titleToTranslate]="info.label" + [depositFormText]="info.valuesLanguage" + ></aou-deposit-container> </ng-container> <ng-container *ngSwitchCase="typeInfoEnum.listLink"> - <dl *ngIf="info.links | isNonEmptyArray"> - <ng-container *ngTemplateOutlet="label; context: {info: info}"></ng-container> - <dd class="value"> - <ul class="list-values"> - <li *ngFor="let v of info.links"> - <a [href]="v.url" - target="_blank" - solidifyTooltipOnEllipsis - > - {{v.name}} - </a> - <ng-container *ngTemplateOutlet="languageSpan; context: {language: v.language}"></ng-container> - </li> - </ul> - </dd> - </dl> + <aou-deposit-container *ngIf="info.links | isNonEmptyArray" + class="container with-padding-top" + [titleToTranslate]="info.label" + [depositFormText]="info.links" + [withUrl]="true" + ></aou-deposit-container> </ng-container> <ng-container *ngSwitchCase="typeInfoEnum.listInfo"> - <dl *ngIf="info.valuesInfo | isNonEmptyArray"> - <ng-container *ngTemplateOutlet="label; context: {info: info}"></ng-container> - <dd class="value"> - <ng-container *ngTemplateOutlet="listInfos; context: {list: info.valuesInfo}"></ng-container> - </dd> - </dl> + <solidify-panel-expandable *ngIf="info.valuesInfo | isNonEmptyArray" + [titleToTranslate]="info.label" + [isOpen]="true" + class="container" + > + <ng-container *ngTemplateOutlet="listInfos; context: {list: info.valuesInfo}"></ng-container> + </solidify-panel-expandable> </ng-container> <ng-container *ngSwitchDefault> @@ -165,7 +183,7 @@ {{info.label | translate}} </ng-template> </ng-template> - <ng-container *ngTemplateOutlet="languageSpan; context: {language: info.language}"></ng-container> + <ng-container *ngTemplateOutlet="languageSpan; context: {language: info.lang}"></ng-container> </dt> </ng-template> @@ -176,3 +194,16 @@ <span class="language"> ({{language}})</span> </ng-template> </ng-template> + +<ng-template #retrieveModelForTranslate + let-info="info" +> + <aou-shared-resource-name-container *ngIf="(info | isNotNullNorUndefined) && (info.value | isNonEmptyString)" + [id]="info.value" + [labelKey]="info.labelKey" + [state]="info.state" + [action]="info.action" + [backTranslate]="info.isBackTranslate" + ></aou-shared-resource-name-container> +</ng-template> + diff --git a/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.scss b/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.scss index 228035853..a294aa890 100644 --- a/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.scss +++ b/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.scss @@ -3,10 +3,60 @@ :host { padding-top: 20px; display: block; + $border-radius: 6px; - .document-file ::ng-deep { - .wrapper { - min-height: initial; + .container { + position: relative; + padding: 10px; + border: 1px solid $extra-light-grey; + border-radius: $border-radius; + margin: 5px 0; + + &.with-padding-top { + padding-top: 30px; + } + + .corner-info { + position: absolute; + top: 0; + background: $primary-color; + color: $white; + width: fit-content; + padding: 2px 10px; + } + + .type { + left: 0; + border-radius: $border-radius 0 0 0; + } + + .general-lang { + right: 0; + border-radius: 0 $border-radius 0 0; + } + } + + .main-infos { + padding-top: 40px; + margin-bottom: 20px; + + .line { + padding: 5px 0; + + .label { + font-weight: bold; + } + } + } + + + .document-file-wrapper { + margin-top: 15px; + + .document-file ::ng-deep { + .wrapper { + min-height: initial; + } } } @@ -46,7 +96,7 @@ margin-left: 0; } - &.is-textarea { + &.wrap { white-space: break-spaces; } } diff --git a/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.ts b/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.ts index 8e5e41e77..d256bfc8a 100644 --- a/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.ts +++ b/src/app/features/deposit/components/presentationals/deposit-summary/deposit-summary.presentational.ts @@ -5,7 +5,8 @@ import { ElementRef, Injector, Input, - OnInit, + OnChanges, + SimpleChanges, } from "@angular/core"; import {FormBuilder} from "@angular/forms"; import { @@ -24,8 +25,7 @@ import {sharedDepositTypeSubtypeActionNameSpace} from "@shared/stores/deposit-ty import {SharedDepositTypeSubtypeState} from "@shared/stores/deposit-type/subtype/shared-deposit-type-subtype.state"; import {sharedDepositSubSubtypeActionNameSpace} from "@shared/stores/deposit-type/subtype/sub-subtype/shared-deposit-sub-subtype.action"; import {SharedDepositSubSubtypeState} from "@shared/stores/deposit-type/subtype/sub-subtype/shared-deposit-sub-subtype.state"; -import {sharedLanguageActionNameSpace} from "@shared/stores/language/shared-language.action"; -import {SharedLanguageState} from "@shared/stores/language/shared-language.state"; +import {AouObjectUtil} from "@shared/utils/aou-object.util"; import { AbstractPresentational, DateUtil, @@ -48,25 +48,35 @@ import { styleUrls: ["deposit-summary.presentational.scss"], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DepositSummaryPresentational extends AbstractPresentational implements OnInit { +export class DepositSummaryPresentational extends AbstractPresentational implements OnChanges { @Input() depositId: string; - private _depositFormModel: DepositFormModel; - @Input() - set depositFormModel(value: DepositFormModel) { - this._depositFormModel = value; - this._resetListInfo(); - this._defineListInfo(); - } - - get depositFormModel(): DepositFormModel { - return this._depositFormModel; - } + depositFormModel: DepositFormModel; listInfoMains: Info[]; + private infoType: Info; + private infoSubType: Info | undefined; + private infoSubSubType: Info | undefined; + private authors: string | undefined; + private keywords: string | undefined; + private abstracts: DepositFormText[] | undefined; + + get getMostPreciseType(): Info { + if (isNotNullNorUndefined(this.infoSubSubType)) { + return this.infoSubSubType; + } + if (isNotNullNorUndefined(this.infoSubType)) { + return this.infoSubType; + } + if (isNotNullNorUndefined(this.infoType)) { + return this.infoType; + } + return undefined; + } + get labelTranslateEnum(): typeof LabelTranslateEnum { return LabelTranslateEnum; } @@ -91,13 +101,12 @@ export class DepositSummaryPresentational extends AbstractPresentational impleme super(); } - ngOnInit(): void { - super.ngOnInit(); - this._defineListInfo(); - } - - detectExternalChanges(): void { - this._changeDetectorRef.detectChanges(); + ngOnChanges(changes: SimpleChanges): void { + super.ngOnChanges(changes); + if (isNotNullNorUndefined(this.depositFormModel)) { + this._resetListInfo(); + this._defineListInfo(); + } } private _resetListInfo(): void { @@ -105,249 +114,74 @@ export class DepositSummaryPresentational extends AbstractPresentational impleme } private _defineListInfo(): void { - if (isNullOrUndefined(this.depositFormModel)) { - this._resetListInfo(); - return; - } - this.listInfoMains = [ - { - label: LabelTranslateEnum.title, - value: this.depositFormModel.type?.title, - }, - { - label: LabelTranslateEnum.originalTitle, - value: this.depositFormModel.description?.originalTitle?.text, - language: this.depositFormModel.description?.originalTitle?.lang, - }, - { - label: LabelTranslateEnum.type, - value: this.depositFormModel.type?.type, - state: SharedDepositTypeState, - action: sharedDepositTypeActionNameSpace, - labelKey: "name", - type: TypeInfoEnum.translate, - }, - { + this.infoType = { + label: LabelTranslateEnum.type, + value: this.depositFormModel.type?.type, + state: SharedDepositTypeState, + action: sharedDepositTypeActionNameSpace, + labelKey: "name", + type: TypeInfoEnum.translate, + }; + + if (isNonEmptyString(this.depositFormModel.type?.subtype)) { + this.infoSubType = { label: LabelTranslateEnum.subtype, value: this.depositFormModel.type?.subtype, state: SharedDepositTypeSubtypeState as any, action: sharedDepositTypeSubtypeActionNameSpace as any, labelKey: "name", type: TypeInfoEnum.translate, - }, - { + }; + } + + if (isNonEmptyString(this.depositFormModel.type?.subSubtype)) { + this.infoSubSubType = { label: LabelTranslateEnum.subsubtype, value: this.depositFormModel.type?.subSubtype, state: SharedDepositSubSubtypeState as any, action: sharedDepositSubSubtypeActionNameSpace as any, labelKey: "name", type: TypeInfoEnum.translate, - }, - { - label: LabelTranslateEnum.language, - value: this.depositFormModel.description?.language, - state: SharedLanguageState, - action: sharedLanguageActionNameSpace, - labelKey: "labels", - type: TypeInfoEnum.translate, - isBackTranslate: true, - }, + }; + } + + this.abstracts = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.abstracts); + + this.authors = this.getAuthors(this.depositFormModel?.contributors?.contributors) + .map(a => a.values.join(" | ")) + .join(" | "); + this.keywords = this.depositFormModel?.description?.keywords?.join(" | "); + + this.listInfoMains = [ + ...this.getOriginalTitle(), { - label: LabelTranslateEnum.keywords, - values: this.depositFormModel.description?.keywords, + label: LabelTranslateEnum.academicStructures, + values: this.depositFormModel?.description?.academicStructures?.map(c => (isNonEmptyString(c.name) ? c.name + " " : "") + (isNonEmptyString(c.code) ? "(" + c.code + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), type: TypeInfoEnum.list, }, { - label: LabelTranslateEnum.mandator, - value: this.depositFormModel.description?.mandator, - }, - { - label: LabelTranslateEnum.note, - value: this.depositFormModel.description?.note, - }, - { - label: LabelTranslateEnum.collection, - value: this.depositFormModel.description?.aouCollection, - }, - { - label: LabelTranslateEnum.awards, - value: this.depositFormModel.description?.awards, - }, - { - label: LabelTranslateEnum.edition, - value: this.depositFormModel.description?.edition, - }, - { - label: LabelTranslateEnum.discipline, - value: this.depositFormModel.description?.discipline, - }, - { - label: LabelTranslateEnum.url, - value: this.depositFormModel.description?.publisherVersionUrl, - }, - { - label: LabelTranslateEnum.pages, - valuesInfo: [ - { - label: LabelTranslateEnum.start, - value: this.depositFormModel.description?.pages?.start, - }, - { - label: LabelTranslateEnum.end, - value: this.depositFormModel.description?.pages?.end, - }, - { - label: LabelTranslateEnum.other, - value: this.depositFormModel.description?.pages?.other, - }, - ], - type: TypeInfoEnum.listInfo, - }, - { - label: LabelTranslateEnum.publisher, - valuesInfo: [ - { - label: LabelTranslateEnum.nameLabel, - value: this.depositFormModel.description?.publisher?.name, - }, - { - label: LabelTranslateEnum.place, - value: this.depositFormModel.description?.publisher?.place, - }, - ], - type: TypeInfoEnum.listInfo, - }, - { - label: LabelTranslateEnum.identifier, - valuesInfo: [ - { - label: LabelTranslateEnum.pmid, - values: this.depositFormModel.description?.identifiers?.dois.map(d => d.doi), - type: TypeInfoEnum.listInfo, - }, - { - label: LabelTranslateEnum.pmid, - value: this.depositFormModel.description?.identifiers?.pmid, - }, - { - label: LabelTranslateEnum.isbn, - value: this.depositFormModel.description?.identifiers?.isbn, - }, - { - label: LabelTranslateEnum.arxiv, - value: this.depositFormModel.description?.identifiers?.arxiv, - }, - { - label: LabelTranslateEnum.rero, - value: this.depositFormModel.description?.identifiers?.rero, - }, - { - label: LabelTranslateEnum.repec, - value: this.depositFormModel.description?.identifiers?.repec, - }, - { - label: LabelTranslateEnum.dblp, - value: this.depositFormModel.description?.identifiers?.dblp, - }, - { - label: LabelTranslateEnum.urn, - value: this.depositFormModel.description?.identifiers?.urn, - }, - { - label: LabelTranslateEnum.localNumber, - value: this.depositFormModel.description?.identifiers?.localNumber, - }, - ], - type: TypeInfoEnum.listInfo, - }, - { - label: LabelTranslateEnum.container, - valuesInfo: [ - { - label: LabelTranslateEnum.title, - value: this.depositFormModel.description?.container?.title?.text, - language: this.depositFormModel.description?.container?.title?.lang, - }, - { - label: LabelTranslateEnum.language, - value: this.depositFormModel.description?.container?.title?.lang, - }, - { - label: LabelTranslateEnum.isbn, - value: this.depositFormModel.description?.container?.identifiers?.isbn, - }, - { - label: LabelTranslateEnum.issn, - value: this.depositFormModel.description?.container?.identifiers?.issn, - }, - { - label: LabelTranslateEnum.dois, - values: this.depositFormModel.description?.container?.identifiers?.dois?.map(d => d.doi), - type: TypeInfoEnum.list, - }, - { - label: LabelTranslateEnum.volume, - value: this.depositFormModel.description?.container?.volume + "", - }, - { - label: LabelTranslateEnum.place, - value: this.depositFormModel.description?.container?.place, - }, - { - label: LabelTranslateEnum.conferenceDate, - value: isNullOrUndefined(this.depositFormModel.description?.container?.conferenceDate) || isEmptyString(this.depositFormModel.description?.container?.conferenceDate) - ? undefined : DateUtil.convertDateToDateString(this.depositFormModel.description?.container?.conferenceDate as any), - }, - { - label: LabelTranslateEnum.editor, - value: this.depositFormModel.description?.container?.editor, - }, - { - label: LabelTranslateEnum.issue, - value: this.depositFormModel.description?.container?.issue + "", - }, - { - label: LabelTranslateEnum.specialIssue, - value: this.depositFormModel.description?.container?.specialIssue, - }, - ], - type: TypeInfoEnum.listInfo, - }, - { - label: LabelTranslateEnum.academicStructures, - values: this.depositFormModel.description?.academicStructures?.map(a => a.name + " (" + a.code + ")"), + label: LabelTranslateEnum.groups, + values: this.depositFormModel?.description?.groups?.map(c => (isNonEmptyString(c.name) ? c.name + " " : "") + (isNonEmptyString(c.code) ? "(" + c.code + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), type: TypeInfoEnum.list, }, - ...this.getAbstracts(this.depositFormModel.description?.abstracts), { label: LabelTranslateEnum.contributors, - values: (this._depositFormModel?.contributors?.contributors ? this._depositFormModel.contributors.contributors : []).map(c => { + value: (this.depositFormModel?.contributors?.contributors ? this.depositFormModel.contributors.contributors : []).map(c => { if (isNotNullNorUndefined(c.collaboration)) { return c.collaboration.name; } if (isNotNullNorUndefined(c.contributor)) { return c.contributor.lastname + ", " + c.contributor.firstname; } - }), - type: TypeInfoEnum.list, + }).join(" | "), + type: TypeInfoEnum.value, + wrap: true, }, { label: LabelTranslateEnum.enteringMembersOfTheCollaboration, value: this.depositFormModel?.contributors?.isCollaboration ? LabelTranslateEnum.yes : LabelTranslateEnum.no, type: TypeInfoEnum.translate, }, - { - label: LabelTranslateEnum.dataset, - link: { - name: this.depositFormModel?.description?.dataset?.doi, - url: this._addHttpSuffixIfMissing(this.depositFormModel?.description?.dataset?.url), - }, - type: TypeInfoEnum.link, - }, - // { - // labelToTranslate: LabelTranslateEnum.contributors, - // value: isNotNullNorUndefined(this.depositFormModel?.contributors?.collaborations) ? this.depositFormModel.contributors.collaborations?.join(", ") : SOLIDIFY_CONSTANTS.STRING_EMPTY, - // }, { label: LabelTranslateEnum.unigeAffiliation, value: this.depositFormModel?.contributors?.isUnige ? LabelTranslateEnum.yes : LabelTranslateEnum.no, @@ -356,76 +190,91 @@ export class DepositSummaryPresentational extends AbstractPresentational impleme { label: LabelTranslateEnum.links, // tslint:disable-next-line:arrow-return-shorthand - links: this.depositFormModel.description?.links?.map(linkGroup => { + links: this.depositFormModel?.description?.links?.map(linkGroup => { return { url: this._addHttpSuffixIfMissing(linkGroup?.target), - name: linkGroup?.description?.text, - language: linkGroup?.description?.lang, - } as LinkInfo; + text: linkGroup?.description?.text, + lang: linkGroup?.description?.lang, + } as DepositSummaryLinkInfo; }), type: TypeInfoEnum.listLink, }, + ...this.getDirectors(this.depositFormModel?.contributors?.contributors), + ...this.getCollaboration(this.depositFormModel?.contributors?.contributors), + ...this.getEditor(this.depositFormModel?.contributors?.contributors), + ...this.getGuestEditor(this.depositFormModel?.contributors?.contributors), + ...this.getPhotographer(this.depositFormModel?.contributors?.contributors), + ...this.getTranslator(this.depositFormModel?.contributors?.contributors), + ...this.getCollaborationMembers(this.depositFormModel?.contributors?.contributors), + ...this.getDate(this.depositFormModel?.description?.dates), { label: LabelTranslateEnum.citations, // tslint:disable-next-line:arrow-return-shorthand - valuesLanguage: this._depositFormModel?.description?.citations?.map(c => { + valuesLanguage: this.depositFormModel?.description?.citations?.map(c => { return { text: c.text, - language: c.lang, - } as ValueLanguage; + lang: c.lang, + } as DepositSummaryValueLanguage; }), type: TypeInfoEnum.listLanguage, }, + ...this.getFundingsLists(this.depositFormModel?.description?.fundings), + // { + // label: LabelTranslateEnum.language, + // value: this.depositFormModel?.description?.language, + // state: SharedLanguageState, + // action: sharedLanguageActionNameSpace, + // labelKey: "labels", + // type: TypeInfoEnum.translate, + // isBackTranslate: true, + // }, { - label: LabelTranslateEnum.groups, - values: this._depositFormModel?.description?.groups?.map(c => (isNonEmptyString(c.name) ? c.name + " " : "") + (isNonEmptyString(c.code) ? "(" + c.code + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), - type: TypeInfoEnum.list, + label: LabelTranslateEnum.mandator, + value: this.depositFormModel?.description?.mandator, }, { - label: LabelTranslateEnum.academicStructures, - values: this._depositFormModel?.description?.academicStructures?.map(c => (isNonEmptyString(c.name) ? c.name + " " : "") + (isNonEmptyString(c.code) ? "(" + c.code + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), - type: TypeInfoEnum.list, + label: LabelTranslateEnum.note, + value: this.depositFormModel?.description?.note, + }, + { + label: LabelTranslateEnum.collection, + value: this.depositFormModel?.description?.aouCollection, + }, + { + label: LabelTranslateEnum.awards, + value: this.depositFormModel?.description?.awards, + }, + { + label: LabelTranslateEnum.edition, + value: this.depositFormModel?.description?.edition, }, + { + label: LabelTranslateEnum.discipline, + value: this.depositFormModel?.description?.discipline, + }, + ...this.getUrl(), + ...this.getPages(), + ...this.getPublisher(), + ...this.getIdentifier(), + ...this.getContainer(), + // { + // labelToTranslate: LabelTranslateEnum.contributors, + // value: isNotNullNorUndefined(this.depositFormModel?.contributors?.collaborations) ? this.depositFormModel.contributors.collaborations?.join(", ") : SOLIDIFY_CONSTANTS.STRING_EMPTY, + // }, + ...this.getDataset(), { label: LabelTranslateEnum.collections, - values: this._depositFormModel?.description?.collections?.map(c => (isNonEmptyString(c.name) ? c.name + " " : "") + (isNonEmptyString(c.number) ? "(" + c.number + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), + values: this.depositFormModel?.description?.collections?.map(c => (isNonEmptyString(c.name) ? c.name + " " : "") + (isNonEmptyString(c.number) ? "(" + c.number + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), type: TypeInfoEnum.list, }, { label: LabelTranslateEnum.classifications, - values: this._depositFormModel?.description?.classifications?.map(c => (isNonEmptyString(c.item) ? c.item + " " : "") + (isNonEmptyString(c.code) ? "(" + c.code + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), + values: this.depositFormModel?.description?.classifications?.map(c => (isNonEmptyString(c.item) ? c.item + " " : "") + (isNonEmptyString(c.code) ? "(" + c.code + ")" : SOLIDIFY_CONSTANTS.STRING_EMPTY)), type: TypeInfoEnum.list, }, - ...this.getAuthors(this._depositFormModel?.contributors?.contributors), - ...this.getDirectors(this._depositFormModel?.contributors?.contributors), - ...this.getCollaboration(this._depositFormModel?.contributors?.contributors), - ...this.getEditor(this._depositFormModel?.contributors?.contributors), - ...this.getGuestEditor(this._depositFormModel?.contributors?.contributors), - ...this.getPhotographer(this._depositFormModel?.contributors?.contributors), - ...this.getTranslator(this._depositFormModel?.contributors?.contributors), - ...this.getCollaborationMembers(this._depositFormModel?.contributors?.contributors), - ...this.getDate(this._depositFormModel?.description?.dates), - ...this.getFundingsLists(this._depositFormModel?.description?.fundings), ]; } - private getAbstracts(abstracts?: DepositFormText[]): Info[] { - if (isNullOrUndefined(abstracts)) { - return []; - } - const listInfo: Info[] = []; - abstracts.forEach(a => { - listInfo.push({ - label: LabelTranslateEnum.abstract, - value: a.text, - type: TypeInfoEnum.value, - language: a.lang, - isTextarea: true, - }); - }); - return listInfo; - } - private getCollaboration(contributors: DepositFormAbstractContributor[]): Info[] { contributors = contributors?.filter(c => isNotNullNorUndefined(c.collaboration)); if (isNullOrUndefined(contributors) || isEmptyArray(contributors)) { @@ -554,6 +403,239 @@ export class DepositSummaryPresentational extends AbstractPresentational impleme } return url.startsWith("https://") || url.startsWith("http://") ? url : "http://" + url; } + + private getOriginalTitle(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.originalTitle)) { + return []; + } + + const originalTitle = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.originalTitle); + if (isNullOrUndefined(originalTitle)) { + return []; + } + + return [{ + label: LabelTranslateEnum.originalTitle, + valuesLanguage: [ + { + text: originalTitle.text, + lang: originalTitle.lang, + }, + ], + type: TypeInfoEnum.listLanguage, + }]; + } + + private getPages(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.pages)) { + return []; + } + + const pages = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.pages); + if (isNullOrUndefined(pages)) { + return []; + } + + return [{ + label: LabelTranslateEnum.pages, + valuesInfo: [ + { + label: LabelTranslateEnum.start, + value: pages.start, + }, + { + label: LabelTranslateEnum.end, + value: pages.end, + }, + { + label: LabelTranslateEnum.other, + value: pages.other, + }, + ], + type: TypeInfoEnum.listInfo, + }]; + } + + private getPublisher(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.publisher)) { + return []; + } + + const publisher = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.publisher); + if (isNullOrUndefined(publisher)) { + return []; + } + + return [{ + label: LabelTranslateEnum.publisher, + valuesInfo: [ + { + label: LabelTranslateEnum.nameLabel, + value: publisher.name, + }, + { + label: LabelTranslateEnum.place, + value: publisher.place, + }, + ], + type: TypeInfoEnum.listInfo, + }]; + } + + private getIdentifier(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.identifiers)) { + return []; + } + + const identifiers = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.identifiers); + if (isNullOrUndefined(identifiers)) { + return []; + } + + return [{ + label: LabelTranslateEnum.identifier, + valuesInfo: [ + { + label: LabelTranslateEnum.pmid, + values: identifiers.dois.map(d => d.doi), + type: TypeInfoEnum.listInfo, + }, + { + label: LabelTranslateEnum.pmid, + value: identifiers.pmid, + }, + { + label: LabelTranslateEnum.isbn, + value: identifiers.isbn, + }, + { + label: LabelTranslateEnum.arxiv, + value: identifiers.arxiv, + }, + { + label: LabelTranslateEnum.rero, + value: identifiers.rero, + }, + { + label: LabelTranslateEnum.repec, + value: identifiers.repec, + }, + { + label: LabelTranslateEnum.dblp, + value: identifiers.dblp, + }, + { + label: LabelTranslateEnum.urn, + value: identifiers.urn, + }, + { + label: LabelTranslateEnum.localNumber, + value: identifiers.localNumber, + }, + ], + type: TypeInfoEnum.listInfo, + }]; + } + + private getContainer(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.container)) { + return []; + } + + const container = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.container); + if (isNullOrUndefined(container)) { + return []; + } + + return [{ + label: LabelTranslateEnum.container, + valuesInfo: [ + { + label: LabelTranslateEnum.title, + value: container.title?.text, + lang: container.title?.lang, + }, + { + label: LabelTranslateEnum.language, + value: container.title?.lang, + }, + { + label: LabelTranslateEnum.isbn, + value: container.identifiers?.isbn, + }, + { + label: LabelTranslateEnum.issn, + value: container.identifiers?.issn, + }, + { + label: LabelTranslateEnum.dois, + values: container.identifiers?.dois?.map(d => d.doi), + type: TypeInfoEnum.list, + }, + { + label: LabelTranslateEnum.volume, + value: container.volume + "", + }, + { + label: LabelTranslateEnum.place, + value: container.place, + }, + { + label: LabelTranslateEnum.conferenceDate, + value: isNullOrUndefined(container.conferenceDate) || isEmptyString(container.conferenceDate) + ? undefined : DateUtil.convertDateToDateString(container.conferenceDate as any), + }, + { + label: LabelTranslateEnum.editor, + value: container.editor, + }, + { + label: LabelTranslateEnum.issue, + value: container.issue + "", + }, + { + label: LabelTranslateEnum.specialIssue, + value: container.specialIssue, + }, + ], + type: TypeInfoEnum.listInfo, + }]; + } + + private getUrl(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.publisherVersionUrl) || isEmptyString(this.depositFormModel?.description?.publisherVersionUrl)) { + return []; + } + + return [{ + label: LabelTranslateEnum.url, + link: { + text: this.depositFormModel?.description?.publisherVersionUrl, + url: this._addHttpSuffixIfMissing(this.depositFormModel?.description?.publisherVersionUrl), + }, + type: TypeInfoEnum.link, + }]; + } + + private getDataset(): Info[] { + if (isNullOrUndefined(this.depositFormModel?.description?.dataset)) { + return []; + } + + const dataset = AouObjectUtil.cleanEmptyAttributes(this.depositFormModel?.description?.dataset); + if (isNullOrUndefined(dataset)) { + return []; + } + + return [{ + label: LabelTranslateEnum.dataset, + link: { + text: dataset.doi, + url: this._addHttpSuffixIfMissing(dataset.url), + }, + type: TypeInfoEnum.link, + }]; + } } interface Info { @@ -561,18 +643,18 @@ interface Info { translateLabel?: boolean; value?: string | Date; values?: string[]; - valuesLanguage?: ValueLanguage[]; + valuesLanguage?: DepositSummaryValueLanguage[]; valuesInfo?: Info[]; type?: TypeInfoEnum; - link?: LinkInfo; - links?: LinkInfo[]; + link?: DepositSummaryLinkInfo; + links?: DepositSummaryLinkInfo[]; labelListEnumTranslation?: KeyValue[]; - language?: string; - isTextarea?: boolean; + lang?: string; state?: Type<ResourceState<any, any>>; action?: ResourceNameSpace; labelKey?: string; isBackTranslate?: boolean; + wrap?: boolean; } enum TypeInfoEnum { @@ -585,13 +667,13 @@ enum TypeInfoEnum { listLink, } -interface LinkInfo { - name: string; +export interface DepositSummaryLinkInfo { + text: string; url: string; - language?: string; + lang?: string; } -interface ValueLanguage { +export interface DepositSummaryValueLanguage { text: string; - language: string; + lang: string; } diff --git a/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts b/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts index 61a617024..d933e3976 100644 --- a/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts +++ b/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts @@ -53,6 +53,8 @@ import {StoreDialogService} from "@shared/services/store-dialog.service"; import {SharedDepositTypeState} from "@shared/stores/deposit-type/shared-deposit-type.state"; import {SharedDepositTypeSubtypeAction} from "@shared/stores/deposit-type/subtype/shared-deposit-type-subtype.action"; import {SharedDepositTypeSubtypeState} from "@shared/stores/deposit-type/subtype/shared-deposit-type-subtype.state"; +import {SharedDepositSubSubtypeAction} from "@shared/stores/deposit-type/subtype/sub-subtype/shared-deposit-sub-subtype.action"; +import {AouObjectUtil} from "@shared/utils/aou-object.util"; import {Observable} from "rxjs"; import { distinctUntilChanged, @@ -68,6 +70,7 @@ import { ConfirmDialogData, DeleteDialog, ExtraButtonToolbar, + isNonEmptyString, isEmptyString, isFalse, isNotNullNorUndefined, @@ -121,7 +124,11 @@ export class DepositDetailRoutable extends AbstractRoutable implements OnInit, O _resId: string | undefined; depositFormModelObs: Observable<DepositFormModel> = MemoizedUtil.current(this._store, DepositState).pipe( - map(deposit => isNullOrUndefined(deposit) ? undefined : JSON.parse(deposit.formData)), + distinctUntilChanged(), + map(deposit => { + const formData = isNullOrUndefined(deposit) ? undefined : JSON.parse(deposit.formData); + return AouObjectUtil.cleanEmptyAttributes(formData); + }), ); depositStatusObs: Observable<Enums.Deposit.StatusEnum> = MemoizedUtil.select(this._store, DepositState, state => state?.current?.status); urlQueryParameters: MappingObject<string | undefined>; @@ -205,6 +212,16 @@ export class DepositDetailRoutable extends AbstractRoutable implements OnInit, O this._store.dispatch(new DepositDocumentFileAction.GetAll(this._resId)); this._store.dispatch(new DepositAction.LoadResource(false)); const currentDepositInState = MemoizedUtil.currentSnapshot(this._store, DepositState); + + if (!this.isEdit) { + if (isNonEmptyString(currentDepositInState.subtype?.type?.resId)) { + this._store.dispatch(new SharedDepositTypeSubtypeAction.GetAll(currentDepositInState.subtype?.type?.resId)); + } + if (isNonEmptyString(currentDepositInState.subtype?.resId)) { + this._store.dispatch(new SharedDepositSubSubtypeAction.GetAll(currentDepositInState.subtype?.resId)); + } + } + if (!this.isEdit && currentDepositInState?.resId !== this._resId) { this._store.dispatch(new DepositAction.GetById(this._resId)); } diff --git a/src/app/features/deposit/deposit.module.ts b/src/app/features/deposit/deposit.module.ts index 996ab8136..24054f411 100644 --- a/src/app/features/deposit/deposit.module.ts +++ b/src/app/features/deposit/deposit.module.ts @@ -2,6 +2,7 @@ import {NgModule} from "@angular/core"; import {DepositDocumentFileContainer} from "@app/features/deposit/components/containers/deposit-document-file/deposit-document-file.container"; import {DepositTableContributorContainer} from "@app/features/deposit/components/containers/deposit-table-contributor/deposit-table-contributor.container"; import {DepositDocumentFileUploadDialog} from "@app/features/deposit/components/dialogs/deposit-document-file-upload/deposit-document-file-upload.dialog"; +import {DepositContainerPresentational} from "@app/features/deposit/components/presentationals/deposit-container/deposit-container.presentational"; import {ValidationStructureDialog} from "@app/features/deposit/components/dialogs/validation-structure/validation-structure.dialog"; import {DepositCommentFormPresentational} from "@app/features/deposit/components/presentationals/deposit-comment-form/deposit-comment-form.presentational"; import {DepositDocumentFileUploadingPresentational} from "@app/features/deposit/components/presentationals/deposit-document-file-uploading/deposit-document-file-uploading.presentational"; @@ -79,6 +80,7 @@ const presentationals = [ DepositFormDescriptionPagePresentational, DepositFormDescriptionDatePresentational, DepositFormDescriptionDoisPresentational, + DepositContainerPresentational, ]; @NgModule({ diff --git a/src/app/models/index.ts b/src/app/models/index.ts index 1ef13d5ec..48c9562dd 100644 --- a/src/app/models/index.ts +++ b/src/app/models/index.ts @@ -180,13 +180,13 @@ export interface Role extends RolePartial, BaseResource { } export interface Structure extends BaseResource { - name?: string; - status?: Enums.Structure.StatusEnum; - cnStructC?: string; - cStruct?: string; - dewey?: string; - validUntil?: string; - parentStructure?: Structure; + name: string; + status: Enums.Structure.StatusEnum; + cnStructC: string; + cStruct: string; + dewey: string; + validUntil: string; + parentStructure: Structure; sortValue?: number; } diff --git a/src/app/shared/stores/structure/shared-structure.state.ts b/src/app/shared/stores/structure/shared-structure.state.ts index d888f61f5..e49e7b9ac 100644 --- a/src/app/shared/stores/structure/shared-structure.state.ts +++ b/src/app/shared/stores/structure/shared-structure.state.ts @@ -1,5 +1,6 @@ import {Injectable} from "@angular/core"; import {ApiEnum} from "@app/shared/enums/api.enum"; +import {StateEnum} from "../../enums/state.enum"; import {Structure} from "@models"; import { Actions, @@ -12,14 +13,12 @@ import { ApiService, defaultResourceStateInitValue, NotificationService, - OrderEnum, QueryParameters, ResourceState, ResourceStateModel, StoreUtil, } from "solidify-frontend"; import {environment} from "../../../../environments/environment"; -import {StateEnum} from "../../enums/state.enum"; export interface SharedStructureStateModel extends ResourceStateModel<Structure> { } @@ -29,10 +28,7 @@ export interface SharedStructureStateModel extends ResourceStateModel<Structure> name: StateEnum.shared_structure, defaults: { ...defaultResourceStateInitValue(), - queryParameters: new QueryParameters(environment.defaultEnumValuePageSizeOption, { - field: "sortValue", - order: OrderEnum.ascending, - }), + queryParameters: new QueryParameters(environment.defaultEnumValuePageSizeOption), }, }) export class SharedStructureState extends ResourceState<SharedStructureStateModel, Structure> { diff --git a/src/app/shared/utils/aou-object.util.ts b/src/app/shared/utils/aou-object.util.ts new file mode 100644 index 000000000..d3ef74528 --- /dev/null +++ b/src/app/shared/utils/aou-object.util.ts @@ -0,0 +1,29 @@ +import { + isEmptyArray, + isEmptyString, + isNullOrUndefined, + isObject, + MappingObjectUtil, +} from "solidify-frontend"; + +export class AouObjectUtil { + static cleanEmptyAttributes<T>(object: T): T | undefined { + const identifiers = {}; + MappingObjectUtil.forEach(object as any, (value, key) => { + if (isNullOrUndefined(value) || isEmptyString(value) || isEmptyArray(value)) { + return; + } + if (isObject(value)) { + value = this.cleanEmptyAttributes(value); + if (isNullOrUndefined(value)) { + return; + } + } + MappingObjectUtil.set(identifiers as any, key, value); + }); + if (MappingObjectUtil.size(identifiers) === 0) { + return undefined; + } + return identifiers as T; + } +} -- GitLab