Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 1.11-maintenance
  • 2.0-maintenance
  • 2.1-maintenance
  • 2.2-maintenance
  • DG-add-institutions-pres-space-orgunit-1432
  • DG/deposit__submission_dialog_dethreatening
  • DLCM-1510_refcator_cypress_tests
  • DLCM-2579_Change_wording_for_user_guide_in_French
  • HCA-PreviewDisseminationPolicy
  • adf-1341-contributor-actions
  • adf-1725-fill-requested-params-in-notifications
  • adf-1821-dip-message
  • adf-1823-research-areas-labels
  • adf-2258-logos-open-new-tab
  • adf-2425-upload-signed-dua-in-notification
  • adf-2480-tooltip-in-dua-logo
  • adf-2765-notification-approved
  • adf-archive-detail-grid-display
  • adf-contributor-tooltip
  • adf-delete-completed-enum-value-for-orders
  • adf-deposit-last-selection
  • adf-fix-institution
  • adf-metadata-type-form
  • bugfix-datepicker-change-locale
  • dlcm-2192-research-domain-not-saved-in_orgunit
  • dlcm-2499_Update_dua_type_to_data_use_policy_and_use_correct_enum
  • dlcm-2629_update_project_role_not_reflected
  • dlcm-2790_allow_root_to_change_preservation_policy
  • e2e-cypress-io-test
  • fpo/1809_allow_to_have_space_in_keyword
  • fpo/1914_clean_lib
  • fpo/2380_allow_manager_of_institution_to_edit_institution
  • fpo/2742_use-pnpm
  • fpo/William-ngxs-class-instead-of-interface
  • fpo/add-inline-option-for-thumbnail
  • fpo/add_server_solidify
  • fpo/allow_admin_to_create_achive_acl
  • fpo/angular-20
  • fpo/api_enum_refactor
  • fpo/backup/1960_avoid_call_on_contributor_avatar_when_missing_and_display_contributor_avatar
  • fpo/citations_in_archive
  • fpo/display_org_unit_logo_on_archive_detail
  • fpo/draft/2109_see_if_possible_to_log_where_ngxs_aciton_is_displatched_to_better_debugging
  • fpo/draft/watch_on_html_and_css_file_from_solidify
  • fpo/enable_ssr
  • fpo/migrate_to_angular_15
  • fpo/optimise_perf_ssr
  • fpo/refacto_use_button_upload_file_everywhere
  • fpo/rename_resource_logo_into_resource_file
  • fpo/run_tour_not_first_time_cookie
  • fpo/sequential_upload
  • fpo/share_ssr_cache_between_root_and_home
  • fpo/solidify-2
  • fpo/ssr-worker
  • fpo/test
  • fpo/test-hook
  • fpo/use-vite
  • fpo/use_new_component_on_solidify
  • fpo/wip/remove_base_href
  • hbo-asciidoc
  • hbo-docker-agent
  • hbo-docker-agent-4.0.0
  • hbo-docker-test
  • hbo-test-docker-image
  • master
  • new-worker
  • rodn-2674-sort-by-issued-date
  • rodn-package-lock-linux
  • rodn-rename-research-domain-labels
  • rodn-solidify-index-update
  • rodn-wip-job-line-links
  • wa/All_Libraries_Upgrade
  • wa/Libraries_Upgrade
  • before-angular-11-12
  • dlcm-1.0.0
  • dlcm-1.10.0
  • dlcm-1.11.0
  • dlcm-1.12.0-rc1
  • dlcm-1.5.0
  • dlcm-1.6.0
  • dlcm-1.7.0
  • dlcm-1.8.0
  • dlcm-1.9.0
  • dlcm-2.0.0
  • dlcm-2.0.0-RC1
  • dlcm-2.0.0-RC2
  • dlcm-2.0.0-RC3
  • dlcm-2.0.1
  • dlcm-2.0.2
  • dlcm-2.0.3
  • dlcm-2.0.4
  • dlcm-2.0.5
  • dlcm-2.0.6
  • dlcm-2.0.7
  • dlcm-2.1.0
  • dlcm-2.1.0-RC1
  • dlcm-2.1.0-RC2
  • dlcm-2.1.0-RC3
  • dlcm-2.1.0-alpha1
  • dlcm-2.1.0-alpha2
  • dlcm-2.1.0-beta1
  • dlcm-2.1.1
  • dlcm-2.1.10
  • dlcm-2.1.11
  • dlcm-2.1.12
  • dlcm-2.1.13
  • dlcm-2.1.2
  • dlcm-2.1.3
  • dlcm-2.1.4
  • dlcm-2.1.5
  • dlcm-2.1.6
  • dlcm-2.1.7
  • dlcm-2.1.8
  • dlcm-2.1.9
  • dlcm-2.2.0
  • dlcm-2.2.0-RC1
  • dlcm-2.2.0-alpha1
  • dlcm-2.2.0-alpha2
  • dlcm-2.2.0-beta1
  • dlcm-2.2.0-beta2
  • dlcm-2.2.1
  • dlcm-2.2.10
  • dlcm-2.2.2
  • dlcm-2.2.3
  • dlcm-2.2.4
  • dlcm-2.2.5
  • dlcm-2.2.6
  • dlcm-2.2.7
  • dlcm-2.2.8
  • dlcm-2.2.9
  • dlcm-2.8.0-RC1
  • dlcm-2.8.0-beta1
  • dlcm-2.8.0-beta2
  • dlcm-3.0.0
  • dlcm-3.0.0-RC1
  • dlcm-3.0.0-RC2
  • dlcm-3.0.0-RC3
  • dlcm-3.0.0-beta1
  • dlcm-test-1
  • hbo-1.8.0
  • v0.0.0
141 results

Target

Select target project
  • dlcm/ui/dlcm-portal
1 result
Select Git revision
  • 1.11-maintenance
  • 2.0-maintenance
  • 2.1-maintenance
  • 2.2-maintenance
  • DG-add-institutions-pres-space-orgunit-1432
  • DG/deposit__submission_dialog_dethreatening
  • DLCM-1510_refcator_cypress_tests
  • DLCM-2579_Change_wording_for_user_guide_in_French
  • HCA-PreviewDisseminationPolicy
  • adf-1341-contributor-actions
  • adf-1725-fill-requested-params-in-notifications
  • adf-1821-dip-message
  • adf-1823-research-areas-labels
  • adf-2258-logos-open-new-tab
  • adf-2425-upload-signed-dua-in-notification
  • adf-2480-tooltip-in-dua-logo
  • adf-2765-notification-approved
  • adf-archive-detail-grid-display
  • adf-contributor-tooltip
  • adf-delete-completed-enum-value-for-orders
  • adf-deposit-last-selection
  • adf-fix-institution
  • adf-metadata-type-form
  • bugfix-datepicker-change-locale
  • dlcm-2192-research-domain-not-saved-in_orgunit
  • dlcm-2499_Update_dua_type_to_data_use_policy_and_use_correct_enum
  • dlcm-2629_update_project_role_not_reflected
  • dlcm-2790_allow_root_to_change_preservation_policy
  • e2e-cypress-io-test
  • fpo/1809_allow_to_have_space_in_keyword
  • fpo/1914_clean_lib
  • fpo/2380_allow_manager_of_institution_to_edit_institution
  • fpo/2742_use-pnpm
  • fpo/William-ngxs-class-instead-of-interface
  • fpo/add-inline-option-for-thumbnail
  • fpo/add_server_solidify
  • fpo/allow_admin_to_create_achive_acl
  • fpo/angular-20
  • fpo/api_enum_refactor
  • fpo/backup/1960_avoid_call_on_contributor_avatar_when_missing_and_display_contributor_avatar
  • fpo/citations_in_archive
  • fpo/display_org_unit_logo_on_archive_detail
  • fpo/draft/2109_see_if_possible_to_log_where_ngxs_aciton_is_displatched_to_better_debugging
  • fpo/draft/watch_on_html_and_css_file_from_solidify
  • fpo/enable_ssr
  • fpo/migrate_to_angular_15
  • fpo/optimise_perf_ssr
  • fpo/refacto_use_button_upload_file_everywhere
  • fpo/rename_resource_logo_into_resource_file
  • fpo/run_tour_not_first_time_cookie
  • fpo/sequential_upload
  • fpo/share_ssr_cache_between_root_and_home
  • fpo/solidify-2
  • fpo/ssr-worker
  • fpo/test
  • fpo/test-hook
  • fpo/use-vite
  • fpo/use_new_component_on_solidify
  • fpo/wip/remove_base_href
  • hbo-asciidoc
  • hbo-docker-agent
  • hbo-docker-agent-4.0.0
  • hbo-docker-test
  • hbo-test-docker-image
  • master
  • new-worker
  • rodn-2674-sort-by-issued-date
  • rodn-package-lock-linux
  • rodn-rename-research-domain-labels
  • rodn-solidify-index-update
  • rodn-wip-job-line-links
  • wa/All_Libraries_Upgrade
  • wa/Libraries_Upgrade
  • before-angular-11-12
  • dlcm-1.0.0
  • dlcm-1.10.0
  • dlcm-1.11.0
  • dlcm-1.12.0-rc1
  • dlcm-1.5.0
  • dlcm-1.6.0
  • dlcm-1.7.0
  • dlcm-1.8.0
  • dlcm-1.9.0
  • dlcm-2.0.0
  • dlcm-2.0.0-RC1
  • dlcm-2.0.0-RC2
  • dlcm-2.0.0-RC3
  • dlcm-2.0.1
  • dlcm-2.0.2
  • dlcm-2.0.3
  • dlcm-2.0.4
  • dlcm-2.0.5
  • dlcm-2.0.6
  • dlcm-2.0.7
  • dlcm-2.1.0
  • dlcm-2.1.0-RC1
  • dlcm-2.1.0-RC2
  • dlcm-2.1.0-RC3
  • dlcm-2.1.0-alpha1
  • dlcm-2.1.0-alpha2
  • dlcm-2.1.0-beta1
  • dlcm-2.1.1
  • dlcm-2.1.10
  • dlcm-2.1.11
  • dlcm-2.1.12
  • dlcm-2.1.13
  • dlcm-2.1.2
  • dlcm-2.1.3
  • dlcm-2.1.4
  • dlcm-2.1.5
  • dlcm-2.1.6
  • dlcm-2.1.7
  • dlcm-2.1.8
  • dlcm-2.1.9
  • dlcm-2.2.0
  • dlcm-2.2.0-RC1
  • dlcm-2.2.0-alpha1
  • dlcm-2.2.0-alpha2
  • dlcm-2.2.0-beta1
  • dlcm-2.2.0-beta2
  • dlcm-2.2.1
  • dlcm-2.2.10
  • dlcm-2.2.2
  • dlcm-2.2.3
  • dlcm-2.2.4
  • dlcm-2.2.5
  • dlcm-2.2.6
  • dlcm-2.2.7
  • dlcm-2.2.8
  • dlcm-2.2.9
  • dlcm-2.8.0-RC1
  • dlcm-2.8.0-beta1
  • dlcm-2.8.0-beta2
  • dlcm-3.0.0
  • dlcm-3.0.0-RC1
  • dlcm-3.0.0-RC2
  • dlcm-3.0.0-RC3
  • dlcm-3.0.0-beta1
  • dlcm-test-1
  • hbo-1.8.0
  • v0.0.0
141 results
Show changes
Commits on Source (8)
Showing
with 276 additions and 145 deletions
......@@ -53,7 +53,7 @@
"normalize.css": "8.0.1",
"patch-package": "6.4.7",
"rxjs": "7.5.2",
"solidify-frontend": "3.0.13",
"solidify-frontend": "3.0.15",
"tiff.js": "1.0.0",
"tslib": "2.3.1",
"videojs-wavesurfer": "3.8.0",
......@@ -19674,9 +19674,9 @@
}
},
"node_modules/solidify-frontend": {
"version": "3.0.13",
"resolved": "https://nexus.unige.ch/repository/npm-all/solidify-frontend/-/solidify-frontend-3.0.13.tgz",
"integrity": "sha512-6/crKKjFB1wkg9gO/Qkb6gF1i4JTTDyQ9CN3g21UIeGz/xxWCuTTNUEbS6ySN8X7Ip33WbCffeKVt4SZ1lvshw==",
"version": "3.0.15",
"resolved": "https://nexus.unige.ch/repository/npm-all/solidify-frontend/-/solidify-frontend-3.0.15.tgz",
"integrity": "sha512-pSK4NYD2TpAIQquBSCq76ogiR3TuAsNhODfBec0pw0VMqGM5Y97Jbi+vqw/E9KYtGsTRVMpZCSkrTe24Q4d3wQ==",
"license": "GPL-2.0-or-later",
"dependencies": {
"tslib": "^2.3.0"
......@@ -35891,9 +35891,9 @@
}
},
"solidify-frontend": {
"version": "3.0.13",
"resolved": "https://nexus.unige.ch/repository/npm-all/solidify-frontend/-/solidify-frontend-3.0.13.tgz",
"integrity": "sha512-6/crKKjFB1wkg9gO/Qkb6gF1i4JTTDyQ9CN3g21UIeGz/xxWCuTTNUEbS6ySN8X7Ip33WbCffeKVt4SZ1lvshw==",
"version": "3.0.15",
"resolved": "https://nexus.unige.ch/repository/npm-all/solidify-frontend/-/solidify-frontend-3.0.15.tgz",
"integrity": "sha512-pSK4NYD2TpAIQquBSCq76ogiR3TuAsNhODfBec0pw0VMqGM5Y97Jbi+vqw/E9KYtGsTRVMpZCSkrTe24Q4d3wQ==",
"requires": {
"tslib": "^2.3.0"
}
......@@ -97,7 +97,7 @@
"normalize.css": "8.0.1",
"patch-package": "6.4.7",
"rxjs": "7.5.2",
"solidify-frontend": "3.0.13",
"solidify-frontend": "3.0.15",
"tiff.js": "1.0.0",
"tslib": "2.3.1",
"videojs-wavesurfer": "3.8.0",
......
......@@ -158,7 +158,7 @@ export class AppComponent extends AbstractAppComponent {
}
private _checkOrcidQueryParam(): void {
if (UrlQueryParamHelper.contains(environment.orcidQueryParam)) {
if (UrlQueryParamHelper.currentUrlContainsQueryParam(environment.orcidQueryParam)) {
this.subscribe(this.currentUserObs.pipe(
filter(user => isNotNullNorUndefined(user)),
take(1),
......
......@@ -42,6 +42,10 @@
<solidify-language-selector [(language)]="language"></solidify-language-selector>
</li>
<li (click)="toggleDarkMode()">
<span>{{(darkMode ? labelTranslateEnum.lightMode : labelTranslateEnum.darkMode) | translate}}</span>
</li>
<ng-template [ngIfElse]="loggedOut"
[ngIf]="!logged"
>
......
......@@ -67,4 +67,8 @@ export class MainToolbarMobilePresentational extends AbstractMainToolbarPresenta
super.login();
this.toggleMenu();
}
toggleDarkMode(): void {
this.darkMode = !this.darkMode;
}
}
<solidify-base-action-dialog [titleToTranslate]="'deposit.aip.modal.title.main' | translate">
<h2>{{'deposit.aip.modal.title.search' | translate }}</h2>
<solidify-search-input (valueChange)="search($event)"
[appearance]="appearanceInputMaterial"
[labelToTranslate]="labelTranslateEnum.nameLabel"
[labelToTranslate]="labelTranslateEnum.search"
[placeholder]="labelTranslateEnum.nameLabel | translate"
[searchAutoFocus]="false"
[value]="searchObs | async"
class="search-bar"
>
</solidify-search-input>
<div [solidifySpinner]="(isLoadingObs | async)"
class="wrapper"
>
<ng-container *ngIf="getListAipToDisplay(listAipObs | async) as listAip">
<ng-template [ngIfElse]="noAip"
[ngIf]="listAip?.length > 0"
<div class="selected-aip">
<mat-label class="label">{{labelTranslateEnum.archivesSelected | translate}}</mat-label>
<mat-chip-list *ngIf="selectedAips.length > 0; else noSelection">
<mat-chip *ngFor="let aip of selectedAips; let i = index"
(removed)="removeAip(i)"
>
<ul>
<li *ngFor="let aip of listAip"
[class.selected]="checkIfSelected(aip.resId)"
class="aip-item"
>
<div (click)="addRemoveSelection(aip.resId)">
{{aip.info.name}}
</div>
</li>
</ul>
</ng-template>
<ng-template #noAip>
{{'deposit.aip.modal.noAipFound' | translate}}
</ng-template>
</ng-container>
{{aip.info.name}}
<solidify-icon [iconName]="iconNameEnum.closeChip"
matChipRemove
></solidify-icon>
</mat-chip>
</mat-chip-list>
<ng-template #noSelection>
<span class="no-selection">{{labelTranslateEnum.noSelection | translate}}</span>
</ng-template>
</div>
<solidify-data-table #dataTablePresentational
(queryParametersChange)="onQueryParametersEvent($event)"
[isClickable]="true"
[listHighlightingId]="selectedAipsId"
[columns]="columns"
[data]="listAipObs | async"
[isDraggable]="false"
[isLoading]="isLoadingObs | async"
[isMultiSelectable]="false"
(selectChange)="selectionChange($event)"
[preloadRowsForPage]="true"
[queryParameters]="queryParametersObs | async"
[displaySpinnerWhenLoading]="true"
[skipInitialQuery]="true"
[displayActionCopyIdToClipboard]="true"
>
</solidify-data-table>
<div class="footer"
mat-dialog-actions
>
......@@ -43,7 +54,7 @@
>{{labelTranslateEnum.close | translate}}
</button>
<button (click)="onSubmit()"
[disabled]="!form.valid || aipsToUpload.length === 0"
[disabled]="!form.valid || selectedAips.length === 0"
color="primary"
mat-flat-button
>{{labelTranslateEnum.confirm | translate}}
......
@import "abstracts/abstracts";
:host {
li {
&.aip-item {
background-color: $extra-light-grey;
margin: 0;
padding: 8px 10px;
cursor: pointer;
.selected-aip {
.label {
display: block;
margin-bottom: 10px;
}
&:nth-child(odd) {
background-color: $extra-ultra-light-grey;
}
&.selected {
background-color: $primary-color;
color: $white;
}
}
}
@include isInDarkMode {
li {
&.aip-item {
background-color: $dark-mode-background;
}
&:nth-child(odd) {
background-color: $dark-mode-toolbar;
}
&.selected {
background-color: $primary-color;
.no-selection {
color: $light-grey;
font-size: 13px;
}
}
}
......@@ -37,16 +37,27 @@ import {
} from "@angular/material/dialog";
import {DepositAipAction} from "@deposit/stores/aip/deposit-aip.action";
import {DepositAipState} from "@deposit/stores/aip/deposit-aip.state";
import {Enums} from "@enums";
import {ArchiveDataFile} from "@home/models/archive-data-file.model";
import {Aip} from "@models";
import {Store} from "@ngxs/store";
import {SharedAbstractDialog} from "@shared/components/dialogs/shared-abstract/shared-abstract.dialog";
import {DataTableComponentEnum} from "@shared/enums/data-table-component.enum";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {AppRoutesEnum} from "@shared/enums/routes.enum";
import {DataTableComponentHelper} from "@shared/helpers/data-table-component.helper";
import {BaseFormDefinition} from "@shared/models/base-form-definition.model";
import {Observable} from "rxjs";
import {map} from "rxjs/operators";
import {
DataTableColumns,
DataTableFieldTypeEnum,
isEmptyArray,
isNullOrUndefined,
MappingObject,
MappingObjectUtil,
MemoizedUtil,
OrderEnum,
PropertyName,
QueryParameters,
} from "solidify-frontend";
......@@ -61,13 +72,87 @@ export class DepositAipUploadDialog extends SharedAbstractDialog<DepositAipUploa
form: FormGroup;
formDefinition: DepositAipUploadFormComponentFormDefinition = new DepositAipUploadFormComponentFormDefinition();
listAipObs: Observable<Aip[]> = MemoizedUtil.list(this._store, DepositAipState);
listAipObs: Observable<Aip[]> = MemoizedUtil.list(this._store, DepositAipState).pipe(
map(list => {
const listIdAipAlreadyLinked = this.data.listIdAipAlreadyLinked;
if (isNullOrUndefined(list) || isEmptyArray(list) || isNullOrUndefined(listIdAipAlreadyLinked) || isEmptyArray(listIdAipAlreadyLinked)) {
return list;
}
return list.filter(aip => !listIdAipAlreadyLinked.includes(aip.resId));
}),
);
queryParametersObs: Observable<QueryParameters> = MemoizedUtil.queryParameters(this._store, DepositAipState);
isLoadingObs: Observable<boolean> = MemoizedUtil.isLoading(this._store, DepositAipState);
aipsToUpload: string[] = [];
selectedAips: Aip[] = [];
get selectedAipsId(): string[] {
return this.selectedAips.map(a => a.resId);
}
searchObs: Observable<string>;
columns: DataTableColumns<ArchiveDataFile>[] = [
{
field: "info.name",
header: LabelTranslateEnum.title,
type: DataTableFieldTypeEnum.string,
order: OrderEnum.ascending,
isSortable: false,
isFilterable: false,
},
{
field: "info.access",
header: LabelTranslateEnum.accessLevel,
type: DataTableFieldTypeEnum.singleSelect,
order: OrderEnum.none,
isSortable: false,
isFilterable: false,
translate: true,
filterEnum: Enums.Deposit.AccessEnumTranslate,
component: DataTableComponentHelper.get(DataTableComponentEnum.accessLevelWithEmbargo),
width: "180px",
},
{
field: "info.dataSensitivity",
header: LabelTranslateEnum.sensitivity,
type: DataTableFieldTypeEnum.singleSelect,
order: OrderEnum.none,
isSortable: false,
isFilterable: false,
translate: true,
filterEnum: Enums.Deposit.DataSensitivityEnumTranslate,
component: DataTableComponentHelper.get(DataTableComponentEnum.sensitivity),
width: "60px",
},
{
field: "info.complianceLevel",
header: LabelTranslateEnum.complianceLevel,
type: DataTableFieldTypeEnum.singleSelect,
order: OrderEnum.none,
sortableField: "dataFile.complianceLevel" as any,
filterableField: "dataFile.complianceLevel" as any,
isSortable: false,
isFilterable: false,
translate: true,
width: "185px",
component: DataTableComponentHelper.get(DataTableComponentEnum.conformityLevelStar),
filterEnum: Enums.DataFile.ComplianceLevelEnumTranslate,
},
{
field: "smartSize",
header: LabelTranslateEnum.size,
type: DataTableFieldTypeEnum.string,
order: OrderEnum.none,
sortableField: "dataFile.fileSize" as any,
filterableField: "dataFile.fileSize" as any,
isSortable: false,
isFilterable: false,
translate: true,
width: "100px",
},
];
constructor(protected readonly _store: Store,
protected readonly _dialogRef: MatDialogRef<DepositAipUploadDialog>,
@Inject(MAT_DIALOG_DATA) public readonly data: DepositAipUploadDialogData,
......@@ -86,13 +171,13 @@ export class DepositAipUploadDialog extends SharedAbstractDialog<DepositAipUploa
search(searchTerm: string, queryParameters?: QueryParameters): void {
if (searchTerm !== "") {
const map = new Map<string, string>();
map.set("info.name", searchTerm);
const searchItems: MappingObject<string> = {};
MappingObjectUtil.set(searchItems, "info.name", searchTerm);
const orgUnitId = this._store.selectSnapshot(state => state.router.state.root.children[0].children[0].params[AppRoutesEnum.paramIdOrgUnitWithoutPrefixParam]);
map.set("info.organizationalUnitId", orgUnitId);
MappingObjectUtil.set(searchItems, "info.organizationalUnitId", orgUnitId);
const newQueryParameters = new QueryParameters();
newQueryParameters.search = {
searchItems: map,
searchItems: searchItems,
};
this._store.dispatch(new DepositAipAction.ChangeQueryParameters(newQueryParameters, true));
} else {
......@@ -100,29 +185,25 @@ export class DepositAipUploadDialog extends SharedAbstractDialog<DepositAipUploa
}
}
onSubmit(): void {
this.submit(this.aipsToUpload);
onQueryParametersEvent(queryParameters: QueryParameters): void {
this._store.dispatch(new DepositAipAction.ChangeQueryParameters(queryParameters));
}
checkIfSelected(aipId: string): boolean {
return this.aipsToUpload.includes(aipId);
onSubmit(): void {
this.submit(this.selectedAipsId);
}
addRemoveSelection(aipId: string): void {
if (this.aipsToUpload.includes(aipId)) {
const index: number = this.aipsToUpload.indexOf(aipId);
this.aipsToUpload.splice(index, 1);
selectionChange(aip: Aip): void {
const indexOf = this.selectedAips.findIndex(a => a.resId === aip.resId);
if (indexOf !== -1) {
this.removeAip(indexOf);
} else {
this.aipsToUpload.push(aipId);
this.selectedAips.push(aip);
}
}
getListAipToDisplay(list: Aip[]): Aip[] {
const listIdAipAlreadyLinked = this.data.listIdAipAlreadyLinked;
if (isNullOrUndefined(list) || isEmptyArray(list) || isNullOrUndefined(listIdAipAlreadyLinked) || isEmptyArray(listIdAipAlreadyLinked)) {
return list;
}
return list.filter(aip => !listIdAipAlreadyLinked.includes(aip.resId));
removeAip(index: number): void {
this.selectedAips.splice(index, 1);
}
}
......
@import "src/sass/abstracts/abstracts";
@import "abstracts/abstracts";
:host {
.list {
.author {
background-color: $white;
background-color: $white !important;
cursor: move;
&:nth-child(odd) {
......@@ -43,6 +43,7 @@
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
background-color: $white !important;
color: $text-color;
.buttons {
visibility: hidden;
......@@ -67,3 +68,17 @@
visibility: hidden;
}
}
@include isInDarkMode {
:host {
.list {
.author {
background-color: $dark-mode-background !important;
&:nth-child(odd) {
background-color: $dark-mode-menu-active !important;
}
}
}
}
}
......@@ -259,8 +259,8 @@ export class DepositDetailEditRoutable extends AbstractDetailEditRoutable<Deposi
icon: IconNameEnum.edit,
displayCondition: current => isNotNullNorUndefined(current?.status)
&& [Enums.Deposit.StatusEnum.COMPLETED, Enums.Deposit.StatusEnum.CLEANED].includes(current.status)
&& this._securityService.isRootOrAdmin()
&& (this._securityService.isManagerOfOrgUnit(current.organizationalUnitId) || this._securityService.isStewardOfOrgUnit(current.organizationalUnitId)),
&& (this._securityService.isRootOrAdmin()
|| (this._securityService.isManagerOfOrgUnit(current.organizationalUnitId) || this._securityService.isStewardOfOrgUnit(current.organizationalUnitId))),
callback: current => this._startMetadataEditing(current),
labelToTranslate: current => LabelTranslateEnum.enableDepositEdition,
order: 41,
......@@ -271,8 +271,8 @@ export class DepositDetailEditRoutable extends AbstractDetailEditRoutable<Deposi
displayCondition: current => isNotNullNorUndefined(current?.status)
&& current.status === Enums.Deposit.StatusEnum.EDITING_METADATA
&& !this.isEdit
&& this._securityService.isRootOrAdmin()
&& (this._securityService.isManagerOfOrgUnit(current.organizationalUnitId) || this._securityService.isStewardOfOrgUnit(current.organizationalUnitId)),
&& (this._securityService.isRootOrAdmin()
|| (this._securityService.isManagerOfOrgUnit(current.organizationalUnitId) || this._securityService.isStewardOfOrgUnit(current.organizationalUnitId))),
callback: current => this._cancelMetadataEditing(current),
labelToTranslate: (current) => LabelTranslateEnum.cancelDepositEdition,
order: 41,
......
......@@ -120,7 +120,6 @@ export interface DepositDataFileStateModel extends CompositionStateModel<Deposit
],
})
export class DepositDataFileState extends CompositionState<DepositDataFileStateModel, DepositDataFile> {
private readonly _KEY_STATUS: keyof DepositDataFile = "status";
private readonly _KEY_RELATIVE_LOCATION: keyof DepositDataFile = "relativeLocation";
constructor(protected readonly _apiService: ApiService,
......
......@@ -635,7 +635,7 @@ export class DepositState extends ResourceLogoState<DepositStateModel, Deposit>
const tab = DepositHelper.tabsStatus.find(t => t.tabEnum === action.tabEnum);
if (isNonEmptyArray(tab?.depositStatusEnum)) {
if (tab.depositStatusEnum.length === 1) {
MappingObjectUtil.set(searchItems, DepositHelper.KEY_STATUS, action.tabEnum);
MappingObjectUtil.set(searchItems, DepositHelper.KEY_STATUS, tab.depositStatusEnum[0]);
} else {
MappingObjectUtil.set(searchItems, DepositHelper.KEY_STATUS_LIST, tab.depositStatusEnum.join(SOLIDIFY_CONSTANTS.COMMA));
}
......
......@@ -158,11 +158,11 @@ export class HomeArchiveDetailRoutable extends SharedAbstractPresentational impl
}
private _checkArchiveQueryParams(): void {
const hasAccessRequest = UrlQueryParamHelper.contains(environment.accessRequestRoute);
const hasAccessRequest = UrlQueryParamHelper.currentUrlContainsQueryParam(environment.accessRequestRoute);
const archive = MemoizedUtil.selectSnapshot(this._store, HomeState, state => state.current);
if (!this._archiveAccessRightService.isDownloadAuthorized(archive) && hasAccessRequest) {
const queryParams: MappingObject<string | undefined> = UrlQueryParamHelper.getQueryParamMappingObject();
const queryParams: MappingObject<string | undefined> = UrlQueryParamHelper.getQueryParamMappingObjectFromCurrentUrl();
this._archiveAccessRightService.openRequestArchiveDialog(this._resId, archive.organizationalUnitId);
// clean url
if (MappingObjectUtil.has(queryParams, environment.accessRequestRoute)) {
......
......@@ -77,7 +77,7 @@ export class PreservationSpaceOrganizationalUnitArchiveAclCreateRoutable extends
ngOnInit(): void {
this._retrieveResIdFromUrl();
this.urlQueryParameters = UrlQueryParamHelper.getQueryParamMappingObject();
this.urlQueryParameters = UrlQueryParamHelper.getQueryParamMappingObjectFromCurrentUrl();
}
protected _retrieveResIdFromUrl(): void {
......
......@@ -696,7 +696,12 @@ export const icons: IconInfos[] = [
{
name: IconNameEnum.orcid,
lib: IconLibEnum.image,
icon: "orcid.png",
icon: "ORCID.svg",
},
{
name: IconNameEnum.ror,
lib: IconLibEnum.image,
icon: "ROR.svg",
},
{
name: IconNameEnum.doi,
......
......@@ -113,9 +113,10 @@ export interface AipInfo extends AipInfoPartial {
}
export interface Aip extends AipPartial, BaseResource {
organizationalUnit?: string;
fileFormat?: AipFileFormat;
virusCheck?: AipChecksumCheck;
virusCheck?: AipVirusCheck;
checksumCheck?: AipChecksumCheck;
info?: AipInfo;
}
export interface AipVirusCheck extends AipVirusCheckPartial {
......
......@@ -159,6 +159,7 @@ export class IconNameEnum extends IconNamePartialEnum {
@PropertyName() static zoomIn: string;
@PropertyName() static menuButtons: string;
@PropertyName() static orcid: string;
@PropertyName() static ror: string;
@PropertyName() static doi: string;
@PropertyName() static archive: string;
@PropertyName() static unigeBlack: string;
......
......@@ -464,6 +464,8 @@ export class LabelTranslateEnum {
static masterType: string = MARK_AS_TRANSLATABLE("general.label.masterType");
static isMasterType: string = MARK_AS_TRANSLATABLE("general.label.isMasterType");
static showOnlyMastersTypes: string = MARK_AS_TRANSLATABLE("general.label.showOnlyMastersTypes");
static archivesSelected: string = MARK_AS_TRANSLATABLE("general.label.archivesSelected");
static noSelection: string = MARK_AS_TRANSLATABLE("general.label.noSelection");
static hide: string = MARK_AS_TRANSLATABLE("general.link.hide");
static show: string = MARK_AS_TRANSLATABLE("general.link.show");
......
......@@ -29,28 +29,31 @@ import {
RouterStateSnapshot,
} from "@angular/router";
import {DlcmData} from "@app/shared/models/dlcm-route.model";
import {LocalStateModel} from "@app/shared/models/local-state.model";
import {PermissionUtil} from "@app/shared/utils/permission.util";
import {AppState} from "@app/stores/app.state";
import {Enums} from "@enums";
import {Store} from "@ngxs/store";
import {ApplicationRolePermissionEnum} from "@shared/enums/application-role-permission.enum";
import {AppRoutesEnum} from "@shared/enums/routes.enum";
import {PublicUrlHelper} from "@shared/helpers/public-url.helper";
import {isNotNullOrUndefined} from "codelyzer/util/isNotNullOrUndefined";
import {Observable} from "rxjs";
import {
Observable,
of,
switchMap,
} from "rxjs";
import {
filter,
map,
take,
} from "rxjs/operators";
import {
isEmptyString,
isFalse,
isNotNullNorUndefinedNorWhiteString,
isNullOrUndefined,
MappingObject,
isTrue,
MappingObjectUtil,
MemoizedUtil,
OAuth2Service,
UrlQueryParamHelper,
UrlUtil,
} from "solidify-frontend";
@Injectable({
......@@ -60,48 +63,76 @@ export class ApplicationRoleGuardService implements CanActivate {
constructor(public readonly router: Router, public readonly store: Store, private readonly _oauthService: OAuth2Service) {
}
canActivate(route: ActivatedRouteSnapshot, state1: RouterStateSnapshot): Observable<boolean> {
const data = route.data as DlcmData;
const permission = isNullOrUndefined(data) ? undefined : data.permission;
return MemoizedUtil.select(this.store, AppState, st => st.isApplicationInitialized).pipe(
canActivate(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): Observable<boolean> {
return MemoizedUtil.select(this.store, AppState, state => state.isApplicationInitialized).pipe(
filter(isApplicationInitialized => isApplicationInitialized),
take(1),
map(() => {
const currentUserRole = this.store.selectSnapshot<Enums.UserApplicationRole.UserApplicationRoleEnum[]>((st: LocalStateModel) => st.application.userRoles);
const isLoggedIn = this.store.selectSnapshot<boolean>((st: LocalStateModel) => st.application.isLoggedIn);
const isAuthorized = PermissionUtil.isUserHavePermission(isLoggedIn, permission, currentUserRole);
if (isAuthorized) {
const stateValue: string = UrlQueryParamHelper.getStateFromUrlWithQueryParamOAuth2(state1.url);
if (!isNullOrUndefined(stateValue) && !isEmptyString(stateValue)) {
const queryParams = UrlQueryParamHelper.getListQueryParams(state1.url);
const queryParamMapping: MappingObject = {};
if (!isNullOrUndefined(queryParams)) {
queryParams.forEach(query => {
const keyValue = query.split(UrlQueryParamHelper.getQueryParamValueSeparator());
MappingObjectUtil.set(queryParamMapping, keyValue[0], keyValue[1]);
});
}
this.router.navigate([stateValue], {queryParams: queryParamMapping});
} else {
if (route.queryParamMap.has(UrlQueryParamHelper.QUERY_PARAM_OAUTH_CODE) || route.queryParamMap.has(UrlQueryParamHelper.QUERY_PARAM_OAUTH_STATE)) {
const queryParamCleaned = Object.assign({}, route.queryParams);
MappingObjectUtil.delete(queryParamCleaned, UrlQueryParamHelper.QUERY_PARAM_OAUTH_CODE);
MappingObjectUtil.delete(queryParamCleaned, UrlQueryParamHelper.QUERY_PARAM_OAUTH_STATE);
this.router.navigate([AppRoutesEnum.home], {queryParams: queryParamCleaned});
}
}
return true;
}
if (!isLoggedIn) {
// if the url is the base url, index or anything under #home, do nothing but if contains path, log-in and redirect to the specific url
const isPublicUrl = PublicUrlHelper.listPublicUrls.find(url => state1.url.startsWith(url));
if (isNotNullOrUndefined(isPublicUrl)) {
this._oauthService.initAuthorizationCodeFlow(state1.url);
}
}
this.router.navigate([AppRoutesEnum.home]);
return false;
}),
switchMap(() => this._shouldNavigate(activatedRoute, routerState)),
);
}
private _shouldNavigate(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): Observable<boolean> {
const currentUserRole = MemoizedUtil.selectSnapshot(this.store, AppState, state => state.userRoles);
const isLoggedIn = MemoizedUtil.selectSnapshot(this.store, AppState, state => state.isLoggedIn);
const permissionRequired = this._getPermissionRequired(activatedRoute);
const isAuthorized = PermissionUtil.isUserHavePermission(isLoggedIn, permissionRequired, currentUserRole);
if (isTrue(isAuthorized)) {
this._redirectToRequestedRoute(activatedRoute, routerState);
return of(true);
}
if (isFalse(isLoggedIn)) {
const pathRequested = routerState.url;
const pathRequestedWithoutQueryParam = UrlUtil.removeParametersFromUrl(pathRequested);
const isPublicUrl = pathRequestedWithoutQueryParam === AppRoutesEnum.root || PublicUrlHelper.listPublicUrls.findIndex(url => pathRequestedWithoutQueryParam.startsWith(url)) !== -1;
if (isFalse(isPublicUrl)) {
return this._oauthService.initAuthorizationCodeFlow(routerState.url);
}
}
this.router.navigate([AppRoutesEnum.home]);
return of(false);
}
private _getPermissionRequired(activatedRoute: ActivatedRouteSnapshot): ApplicationRolePermissionEnum | undefined {
const data = activatedRoute.data as DlcmData;
return isNullOrUndefined(data) ? undefined : data.permission;
}
private _redirectToRequestedRoute(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): void {
const redirectPath: string = UrlQueryParamHelper.getRedirectPathFromPath(routerState.url);
const isRedirectPathDefined = isNotNullNorUndefinedNorWhiteString(redirectPath);
if (isRedirectPathDefined) {
this._redirectToInitialTarget(redirectPath);
} else {
this._redirectWithoutOAuth2QueryParamIfPresent(activatedRoute);
}
}
/***
* Redirect to initial target after login
* @param redirectPath (ex: "/admin/organizational-unit/create?roleId=MANAGER&personId=64344f4e-5e87-463d-a213-48fa4ab3be85&orgUnitName=Test%20creation%20org%20unit")
* @private
*/
private _redirectToInitialTarget(redirectPath: string): void {
const path = UrlQueryParamHelper.removeParametersFromPath(redirectPath);
const queryParamMapping = UrlQueryParamHelper.getQueryParamMappingObjectFromUrl(redirectPath, true);
const queryParamObject = MappingObjectUtil.toObject(queryParamMapping);
this.router.navigate([path], {queryParams: queryParamObject});
}
private _redirectWithoutOAuth2QueryParamIfPresent(activatedRoute: ActivatedRouteSnapshot): void {
const isOAuth2InfoPresent = activatedRoute.queryParamMap.has(UrlQueryParamHelper.QUERY_PARAM_OAUTH_CODE) || activatedRoute.queryParamMap.has(UrlQueryParamHelper.QUERY_PARAM_OAUTH_STATE);
if (isOAuth2InfoPresent) {
this._redirectWithoutOAuth2QueryParam(activatedRoute);
}
}
private _redirectWithoutOAuth2QueryParam(activatedRoute: ActivatedRouteSnapshot): void {
const queryParamCleaned = Object.assign({}, activatedRoute.queryParams);
MappingObjectUtil.delete(queryParamCleaned, UrlQueryParamHelper.QUERY_PARAM_OAUTH_CODE);
MappingObjectUtil.delete(queryParamCleaned, UrlQueryParamHelper.QUERY_PARAM_OAUTH_STATE);
this.router.navigate([AppRoutesEnum.home], {queryParams: queryParamCleaned});
}
}
......@@ -26,7 +26,6 @@ import {AppRoutesEnum} from "@shared/enums/routes.enum";
export class PublicUrlHelper {
static listPublicUrls: string[] = [
AppRoutesEnum.root,
AppRoutesEnum.index,
AppRoutesEnum.home,
];
......