Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

general: Managing multiple resources in a route #557

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion projects/rero/ng-core/src/lib/record/action-status.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* RERO angular core
* Copyright (C) 2020 RERO
* Copyright (C) 2019-2023 RERO
* Copyright (C) 2019-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -22,4 +23,6 @@ export interface ActionStatus {
can: boolean;
message: string;
url?: string;
routerLink?: string[];
type?: string | undefined | null;
}
35 changes: 22 additions & 13 deletions projects/rero/ng-core/src/lib/record/record-ui.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* RERO angular core
* Copyright (C) 2020 RERO
* Copyright (C) 2019-2023 RERO
* Copyright (C) 2019-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand Down Expand Up @@ -202,6 +203,10 @@ export class RecordUiService {
*/
canUpdateRecord$(record: object, type: string): Observable<ActionStatus> {
const config = this.getResourceConfig(type);
// The canUpdate function takes precedence over permissions
if (config.canUpdate) {
return config.canUpdate(record).pipe(first());
}
if (config.permissions) {
const permissions = config.permissions(record);
return permissions.pipe(
Expand All @@ -214,9 +219,7 @@ export class RecordUiService {
})
);
}
return (config.canUpdate)
? config.canUpdate(record).pipe(first())
: of({ can: true, message: '' });
return of({ can: true, message: '' });
}

/**
Expand All @@ -227,6 +230,10 @@ export class RecordUiService {
*/
canDeleteRecord$(record: object, type: string): Observable<ActionStatus> {
const config = this.getResourceConfig(type);
// The canDelete function takes precedence over permissions
if (config.canDelete) {
return config.canDelete(record).pipe(first());
}
if (config.permissions) {
const permissions = config.permissions(record);
return permissions.pipe(
Expand All @@ -239,9 +246,7 @@ export class RecordUiService {
})
);
}
return (config.canDelete)
? config.canDelete(record).pipe(first())
: of({ can: true, message: '' });
return of({ can: true, message: '' });
}

/**
Expand All @@ -252,6 +257,10 @@ export class RecordUiService {
*/
canReadRecord$(record: object, type: string): Observable<ActionStatus> {
const config = this.getResourceConfig(type);
// The canRead function takes precedence over permissions
if (config.canRead) {
return config.canRead(record).pipe(first());
}
if (config.permissions) {
const permissions = config.permissions(record);
return permissions.pipe(
Expand All @@ -264,9 +273,7 @@ export class RecordUiService {
})
);
}
return (config.canRead)
? config.canRead(record).pipe(first())
: of({ can: true, message: '' });
return of({ can: true, message: '' });
}

/**
Expand All @@ -277,14 +284,16 @@ export class RecordUiService {
*/
canUseRecord$(record: object, type: string): Observable<ActionStatus> {
const config = this.getResourceConfig(type);
// The canUse function takes precedence over permissions
if (config.canUse) {
return config.canUse(record).pipe(first());
}
if (config.permissions) {
const permissions = config.permissions(record);
if ('canUse' in permissions) {
return permissions.canUse;
}
}
return (config.canUse)
? config.canUse(record).pipe(first())
: of({ can: false, message: '' });
return of({ can: false, message: '' });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ export class RecordSearchPageComponent implements OnInit, OnDestroy {
return;
}

const defaulSortValue = this.q ? 'defaultQuery' : 'defaultNoQuery';
const defaultSortValue = this.q ? 'defaultQuery' : 'defaultNoQuery';
config.sortOptions.forEach((option: SortOption) => {
if (option[defaulSortValue] === true) {
if (option[defaultSortValue] === true) {
this.sort = option.value;
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!--
RERO angular core
Copyright (C) 2022 RERO
Copyright (C) 2022 UCLouvain
Copyright (C) 2019-2023 RERO
Copyright (C) 2019-2023 UCLouvain

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
Expand Down Expand Up @@ -36,7 +36,7 @@ <h5 *ngIf="typesInTabs.length === 1 && showLabel">
</h5>
<ng-container *ngIf="hasNoRecord; else results">
<div class="alert alert-info my-4">{{ emptyRecordMessage }}</div>
<a class="btn btn-primary" routerLink="new" *ngIf="adminMode.can && addStatus.can">
<a class="btn btn-primary" [routerLink]="addStatus.routerLink || ['new']" *ngIf="adminMode.can && addStatus.can">
<i class="fa fa-plus mr-0 mr-sm-1"></i>
<span class="d-none d-sm-inline" translate>Add</span>
</a>
Expand All @@ -56,7 +56,7 @@ <h5 *ngIf="typesInTabs.length === 1 && showLabel">
<strong>{{ resultsText }}</strong>
</div>
<div class="col ml-auto text-right">
<a class="btn btn-primary" [routerLink]="addStatus?.url || ['new']" *ngIf="adminMode.can && addStatus.can">
<a id="search-add-button" class="btn btn-primary" [routerLink]="addStatus.routerLink || ['new']" *ngIf="adminMode.can && addStatus.can">
<i class="fa fa-plus mr-0 mr-sm-1"></i>
<span class="d-none d-sm-inline" translate>Add</span>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ describe('RecordSearchComponent', () => {
component.types[0].total = 2;

expect(component.types[0].total).toBe(2);
component.deleteRecord('1');
component.deleteRecord({ pid: '1' });
expect(component.types[0].total).toBe(2);
});

Expand All @@ -242,7 +242,7 @@ describe('RecordSearchComponent', () => {
component['_config'].total = 2;

expect(component['_config'].total).toBe(2);
component.deleteRecord('1');
component.deleteRecord({ pid: '1' });
tick(10000); // wait for refreshing records
expect(component['_config'].total).toBe(1);
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,11 @@ export class RecordSearchComponent implements OnInit, OnChanges, OnDestroy {

/**
* Delete a record by its PID.
* @param pid - string, PID to delete
* @param event - object
*/
deleteRecord(pid: string) {
this._recordUiService.deleteRecord(this.currentType, pid).pipe(
deleteRecord(event: { pid: string, type?: string }) {
const type = event.type ?? this.currentType;
this._recordUiService.deleteRecord(type, event.pid).pipe(
switchMap(result => {
if (result === true) {
this.page = 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<!--
RERO angular core
Copyright (C) 2020 RERO

Copyright (C) 2019-2023 RERO
Copyright (C) 2019-2023 UCLouvain

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
Expand All @@ -32,8 +33,8 @@
class="btn btn-sm btn-outline-primary ml-2"
[title]="'Edit' | translate"
[name]="'Edit' | translate"
(click)="editRecord(record.id)"
routerLink="edit/{{ record.id }}">
(click)="editRecord(record.id, updateStatus?.routerLink)"
[routerLink]="updateStatus.routerLink || ['edit', record.id]">
<i class="fa fa-pencil"></i>
</button>

Expand All @@ -44,7 +45,7 @@
class="btn btn-sm btn-outline-danger"
[title]="'Delete' | translate"
[name]="'Delete' | translate"
(click)="deleteRecord(record.id)">
(click)="deleteRecord(record.id, deleteStatus?.type)">
<i class="fa fa-trash"></i>
</button>
<ng-template #deleteMessageLink>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ describe('RecordSearchResultComponent', () => {
});

it('should delete record', () => {
component.deletedRecord.subscribe((pid: string) => {
expect(pid).toBe('1');
component.deletedRecord.subscribe((result: { pid: string, type: string | undefined | null }) => {
expect(result.pid).toBe('1');
});
component.deleteRecord('1');
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* RERO angular core
* Copyright (C) 2020 RERO
* Copyright (C) 2019-2023 RERO
* Copyright (C) 2019-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand Down Expand Up @@ -113,7 +114,7 @@ export class RecordSearchResultComponent implements OnInit {
/**
* Event emitted when a record is deleted
*/
@Output() deletedRecord = new EventEmitter<string>();
@Output() deletedRecord = new EventEmitter<{pid: string, type?: string | undefined | null }>();

/**
* Directive for displaying search results
Expand Down Expand Up @@ -190,17 +191,19 @@ export class RecordSearchResultComponent implements OnInit {
/**
* Delete a record
* @param pid - string, pid to delete
* @param type - string, resource type
*/
deleteRecord(pid: string) {
return this.deletedRecord.emit(pid);
deleteRecord(pid: string, type?: string) {
return this.deletedRecord.emit({ pid, type });
}

/**
* Edit a record
* @param pid - string: the pid to edit
*/
editRecord(pid: string) {
this._router.navigate(['/', 'records', this.type, 'edit', pid]);
editRecord(pid: string, url?: string[]) {
const params = url ?? ['/', 'records', this.type, 'edit', pid];
this._router.navigate(params);
}

/**
Expand Down