RED-9321: refactored trash and search modules.
This commit is contained in:
parent
0fe7584f4b
commit
c4912ffd8f
@ -147,7 +147,7 @@ const mainRoutes: IqserRoutes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'search',
|
path: 'search',
|
||||||
loadChildren: () => import('./modules/search/search.module').then(m => m.SearchModule),
|
loadComponent: () => import('./modules/search/search-screen/search-screen.component'),
|
||||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard, loadAllDossiersGuard()],
|
canActivate: [CompositeRouteGuard, IqserPermissionsGuard, loadAllDossiersGuard()],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||||
@ -159,7 +159,7 @@ const mainRoutes: IqserRoutes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'trash',
|
path: 'trash',
|
||||||
loadChildren: () => import('./modules/trash/trash.module').then(m => m.TrashModule),
|
loadChildren: () => import('./modules/trash/trash.routes'),
|
||||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [IqserAuthGuard, RedRoleGuard, TrashGuard],
|
routeGuards: [IqserAuthGuard, RedRoleGuard, TrashGuard],
|
||||||
|
|||||||
@ -3,11 +3,31 @@ import { workflowFileStatusTranslations } from '@translations/file-status-transl
|
|||||||
import { ISearchListItem } from '@red/domain';
|
import { ISearchListItem } from '@red/domain';
|
||||||
import { escapeHtml } from '@iqser/common-ui/lib/utils';
|
import { escapeHtml } from '@iqser/common-ui/lib/utils';
|
||||||
import { getDossierRouterLink } from '@utils/router-links';
|
import { getDossierRouterLink } from '@utils/router-links';
|
||||||
|
import { MatTooltip } from '@angular/material/tooltip';
|
||||||
|
import { NgForOf, NgIf } from '@angular/common';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { StopPropagationDirective } from '@iqser/common-ui';
|
||||||
|
import { InitialsAvatarComponent } from '@common-ui/users';
|
||||||
|
import { StatusBarComponent } from '@common-ui/shared';
|
||||||
|
import { MatIcon } from '@angular/material/icon';
|
||||||
|
import { RouterLink } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-search-item-template',
|
selector: 'redaction-search-item-template',
|
||||||
templateUrl: './search-item-template.component.html',
|
templateUrl: './search-item-template.component.html',
|
||||||
styleUrls: ['./search-item-template.component.scss'],
|
styleUrls: ['./search-item-template.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
MatTooltip,
|
||||||
|
NgIf,
|
||||||
|
TranslateModule,
|
||||||
|
NgForOf,
|
||||||
|
StopPropagationDirective,
|
||||||
|
InitialsAvatarComponent,
|
||||||
|
StatusBarComponent,
|
||||||
|
MatIcon,
|
||||||
|
RouterLink,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class SearchItemTemplateComponent implements OnChanges {
|
export class SearchItemTemplateComponent implements OnChanges {
|
||||||
@Input() item: ISearchListItem;
|
@Input() item: ISearchListItem;
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core';
|
||||||
import { ListingComponent, listingProvidersFactory, LoadingService, SearchPositions, TableColumnConfig } from '@iqser/common-ui';
|
import {
|
||||||
|
IqserListingModule,
|
||||||
|
ListingComponent,
|
||||||
|
listingProvidersFactory,
|
||||||
|
LoadingService,
|
||||||
|
SearchPositions,
|
||||||
|
TableColumnConfig,
|
||||||
|
} from '@iqser/common-ui';
|
||||||
import { combineLatest, Observable, of } from 'rxjs';
|
import { combineLatest, Observable, of } from 'rxjs';
|
||||||
import { debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators';
|
import { debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
|
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
import { RouterHistoryService } from '@services/router-history.service';
|
import { RouterHistoryService } from '@services/router-history.service';
|
||||||
import {
|
import {
|
||||||
Dossier,
|
Dossier,
|
||||||
@ -25,14 +32,18 @@ import { DossierTemplatesService } from '@services/dossier-templates/dossier-tem
|
|||||||
import { UserService } from '@users/user.service';
|
import { UserService } from '@users/user.service';
|
||||||
import { IFilterGroup, keyChecker, NestedFilter } from '@iqser/common-ui/lib/filtering';
|
import { IFilterGroup, keyChecker, NestedFilter } from '@iqser/common-ui/lib/filtering';
|
||||||
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
|
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
|
||||||
|
import { AsyncPipe, NgIf } from '@angular/common';
|
||||||
|
import { SearchItemTemplateComponent } from '../search-item-template/search-item-template.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './search-screen.component.html',
|
templateUrl: './search-screen.component.html',
|
||||||
styleUrls: ['./search-screen.component.scss'],
|
styleUrls: ['./search-screen.component.scss'],
|
||||||
providers: listingProvidersFactory(SearchScreenComponent),
|
providers: listingProvidersFactory(SearchScreenComponent),
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [IqserListingModule, TranslateModule, AsyncPipe, NgIf, SearchItemTemplateComponent],
|
||||||
})
|
})
|
||||||
export class SearchScreenComponent extends ListingComponent<ISearchListItem> implements OnDestroy {
|
export default class SearchScreenComponent extends ListingComponent<ISearchListItem> implements OnDestroy {
|
||||||
readonly searchPositions = SearchPositions;
|
readonly searchPositions = SearchPositions;
|
||||||
|
|
||||||
readonly tableHeaderLabel = _('search-screen.table-header');
|
readonly tableHeaderLabel = _('search-screen.table-header');
|
||||||
@ -46,7 +57,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
|
|
||||||
readonly searchResults$ = new Observable<ISearchListItem[]>();
|
readonly searchResults$ = new Observable<ISearchListItem[]>();
|
||||||
|
|
||||||
readonly dossierTemplates$ = this._dossierTemplateService.loadAll().pipe(tap(templates => this._addTemplateFilter(templates)));
|
readonly dossierTemplates$ = this._dossierTemplateService.loadAll().pipe(tap(templates => this.#addTemplateFilter(templates)));
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _router: Router,
|
private readonly _router: Router,
|
||||||
@ -65,10 +76,10 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
if (!Object.keys(this._activatedRoute.snapshot.queryParams).length) {
|
if (!Object.keys(this._activatedRoute.snapshot.queryParams).length) {
|
||||||
this._router.navigate(['main']).then();
|
this._router.navigate(['main']).then();
|
||||||
}
|
}
|
||||||
this.searchResults$ = combineLatest([this._queryChanged$, this._filtersChanged$]).pipe(
|
this.searchResults$ = combineLatest([this.#queryChanged$, this.#filtersChanged$]).pipe(
|
||||||
tap(() => this._loadingService.start()),
|
tap(() => this._loadingService.start()),
|
||||||
tap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
|
tap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
|
||||||
this._updateNavigation(query, dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive),
|
this.#updateNavigation(query, dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive),
|
||||||
),
|
),
|
||||||
switchMap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
|
switchMap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
|
||||||
this._platformSearchService.search({
|
this._platformSearchService.search({
|
||||||
@ -81,43 +92,43 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
includeArchivedDossiers: !onlyActive,
|
includeArchivedDossiers: !onlyActive,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
map(searchResult => this._toMatchedDocuments(searchResult)),
|
map(searchResult => this.#toMatchedDocuments(searchResult)),
|
||||||
map(docs => this._toListItems(docs)),
|
map(docs => this.#toListItems(docs)),
|
||||||
tap(result => this.entitiesService.setEntities(result)),
|
tap(result => this.entitiesService.setEntities(result)),
|
||||||
tap(() => this._loadingService.stop()),
|
tap(() => this._loadingService.stop()),
|
||||||
);
|
);
|
||||||
this.searchService.skip = true;
|
this.searchService.skip = true;
|
||||||
this.sortingService.setSortingOption({ column: 'searchKey', order: SortingOrders.desc });
|
this.sortingService.setSortingOption({ column: 'searchKey', order: SortingOrders.desc });
|
||||||
this._initFilters();
|
this.#initFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _routeDossierIds(): string[] {
|
get #routeDossierIds(): string[] {
|
||||||
return this._activatedRoute.snapshot.queryParamMap.get('dossierIds').split(',');
|
return this._activatedRoute.snapshot.queryParamMap.get('dossierIds').split(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _routeDossierTemplateIds(): string[] {
|
get #routeDossierTemplateIds(): string[] {
|
||||||
return this._activatedRoute.snapshot.queryParamMap.get('dossierTemplateIds')?.split(',');
|
return this._activatedRoute.snapshot.queryParamMap.get('dossierTemplateIds')?.split(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _routeStatus(): WorkflowFileStatus {
|
get #routeStatus(): WorkflowFileStatus {
|
||||||
return this._activatedRoute.snapshot.queryParamMap.get('status') as WorkflowFileStatus;
|
return this._activatedRoute.snapshot.queryParamMap.get('status') as WorkflowFileStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _routeAssignee(): string {
|
get #routeAssignee(): string {
|
||||||
return this._activatedRoute.snapshot.queryParamMap.get('assignee');
|
return this._activatedRoute.snapshot.queryParamMap.get('assignee');
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _routeOnlyActive(): boolean {
|
get #routeOnlyActive(): boolean {
|
||||||
return this._activatedRoute.snapshot.queryParamMap.get('onlyActive') === 'true';
|
return this._activatedRoute.snapshot.queryParamMap.get('onlyActive') === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _routeQuery(): string {
|
get #routeQuery(): string {
|
||||||
return this._activatedRoute.snapshot.queryParamMap.get('query');
|
return this._activatedRoute.snapshot.queryParamMap.get('query');
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _queryChanged$(): Observable<string> {
|
get #queryChanged$(): Observable<string> {
|
||||||
return this.searchService.valueChanges$.pipe(
|
return this.searchService.valueChanges$.pipe(
|
||||||
startWith(this._routeQuery),
|
startWith(this.#routeQuery),
|
||||||
tap(query => (this.searchService.searchValue = query)),
|
tap(query => (this.searchService.searchValue = query)),
|
||||||
debounceTime(300),
|
debounceTime(300),
|
||||||
);
|
);
|
||||||
@ -127,7 +138,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
return this._featuresService.isEnabled(DOSSIERS_ARCHIVE);
|
return this._featuresService.isEnabled(DOSSIERS_ARCHIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _filtersChanged$(): Observable<[string[], WorkflowFileStatus, string, string[], boolean]> {
|
get #filtersChanged$(): Observable<[string[], WorkflowFileStatus, string, string[], boolean]> {
|
||||||
const onlyActiveDossiers$ = this.#enabledArchive
|
const onlyActiveDossiers$ = this.#enabledArchive
|
||||||
? this.filterService.getSingleFilter('onlyActiveDossiers').pipe(map(f => !!f.checked))
|
? this.filterService.getSingleFilter('onlyActiveDossiers').pipe(map(f => !!f.checked))
|
||||||
: of(true);
|
: of(true);
|
||||||
@ -141,11 +152,11 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
return [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive];
|
return [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive];
|
||||||
}),
|
}),
|
||||||
startWith<[string[], WorkflowFileStatus, string, string[], boolean]>([
|
startWith<[string[], WorkflowFileStatus, string, string[], boolean]>([
|
||||||
this._routeDossierIds,
|
this.#routeDossierIds,
|
||||||
this._routeStatus,
|
this.#routeStatus,
|
||||||
this._routeAssignee,
|
this.#routeAssignee,
|
||||||
this._routeDossierTemplateIds,
|
this.#routeDossierTemplateIds,
|
||||||
this._routeOnlyActive,
|
this.#routeOnlyActive,
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -155,8 +166,8 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
this.searchService.searchValue = newQuery ?? '';
|
this.searchService.searchValue = newQuery ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
private _initFilters() {
|
#initFilters() {
|
||||||
const dossierIds = this._routeDossierIds;
|
const dossierIds = this.#routeDossierIds;
|
||||||
const dossierToFilter = ({ dossierName, id }: Dossier) => {
|
const dossierToFilter = ({ dossierName, id }: Dossier) => {
|
||||||
const checked = dossierIds.includes(id);
|
const checked = dossierIds.includes(id);
|
||||||
return new NestedFilter({ id, label: dossierName, checked });
|
return new NestedFilter({ id, label: dossierName, checked });
|
||||||
@ -170,7 +181,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
checker: keyChecker('dossierId'),
|
checker: keyChecker('dossierId'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const status = this._routeStatus;
|
const status = this.#routeStatus;
|
||||||
const statusToFilter = (workflowStatus: WorkflowFileStatus) => {
|
const statusToFilter = (workflowStatus: WorkflowFileStatus) => {
|
||||||
const checked = status === workflowStatus;
|
const checked = status === workflowStatus;
|
||||||
return new NestedFilter({
|
return new NestedFilter({
|
||||||
@ -188,7 +199,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
checker: keyChecker('status'),
|
checker: keyChecker('status'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const assignee = this._routeAssignee;
|
const assignee = this.#routeAssignee;
|
||||||
const assigneeToFilter = (userId: string) => {
|
const assigneeToFilter = (userId: string) => {
|
||||||
const checked = assignee === userId;
|
const checked = assignee === userId;
|
||||||
return new NestedFilter({ id: userId, label: this._userService.getName(userId), checked });
|
return new NestedFilter({ id: userId, label: this._userService.getName(userId), checked });
|
||||||
@ -215,12 +226,12 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
this.filterService.addFilterGroups([dossierNameFilter, workflowStatusFilter, assigneeFilter]);
|
this.filterService.addFilterGroups([dossierNameFilter, workflowStatusFilter, assigneeFilter]);
|
||||||
const onlyActiveLabel = this._translateService.instant('search-screen.filters.only-active');
|
const onlyActiveLabel = this._translateService.instant('search-screen.filters.only-active');
|
||||||
if (this.#enabledArchive) {
|
if (this.#enabledArchive) {
|
||||||
this.filterService.addSingleFilter({ id: 'onlyActiveDossiers', label: onlyActiveLabel, checked: this._routeOnlyActive });
|
this.filterService.addSingleFilter({ id: 'onlyActiveDossiers', label: onlyActiveLabel, checked: this.#routeOnlyActive });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addTemplateFilter(templates: DossierTemplate[]) {
|
#addTemplateFilter(templates: DossierTemplate[]) {
|
||||||
const templatesIds = this._routeDossierTemplateIds;
|
const templatesIds = this.#routeDossierTemplateIds;
|
||||||
const templateToFilter = ({ name, id }: DossierTemplate) => {
|
const templateToFilter = ({ name, id }: DossierTemplate) => {
|
||||||
const checked = templatesIds?.includes(id);
|
const checked = templatesIds?.includes(id);
|
||||||
return new NestedFilter({ id, label: name, checked });
|
return new NestedFilter({ id, label: name, checked });
|
||||||
@ -236,7 +247,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
this.filterService.addFilterGroups([templateNameFilter]);
|
this.filterService.addFilterGroups([templateNameFilter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _updateNavigation(
|
#updateNavigation(
|
||||||
query?: string,
|
query?: string,
|
||||||
dossierIds?: string[],
|
dossierIds?: string[],
|
||||||
workflowStatus?: WorkflowFileStatus,
|
workflowStatus?: WorkflowFileStatus,
|
||||||
@ -255,15 +266,15 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
|
|||||||
return this._router.navigate([], { queryParams, replaceUrl: true });
|
return this._router.navigate([], { queryParams, replaceUrl: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _toMatchedDocuments({ matchedDocuments }: ISearchResponse): IMatchedDocument[] {
|
#toMatchedDocuments({ matchedDocuments }: ISearchResponse): IMatchedDocument[] {
|
||||||
return matchedDocuments.filter(doc => doc.score > 0 && doc.matchedTerms.length > 0);
|
return matchedDocuments.filter(doc => doc.score > 0 && doc.matchedTerms.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _toListItems(matchedDocuments: IMatchedDocument[]): ISearchListItem[] {
|
#toListItems(matchedDocuments: IMatchedDocument[]): ISearchListItem[] {
|
||||||
return matchedDocuments.map(document => this._toListItem(document)).filter(value => value);
|
return matchedDocuments.map(document => this.#toListItem(document)).filter(value => value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _toListItem({
|
#toListItem({
|
||||||
dossierId,
|
dossierId,
|
||||||
fileId,
|
fileId,
|
||||||
unmatchedTerms,
|
unmatchedTerms,
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { SearchScreenComponent } from './search-screen/search-screen.component';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { IqserListingModule, StopPropagationDirective } from '@iqser/common-ui';
|
|
||||||
import { SharedModule } from '@shared/shared.module';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { SearchItemTemplateComponent } from './search-item-template/search-item-template.component';
|
|
||||||
import { InitialsAvatarComponent, IqserUsersModule } from '@iqser/common-ui/lib/users';
|
|
||||||
import { StatusBarComponent } from '@iqser/common-ui/lib/shared';
|
|
||||||
|
|
||||||
const routes = [{ path: '', component: SearchScreenComponent }];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [SearchScreenComponent, SearchItemTemplateComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
RouterModule.forChild(routes),
|
|
||||||
SharedModule,
|
|
||||||
IqserUsersModule,
|
|
||||||
TranslateModule,
|
|
||||||
IqserListingModule,
|
|
||||||
StatusBarComponent,
|
|
||||||
StopPropagationDirective,
|
|
||||||
InitialsAvatarComponent,
|
|
||||||
],
|
|
||||||
})
|
|
||||||
export class SearchModule {}
|
|
||||||
@ -1,6 +1,13 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { ListingComponent, listingProvidersFactory, LoadingService, TableColumnConfig } from '@iqser/common-ui';
|
import {
|
||||||
|
CircleButtonComponent,
|
||||||
|
IqserListingModule,
|
||||||
|
ListingComponent,
|
||||||
|
listingProvidersFactory,
|
||||||
|
LoadingService,
|
||||||
|
TableColumnConfig,
|
||||||
|
} from '@iqser/common-ui';
|
||||||
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
|
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
|
||||||
import { TrashItem } from '@red/domain';
|
import { TrashItem } from '@red/domain';
|
||||||
import { TrashService } from '@services/entity-services/trash.service';
|
import { TrashService } from '@services/entity-services/trash.service';
|
||||||
@ -8,6 +15,9 @@ import { RouterHistoryService } from '@services/router-history.service';
|
|||||||
import { firstValueFrom, Observable } from 'rxjs';
|
import { firstValueFrom, Observable } from 'rxjs';
|
||||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||||
import { TrashDialogService } from '../services/trash-dialog.service';
|
import { TrashDialogService } from '../services/trash-dialog.service';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { AsyncPipe, NgIf } from '@angular/common';
|
||||||
|
import { TrashTableItemComponent } from './trash-table-item/trash-table-item.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './trash-screen.component.html',
|
templateUrl: './trash-screen.component.html',
|
||||||
@ -16,11 +26,13 @@ import { TrashDialogService } from '../services/trash-dialog.service';
|
|||||||
entitiesService: TrashService,
|
entitiesService: TrashService,
|
||||||
component: TrashScreenComponent,
|
component: TrashScreenComponent,
|
||||||
}),
|
}),
|
||||||
|
standalone: true,
|
||||||
|
imports: [IqserListingModule, TranslateModule, CircleButtonComponent, NgIf, TrashTableItemComponent, AsyncPipe],
|
||||||
})
|
})
|
||||||
export class TrashScreenComponent extends ListingComponent<TrashItem> implements OnInit {
|
export class TrashScreenComponent extends ListingComponent<TrashItem> implements OnInit {
|
||||||
readonly tableHeaderLabel = _('trash.table-header.title');
|
readonly tableHeaderLabel = _('trash.table-header.title');
|
||||||
readonly canRestoreSelected$ = this._canRestoreSelected$;
|
readonly canRestoreSelected$ = this.#canRestoreSelected$;
|
||||||
readonly canHardDeleteSelected$ = this._canHardDeleteSelected$;
|
readonly canHardDeleteSelected$ = this.#canHardDeleteSelected$;
|
||||||
readonly tableColumnConfigs: TableColumnConfig<TrashItem>[] = [
|
readonly tableColumnConfigs: TableColumnConfig<TrashItem>[] = [
|
||||||
{ label: _('trash.table-col-names.name'), sortByKey: 'name' },
|
{ label: _('trash.table-col-names.name'), sortByKey: 'name' },
|
||||||
{ label: _('trash.table-col-names.owner'), class: 'user-column', sortByKey: 'ownerName' },
|
{ label: _('trash.table-col-names.owner'), class: 'user-column', sortByKey: 'ownerName' },
|
||||||
@ -43,14 +55,14 @@ export class TrashScreenComponent extends ListingComponent<TrashItem> implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _canRestoreSelected$(): Observable<boolean> {
|
get #canRestoreSelected$(): Observable<boolean> {
|
||||||
return this.listingService.selectedEntities$.pipe(
|
return this.listingService.selectedEntities$.pipe(
|
||||||
map(entities => entities.length && !entities.find(dossier => !(dossier.canRestore && dossier.hasRestoreRights))),
|
map(entities => entities.length && !entities.find(dossier => !(dossier.canRestore && dossier.hasRestoreRights))),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _canHardDeleteSelected$(): Observable<boolean> {
|
get #canHardDeleteSelected$(): Observable<boolean> {
|
||||||
return this.listingService.selectedEntities$.pipe(
|
return this.listingService.selectedEntities$.pipe(
|
||||||
map(entities => entities.length && !entities.find(dossier => !dossier.hasHardDeleteRights)),
|
map(entities => entities.length && !entities.find(dossier => !dossier.hasHardDeleteRights)),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
|
|||||||
@ -2,15 +2,34 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Out
|
|||||||
import { Dossier, DossierStats, TrashFile, TrashItem, User } from '@red/domain';
|
import { Dossier, DossierStats, TrashFile, TrashItem, User } from '@red/domain';
|
||||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||||
import { DossierStatsService } from '@services/dossiers/dossier-stats.service';
|
import { DossierStatsService } from '@services/dossiers/dossier-stats.service';
|
||||||
import { PartialDossier } from '@shared/components/dossier-name-column/dossier-name-column.component';
|
import { DossierNameColumnComponent, PartialDossier } from '@shared/components/dossier-name-column/dossier-name-column.component';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { getCurrentUser } from '@common-ui/users';
|
import { getCurrentUser, InitialsAvatarComponent } from '@common-ui/users';
|
||||||
|
import { MatIcon } from '@angular/material/icon';
|
||||||
|
import { FileNameColumnComponent } from '@shared/components/file-name-column/file-name-column.component';
|
||||||
|
import { AsyncPipe, DatePipe, NgIf } from '@angular/common';
|
||||||
|
import { CircleButtonComponent } from '@iqser/common-ui';
|
||||||
|
import { RouterLink } from '@angular/router';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-trash-table-item [item]',
|
selector: 'redaction-trash-table-item [item]',
|
||||||
templateUrl: './trash-table-item.component.html',
|
templateUrl: './trash-table-item.component.html',
|
||||||
styleUrls: ['./trash-table-item.component.scss'],
|
styleUrls: ['./trash-table-item.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
MatIcon,
|
||||||
|
FileNameColumnComponent,
|
||||||
|
DossierNameColumnComponent,
|
||||||
|
NgIf,
|
||||||
|
InitialsAvatarComponent,
|
||||||
|
CircleButtonComponent,
|
||||||
|
AsyncPipe,
|
||||||
|
RouterLink,
|
||||||
|
DatePipe,
|
||||||
|
TranslateModule,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class TrashTableItemComponent implements OnChanges {
|
export class TrashTableItemComponent implements OnChanges {
|
||||||
@Input() item: TrashItem;
|
@Input() item: TrashItem;
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { TrashScreenComponent } from './trash-screen/trash-screen.component';
|
|
||||||
import { CircleButtonComponent, IqserListingModule } from '@iqser/common-ui';
|
|
||||||
import { TrashTableItemComponent } from './trash-screen/trash-table-item/trash-table-item.component';
|
|
||||||
import { SharedModule } from '@shared/shared.module';
|
|
||||||
import { TrashDialogService } from './services/trash-dialog.service';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { InitialsAvatarComponent, IqserUsersModule } from '@iqser/common-ui/lib/users';
|
|
||||||
import { FileNameColumnComponent } from '@shared/components/file-name-column/file-name-column.component';
|
|
||||||
import { DossierNameColumnComponent } from '@shared/components/dossier-name-column/dossier-name-column.component';
|
|
||||||
|
|
||||||
const routes = [{ path: '', component: TrashScreenComponent }];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [TrashScreenComponent, TrashTableItemComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
RouterModule.forChild(routes),
|
|
||||||
SharedModule,
|
|
||||||
IqserUsersModule,
|
|
||||||
TranslateModule,
|
|
||||||
IqserListingModule,
|
|
||||||
CircleButtonComponent,
|
|
||||||
FileNameColumnComponent,
|
|
||||||
InitialsAvatarComponent,
|
|
||||||
DossierNameColumnComponent,
|
|
||||||
],
|
|
||||||
providers: [TrashDialogService],
|
|
||||||
})
|
|
||||||
export class TrashModule {}
|
|
||||||
5
apps/red-ui/src/app/modules/trash/trash.routes.ts
Normal file
5
apps/red-ui/src/app/modules/trash/trash.routes.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { TrashScreenComponent } from './trash-screen/trash-screen.component';
|
||||||
|
import { TrashDialogService } from './services/trash-dialog.service';
|
||||||
|
import { IqserRoutes } from '@iqser/common-ui';
|
||||||
|
|
||||||
|
export default [{ path: '', component: TrashScreenComponent, providers: [TrashDialogService] }] satisfies IqserRoutes;
|
||||||
Loading…
x
Reference in New Issue
Block a user