RED-6713: update tenants handling

This commit is contained in:
Dan Percic 2023-07-06 13:12:40 +03:00
parent 62bd383b88
commit 269bd94cfe
187 changed files with 600 additions and 567 deletions

View File

@ -1,11 +1,8 @@
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
import {
CompositeRouteGuard,
CustomRouteReuseStrategy,
DEFAULT_REDIRECT_KEY,
ifLoggedIn,
ifNotLoggedIn,
IqserAuthGuard,
IqserPermissionsGuard,
IqserRoutes,
TenantSelectComponent,
@ -27,6 +24,9 @@ import { DossierFilesGuard } from '@guards/dossier-files-guard';
import { WebViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
import { Roles } from '@users/roles';
import { mainResolver } from '@utils/main.resolver';
import { hasAnyRoleGuard, IqserAuthGuard } from '@iqser/common-ui/lib/users';
import { CustomRouteReuseStrategy } from '@iqser/common-ui/lib/utils';
import { ifLoggedIn } from '@guards/if-logged-in.guard';
const dossierTemplateIdRoutes: IqserRoutes = [
{
@ -182,7 +182,7 @@ const mainRoutes: IqserRoutes = [
children: dossierTemplateIdRoutes,
canActivate: [CompositeRouteGuard, IqserPermissionsGuard, templateExistsWhenEnteringDossierList()],
data: {
routeGuards: [IqserAuthGuard, RedRoleGuard, DossierTemplatesGuard, DashboardGuard],
routeGuards: [IqserAuthGuard, RedRoleGuard],
permissions: {
allow: [
Roles.any,
@ -220,7 +220,7 @@ const routes: IqserRoutes = [
},
{
path: ':tenant/main',
canActivate: [ifLoggedIn],
canActivate: [ifLoggedIn()],
component: BaseScreenComponent,
resolve: {
whateverThisMainRouteNeeds: mainResolver,
@ -230,7 +230,7 @@ const routes: IqserRoutes = [
{
path: ':tenant/auth-error',
component: AuthErrorComponent,
canActivate: [IqserAuthGuard],
canActivate: [hasAnyRoleGuard()],
},
{
path: '**',

View File

@ -21,7 +21,6 @@ import {
IqserListingModule,
IqserLoadingModule,
IqserTranslateModule,
IqserUsersModule,
LanguageService,
LogoComponent,
MAX_RETRIES_ON_SERVER_ERROR,
@ -71,6 +70,7 @@ import { SkeletonStatsComponent } from '@components/skeleton/skeleton-stats/skel
import { UserMenuComponent } from '@components/user-menu/user-menu.component';
import { TenantsMenuComponent } from '@components/tenants-menu/tenants-menu.component';
import { MatDividerModule } from '@angular/material/divider';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
export const appModuleFactory = (config: AppConfig) => {
@NgModule({

View File

@ -6,13 +6,14 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core';
import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action';
import { filter, map, startWith } from 'rxjs/operators';
import { IqserPermissionsService, List, shareDistinctLast, TenantsService } from '@iqser/common-ui';
import { IqserPermissionsService, TenantsService } from '@iqser/common-ui';
import { BreadcrumbsService } from '@services/breadcrumbs.service';
import { FeaturesService } from '@services/features.service';
import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@red/domain';
import { Roles } from '@users/roles';
import { REDDocumentViewer } from '../../modules/pdf-viewer/services/document-viewer.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { List, shareDistinctLast } from '@iqser/common-ui/lib/utils';
const isNavigationStart = event => event instanceof NavigationStart;
const isSearchScreen: (url: string) => boolean = url => url.includes('/search');
@ -22,6 +23,12 @@ const isSearchScreen: (url: string) => boolean = url => url.includes('/search');
styleUrls: ['./base-screen.component.scss'],
})
export class BaseScreenComponent {
readonly #navigationStart$ = this._router.events.pipe(
filter(isNavigationStart),
map((event: NavigationStart) => event.url),
startWith(this._router.url),
shareDistinctLast(),
);
readonly roles = Roles;
readonly documentViewer = inject(REDDocumentViewer);
readonly currentUser = this.userService.currentUser;
@ -44,12 +51,6 @@ export class BaseScreenComponent {
action: (query): void => this.#search(query, []),
},
];
readonly #navigationStart$ = this._router.events.pipe(
filter(isNavigationStart),
map((event: NavigationStart) => event.url),
startWith(this._router.url),
shareDistinctLast(),
);
readonly isSearchScreen$ = this.#navigationStart$.pipe(map(isSearchScreen));
constructor(

View File

@ -4,7 +4,7 @@ import { NotificationsService } from '@services/notifications.service';
import { Notification } from '@red/domain';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { isToday, shareLast, trackByFactory } from '@iqser/common-ui';
import { isToday, shareLast, trackByFactory } from '@iqser/common-ui/lib/utils';
import dayjs, { Dayjs } from 'dayjs';
import { TranslateService } from '@ngx-translate/core';

View File

@ -1,11 +1,11 @@
<div id="tenants-menu-items">
<ng-container *ngFor="let item of storedTenants | keyvalue; trackBy: trackBy">
<ng-container *ngFor="let item of storedTenants; trackBy: trackBy">
<div class="label">{{ item.key }}</div>
<a
(click)="selectTenant(stored.tenant.tenantId, stored.email)"
(click)="selectTenant(stored.tenantId, stored.email)"
*ngFor="let stored of item.value"
[id]="stored.tenant.tenantId"
[id]="stored.tenantId + stored.email"
mat-menu-item
>
{{ stored.email }}

View File

@ -1,8 +1,9 @@
import { Component, inject } from '@angular/core';
import { BASE_HREF, getConfig, getCurrentUser, IStoredTenant, KeycloakStatusService, TenantsService } from '@iqser/common-ui';
import { getConfig, getKeycloakOptions, IStoredTenantId, KeycloakStatusService, TenantsService } from '@iqser/common-ui';
import { User } from '@red/domain';
import { KeyValue } from '@angular/common';
import { KeycloakService } from 'keycloak-angular';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { BASE_HREF } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'app-tenants-menu',
@ -10,48 +11,49 @@ import { KeycloakService } from 'keycloak-angular';
styleUrls: ['./tenants-menu.component.scss'],
})
export class TenantsMenuComponent {
readonly tenantsService = inject(TenantsService);
readonly storedTenants: Map<string, IStoredTenant[]>;
readonly #baseHref = inject(BASE_HREF);
readonly #keycloakService = inject(KeycloakService);
readonly #keycloakStatusService = inject(KeycloakStatusService);
readonly #currentUser = getCurrentUser<User>();
readonly #config = getConfig();
readonly tenantsService = inject(TenantsService);
readonly storedTenants: { key: string; value: IStoredTenantId[] }[];
constructor() {
this.storedTenants = this.#getStoredTenants();
}
trackBy(_index: number, item: KeyValue<string, IStoredTenant[]>) {
trackBy(_index: number, item: { key: string; value: IStoredTenantId[] }) {
return item.key;
}
// TODO: this should be moved to the keycloak status service
async selectTenant(tenantId?: string, email?: string) {
let tenantUrl = tenantId ? '/' + tenantId : '/';
if (email) {
tenantUrl += '?username=' + email;
if (tenantId && tenantId !== this.tenantsService.activeTenantId) {
await this.#keycloakService.init(getKeycloakOptions(this.#baseHref, this.#config, tenantId));
}
if (tenantId === this.tenantsService.activeTenantId) {
if (tenantId) {
const url = this.#keycloakService.getKeycloakInstance().createLoginUrl({
redirectUri: this.#keycloakStatusService.createLoginUrl(),
redirectUri: this.#keycloakStatusService.createLoginUrl(tenantId),
idpHint: this.#config.OAUTH_IDP_HINT,
loginHint: email ?? undefined,
});
return this.#keycloakService.logout(url);
}
window.open(window.location.origin + this.#baseHref + tenantUrl, '_blank');
return this.#keycloakService.logout(window.location.origin + this.#baseHref);
}
#getStoredTenants(): Map<string, IStoredTenant[]> {
#getStoredTenants() {
const storedTenants = this.tenantsService.getStoredTenants();
const otherTenant = storedTenants.filter(t => {
const isCurrentTenant = t.tenant.tenantId === this.tenantsService.activeTenantId;
const isCurrentTenant = t.tenantId === this.tenantsService.activeTenantId;
const isCurrentUser = t.email === this.#currentUser.email || t.email === this.#currentUser.username;
return !(isCurrentTenant && isCurrentUser);
});
return otherTenant.groupBy(t => t.tenant.displayName);
const grouped = otherTenant.groupBy(t => t.tenantId);
return [...grouped.keys()].sort((a, b) => a.localeCompare(b)).map(key => ({ key, value: grouped.get(key) }));
}
}

View File

@ -5,7 +5,7 @@
</a>
</ng-container>
<a *ngIf="tenantsService.hasMultiple()" [id]="'switch-accounts'" [matMenuTriggerFor]="tenantsMenu" mat-menu-item>
<a *ngIf="tenantsService.hasMultiple" [id]="'switch-accounts'" [matMenuTriggerFor]="tenantsMenu" mat-menu-item>
{{ 'top-bar.navigation-items.my-account.children.select-tenant' | translate }}
</a>

View File

@ -1,9 +1,11 @@
import { Component, inject } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Roles } from '@users/roles';
import { getCurrentUser, IqserPermissionsService, List, TenantsService } from '@iqser/common-ui';
import { IqserPermissionsService, TenantsService } from '@iqser/common-ui';
import { User } from '@red/domain';
import { UserService } from '@users/user.service';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { List } from '@iqser/common-ui/lib/utils';
interface MenuItem {
readonly id: string;
@ -20,10 +22,10 @@ interface MenuItem {
styleUrls: ['./user-menu.component.scss'],
})
export class UserMenuComponent {
readonly #permissionsService = inject(IqserPermissionsService);
readonly currentUser = getCurrentUser<User>();
readonly tenantsService = inject(TenantsService);
readonly userService = inject(UserService);
readonly #permissionsService = inject(IqserPermissionsService);
readonly userMenuItems: List<MenuItem> = [
{
id: 'account',

View File

@ -3,6 +3,9 @@ import { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';
import { DOSSIER_TEMPLATE_ID } from '@red/domain';
import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service';
import { TenantsService } from '@iqser/common-ui';
import { NGXLogger } from 'ngx-logger';
import { firstValueFrom } from 'rxjs';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
export function templateExistsWhenEnteringAdmin(): CanActivateFn {
return async function (route: ActivatedRouteSnapshot): Promise<boolean> {
@ -20,10 +23,18 @@ export function templateExistsWhenEnteringAdmin(): CanActivateFn {
export function templateExistsWhenEnteringDossierList(): CanActivateFn {
return async function (route: ActivatedRouteSnapshot) {
const dossierTemplateId: string = route.paramMap.get(DOSSIER_TEMPLATE_ID);
const dashboardStatsService = inject(DashboardStatsService);
const dossierTemplatesService = inject(DossierTemplatesService);
const logger = inject(NGXLogger);
const router = inject(Router);
const tenantsService = inject(TenantsService);
const dossierTemplateStats = inject(DashboardStatsService).find(dossierTemplateId);
await firstValueFrom(dashboardStatsService.loadAll());
await firstValueFrom(dossierTemplatesService.loadAll());
const dossierTemplateStats = dashboardStatsService.find(dossierTemplateId);
if (!dossierTemplateStats || dossierTemplateStats.isEmpty) {
await inject(Router).navigate([inject(TenantsService).activeTenantId, 'main']);
logger.warn('[ROUTES] Dossier template not found, redirecting to main');
await router.navigate([tenantsService.activeTenantId, 'main']);
return false;
}
return true;

View File

@ -0,0 +1,47 @@
import { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';
import { inject } from '@angular/core';
import { NGXLogger } from 'ngx-logger';
import { keycloakInitializer, KeycloakStatusService, TenantsService } from '@iqser/common-ui';
import { KeycloakService } from 'keycloak-angular';
import { UserService } from '@users/user.service';
export function ifLoggedIn(): CanActivateFn {
return async (route: ActivatedRouteSnapshot) => {
const logger = inject(NGXLogger);
logger.info('[ROUTES] Check if can activate main');
const tenantsService = inject(TenantsService);
const keycloakService = inject(KeycloakService);
const usersService = inject(UserService);
const keycloakStatusService = inject(KeycloakStatusService);
const keycloakInstance = keycloakService.getKeycloakInstance();
const tenant = route.paramMap.get('tenant');
const queryParams = new URLSearchParams(window.location.search);
const username = queryParams.get('username');
if (!keycloakInstance) {
if (!tenant) {
logger.error('[ROUTES] No tenant found, something is wrong...');
return inject(Router).navigate(['/']);
}
logger.info('[KEYCLOAK] Keycloak init...');
await keycloakInitializer(tenant);
logger.info('[KEYCLOAK] Keycloak init done!');
await tenantsService.selectTenant(tenant);
await usersService.initialize();
}
const isLoggedIn = await keycloakService.isLoggedIn();
if (isLoggedIn) {
logger.info('[ROUTES] Is logged in, continuing');
return true;
}
logger.warn('[ROUTES] Redirect to login');
keycloakStatusService.createLoginUrlAndExecute(username);
return false;
};
}

View File

@ -1,10 +1,11 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CompositeRouteGuard, IqserAuthGuard, IqserPermissionsGuard, IqserRoutes } from '@iqser/common-ui';
import { CompositeRouteGuard, IqserPermissionsGuard, IqserRoutes } from '@iqser/common-ui';
import { RedRoleGuard } from '@users/red-role.guard';
import { BaseAccountScreenComponent } from './base-account-screen/base-account-screen-component';
import { PreferencesComponent } from './screens/preferences/preferences.component';
import { Roles } from '@users/roles';
import { IqserAuthGuard } from '@iqser/common-ui/lib/users';
const routes: IqserRoutes = [
{ path: '', redirectTo: 'user-profile', pathMatch: 'full' },

View File

@ -1,8 +1,9 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { getCurrentUser, IqserPermissionsService } from '@iqser/common-ui';
import { IqserPermissionsService } from '@iqser/common-ui';
import { Roles } from '@users/roles';
import { User } from '@red/domain';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
interface NavItem {
readonly label: string;

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { NotificationPreferencesService } from '../../../services/notification-preferences.service';
import { BaseFormComponent, getCurrentUser, LoadingService, Toaster } from '@iqser/common-ui';
import { BaseFormComponent, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
NotificationCategoriesValues,
@ -12,6 +12,7 @@ import {
} from '@red/domain';
import { firstValueFrom } from 'rxjs';
import { notificationsSettingsTranslations } from '@translations/notifications-settings-translations';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
templateUrl: './notifications-screen.component.html',
@ -24,6 +25,7 @@ export class NotificationsScreenComponent extends BaseFormComponent implements O
readonly notificationGroupsValues = NotificationGroupsValues;
readonly translations = notificationsSettingsTranslations;
readonly currentUser = getCurrentUser<User>();
constructor(
private readonly _toaster: Toaster,
private readonly _formBuilder: UntypedFormBuilder,

View File

@ -2,8 +2,9 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/
import { PreferencesKeys, UserPreferenceService } from '@users/user-preference.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { AsControl, BaseFormComponent, IqserPermissionsService } from '@iqser/common-ui';
import { BaseFormComponent, IqserPermissionsService } from '@iqser/common-ui';
import { Roles } from '@users/roles';
import { AsControl } from '@iqser/common-ui/lib/utils';
interface PreferencesForm {
// preferences

View File

@ -1,5 +1,5 @@
import { NgModule } from '@angular/core';
import { CompositeRouteGuard, IqserAuthGuard, IqserPermissionsGuard, IqserRoutes } from '@iqser/common-ui';
import { CompositeRouteGuard, IqserPermissionsGuard, IqserRoutes } from '@iqser/common-ui';
import { RedRoleGuard } from '@users/red-role.guard';
import { EntitiesListingScreenComponent } from './screens/entities-listing/entities-listing-screen.component';
import { PendingChangesGuard } from '@guards/can-deactivate.guard';
@ -18,6 +18,7 @@ import { entityExistsGuard } from '@guards/entity-exists-guard.service';
import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-screen.component';
import { PermissionsGuard } from '@guards/permissions-guard';
import { Roles } from '@users/roles';
import { IqserAuthGuard } from '@iqser/common-ui/lib/users';
const dossierTemplateIdRoutes: IqserRoutes = [
{

View File

@ -49,13 +49,13 @@ import {
IqserHelpModeModule,
IqserListingModule,
IqserUploadFileModule,
IqserUsersModule,
RoundCheckboxComponent,
TenantPipe,
} from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { AuditInfoDialogComponent } from './dialogs/audit-info-dialog/audit-info-dialog.component';
import { DossierTemplateActionsComponent } from './shared/components/dossier-template-actions/dossier-template-actions.component';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
const dialogs = [
AddEditCloneDossierTemplateDialogComponent,

View File

@ -4,21 +4,22 @@ import { Router } from '@angular/router';
import { firstValueFrom, Observable } from 'rxjs';
import { AdminDialogService } from '../services/admin-dialog.service';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { getParam, LoadingService, TenantsService } from '@iqser/common-ui';
import { LoadingService, TenantsService } from '@iqser/common-ui';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { map } from 'rxjs/operators';
import { PermissionsService } from '@services/permissions.service';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './base-entity-screen.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BaseEntityScreenComponent {
readonly disabledItems$: Observable<string[]>;
readonly canDeleteEntity$: Observable<boolean>;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly #entityType = getParam(ENTITY_TYPE);
readonly disabledItems$: Observable<string[]>;
readonly canDeleteEntity$: Observable<boolean>;
constructor(
private readonly _router: Router,

View File

@ -1,13 +1,14 @@
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { AdminDialogService } from '../../../services/admin-dialog.service';
import { BaseFormComponent, IProfileUpdateRequest, LoadingService, Toaster } from '@iqser/common-ui';
import { BaseFormComponent, LoadingService, Toaster } from '@iqser/common-ui';
import { rolesTranslations } from '@translations/roles-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { User } from '@red/domain';
import { UserService } from '@users/user.service';
import { HttpStatusCode } from '@angular/common/http';
import { firstValueFrom } from 'rxjs';
import { IProfileUpdateRequest } from '@iqser/common-ui/lib/users';
@Component({
selector: 'redaction-user-details',
@ -15,17 +16,15 @@ import { firstValueFrom } from 'rxjs';
styleUrls: ['./user-details.component.scss'],
})
export class UserDetailsComponent extends BaseFormComponent implements OnChanges {
/** e.g. a RED_ADMIN is automatically a RED_USER_ADMIN => can't disable RED_USER_ADMIN as long as RED_ADMIN is checked */
private readonly _ROLE_REQUIREMENTS = { RED_MANAGER: 'RED_USER', RED_ADMIN: 'RED_USER_ADMIN' };
@Input() user: User;
@Output() readonly toggleResetPassword = new EventEmitter();
@Output() readonly closeDialog = new EventEmitter();
@Output() readonly cancel = new EventEmitter();
readonly ROLES = ['RED_USER', 'RED_MANAGER', 'RED_USER_ADMIN', 'RED_ADMIN'];
readonly translations = rolesTranslations;
/** e.g. a RED_ADMIN is automatically a RED_USER_ADMIN => can't disable RED_USER_ADMIN as long as RED_ADMIN is checked */
private readonly _ROLE_REQUIREMENTS = { RED_MANAGER: 'RED_USER', RED_ADMIN: 'RED_USER_ADMIN' };
constructor(
private readonly _formBuilder: UntypedFormBuilder,
private readonly _toaster: Toaster,

View File

@ -3,7 +3,6 @@ import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
import {
CircleButtonTypes,
getCurrentUser,
IqserPermissionsService,
ListingComponent,
listingProvidersFactory,
@ -19,6 +18,7 @@ import { Dayjs } from 'dayjs';
import { RouterHistoryService } from '@services/router-history.service';
import { Roles } from '@users/roles';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
const PAGE_SIZE = 50;
@ -28,6 +28,8 @@ const PAGE_SIZE = 50;
providers: listingProvidersFactory(AuditScreenComponent),
})
export class AuditScreenComponent extends ListingComponent<Audit> implements OnInit, OnDestroy {
private _previousFrom: Dayjs;
private _previousTo: Dayjs;
readonly circleButtonTypes = CircleButtonTypes;
readonly ALL_CATEGORIES = 'allCategories';
readonly ALL_USERS = _('audit-screen.all-users');
@ -37,11 +39,9 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
readonly permissionsService = inject(IqserPermissionsService);
readonly roles = Roles;
readonly currentUser = getCurrentUser<User>();
categories: string[] = [];
userIds: Set<string>;
logs: IAuditResponse;
readonly tableColumnConfigs: TableColumnConfig<Audit>[] = [
{ label: _('audit-screen.table-col-names.message') },
{ label: _('audit-screen.table-col-names.date') },
@ -49,8 +49,6 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
{ label: _('audit-screen.table-col-names.category') },
];
readonly tableHeaderLabel = _('audit-screen.table-header.title');
private _previousFrom: Dayjs;
private _previousTo: Dayjs;
constructor(
private readonly _formBuilder: UntypedFormBuilder,

View File

@ -1,21 +1,15 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DefaultColorTypes, DOSSIER_TEMPLATE_ID, User } from '@red/domain';
import { AdminDialogService } from '../../services/admin-dialog.service';
import {
CircleButtonTypes,
getCurrentUser,
getParam,
IListable,
ListingComponent,
listingProvidersFactory,
TableColumnConfig,
} from '@iqser/common-ui';
import { CircleButtonTypes, IListable, ListingComponent, listingProvidersFactory, TableColumnConfig } from '@iqser/common-ui';
import { defaultColorsTranslations } from '@translations/default-colors-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { combineLatest } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam } from '@iqser/common-ui/lib/utils';
interface ListItem extends IListable {
readonly key: string;
@ -29,6 +23,7 @@ interface ListItem extends IListable {
providers: listingProvidersFactory(DefaultColorsScreenComponent),
})
export class DefaultColorsScreenComponent extends ListingComponent<ListItem> {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = getCurrentUser<User>();
readonly roles = Roles;
@ -39,7 +34,6 @@ export class DefaultColorsScreenComponent extends ListingComponent<ListItem> {
{ label: _('default-colors-screen.table-col-names.color'), class: 'flex-center' },
];
readonly context$;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(private readonly _dialogService: AdminDialogService, private readonly _defaultColorsService: DefaultColorsService) {
super();

View File

@ -1,5 +1,5 @@
import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { getCurrentUser, IconButtonTypes, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui';
import { IconButtonTypes, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RouterHistoryService } from '@services/router-history.service';
import { DigitalSignatureService } from '../../services/digital-signature.service';
@ -9,6 +9,7 @@ import { PkcsSignatureConfigurationComponent } from '../../dialogs/configure-dig
import { KmsSignatureConfigurationComponent } from '../../dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component';
import { DigitalSignatureOptions, IKmsDigitalSignatureRequest, IPkcsDigitalSignatureRequest, User } from '@red/domain';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
selector: 'redaction-digital-signature-screen',

View File

@ -2,8 +2,6 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import {
CircleButtonTypes,
defaultDialogConfig,
getCurrentUser,
getParam,
IconButtonTypes,
ListingComponent,
listingProvidersFactory,
@ -21,6 +19,8 @@ import {
AddEditDossierAttributeDialogComponent,
AddEditDossierAttributeDialogData,
} from './add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './dossier-attributes-listing-screen.component.html',
@ -31,6 +31,7 @@ import {
}),
})
export class DossierAttributesListingScreenComponent extends ListingComponent<DossierAttributeConfig> implements OnInit {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = getCurrentUser<User>();
@ -42,7 +43,6 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
];
@ViewChild('impactedTemplates') impactedTemplatesRef: TemplateRef<unknown>;
readonly canEditDossierAttributes = this.permissionsService.canEditGlobalDossierAttributes();
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
readonly permissionsService: PermissionsService,

View File

@ -1,13 +1,5 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import {
defaultDialogConfig,
getParam,
IconButtonTypes,
ListingComponent,
listingProvidersFactory,
SortingOrders,
TableColumnConfig,
} from '@iqser/common-ui';
import { defaultDialogConfig, IconButtonTypes, ListingComponent, listingProvidersFactory, TableColumnConfig } from '@iqser/common-ui';
import { type DonutChartConfig, DOSSIER_TEMPLATE_ID, type DossierState } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { firstValueFrom, Observable } from 'rxjs';
@ -20,6 +12,8 @@ import {
AddEditDossierStateDialogComponent,
AddEditDossierStateDialogData,
} from '../add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component';
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './dossier-states-listing-screen.component.html',
@ -27,6 +21,7 @@ import {
providers: listingProvidersFactory(DossierStatesListingScreenComponent),
})
export class DossierStatesListingScreenComponent extends ListingComponent<DossierState> implements OnInit, OnDestroy {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly tableHeaderLabel = _('dossier-states-listing.table-header.title');
readonly tableColumnConfigs: TableColumnConfig<DossierState>[] = [
@ -35,7 +30,6 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
{ label: _('dossier-states-listing.table-col-names.dossiers-count'), class: 'flex-center' },
];
readonly chartConfig$: Observable<DonutChartConfig[]>;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
private readonly _dialog: MatDialog,

View File

@ -4,7 +4,6 @@ import { AdminDialogService } from '../../../services/admin-dialog.service';
import { DossierTemplate, User } from '@red/domain';
import {
CircleButtonTypes,
getCurrentUser,
IconButtonTypes,
IqserPermissionsService,
ListingComponent,
@ -17,6 +16,7 @@ import { RouterHistoryService } from '@services/router-history.service';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { firstValueFrom } from 'rxjs';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
templateUrl: './dossier-templates-listing-screen.component.html',

View File

@ -12,10 +12,10 @@ import {
IqserHelpModeModule,
IqserListingModule,
IqserRoutes,
IqserUsersModule,
} from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { DossierTemplateActionsComponent } from '../../shared/components/dossier-template-actions/dossier-template-actions.component';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
const routes: IqserRoutes = [{ path: '', component: DossierTemplatesListingScreenComponent }];

View File

@ -1,7 +1,6 @@
import { Component } from '@angular/core';
import {
CircleButtonTypes,
getParam,
IconButtonTypes,
ListingComponent,
listingProvidersFactory,
@ -17,6 +16,7 @@ import { DossierTemplateStatsService } from '@services/entity-services/dossier-t
import { tap } from 'rxjs/operators';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { PermissionsService } from '@services/permissions.service';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './entities-listing-screen.component.html',
@ -24,6 +24,7 @@ import { PermissionsService } from '@services/permissions.service';
providers: listingProvidersFactory(EntitiesListingScreenComponent),
})
export class EntitiesListingScreenComponent extends ListingComponent<Dictionary> {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly tableHeaderLabel = _('entities-listing.table-header.title');
@ -34,7 +35,6 @@ export class EntitiesListingScreenComponent extends ListingComponent<Dictionary>
{ label: _('entities-listing.table-col-names.dictionary-entries') },
];
readonly templateStats$: Observable<DossierTemplateStats>;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
private readonly _loadingService: LoadingService,

View File

@ -2,12 +2,14 @@ import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/
import { ActivatedRoute } from '@angular/router';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { getCurrentUser, getParam, IqserPermissionsService, List, LoadingService } from '@iqser/common-ui';
import { IqserPermissionsService, LoadingService } from '@iqser/common-ui';
import { BehaviorSubject } from 'rxjs';
import { DICTIONARY_TO_ENTRY_TYPE_MAP, DICTIONARY_TYPE_KEY_MAP, DictionaryType, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { Roles } from '@users/roles';
import { NGXLogger } from 'ngx-logger';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam, List } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './dictionary-screen.component.html',
@ -15,15 +17,15 @@ import { NGXLogger } from 'ngx-logger';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DictionaryScreenComponent implements OnInit {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
@ViewChild('dictionaryManager', { static: false })
private readonly _dictionaryManager: DictionaryManagerComponent;
readonly currentUser = getCurrentUser<User>();
readonly roles = Roles;
readonly initialEntries$ = new BehaviorSubject<string[]>([]);
isLeavingPage = false;
readonly type: DictionaryType;
readonly entityType = getParam(ENTITY_TYPE);
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
@ViewChild('dictionaryManager', { static: false })
private readonly _dictionaryManager: DictionaryManagerComponent;
constructor(
route: ActivatedRoute,

View File

@ -5,9 +5,10 @@ import { ActivatedRoute } from '@angular/router';
import { getCurrentUser } from '@users/user.service';
import { PermissionsService } from '@services/permissions.service';
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
import { IconButtonTypes, IqserEventTarget } from '@iqser/common-ui';
import { IconButtonTypes } from '@iqser/common-ui';
import { Observable } from 'rxjs';
import { Roles } from '@users/roles';
import { IqserEventTarget } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-entity-info',
@ -16,14 +17,13 @@ import { Roles } from '@users/roles';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EntityInfoComponent {
@ViewChild(AddEditEntityComponent) private readonly _addEditEntityComponent: AddEditEntityComponent;
readonly currentUser = getCurrentUser();
readonly entity$: Observable<Dictionary>;
readonly dossierTemplateId: string;
readonly roles = Roles;
readonly iconButtonTypes = IconButtonTypes;
@ViewChild(AddEditEntityComponent) private readonly _addEditEntityComponent: AddEditEntityComponent;
constructor(route: ActivatedRoute, dictionariesMapService: DictionariesMapService, readonly permissionsService: PermissionsService) {
this.dossierTemplateId = route.parent.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
const entityType = route.parent.snapshot.paramMap.get(ENTITY_TYPE);

View File

@ -4,11 +4,12 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as Papa from 'papaparse';
import { firstValueFrom, Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { IconButtonTypes, ListingComponent, listingProvidersFactory, TableColumnConfig, Toaster, trackByFactory } from '@iqser/common-ui';
import { IconButtonTypes, ListingComponent, listingProvidersFactory, TableColumnConfig, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileAttributeConfig, FileAttributeConfigTypes, FileAttributeEncodingTypes, IField, IFileAttributesConfig } from '@red/domain';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { fileAttributeEncodingTypesTranslations } from '@translations/file-attribute-encoding-types-translations';
import { trackByFactory } from '@iqser/common-ui/lib/utils';
export interface IFileAttributesCSVImportData {
readonly csv: File;

View File

@ -3,8 +3,6 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
import {
CircleButtonTypes,
defaultDialogConfig,
getCurrentUser,
getParam,
IconButtonTypes,
largeDialogConfig,
ListingComponent,
@ -32,6 +30,8 @@ import {
IFileAttributesCSVImportData,
} from './file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
import { FileAttributesConfigurationsDialogComponent } from './file-attributes-configurations-dialog/file-attributes-configurations-dialog.component';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './file-attributes-listing-screen.component.html',
@ -39,6 +39,10 @@ import { FileAttributesConfigurationsDialogComponent } from './file-attributes-c
providers: listingProvidersFactory(FileAttributesListingScreenComponent),
})
export class FileAttributesListingScreenComponent extends ListingComponent<FileAttributeConfig> implements OnInit, OnDestroy {
@ViewChild('impactedTemplates') private readonly _impactedTemplatesRef: TemplateRef<unknown>;
#existingConfiguration: IFileAttributesConfig;
@ViewChild('fileInput') private _fileInput: ElementRef;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = getCurrentUser<User>();
@ -59,18 +63,6 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
},
];
readonly roles = Roles;
@ViewChild('impactedTemplates') private readonly _impactedTemplatesRef: TemplateRef<unknown>;
#existingConfiguration: IFileAttributesConfig;
@ViewChild('fileInput') private _fileInput: ElementRef;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
private get _numberOfDisplayedAttrs(): number {
return this.entitiesService.all.filter(attr => attr.displayedInFileList).length;
}
private get _numberOfFilterableAttrs(): number {
return this.entitiesService.all.filter(attr => attr.filterable).length;
}
constructor(
readonly permissionsService: PermissionsService,
@ -84,6 +76,14 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
super();
}
private get _numberOfDisplayedAttrs(): number {
return this.entitiesService.all.filter(attr => attr.displayedInFileList).length;
}
private get _numberOfFilterableAttrs(): number {
return this.entitiesService.all.filter(attr => attr.filterable).length;
}
async ngOnInit() {
await this.#loadData();
}

View File

@ -1,10 +1,11 @@
import { Component } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { SystemPreferences } from '@red/domain';
import { BaseFormComponent, IqserPermissionsService, KeysOf, LoadingService } from '@iqser/common-ui';
import { BaseFormComponent, IqserPermissionsService, LoadingService } from '@iqser/common-ui';
import { SystemPreferencesService } from '@services/system-preferences.service';
import { systemPreferencesTranslations } from '@translations/system-preferences-translations';
import { Roles } from '@users/roles';
import { KeysOf } from '@iqser/common-ui/lib/utils';
export type ValueType = 'number' | 'string' | 'boolean';
@ -13,24 +14,24 @@ export type ValueType = 'number' | 'string' | 'boolean';
templateUrl: './system-preferences-form.component.html',
})
export class SystemPreferencesFormComponent extends BaseFormComponent {
#initialConfiguration: SystemPreferences;
readonly translations = systemPreferencesTranslations;
readonly keys: { name: KeysOf<SystemPreferences>; type: ValueType }[] = [
{ name: 'softDeleteCleanupTime', type: 'number' },
{ name: 'downloadCleanupNotDownloadFilesHours', type: 'number' },
{ name: 'downloadCleanupDownloadFilesHours', type: 'number' },
];
private _initialConfiguration: SystemPreferences;
constructor(
private readonly _loadingService: LoadingService,
private readonly _systemPreferencesService: SystemPreferencesService,
private readonly _formBuilder: UntypedFormBuilder,
private readonly _permissionsService: IqserPermissionsService,
permissionsService: IqserPermissionsService,
) {
super();
this.form = this._getForm();
this._loadData();
if (!_permissionsService.has(Roles.appConfiguration.write)) {
this.form = this.#getForm();
this.#loadData();
if (!permissionsService.has(Roles.appConfiguration.write)) {
this.form.disable();
}
}
@ -38,19 +39,21 @@ export class SystemPreferencesFormComponent extends BaseFormComponent {
async save(): Promise<void> {
this._loadingService.start();
await this._systemPreferencesService.update(this.form.getRawValue());
this._loadData();
this.#loadData();
this._loadingService.stop();
}
private _getForm(): UntypedFormGroup {
#getForm() {
const controlsConfig = {};
this.keys.forEach(key => (controlsConfig[key.name] = [this._systemPreferencesService.values[key.name], Validators.required]));
this.keys.forEach(key => {
controlsConfig[key.name] = [this._systemPreferencesService.values[key.name], Validators.required];
});
return this._formBuilder.group(controlsConfig);
}
private _loadData() {
this._initialConfiguration = this._systemPreferencesService.values;
this.form.patchValue(this._initialConfiguration, { emitEvent: false });
#loadData() {
this.#initialConfiguration = this._systemPreferencesService.values;
this.form.patchValue(this.#initialConfiguration, { emitEvent: false });
this.initialFormValue = this.form.getRawValue();
}
}

View File

@ -3,8 +3,9 @@ import { CommonModule } from '@angular/common';
import { DossierTemplateInfoScreenComponent } from './info-screen/dossier-template-info-screen.component';
import { RouterModule } from '@angular/router';
import { SharedModule } from '@shared/shared.module';
import { HasScrollbarDirective, IqserHelpModeModule, IqserUsersModule } from '@iqser/common-ui';
import { HasScrollbarDirective, IqserHelpModeModule } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
const routes = [{ path: '', component: DossierTemplateInfoScreenComponent }];

View File

@ -3,7 +3,7 @@ import { DossierTemplatesService } from '@services/dossier-templates/dossier-tem
import { DOSSIER_TEMPLATE_ID, type DossierTemplate, type DossierTemplateStats } from '@red/domain';
import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service';
import { dossierTemplateStatusTranslations } from '@translations/dossier-template-status-translations';
import { ContextComponent, getParam } from '@iqser/common-ui';
import { ContextComponent, getParam } from '@iqser/common-ui/lib/utils';
interface Context {
readonly dossierTemplate: DossierTemplate;

View File

@ -2,12 +2,10 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
CircleButtonTypes,
getParam,
IconButtonTypes,
ListingComponent,
listingProvidersFactory,
LoadingService,
SortingOrders,
TableColumnConfig,
} from '@iqser/common-ui';
import { DOSSIER_TEMPLATE_ID, Justification } from '@red/domain';
@ -16,6 +14,8 @@ import { JustificationsDialogService } from '../justifications-dialog.service';
import { UserPreferenceService } from '@users/user-preference.service';
import { firstValueFrom } from 'rxjs';
import { PermissionsService } from '@services/permissions.service';
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-justifications-screen',
@ -28,6 +28,7 @@ import { PermissionsService } from '@services/permissions.service';
}),
})
export class JustificationsScreenComponent extends ListingComponent<Justification> implements OnInit {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly tableHeaderLabel = _('justifications-listing.table-header');
@ -37,7 +38,6 @@ export class JustificationsScreenComponent extends ListingComponent<Justificatio
{ label: _('justifications-listing.table-col-names.description'), width: '2fr' },
];
readonly canAddEditJustifications = this.permissionsService.canAddEditJustifications();
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
private readonly _justificationService: JustificationsService,

View File

@ -1,8 +1,9 @@
import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core';
import { DOSSIER_TEMPLATE_ID, Justification } from '@red/domain';
import { CircleButtonTypes, getParam } from '@iqser/common-ui';
import { CircleButtonTypes } from '@iqser/common-ui';
import { JustificationsDialogService } from '../justifications-dialog.service';
import { PermissionsService } from '@services/permissions.service';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-table-item',
@ -10,10 +11,10 @@ import { PermissionsService } from '@services/permissions.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TableItemComponent {
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID);
readonly circleButtonTypes = CircleButtonTypes;
@Input() justification: Justification;
readonly canAddEditJustifications = inject(PermissionsService).canAddEditJustifications();
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID);
constructor(private readonly _dialogService: JustificationsDialogService) {}

View File

@ -1,6 +1,6 @@
import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { size } from '@iqser/common-ui';
import { size } from '@iqser/common-ui/lib/utils';
import { LicenseService } from '@services/license.service';
import { map, tap } from 'rxjs/operators';
import type { DonutChartConfig, ILicenseReport } from '@red/domain';

View File

@ -1,12 +1,13 @@
import { Component } from '@angular/core';
import { ConfigService } from '@services/config.service';
import { TranslateService } from '@ngx-translate/core';
import { ButtonConfig, getCurrentUser, IconButtonTypes, IqserPermissionsService } from '@iqser/common-ui';
import { ButtonConfig, IconButtonTypes, IqserPermissionsService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RouterHistoryService } from '@services/router-history.service';
import { LicenseService } from '@services/license.service';
import { Roles } from '@users/roles';
import type { User } from '@red/domain';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
templateUrl: './license-screen.component.html',

View File

@ -1,13 +1,5 @@
import { Component, OnDestroy } from '@angular/core';
import {
getCurrentUser,
IqserPermissionsService,
ListingComponent,
listingProvidersFactory,
LoadingService,
SortingOrders,
TableColumnConfig,
} from '@iqser/common-ui';
import { IqserPermissionsService, ListingComponent, listingProvidersFactory, LoadingService, TableColumnConfig } from '@iqser/common-ui';
import { PermissionsMapping, User } from '@red/domain';
import { ConfigService } from '../config.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -20,6 +12,8 @@ import { switchMap, tap } from 'rxjs/operators';
import { permissionsTranslations } from '@translations/permissions-translations';
import { RouterHistoryService } from '@services/router-history.service';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
@Component({
templateUrl: './permissions-screen.component.html',
@ -27,6 +21,7 @@ import { Roles } from '@users/roles';
providers: listingProvidersFactory(PermissionsScreenComponent),
})
export class PermissionsScreenComponent extends ListingComponent<PermissionsMapping> implements OnDestroy {
readonly #subscription: Subscription = new Subscription();
readonly roles = Roles;
readonly currentUser = getCurrentUser<User>();
readonly translations = permissionsTranslations;
@ -34,7 +29,6 @@ export class PermissionsScreenComponent extends ListingComponent<PermissionsMapp
readonly tableHeaderLabel = _('permissions-screen.table-header.title');
readonly targetObject: string;
readonly mappedPermissions: string[];
readonly #subscription: Subscription = new Subscription();
constructor(
route: ActivatedRoute,

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { DOSSIER_TEMPLATE_ID, IPlaceholdersResponse, IReportTemplate, User } from '@red/domain';
import { download } from '@utils/file-download-utils';
import { getCurrentUser, getParam, IConfirmationDialogData, LoadingService, Toaster } from '@iqser/common-ui';
import { IConfirmationDialogData, LoadingService, Toaster } from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
import {
generalPlaceholdersDescriptionsTranslations,
@ -13,6 +13,8 @@ import { AdminDialogService } from '../../../services/admin-dialog.service';
import { ReportTemplateService } from '@services/report-template.service';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam } from '@iqser/common-ui/lib/utils';
interface Placeholder {
placeholder: string;
@ -30,12 +32,12 @@ const placeholderTypes: PlaceholderType[] = ['generalPlaceholders', 'fileAttribu
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ReportsScreenComponent implements OnInit {
@ViewChild('fileInput') private readonly _fileInput: ElementRef;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly placeholders$ = new BehaviorSubject<Placeholder[]>([]);
readonly availableTemplates$ = new BehaviorSubject<IReportTemplate[]>([]);
readonly currentUser = getCurrentUser<User>();
readonly roles = Roles;
@ViewChild('fileInput') private readonly _fileInput: ElementRef;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
private readonly _reportTemplateService: ReportTemplateService,

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { saveAs } from 'file-saver';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RulesService } from '../../../services/rules.service';
@ -8,6 +8,7 @@ import { firstValueFrom } from 'rxjs';
import { DOSSIER_TEMPLATE_ID } from '@red/domain';
import { EditorThemeService } from '@services/editor-theme.service';
import { ComponentCanDeactivate } from '@guards/can-deactivate.guard';
import { Debounce, getParam } from '@iqser/common-ui/lib/utils';
import ICodeEditor = monaco.editor.ICodeEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
@ -18,6 +19,11 @@ import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorCon
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
@ViewChild('fileInput')
private _fileInput: ElementRef;
private _codeEditor: ICodeEditor;
private _decorations: string[] = [];
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly editorOptions: IStandaloneEditorConstructionOptions = {
theme: 'vs',
@ -25,19 +31,10 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
automaticLayout: true,
readOnly: !this.permissionsService.canEditRules(),
};
initialLines: string[] = [];
currentLines: string[] = [];
isLeaving = false;
@ViewChild('fileInput')
private _fileInput: ElementRef;
private _codeEditor: ICodeEditor;
private _decorations: string[] = [];
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
readonly permissionsService: PermissionsService,
private readonly _rulesService: RulesService,

View File

@ -11,7 +11,6 @@ import {
ListingComponent,
listingProvidersFactory,
LoadingService,
NestedFilter,
SearchPositions,
TableColumnConfig,
} from '@iqser/common-ui';
@ -22,6 +21,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { userTypeChecker, userTypeFilters } from '../../../../utils';
import { RouterHistoryService } from '@services/router-history.service';
import { Roles } from '@users/roles';
import { NestedFilter } from '@iqser/common-ui/lib/filtering';
function configToFilter({ key, label }: DonutChartConfig) {
return new NestedFilter({

View File

@ -2,20 +2,7 @@ import { ChangeDetectorRef, Component, ElementRef, inject, OnInit, ViewChild } f
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
import { HttpClient } from '@angular/common/http';
import { FormBuilder, FormGroup } from '@angular/forms';
import {
AsControl,
BASE_HREF_FN,
Debounce,
getConfig,
getCurrentUser,
getParam,
IconButtonTypes,
IqserPermissionsService,
LoadingService,
TenantsService,
Toaster,
trackByFactory,
} from '@iqser/common-ui';
import { getConfig, IconButtonTypes, IqserPermissionsService, LoadingService, TenantsService, Toaster } from '@iqser/common-ui';
import {
AppConfig,
DOSSIER_TEMPLATE_ID,
@ -42,6 +29,8 @@ import { Roles } from '@users/roles';
import { environment } from '@environments/environment';
import { tap } from 'rxjs/operators';
import { watermarkTranslations } from '@translations/watermark-translations';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { AsControl, BASE_HREF_FN, Debounce, getParam, trackByFactory } from '@iqser/common-ui/lib/utils';
export const DEFAULT_WATERMARK: Partial<IWatermark> = {
text: 'Watermark',
@ -72,6 +61,13 @@ interface WatermarkForm {
styleUrls: ['./watermark-screen.component.scss'],
})
export class WatermarkScreenComponent implements OnInit {
@ViewChild('viewer', { static: true }) private readonly _viewer: ElementRef<HTMLDivElement>;
private readonly _convertPath = inject(BASE_HREF_FN);
readonly #loaded$ = new BehaviorSubject(false);
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly #watermarkId = Number(getParam(WATERMARK_ID));
readonly #config = getConfig<AppConfig>();
#watermark: Partial<IWatermark> = {};
readonly iconButtonTypes = IconButtonTypes;
readonly translations = watermarkTranslations;
readonly trackBy = trackByFactory();
@ -89,13 +85,6 @@ export class WatermarkScreenComponent implements OnInit {
readonly watermarkHorizontalAlignments = Object.values(WATERMARK_HORIZONTAL_ALIGNMENTS);
readonly watermarkVerticalAlignments = Object.values(WATERMARK_VERTICAL_ALIGNMENTS);
currentAlignment: WatermarkAlignment;
@ViewChild('viewer', { static: true }) private readonly _viewer: ElementRef<HTMLDivElement>;
private readonly _convertPath = inject(BASE_HREF_FN);
readonly #loaded$ = new BehaviorSubject(false);
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly #watermarkId = Number(getParam(WATERMARK_ID));
readonly #config = getConfig<AppConfig>();
#watermark: Partial<IWatermark> = {};
constructor(
private readonly _http: HttpClient,

View File

@ -9,11 +9,9 @@ import {
HasScrollbarDirective,
IconButtonComponent,
IqserAllowDirective,
IqserAuthGuard,
IqserHelpModeModule,
IqserListingModule,
IqserRoutes,
IqserUsersModule,
TenantPipe,
} from '@iqser/common-ui';
import { RedRoleGuard } from '@users/red-role.guard';
@ -27,6 +25,7 @@ import { MatSliderModule } from '@angular/material/slider';
import { ColorPickerModule } from 'ngx-color-picker';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { IqserAuthGuard, IqserUsersModule } from '@iqser/common-ui/lib/users';
const routes: IqserRoutes = [
{

View File

@ -1,8 +1,6 @@
import { Component } from '@angular/core';
import {
CircleButtonTypes,
getCurrentUser,
getParam,
IconButtonTypes,
IConfirmationDialogData,
IqserPermissionsService,
@ -18,6 +16,8 @@ import { WatermarkService } from '@services/entity-services/watermark.service';
import { AdminDialogService } from '../../../services/admin-dialog.service';
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './watermarks-listing-screen.component.html',
@ -25,6 +25,7 @@ import { Roles } from '@users/roles';
providers: listingProvidersFactory(WatermarksListingScreenComponent),
})
export class WatermarksListingScreenComponent extends ListingComponent<Watermark> {
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = getCurrentUser<User>();
@ -37,7 +38,6 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
{ label: _('watermarks-listing.table-col-names.modified-on'), sortByKey: 'dateModified' },
];
readonly tableHeaderLabel = _('watermarks-listing.table-header.title');
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
private readonly _loadingService: LoadingService,

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { filterEach, GenericService } from '@iqser/common-ui';
import { GenericService } from '@iqser/common-ui';
import { forkJoin, Observable, of } from 'rxjs';
import {
IDigitalSignatureRequest,
@ -9,6 +9,7 @@ import {
IPkcsDigitalSignatureRequest,
} from '@red/domain';
import { catchError, map } from 'rxjs/operators';
import { filterEach } from '@iqser/common-ui/lib/utils';
@Injectable()
export class DigitalSignatureService extends GenericService<IDigitalSignatureRequest> {

View File

@ -5,9 +5,10 @@ import { adminSideNavTranslations } from '@translations/admin-side-nav-translati
import { ActivatedRoute, RouterLink, RouterLinkActive } from '@angular/router';
import { AdminSideNavType, AdminSideNavTypes, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User, WATERMARK_ID } from '@red/domain';
import { Roles } from '@users/roles';
import { getCurrentUser, IqserHelpModeModule, IqserPermissionsService, SideNavComponent, TenantPipe } from '@iqser/common-ui';
import { IqserHelpModeModule, IqserPermissionsService, SideNavComponent, TenantPipe } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { NgForOf, NgIf } from '@angular/common';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
interface NavItem {
readonly label: string;

View File

@ -1,19 +1,13 @@
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AdminDialogService } from '../../../services/admin-dialog.service';
import {
CircleButtonComponent,
CircleButtonTypes,
getCurrentUser,
IqserHelpModeModule,
LoadingService,
TenantsService,
} from '@iqser/common-ui';
import { CircleButtonComponent, CircleButtonTypes, IqserHelpModeModule, LoadingService, TenantsService } from '@iqser/common-ui';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { firstValueFrom } from 'rxjs';
import { DOSSIER_TEMPLATE_ID, type User } from '@red/domain';
import { NgIf } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
selector: 'redaction-dossier-template-actions',

View File

@ -4,10 +4,11 @@ import { ArchivedDossiersScreenComponent } from './screens/archived-dossiers-scr
import { ArchiveRoutingModule } from './archive-routing.module';
import { TableItemComponent } from './components/table-item/table-item.component';
import { ConfigService } from './services/config.service';
import { IqserHelpModeModule, IqserListingModule, IqserUsersModule } from '@iqser/common-ui';
import { IqserHelpModeModule, IqserListingModule } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { SharedModule } from '@shared/shared.module';
import { SharedDossiersModule } from '../shared-dossiers/shared-dossiers.module';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
@NgModule({
declarations: [TableItemComponent, ArchivedDossiersScreenComponent],

View File

@ -1,11 +1,12 @@
import { Injectable } from '@angular/core';
import { IFilterGroup, keyChecker, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
import { TableColumnConfig } from '@iqser/common-ui';
import { Dossier, User } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { dossierMemberChecker, dossierMemberQuickChecker, dossierOwnerQuickChecker, dossierTemplateChecker } from '@utils/index';
import { UserService } from '@users/user.service';
import { TranslateService } from '@ngx-translate/core';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { IFilterGroup, keyChecker, NestedFilter } from '@iqser/common-ui/lib/filtering';
@Injectable()
export class ConfigService {

View File

@ -1,8 +1,9 @@
import { Component, inject, OnInit } from '@angular/core';
import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service';
import { UserPreferenceService } from '@users/user-preference.service';
import { getCurrentUser, trackByFactory } from '@iqser/common-ui';
import { trackByFactory } from '@iqser/common-ui/lib/utils';
import { User } from '@red/domain';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
templateUrl: './dashboard-screen.component.html',

View File

@ -13,16 +13,7 @@ import {
} from '@red/domain';
import { TranslateChartService } from '@services/translate-chart.service';
import { UserService } from '@users/user.service';
import {
ContextComponent,
FilterService,
getCurrentUser,
getParam,
INestedFilter,
ProgressBarConfigModel,
shareLast,
Toaster,
} from '@iqser/common-ui';
import { ProgressBarConfigModel, Toaster } from '@iqser/common-ui';
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { combineLatestWith, firstValueFrom } from 'rxjs';
@ -31,6 +22,9 @@ import { map, tap } from 'rxjs/operators';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { FilesMapService } from '@services/files/files-map.service';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { FilterService, INestedFilter } from '@iqser/common-ui/lib/filtering';
import { ContextComponent, getParam, shareLast } from '@iqser/common-ui/lib/utils';
interface DossierDetailsContext {
needsWorkFilters: INestedFilter[] | undefined;
@ -45,17 +39,16 @@ interface DossierDetailsContext {
styleUrls: ['./dossier-details.component.scss'],
})
export class DossierDetailsComponent extends ContextComponent<DossierDetailsContext> {
#currentChartSubtitleIndex = 0;
readonly #dossierId = getParam(DOSSIER_ID);
@Input() dossierAttributes: DossierAttributeWithValue[];
@Output() readonly toggleCollapse = new EventEmitter();
editingOwner = false;
readonly roles = Roles;
readonly currentUser = getCurrentUser<User>();
readonly collapseTooltip = _('dossier-details.collapse');
readonly expandTooltip = _('dossier-details.expand');
chartConfig: DonutChartConfig[] = [];
#currentChartSubtitleIndex = 0;
readonly #dossierId = getParam(DOSSIER_ID);
constructor(
private readonly _toaster: Toaster,

View File

@ -3,11 +3,8 @@ import {
ActionConfig,
CircleButtonTypes,
EntitiesService,
List,
ListingService,
LoadingService,
some,
SortingService,
TenantsService,
Toaster,
} from '@iqser/common-ui';
@ -22,6 +19,8 @@ import { ConfigService } from '../../config.service';
import { PrimaryFileAttributeService } from '@services/primary-file-attribute.service';
import { Router } from '@angular/router';
import { Roles } from '@users/roles';
import { SortingService } from '@iqser/common-ui/lib/sorting';
import { List, some } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-dossier-overview-screen-header [dossier] [upload]',

View File

@ -1,6 +1,7 @@
import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, Optional, ViewChild } from '@angular/core';
import { Dossier, File, IFileAttributeConfig } from '@red/domain';
import { Debounce, HelpModeService } from '@iqser/common-ui';
import { HelpModeService } from '@iqser/common-ui';
import { Debounce } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-workflow-item [file] [dossier] [displayedAttributes]',
@ -8,13 +9,12 @@ import { Debounce, HelpModeService } from '@iqser/common-ui';
styleUrls: ['./workflow-item.component.scss'],
})
export class WorkflowItemComponent implements OnInit {
@ViewChild('actionsWrapper', { static: true }) private _actionsWrapper: ElementRef;
@Input() file: File;
@Input() dossier: Dossier;
@Input() displayedAttributes: IFileAttributeConfig[];
width: number;
@ViewChild('actionsWrapper', { static: true }) private _actionsWrapper: ElementRef;
constructor(private readonly _changeRef: ChangeDetectorRef, @Optional() readonly helpModeService: HelpModeService) {}
ngOnInit(): void {

View File

@ -2,16 +2,9 @@ import { Injectable, TemplateRef } from '@angular/core';
import {
ActionConfig,
getConfig,
getCurrentUser,
getParam,
IFilterGroup,
INestedFilter,
IqserPermissionsService,
keyChecker,
List,
ListingMode,
ListingModes,
NestedFilter,
TableColumnConfig,
WorkflowColumn,
WorkflowConfig,
@ -46,6 +39,9 @@ import { DictionariesMapService } from '@services/entity-services/dictionaries-m
import { UserPreferenceService } from '@users/user-preference.service';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { IFilterGroup, INestedFilter, keyChecker, NestedFilter } from '@iqser/common-ui/lib/filtering';
import { getParam, List } from '@iqser/common-ui/lib/utils';
@Injectable()
export class ConfigService {

View File

@ -10,7 +10,6 @@ import {
IqserListingModule,
IqserLoadingModule,
IqserRoutes,
IqserUsersModule,
StatusBarComponent,
StopPropagationDirective,
TenantPipe,
@ -28,6 +27,7 @@ import { DossierOverviewScreenHeaderComponent } from './components/screen-header
import { ViewModeSelectionComponent } from './components/view-mode-selection/view-mode-selection.component';
import { FileAttributeComponent } from './components/file-attribute/file-attribute.component';
import { SharedModule } from '@shared/shared.module';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
const routes: IqserRoutes = [
{

View File

@ -19,16 +19,11 @@ import {
CircleButtonTypes,
CustomError,
ErrorService,
getParam,
IqserPermissionsService,
ListingComponent,
ListingModes,
listingProvidersFactory,
LoadingService,
NestedFilter,
OnAttach,
OnDetach,
shareLast,
TableColumnConfig,
TableComponent,
WorkflowConfig,
@ -46,6 +41,8 @@ import { BulkActionsService } from '../services/bulk-actions.service';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
import { Roles } from '@users/roles';
import { NestedFilter } from '@iqser/common-ui/lib/filtering';
import { getParam, OnAttach, OnDetach, shareLast } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './dossier-overview-screen.component.html',

View File

@ -1,6 +1,7 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
import { DossierStats, StatusSorter } from '@red/domain';
import { List, StatusBarConfig } from '@iqser/common-ui';
import { StatusBarConfig } from '@iqser/common-ui';
import { List } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-dossier-documents-status',

View File

@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { TranslateChartService } from '@services/translate-chart.service';
import { map } from 'rxjs/operators';
import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service';
import { getParam } from '@iqser/common-ui';
import { getParam } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-dossiers-listing-details',

View File

@ -1,13 +1,5 @@
import { Injectable, TemplateRef } from '@angular/core';
import {
ButtonConfig,
IFilterGroup,
INestedFilter,
keyChecker,
NestedFilter,
OverlappingElements,
TableColumnConfig,
} from '@iqser/common-ui';
import { ButtonConfig, TableColumnConfig } from '@iqser/common-ui';
import {
annotationDefaultColorConfig,
AnnotationShapeMap,
@ -35,6 +27,7 @@ import { DossierStatesMapService } from '@services/entity-services/dossier-state
import { PermissionsService } from '@services/permissions.service';
import { SharedDialogService } from '@shared/services/dialog.service';
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
import { IFilterGroup, INestedFilter, keyChecker, NestedFilter } from '@iqser/common-ui/lib/filtering';
@Injectable()
export class ConfigService {

View File

@ -6,7 +6,6 @@ import {
IqserHelpModeModule,
IqserListingModule,
IqserRoutes,
IqserUsersModule,
StatusBarComponent,
} from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
@ -21,6 +20,7 @@ import { DossierWorkloadColumnComponent } from './components/dossier-workload-co
import { DossierDocumentsStatusComponent } from './components/dossier-documents-status/dossier-documents-status.component';
import { DossierFilesGuard } from '@guards/dossier-files-guard';
import { ACTIVE_DOSSIERS_SERVICE } from '../../tokens';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
const routes: IqserRoutes = [
{

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { Dossier, DOSSIER_TEMPLATE_ID, DossierTemplate } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { ButtonConfig, ListingComponent, listingProvidersFactory, OnAttach, TableComponent } from '@iqser/common-ui';
import { ButtonConfig, ListingComponent, listingProvidersFactory, TableComponent } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ConfigService } from '../config.service';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
@ -10,6 +10,7 @@ import { Router } from '@angular/router';
import { UserPreferenceService } from '@users/user-preference.service';
import { SharedDialogService } from '@shared/services/dialog.service';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { OnAttach } from '@iqser/common-ui/lib/utils';
@Component({
templateUrl: './dossiers-listing-screen.component.html',
@ -18,17 +19,17 @@ import { DossierTemplatesService } from '@services/dossier-templates/dossier-tem
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DossiersListingScreenComponent extends ListingComponent<Dossier> implements OnInit, OnAttach {
readonly tableColumnConfigs = this._configService.tableConfig;
readonly tableHeaderLabel = _('dossier-listing.table-header.title');
readonly buttonConfigs: ButtonConfig[];
readonly dossierTemplate: DossierTemplate;
readonly computeFilters$ = this._activeDossiersService.all$.pipe(tap(() => this._computeAllFilters()));
@ViewChild('needsWorkFilterTemplate', {
read: TemplateRef,
static: true,
})
private readonly _needsWorkFilterTemplate: TemplateRef<unknown>;
@ViewChild(TableComponent) private readonly _tableComponent: TableComponent<Dossier>;
readonly tableColumnConfigs = this._configService.tableConfig;
readonly tableHeaderLabel = _('dossier-listing.table-header.title');
readonly buttonConfigs: ButtonConfig[];
readonly dossierTemplate: DossierTemplate;
readonly computeFilters$ = this._activeDossiersService.all$.pipe(tap(() => this._computeAllFilters()));
constructor(
router: Router,

View File

@ -3,9 +3,9 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { TranslateService } from '@ngx-translate/core';
import { annotationChangesTranslations } from '@translations/annotation-changes-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { KeysOf } from '@iqser/common-ui';
import { ListItem } from '@models/file/list-item';
import { MultiSelectService } from '../../services/multi-select.service';
import { KeysOf } from '@iqser/common-ui/lib/utils';
interface Engine {
readonly icon: string;
@ -41,16 +41,14 @@ const changesProperties: KeysOf<AnnotationWrapper>[] = [
styleUrls: ['./annotation-details.component.scss'],
})
export class AnnotationDetailsComponent implements OnChanges {
private readonly _translateService = inject(TranslateService);
private readonly _multiSelectService = inject(MultiSelectService);
@Input() annotation: ListItem<AnnotationWrapper>;
isPopoverOpen = false;
engines: Engine[];
changesTooltip: string;
noSelection: boolean;
private readonly _translateService = inject(TranslateService);
private readonly _multiSelectService = inject(MultiSelectService);
getChangesTooltip(): string | undefined {
const changes = changesProperties.filter(key => this.annotation.item[key]);

View File

@ -1,6 +1,6 @@
import { ChangeDetectorRef, Component, computed, ElementRef, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { FilterService, HasScrollbarDirective, IqserEventTarget } from '@iqser/common-ui';
import { HasScrollbarDirective } from '@iqser/common-ui';
import { MultiSelectService } from '../../services/multi-select.service';
import { AnnotationReferencesService } from '../../services/annotation-references.service';
import { UserPreferenceService } from '@users/user-preference.service';
@ -9,6 +9,8 @@ import { EarmarkGroup } from '@red/domain';
import { REDAnnotationManager } from '../../../pdf-viewer/services/annotation-manager.service';
import { AnnotationsListingService } from '../../services/annotations-listing.service';
import { ListItem } from '@models/file/list-item';
import { FilterService } from '@iqser/common-ui/lib/filtering';
import { IqserEventTarget } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-annotations-list',
@ -16,15 +18,14 @@ import { ListItem } from '@models/file/list-item';
styleUrls: ['./annotations-list.component.scss'],
})
export class AnnotationsListComponent extends HasScrollbarDirective implements OnChanges {
@Input() annotations: ListItem<AnnotationWrapper>[];
@Output() readonly pagesPanelActive = new EventEmitter<boolean>();
readonly #earmarkGroups = computed(() => {
if (this._viewModeService.isEarmarks()) {
return this.#getEarmarksGroups();
}
return [] as EarmarkGroup[];
});
@Input() annotations: ListItem<AnnotationWrapper>[];
@Output() readonly pagesPanelActive = new EventEmitter<boolean>();
constructor(
protected readonly _elementRef: ElementRef,

View File

@ -2,12 +2,14 @@ import { ChangeDetectorRef, Component, HostBinding, Input, OnInit, ViewChild } f
import type { IComment, User } from '@red/domain';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { PermissionsService } from '@services/permissions.service';
import { ContextComponent, getCurrentUser, InputWithActionComponent, LoadingService, trackByFactory } from '@iqser/common-ui';
import { InputWithActionComponent, LoadingService } from '@iqser/common-ui';
import { Observable } from 'rxjs';
import { CommentingService } from '../../services/commenting.service';
import { tap } from 'rxjs/operators';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { ManualRedactionService } from '../../services/manual-redaction.service';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { ContextComponent, trackByFactory } from '@iqser/common-ui/lib/utils';
interface CommentsContext {
hiddenComments: boolean;
@ -19,12 +21,12 @@ interface CommentsContext {
styleUrls: ['./comments.component.scss'],
})
export class CommentsComponent extends ContextComponent<CommentsContext> implements OnInit {
@HostBinding('class.hidden') private _hidden = true;
@ViewChild(InputWithActionComponent) private readonly _input: InputWithActionComponent;
@Input() annotation: AnnotationWrapper;
readonly trackBy = trackByFactory();
readonly currentUser = getCurrentUser<User>();
hiddenComments$: Observable<boolean>;
@HostBinding('class.hidden') private _hidden = true;
@ViewChild(InputWithActionComponent) private readonly _input: InputWithActionComponent;
constructor(
readonly permissionsService: PermissionsService,

View File

@ -6,7 +6,7 @@ import { FilePreviewStateService } from '../../services/file-preview-state.servi
import { type FileAttributeConfigType, FileAttributeConfigTypes } from '@red/domain';
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { ContextComponent } from '@iqser/common-ui';
import { ContextComponent } from '@iqser/common-ui/lib/utils';
import { toSignal } from '@angular/core/rxjs-interop';
interface FileAttribute {

View File

@ -3,16 +3,7 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
import { MatDialog } from '@angular/material/dialog';
import scrollIntoView from 'scroll-into-view-if-needed';
import {
AutoUnsubscribe,
bool,
CircleButtonTypes,
Debounce,
FilterService,
IconButtonTypes,
INestedFilter,
IqserEventTarget,
} from '@iqser/common-ui';
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
import { combineLatest, delay, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ExcludedPagesService } from '../../services/excluded-pages.service';
@ -31,6 +22,8 @@ import { SuggestionsService } from '../../services/suggestions.service';
import { ListItem } from '@models/file/list-item';
import { PageRotationService } from '../../../pdf-viewer/services/page-rotation.service';
import { getLocalStorageDataByFileId } from '@utils/local-storage';
import { FilterService, INestedFilter } from '@iqser/common-ui/lib/filtering';
import { AutoUnsubscribe, bool, Debounce, IqserEventTarget } from '@iqser/common-ui/lib/utils';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
@ -41,9 +34,10 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
styleUrls: ['./file-workload.component.scss'],
})
export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
@ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef;
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
displayedAnnotations = new Map<number, AnnotationWrapper[]>();
displayedPages: number[] = [];
pagesPanelActive = true;
@ -52,8 +46,6 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
this.viewModeService.isEarmarks() ? _('file-preview.tabs.highlights.label') : _('file-preview.tabs.annotations.label'),
);
readonly currentPageIsExcluded = computed(() => this.state.file().excludedPages.includes(this.pdf.currentPage()));
@ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef;
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
constructor(
readonly filterService: FilterService,
@ -116,20 +108,6 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
);
}
ngOnInit(): void {
setTimeout(() => {
const showExcludePages = getLocalStorageDataByFileId(this.state.file()?.id, 'show-exclude-pages') ?? false;
if (showExcludePages) {
this.excludedPagesService.show();
}
const showDocumentInfo = getLocalStorageDataByFileId(this.state.file()?.id, 'show-document-info') ?? false;
if (showDocumentInfo) {
this.documentInfoService.show();
}
});
}
get activeAnnotations(): AnnotationWrapper[] {
return this.displayedAnnotations.get(this.pdf.currentPage()) || [];
}
@ -170,6 +148,20 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
}
}
ngOnInit(): void {
setTimeout(() => {
const showExcludePages = getLocalStorageDataByFileId(this.state.file()?.id, 'show-exclude-pages') ?? false;
if (showExcludePages) {
this.excludedPagesService.show();
}
const showDocumentInfo = getLocalStorageDataByFileId(this.state.file()?.id, 'show-document-info') ?? false;
if (showDocumentInfo) {
this.documentInfoService.show();
}
});
}
selectAllOnActivePage() {
this.listingService.selectAnnotations(this.activeAnnotations);
}

View File

@ -3,12 +3,13 @@ import { PermissionsService } from '@services/permissions.service';
import { ViewedPagesService } from '@services/files/viewed-pages.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { PageRotationService } from '../../../pdf-viewer/services/page-rotation.service';
import { ContextComponent, getConfig } from '@iqser/common-ui';
import { getConfig } from '@iqser/common-ui';
import { map, tap } from 'rxjs/operators';
import { AppConfig, ViewedPage } from '@red/domain';
import { ViewedPagesMapService } from '@services/files/viewed-pages-map.service';
import { pairwise } from 'rxjs';
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
import { ContextComponent } from '@iqser/common-ui/lib/utils';
interface PageIndicatorContext {
isRotated: boolean;
@ -21,14 +22,13 @@ interface PageIndicatorContext {
styleUrls: ['./page-indicator.component.scss'],
})
export class PageIndicatorComponent extends ContextComponent<PageIndicatorContext> implements OnChanges, OnInit {
readonly #config = getConfig<AppConfig>();
@Input({ required: true }) number: number;
@Input() showDottedIcon = false;
@Input() activeSelection = false;
@Input() read = false;
@Output() readonly pageSelected = new EventEmitter<number>();
pageReadTimeout: number = null;
readonly #config = getConfig<AppConfig>();
constructor(
private readonly _viewedPagesService: ViewedPagesService,

View File

@ -1,5 +1,5 @@
import { Component, inject, Input } from '@angular/core';
import { List } from '@iqser/common-ui';
import { List } from '@iqser/common-ui/lib/utils';
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
import { MultiSelectService } from '../../services/multi-select.service';
import { AnnotationsListingService } from '../../services/annotations-listing.service';
@ -14,13 +14,13 @@ import { ViewedPage } from '@red/domain';
styleUrls: ['./pages.component.scss'],
})
export class PagesComponent {
@Input({ required: true }) pages: List<number>;
@Input({ required: true }) displayedAnnotations: Map<number, AnnotationWrapper[]>;
protected readonly _pdf = inject(PdfViewer);
readonly #state = inject(FilePreviewStateService);
readonly viewedPages$ = inject(ViewedPagesMapService).get$(this.#state.fileId);
readonly #multiSelectService = inject(MultiSelectService);
readonly #listingService = inject(AnnotationsListingService);
protected readonly _pdf = inject(PdfViewer);
@Input({ required: true }) pages: List<number>;
@Input({ required: true }) displayedAnnotations: Map<number, AnnotationWrapper[]>;
readonly viewedPages$ = inject(ViewedPagesMapService).get$(this.#state.fileId);
pageSelectedByClick($event: number): void {
this._pdf.navigateTo($event);

View File

@ -1,6 +1,6 @@
import { Component, computed } from '@angular/core';
import { File, User } from '@red/domain';
import { getCurrentUser, LoadingService, Toaster } from '@iqser/common-ui';
import { LoadingService, Toaster } from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -9,6 +9,7 @@ import { FilesService } from '@services/files/files.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { FileAssignService } from '../../../shared-dossiers/services/file-assign.service';
import { moveElementInArray } from '@utils/functions';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
selector: 'redaction-user-management',
@ -16,17 +17,6 @@ import { moveElementInArray } from '@utils/functions';
styleUrls: ['./user-management.component.scss'],
})
export class UserManagementComponent {
readonly translations = workflowFileStatusTranslations;
readonly statusBarConfig = computed(() => [{ length: 1, color: this.state.file().workflowStatus }]);
readonly assignTooltip = computed(() => {
const file = this.state.file();
return file.isUnderApproval
? _('dossier-overview.assign-approver')
: file.assignee
? _('file-preview.change-reviewer')
: _('file-preview.assign-reviewer');
});
editingReviewer = false;
protected readonly _canAssignToSelf = computed(() => this.permissionsService.canAssignToSelf(this.state.file(), this.state.dossier()));
protected readonly _canAssignUser = computed(() => this.permissionsService.canAssignUser(this.state.file(), this.state.dossier()));
protected readonly _canUnassignUser = computed(() => this.permissionsService.canUnassignUser(this.state.file(), this.state.dossier()));
@ -45,6 +35,17 @@ export class UserManagementComponent {
: this.#customSort([...dossier.memberIds, ...unassignUser]);
});
protected readonly _currentUserId = getCurrentUser().id;
readonly translations = workflowFileStatusTranslations;
readonly statusBarConfig = computed(() => [{ length: 1, color: this.state.file().workflowStatus }]);
readonly assignTooltip = computed(() => {
const file = this.state.file();
return file.isUnderApproval
? _('dossier-overview.assign-approver')
: file.assignee
? _('file-preview.change-reviewer')
: _('file-preview.assign-reviewer');
});
editingReviewer = false;
constructor(
readonly fileAssignService: FileAssignService,

View File

@ -3,11 +3,12 @@ import { ViewMode, ViewModes } from '@red/domain';
import { ViewModeService } from '../../services/view-mode.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { FileDataService } from '../../services/file-data.service';
import { BASE_HREF, ConfirmOptions, IConfirmationDialogData, Toaster } from '@iqser/common-ui';
import { ConfirmOptions, IConfirmationDialogData, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserPreferenceService } from '@users/user-preference.service';
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
import { Roles } from '@users/roles';
import { BASE_HREF } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-view-switch',

View File

@ -7,7 +7,7 @@ import { SkippedService } from './services/skipped.service';
import { AnnotationActionsService } from './services/annotation-actions.service';
import { FilePreviewStateService } from './services/file-preview-state.service';
import { AnnotationReferencesService } from './services/annotation-references.service';
import { EntitiesService, FilterService, ListingService, SearchService, SortingService } from '@iqser/common-ui';
import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui';
import { AnnotationProcessingService } from './services/annotation-processing.service';
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
import { FileDataService } from './services/file-data.service';
@ -15,6 +15,8 @@ import { AnnotationsListingService } from './services/annotations-listing.servic
import { StampService } from './services/stamp.service';
import { PdfProxyService } from './services/pdf-proxy.service';
import { PdfAnnotationActionsService } from './services/pdf-annotation-actions.service';
import { FilterService } from '@iqser/common-ui/lib/filtering';
import { SortingService } from '@iqser/common-ui/lib/sorting';
export const filePreviewScreenProviders = [
FilterService,

View File

@ -13,25 +13,14 @@ import {
} from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
import {
AutoUnsubscribe,
Bind,
bool,
CircleButtonTypes,
ConfirmOption,
ConfirmOptions,
copyLocalStorageFiltersValues,
CustomError,
Debounce,
ErrorService,
FilterService,
HelpModeService,
IConfirmationDialogData,
List,
LoadingService,
NestedFilter,
OnAttach,
OnDetach,
processFilters,
TenantsService,
Toaster,
} from '@iqser/common-ui';
@ -78,6 +67,8 @@ import { SuggestionsService } from './services/suggestions.service';
import { IqserDialog } from '../../../../../../libs/common-ui/src/lib/dialog/iqser-dialog.service';
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { copyLocalStorageFiltersValues, FilterService, NestedFilter, processFilters } from '@iqser/common-ui/lib/filtering';
import { AutoUnsubscribe, Bind, bool, Debounce, List, OnAttach, OnDetach } from '@iqser/common-ui/lib/utils';
const textActions = [TextPopups.REDACT_TEXT, TextPopups.ADD_HINT, TextPopups.ADD_FALSE_POSITIVE];
@ -90,18 +81,18 @@ export class FilePreviewScreenComponent
extends AutoUnsubscribe
implements AfterViewInit, OnInit, OnDestroy, OnAttach, OnDetach, ComponentCanDeactivate
{
readonly circleButtonTypes = CircleButtonTypes;
readonly roles = Roles;
fullScreen = false;
readonly fileId = this.state.fileId;
readonly dossierId = this.state.dossierId;
width: number;
@ViewChild('annotationFilterTemplate', {
read: TemplateRef,
static: false,
})
private readonly _filterTemplate: TemplateRef<unknown>;
@ViewChild('actionsWrapper', { static: false }) private readonly _actionsWrapper: ElementRef;
readonly circleButtonTypes = CircleButtonTypes;
readonly roles = Roles;
fullScreen = false;
readonly fileId = this.state.fileId;
readonly dossierId = this.state.dossierId;
width: number;
constructor(
readonly pdf: PdfViewer,

View File

@ -12,11 +12,9 @@ import {
InputWithActionComponent,
IqserAllowDirective,
IqserDenyDirective,
IqserFiltersModule,
IqserHelpModeModule,
IqserRoutes,
IqserUploadFileModule,
IqserUsersModule,
LogPipe,
PreventDefaultDirective,
RoundCheckboxComponent,
@ -66,6 +64,8 @@ import { SharedModule } from '@shared/shared.module';
import { SharedDossiersModule } from '../shared-dossiers/shared-dossiers.module';
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
import { RemoveRedactionDialogComponent } from './dialogs/remove-redaction-dialog/remove-redaction-dialog.component';
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
import { IqserFiltersModule } from '@iqser/common-ui/lib/filtering';
const routes: IqserRoutes = [
{

View File

@ -1,13 +1,12 @@
import { Injectable } from '@angular/core';
import { ManualRedactionService } from './manual-redaction.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { firstValueFrom, Observable, of } from 'rxjs';
import { firstValueFrom, Observable } from 'rxjs';
import { getFirstRelevantTextPart } from '../../../utils';
import { Core } from '@pdftron/webviewer';
import {
DictionaryEntryTypes,
EarmarkOperation,
IAddRedactionRequest,
ILegalBasisChangeRequest,
IRecategorizationRequest,
IRectangle,
@ -20,7 +19,7 @@ import {
AcceptRecommendationDialogComponent,
AcceptRecommendationReturnType,
} from '../dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component';
import { defaultDialogConfig, isJustOne, List } from '@iqser/common-ui';
import { defaultDialogConfig } from '@iqser/common-ui';
import { filter } from 'rxjs/operators';
import { MatDialog } from '@angular/material/dialog';
import { FilePreviewStateService } from './file-preview-state.service';
@ -38,6 +37,7 @@ import {
import { RemoveRedactionOptions } from '../dialogs/remove-redaction-dialog/remove-redaction-options';
import { IqserDialog } from '../../../../../../../libs/common-ui/src/lib/dialog/iqser-dialog.service';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { isJustOne, List } from '@iqser/common-ui/lib/utils';
@Injectable()
export class AnnotationActionsService {

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { SuperTypeSorter } from '../../../utils';
import { Filter, handleCheckedValue, IFilter, INestedFilter, NestedFilter } from '@iqser/common-ui';
import { Filter, handleCheckedValue, IFilter, INestedFilter, NestedFilter } from '@iqser/common-ui/lib/filtering';
import { annotationTypesTranslations } from '@translations/annotation-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { annotationDefaultColorConfig } from '@red/domain';

View File

@ -1,11 +1,13 @@
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Injectable, OnDestroy } from '@angular/core';
import { EntitiesService, FilterService, ListingService, SearchService, SortingService } from '@iqser/common-ui';
import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui';
import { filter, tap } from 'rxjs/operators';
import { MultiSelectService } from './multi-select.service';
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
import { Subscription } from 'rxjs';
import { FilterService } from '@iqser/common-ui/lib/filtering';
import { SortingService } from '@iqser/common-ui/lib/sorting';
@Injectable()
export class AnnotationsListingService extends ListingService<AnnotationWrapper> implements OnDestroy {

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { shareDistinctLast } from '@iqser/common-ui';
import { shareDistinctLast } from '@iqser/common-ui/lib/utils';
@Injectable()
export class CommentingService {

View File

@ -3,7 +3,7 @@ import { firstValueFrom, from, merge, Observable, of, pairwise, Subject, switchM
import { Dictionary, Dossier, DOSSIER_ID, DOSSIER_TEMPLATE_ID, File, FILE_ID } from '@red/domain';
import { FilesMapService } from '@services/files/files-map.service';
import { PermissionsService } from '@services/permissions.service';
import { getParam, LoadingService, wipeCache } from '@iqser/common-ui';
import { LoadingService, wipeCache } from '@iqser/common-ui';
import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators';
import { FileManagementService } from '@services/files/file-management.service';
import { dossiersServiceResolver } from '@services/entity-services/dossiers.service.provider';
@ -15,6 +15,7 @@ import { DictionariesMapService } from '@services/entity-services/dictionaries-m
import { DossierDictionariesMapService } from '@services/entity-services/dossier-dictionaries-map.service';
import { toSignal } from '@angular/core/rxjs-interop';
import { ViewModeService } from './view-mode.service';
import { getParam } from '@iqser/common-ui/lib/utils';
const ONE_MEGABYTE = 1024 * 1024;
@ -31,6 +32,8 @@ function isDownload(event: HttpEvent<Blob>): event is HttpProgressEvent {
@Injectable()
export class FilePreviewStateService {
readonly #reloadBlob$ = new Subject();
readonly #dossierFileChange: Signal<boolean>;
readonly file$: Observable<File>;
readonly file: Signal<File>;
readonly dossier: Signal<Dossier>;
@ -38,12 +41,9 @@ export class FilePreviewStateService {
readonly isWritable: Signal<boolean>;
readonly dossierDictionary: Signal<Dictionary>;
readonly blob$: Observable<Blob>;
readonly dossierId = getParam(DOSSIER_ID);
readonly dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly fileId = getParam(FILE_ID);
readonly #reloadBlob$ = new Subject();
readonly #dossierFileChange: Signal<boolean>;
// readonly #routeKey = getReusableRouteKey(inject(ActivatedRoute).snapshot);
// readonly isAttached = inject(CustomRouteReuseStrategy).attached$.pipe(

View File

@ -11,7 +11,7 @@ import type {
ManualRedactionActions,
} from '@red/domain';
import { type AnnotationWrapper } from '@models/file/annotation.wrapper';
import { GenericService, IqserPermissionsService, List, Toaster } from '@iqser/common-ui';
import { GenericService, IqserPermissionsService, Toaster } from '@iqser/common-ui';
import { tap } from 'rxjs/operators';
import { PermissionsService } from '@services/permissions.service';
import { dictionaryActionsTranslations, manualRedactionActionsTranslations } from '@translations/annotation-actions-translations';
@ -22,6 +22,7 @@ import { type ManualRedactionEntryType } from '@models/file/manual-redaction-ent
import { NGXLogger } from 'ngx-logger';
import { Roles } from '@users/roles';
import { firstValueFrom, of } from 'rxjs';
import { List } from '@iqser/common-ui/lib/utils';
function getResponseType(error: boolean, isConflict: boolean) {
const isConflictError = isConflict ? 'conflictError' : 'error';

View File

@ -5,11 +5,12 @@ import { PermissionsService } from '@services/permissions.service';
import { FilePreviewStateService } from './file-preview-state.service';
import { TranslateService } from '@ngx-translate/core';
import { AnnotationActionsService } from './annotation-actions.service';
import { BASE_HREF_FN, IqserPermissionsService } from '@iqser/common-ui';
import { IqserPermissionsService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { IHeaderElement } from '@red/domain';
import { Roles } from '@users/roles';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
@Injectable()
export class PdfAnnotationActionsService {

View File

@ -9,7 +9,7 @@ import {
} from '@models/file/manual-redaction-entry.wrapper';
import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service';
import { UserPreferenceService } from '@users/user-preference.service';
import { BASE_HREF_FN, getCurrentUser, IqserPermissionsService, isJustOne, shareDistinctLast } from '@iqser/common-ui';
import { IqserPermissionsService } from '@iqser/common-ui';
import { toPosition } from '../utils/pdf-calculation.utils';
import { MultiSelectService } from './multi-select.service';
import { FilePreviewStateService } from './file-preview-state.service';
@ -35,11 +35,21 @@ import { PdfAnnotationActionsService } from './pdf-annotation-actions.service';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { Roles } from '@users/roles';
import { AnnotationActionsService } from './annotation-actions.service';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { BASE_HREF_FN, isJustOne, shareDistinctLast } from '@iqser/common-ui/lib/utils';
import Annotation = Core.Annotations.Annotation;
import Quad = Core.Math.Quad;
@Injectable()
export class PdfProxyService {
private readonly _convertPath = inject(BASE_HREF_FN);
readonly #visibilityOffIcon = this._convertPath('/assets/icons/general/visibility-off.svg');
readonly #visibilityIcon = this._convertPath('/assets/icons/general/visibility.svg');
readonly #falsePositiveIcon = this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg');
readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss)
? this._convertPath('/assets/icons/general/pdftron-action-add-component.svg')
: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
readonly #addHintIcon = this._convertPath('/assets/icons/general/pdftron-action-add-hint.svg');
readonly annotationSelected$ = this.#annotationSelected$;
readonly manualAnnotationRequested$ = new Subject<ManualRedactionEntryWrapper>();
readonly redactTextRequested$ = new Subject<ManualRedactionEntryWrapper>();
@ -54,14 +64,6 @@ export class PdfProxyService {
const isAllowed = this._permissionsService.canPerformAnnotationActions(this._state.file(), this._state.dossier());
return isAllowed && isStandard;
});
private readonly _convertPath = inject(BASE_HREF_FN);
readonly #visibilityOffIcon = this._convertPath('/assets/icons/general/visibility-off.svg');
readonly #visibilityIcon = this._convertPath('/assets/icons/general/visibility.svg');
readonly #falsePositiveIcon = this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg');
readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss)
? this._convertPath('/assets/icons/general/pdftron-action-add-component.svg')
: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
readonly #addHintIcon = this._convertPath('/assets/icons/general/pdftron-action-add-hint.svg');
constructor(
private readonly _translateService: TranslateService,

View File

@ -1,11 +1,11 @@
import { effect, Injectable, Signal, signal } from '@angular/core';
import { bool } from '@iqser/common-ui';
import { bool } from '@iqser/common-ui/lib/utils';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
@Injectable()
export class SkippedService {
readonly hideSkipped: Signal<boolean>;
readonly #hideSkipped = signal(false);
readonly hideSkipped: Signal<boolean>;
constructor(private readonly _annotationManager: REDAnnotationManager) {
this.hideSkipped = this.#hideSkipped.asReadonly();

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { bool } from '@iqser/common-ui';
import { bool } from '@iqser/common-ui/lib/utils';
import { Core } from '@pdftron/webviewer';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
import { UserPreferenceService } from '@users/user-preference.service';

View File

@ -1,4 +1,4 @@
import { List, ValuesOf } from '@iqser/common-ui';
import { List, ValuesOf } from '@iqser/common-ui/lib/utils';
export const ActionsHelpModeKeys = {
redaction: 'redaction',

View File

@ -9,7 +9,7 @@ import { IRectangle, ISectionGrid, ISectionRectangle, SuperTypes } from '@red/do
import { firstValueFrom } from 'rxjs';
import { PdfViewer } from './pdf-viewer.service';
import { REDAnnotationManager } from './annotation-manager.service';
import { List } from '@iqser/common-ui';
import { List } from '@iqser/common-ui/lib/utils';
import { REDDocumentViewer } from './document-viewer.service';
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
import Annotation = Core.Annotations.Annotation;

View File

@ -1,6 +1,6 @@
import { Injectable, signal } from '@angular/core';
import { Core } from '@pdftron/webviewer';
import type { List } from '@iqser/common-ui';
import type { List } from '@iqser/common-ui/lib/utils';
import { AnnotationPredicate, DeleteAnnotationsOptions } from '../utils/types';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { fromEvent, Observable } from 'rxjs';
@ -13,13 +13,12 @@ import Annotation = Core.Annotations.Annotation;
@Injectable()
export class REDAnnotationManager {
readonly #hidden = signal(new Set<string>());
#manager: AnnotationManager;
annotationSelected$: Observable<[Annotation[], string]>;
resizingAnnotationId?: string = undefined;
readonly #hidden = signal(new Set<string>());
readonly hidden = this.#hidden.asReadonly();
#manager: AnnotationManager;
get selected() {
return this.#manager.getSelectedAnnotations();
}

View File

@ -6,7 +6,7 @@ import { filter, tap } from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { PdfViewer } from './pdf-viewer.service';
import { UserPreferenceService } from '@users/user-preference.service';
import { log } from '@iqser/common-ui';
import { log } from '@iqser/common-ui/lib/utils';
import { stopAndPrevent, stopAndPreventIfNotAllowed } from '../utils/functions';
import { RotationType, RotationTypes } from '@red/domain';
import { AnnotationToolNames } from '../utils/constants';
@ -17,22 +17,20 @@ import Quad = Core.Math.Quad;
@Injectable()
export class REDDocumentViewer {
readonly loaded$: Observable<boolean>;
keyUp$: Observable<KeyboardEvent>;
readonly selectedText: Signal<string>;
readonly loaded: Signal<boolean>;
readonly pageComplete: Signal<unknown | undefined>;
#document: DocumentViewer;
readonly #loaded = signal(false);
readonly #pageComplete = signal<unknown | undefined>(undefined);
readonly #selectedText = signal('');
readonly #logger = inject(NGXLogger);
readonly #userPreferenceService = inject(UserPreferenceService);
readonly #pdf = inject(PdfViewer);
readonly #activatedRoute = inject(ActivatedRoute);
readonly #ngZone = inject(NgZone);
readonly loaded$: Observable<boolean>;
keyUp$: Observable<KeyboardEvent>;
readonly selectedText: Signal<string>;
readonly loaded: Signal<boolean>;
readonly pageComplete: Signal<unknown | undefined>;
constructor() {
this.loaded = this.#loaded.asReadonly();

View File

@ -1,6 +1,6 @@
import { DestroyRef, inject, Injectable, signal, Signal } from '@angular/core';
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
import { BASE_HREF_FN, ErrorService, getConfig, shareDistinctLast } from '@iqser/common-ui';
import { ErrorService, getConfig } from '@iqser/common-ui';
import { AppConfig, File, IHeaderElement } from '@red/domain';
import { ActivatedRoute } from '@angular/router';
import { map, startWith } from 'rxjs/operators';
@ -15,6 +15,7 @@ import { UserPreferenceService } from '@users/user-preference.service';
import { environment } from '@environments/environment';
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { BASE_HREF_FN, shareDistinctLast } from '@iqser/common-ui/lib/utils';
import TextTool = Core.Tools.TextTool;
import Annotation = Core.Annotations.Annotation;
import TextHighlightAnnotation = Core.Annotations.TextHighlightAnnotation;
@ -23,21 +24,6 @@ import Quad = Core.Math.Quad;
@Injectable()
export class PdfViewer {
readonly currentPage$ = inject(ActivatedRoute).queryParamMap.pipe(
map(params => Number(params.get('page') ?? '1')),
shareDistinctLast(),
);
readonly currentPage = toSignal(this.currentPage$);
documentViewer: DocumentViewer;
fileId: string;
dossierId: string;
pageChanged$: Observable<number>;
readonly isCompareMode: Signal<boolean>;
readonly totalPages: Signal<number>;
private readonly _convertPath = inject(BASE_HREF_FN);
#instance: WebViewerInstance;
readonly #licenseKey = inject(LicenseService).activeLicenseKey;
@ -55,6 +41,17 @@ export class PdfViewer {
};
readonly #destroyRef = inject(DestroyRef);
readonly #totalPages = signal<number>(0);
readonly currentPage$ = inject(ActivatedRoute).queryParamMap.pipe(
map(params => Number(params.get('page') ?? '1')),
shareDistinctLast(),
);
readonly currentPage = toSignal(this.currentPage$);
documentViewer: DocumentViewer;
fileId: string;
dossierId: string;
pageChanged$: Observable<number>;
readonly isCompareMode: Signal<boolean>;
readonly totalPages: Signal<number>;
constructor(
private readonly _logger: NGXLogger,

View File

@ -1,5 +1,4 @@
import { inject, Injectable } from '@angular/core';
import { BASE_HREF_FN } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HeaderElements } from '../../file-preview/utils/constants';
@ -8,15 +7,16 @@ import { REDAnnotationManager } from './annotation-manager.service';
import { AnnotationDrawService } from './annotation-draw.service';
import { BehaviorSubject, Observable } from 'rxjs';
import { Core } from '@pdftron/webviewer';
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
import Annotation = Core.Annotations.Annotation;
@Injectable()
export class ReadableRedactionsService {
readonly active$: Observable<boolean>;
private readonly _convertPath = inject(BASE_HREF_FN);
readonly #enableIcon = this._convertPath('/assets/icons/general/redaction-preview.svg');
readonly #disableIcon = this._convertPath('/assets/icons/general/redaction-final.svg');
readonly #active$ = new BehaviorSubject<boolean>(true);
readonly active$: Observable<boolean>;
constructor(
private readonly _pdf: PdfViewer,

View File

@ -3,9 +3,9 @@ import { UserPreferenceService } from '@users/user-preference.service';
import { HeaderElements } from '../../file-preview/utils/constants';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateService } from '@ngx-translate/core';
import { BASE_HREF_FN } from '@iqser/common-ui';
import { PdfViewer } from './pdf-viewer.service';
import { REDDocumentViewer } from './document-viewer.service';
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
@Injectable()
export class TooltipsService {

View File

@ -2,7 +2,7 @@ import { inject, Injectable, NgZone } from '@angular/core';
import { IHeaderElement, RotationTypes } from '@red/domain';
import { HeaderElements, HeaderElementType } from '../../file-preview/utils/constants';
import { TranslateService } from '@ngx-translate/core';
import { BASE_HREF_FN, IqserPermissionsService } from '@iqser/common-ui';
import { IqserPermissionsService } from '@iqser/common-ui';
import { TooltipsService } from './tooltips.service';
import { PageRotationService } from './page-rotation.service';
import { PdfViewer } from './pdf-viewer.service';
@ -14,6 +14,7 @@ import { ViewerEvent, VisibilityChangedEvent } from '../utils/types';
import { ReadableRedactionsService } from './readable-redactions.service';
import { filter, map, tap } from 'rxjs/operators';
import { Roles } from '@users/roles';
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
const divider: IHeaderElement = {
type: 'divider',
@ -21,8 +22,6 @@ const divider: IHeaderElement = {
@Injectable()
export class ViewerHeaderService {
readonly events$: Observable<ViewerEvent>;
toggleLoadAnnotations$: Observable<boolean>;
readonly #convertPath = inject(BASE_HREF_FN);
readonly #iqserPermissionService = inject(IqserPermissionsService);
#buttons: Map<HeaderElementType, IHeaderElement>;
@ -40,6 +39,8 @@ export class ViewerHeaderService {
]);
#docBeforeCompare: Blob;
readonly #events$ = new Subject<ViewerEvent>();
readonly events$: Observable<ViewerEvent>;
toggleLoadAnnotations$: Observable<boolean>;
constructor(
private readonly _filesMapService: FilesMapService,

View File

@ -1,6 +1,7 @@
import { CustomError, List } from '@iqser/common-ui';
import { CustomError } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HeaderElements, TextPopups } from '../../file-preview/utils/constants';
import { List } from '@iqser/common-ui/lib/utils';
export const ROTATION_BUTTONS = [HeaderElements.ROTATE_LEFT_BUTTON, HeaderElements.ROTATE_RIGHT_BUTTON];
export const ROTATION_ACTION_BUTTONS = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION];

View File

@ -1,4 +1,4 @@
import { List } from '@iqser/common-ui';
import { List } from '@iqser/common-ui/lib/utils';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { ALLOWED_KEYBOARD_SHORTCUTS } from './constants';

View File

@ -1,7 +1,7 @@
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
import { ISearchListItem } from '@red/domain';
import { escapeHtml } from '@iqser/common-ui';
import { escapeHtml } from '@iqser/common-ui/lib/utils';
import { getDossierRouterLink } from '@utils/router-links';
@Component({

View File

@ -1,15 +1,5 @@
import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core';
import {
IFilterGroup,
keyChecker,
ListingComponent,
listingProvidersFactory,
LoadingService,
NestedFilter,
SearchPositions,
SortingOrders,
TableColumnConfig,
} from '@iqser/common-ui';
import { ListingComponent, listingProvidersFactory, LoadingService, SearchPositions, TableColumnConfig } from '@iqser/common-ui';
import { combineLatest, Observable, of } from 'rxjs';
import { debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
@ -33,6 +23,8 @@ import { FeaturesService } from '@services/features.service';
import { DossiersCacheService } from '@services/dossiers/dossiers-cache.service';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { UserService } from '@users/user.service';
import { IFilterGroup, keyChecker, NestedFilter } from '@iqser/common-ui/lib/filtering';
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
@Component({
templateUrl: './search-screen.component.html',

View File

@ -2,10 +2,11 @@ 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, IqserUsersModule, StatusBarComponent, StopPropagationDirective, TenantPipe } from '@iqser/common-ui';
import { IqserListingModule, StatusBarComponent, StopPropagationDirective, TenantPipe } 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 { IqserUsersModule } from '@iqser/common-ui/lib/users';
const routes = [{ path: '', component: SearchScreenComponent }];

View File

@ -1,6 +1,6 @@
import { Component, Input, OnChanges } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { CircleButtonTypes, getCurrentUser, IqserPermissionsService, ScrollableParentViews } from '@iqser/common-ui';
import { CircleButtonTypes, IqserPermissionsService, ScrollableParentViews } from '@iqser/common-ui';
import type { Dossier, File, User } from '@red/domain';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { LongPressEvent } from '@shared/directives/long-press.directive';
@ -8,6 +8,7 @@ import { UserPreferenceService } from '@users/user-preference.service';
import { FilesMapService } from '@services/files/files-map.service';
import { ReanalysisService } from '@services/reanalysis.service';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
@Component({
selector: 'redaction-dossiers-listing-actions [dossier]',

View File

@ -5,10 +5,8 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import {
CircleButtonType,
CircleButtonTypes,
getCurrentUser,
IConfirmationDialogData,
IqserPermissionsService,
IqserTooltipPositions,
LoadingService,
TenantsService,
Toaster,
@ -33,6 +31,8 @@ import { Roles } from '@users/roles';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { toObservable } from '@angular/core/rxjs-interop';
import { setLocalStorageDataByFileId } from '@utils/local-storage';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { IqserTooltipPositions } from '@iqser/common-ui/lib/utils';
@Component({
selector: 'redaction-file-actions',
@ -40,20 +40,19 @@ import { setLocalStorageDataByFileId } from '@utils/local-storage';
styleUrls: ['./file-actions.component.scss'],
})
export class FileActionsComponent implements OnChanges {
@ViewChild(ExpandableFileActionsComponent)
private readonly _expandableActionsComponent: ExpandableFileActionsComponent;
@Input({ required: true }) file: File;
@Input({ required: true }) dossier: Dossier;
@Input({ required: true }) type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
@Input() maxWidth: number;
@Input() minWidth: number;
@Input() fileActionsHelpModeKey: 'document_features_in_dossier' | 'editor_document_features' = 'document_features_in_dossier';
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = getCurrentUser<User>();
toggleTooltip?: string;
assignTooltip?: string;
buttonType?: CircleButtonType;
showSetToNew = false;
showUndoApproval = false;
showAssignToSelf = false;
@ -80,9 +79,6 @@ export class FileActionsComponent implements OnChanges {
tooltipPosition = IqserTooltipPositions.above;
buttons: Action[];
@ViewChild(ExpandableFileActionsComponent)
private readonly _expandableActionsComponent: ExpandableFileActionsComponent;
constructor(
private readonly _injector: Injector,
private readonly _filesService: FilesService,

View File

@ -1,7 +1,7 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserService } from '@users/user.service';
import { getCurrentUser, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { FormBuilder, Validators } from '@angular/forms';
import { File, User, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -9,6 +9,7 @@ import { FilesService } from '@services/files/files.service';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { PermissionsService } from '@services/permissions.service';
import { moveElementInArray } from '@utils/functions';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
class DialogData {
targetStatus: WorkflowFileStatus;

View File

@ -8,7 +8,7 @@ import { PermissionsService } from '@services/permissions.service';
import { firstValueFrom, Observable } from 'rxjs';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
import { ContextComponent, shareLast } from '@iqser/common-ui';
import { ContextComponent, shareLast } from '@iqser/common-ui/lib/utils';
import { Roles } from '@users/roles';
interface EditDossierDownloadPackageContext {
@ -24,6 +24,7 @@ export class EditDossierDownloadPackageComponent
extends ContextComponent<EditDossierDownloadPackageContext>
implements OnInit, EditDossierSectionInterface
{
#existsWatermarks$: Observable<boolean>;
form: FormGroup;
downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(
(type: DownloadFileType) => ({
@ -32,10 +33,8 @@ export class EditDossierDownloadPackageComponent
}),
);
availableReportTypes: IReportTemplate[] = [];
readonly roles = Roles;
@Input() dossier: Dossier;
#existsWatermarks$: Observable<boolean>;
constructor(
private readonly _dossiersService: DossiersService,

Some files were not shown because too many files have changed in this diff Show More