RED-3800: Cleanup iqser-cache lib, small file preview refactor
This commit is contained in:
parent
a47cbdfacb
commit
4d2fa2119b
@ -11,7 +11,6 @@
|
||||
{
|
||||
"enforceBuildableLibDependency": true,
|
||||
"allow": [
|
||||
"@redaction/red-cache",
|
||||
"@services/**",
|
||||
"@components/**",
|
||||
"@guards/**",
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": 1,
|
||||
"projects": {
|
||||
"red-cache": {
|
||||
"iqser-cache": {
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "library",
|
||||
"root": "libs/red-cache",
|
||||
"sourceRoot": "libs/red-cache/src",
|
||||
"root": "libs/iqser-cache",
|
||||
"sourceRoot": "libs/iqser-cache/src",
|
||||
"prefix": "redaction",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
|
||||
@ -13,7 +13,7 @@ import { ServiceWorkerModule } from '@angular/service-worker';
|
||||
import { environment } from '@environments/environment';
|
||||
import { AuthModule } from './modules/auth/auth.module';
|
||||
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
|
||||
import { HttpCacheInterceptor } from '@red/cache';
|
||||
import { HttpCacheInterceptor } from '@iqser/cache';
|
||||
import { NotificationsComponent } from '@components/notifications/notifications.component';
|
||||
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
<ng-container *ngIf="state.file$ | async as file">
|
||||
<iqser-empty-state
|
||||
*ngIf="file.excluded && (documentInfoService.hidden$ | async) && excludedPagesService.hidden$ | async"
|
||||
[horizontalPadding]="40"
|
||||
[text]="'file-preview.tabs.is-excluded' | translate"
|
||||
icon="red:needs-work"
|
||||
></iqser-empty-state>
|
||||
|
||||
<redaction-document-info *ngIf="documentInfoService.shown$ | async"></redaction-document-info>
|
||||
|
||||
<redaction-file-workload
|
||||
*ngIf="!file.excluded"
|
||||
[activeViewerPage]="pdf.currentPage$ | async"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[dialogRef]="state.dialogRef"
|
||||
[file]="file"
|
||||
></redaction-file-workload>
|
||||
|
||||
<ng-template #annotationActionsTemplate let-annotation="annotation">
|
||||
<redaction-annotation-actions
|
||||
[annotations]="[annotation]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformAnnotationActions$ | async"
|
||||
[iqserHelpMode]="getActionsHelpModeKey(annotation)"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
></redaction-annotation-actions>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: contents;
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { DocumentInfoService } from '../../services/document-info.service';
|
||||
import { ExcludedPagesService } from '../../services/excluded-pages.service';
|
||||
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { PdfProxyService } from '../../services/pdf-proxy.service';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { ActionsHelpModeKeys } from '../../utils/constants';
|
||||
import { ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-preview-right-container',
|
||||
templateUrl: './file-preview-right-container.component.html',
|
||||
styleUrls: ['./file-preview-right-container.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FilePreviewRightContainerComponent {
|
||||
constructor(
|
||||
readonly pdf: PdfViewer,
|
||||
readonly pdfProxyService: PdfProxyService,
|
||||
readonly state: FilePreviewStateService,
|
||||
readonly documentInfoService: DocumentInfoService,
|
||||
readonly excludedPagesService: ExcludedPagesService,
|
||||
) {}
|
||||
|
||||
get scrollableParentView(): ScrollableParentView {
|
||||
return ScrollableParentViews.ANNOTATIONS_LIST;
|
||||
}
|
||||
|
||||
getActionsHelpModeKey(annotation: AnnotationWrapper): string {
|
||||
const type = annotation?.typeLabel?.split('.')[1];
|
||||
const typeValue = annotation?.typeValue;
|
||||
if (type === 'hint' && (typeValue === 'ocr' || typeValue === 'formula' || typeValue === 'image')) {
|
||||
return ActionsHelpModeKeys[`${type}-${typeValue}`];
|
||||
}
|
||||
return ActionsHelpModeKeys[type];
|
||||
}
|
||||
}
|
||||
@ -70,36 +70,12 @@
|
||||
</div>
|
||||
|
||||
<div class="right-container">
|
||||
<iqser-empty-state
|
||||
*ngIf="file.excluded && (documentInfoService.hidden$ | async) && excludedPagesService.hidden$ | async"
|
||||
[horizontalPadding]="40"
|
||||
[text]="'file-preview.tabs.is-excluded' | translate"
|
||||
icon="red:needs-work"
|
||||
></iqser-empty-state>
|
||||
|
||||
<redaction-document-info *ngIf="documentInfoService.shown$ | async"></redaction-document-info>
|
||||
|
||||
<redaction-file-workload
|
||||
*ngIf="!file.excluded"
|
||||
[activeViewerPage]="pdf.currentPage$ | async"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[dialogRef]="dialogRef"
|
||||
[file]="file"
|
||||
></redaction-file-workload>
|
||||
<redaction-file-preview-right-container></redaction-file-preview-right-container>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #annotationActionsTemplate let-annotation="annotation">
|
||||
<redaction-annotation-actions
|
||||
[annotations]="[annotation]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformAnnotationActions$ | async"
|
||||
[iqserHelpMode]="getActionsHelpModeKey(annotation)"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
></redaction-annotation-actions>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #annotationFilterTemplate let-filter="filter">
|
||||
<redaction-type-filter [dossierTemplateId]="state.dossierTemplateId" [filter]="filter"></redaction-type-filter>
|
||||
</ng-template>
|
||||
|
||||
@ -14,10 +14,8 @@ import {
|
||||
OnAttach,
|
||||
OnDetach,
|
||||
processFilters,
|
||||
ScrollableParentView,
|
||||
ScrollableParentViews,
|
||||
} from '@iqser/common-ui';
|
||||
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
||||
import { MatDialogState } from '@angular/material/dialog';
|
||||
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationDrawService } from '../pdf-viewer/services/annotation-draw.service';
|
||||
@ -31,10 +29,7 @@ import { FilesService } from '@services/files/files.service';
|
||||
import { FileManagementService } from '@services/files/file-management.service';
|
||||
import { catchError, filter, map, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
import { ExcludedPagesService } from './services/excluded-pages.service';
|
||||
import { ViewModeService } from './services/view-mode.service';
|
||||
import { MultiSelectService } from './services/multi-select.service';
|
||||
import { DocumentInfoService } from './services/document-info.service';
|
||||
import { ReanalysisService } from '@services/reanalysis.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { FilePreviewStateService } from './services/file-preview-state.service';
|
||||
@ -45,7 +40,7 @@ import { PageRotationService } from '../pdf-viewer/services/page-rotation.servic
|
||||
import { ComponentCanDeactivate } from '@guards/can-deactivate.guard';
|
||||
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
|
||||
import { FileDataService } from './services/file-data.service';
|
||||
import { ActionsHelpModeKeys, ALL_HOTKEYS, TextPopups } from './utils/constants';
|
||||
import { ALL_HOTKEYS, TextPopups } from './utils/constants';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { StampService } from './services/stamp.service';
|
||||
import { PdfViewer } from '../pdf-viewer/services/pdf-viewer.service';
|
||||
@ -68,7 +63,6 @@ const textActions = [TextPopups.ADD_DICTIONARY, TextPopups.ADD_FALSE_POSITIVE];
|
||||
export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach, ComponentCanDeactivate {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
dialogRef: MatDialogRef<unknown>;
|
||||
fullScreen = false;
|
||||
readonly fileId = this.state.fileId;
|
||||
readonly dossierId = this.state.dossierId;
|
||||
@ -81,13 +75,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
constructor(
|
||||
readonly pdf: PdfViewer,
|
||||
readonly documentInfoService: DocumentInfoService,
|
||||
readonly state: FilePreviewStateService,
|
||||
readonly listingService: AnnotationsListingService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
readonly multiSelectService: MultiSelectService,
|
||||
readonly excludedPagesService: ExcludedPagesService,
|
||||
readonly userPreferenceService: UserPreferenceService,
|
||||
readonly pdfProxyService: PdfProxyService,
|
||||
private readonly _listingService: AnnotationsListingService,
|
||||
private readonly _router: Router,
|
||||
private readonly _ngZone: NgZone,
|
||||
private readonly _logger: NGXLogger,
|
||||
@ -102,14 +94,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
private readonly _fileDataService: FileDataService,
|
||||
private readonly _viewModeService: ViewModeService,
|
||||
private readonly _documentViewer: REDDocumentViewer,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _changeRef: ChangeDetectorRef,
|
||||
private readonly _dialogService: FilePreviewDialogService,
|
||||
private readonly _pageRotationService: PageRotationService,
|
||||
private readonly _viewerHeaderService: ViewerHeaderService,
|
||||
private readonly _annotationDrawService: AnnotationDrawService,
|
||||
private readonly _annotationProcessingService: AnnotationProcessingService,
|
||||
private readonly _stampService: StampService,
|
||||
readonly pdfProxyService: PdfProxyService,
|
||||
private readonly _injector: Injector,
|
||||
) {
|
||||
super();
|
||||
@ -124,10 +115,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return this._pageRotationService.hasRotations;
|
||||
}
|
||||
|
||||
get scrollableParentView(): ScrollableParentView {
|
||||
return ScrollableParentViews.ANNOTATIONS_LIST;
|
||||
}
|
||||
|
||||
get #textSelected$() {
|
||||
const textSelected$ = combineLatest([
|
||||
this._documentViewer.textSelected$,
|
||||
@ -206,7 +193,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
ngOnDetach() {
|
||||
this._viewerHeaderService.resetCompareButtons();
|
||||
super.ngOnDetach();
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
|
||||
async ngOnAttach(previousRoute: ActivatedRouteSnapshot) {
|
||||
@ -220,7 +207,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
await this._fileDataService.loadRedactionLog();
|
||||
this._viewerHeaderService.updateElements();
|
||||
await this.#updateQueryParamsPage(Number(previousRoute.queryParams.page ?? '1'));
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
@ -247,7 +234,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return this._ngZone.run(() => {
|
||||
const file = this.state.file;
|
||||
|
||||
this.dialogRef = this._dialogService.openDialog(
|
||||
this.state.dialogRef = this._dialogService.openDialog(
|
||||
'manualAnnotation',
|
||||
null,
|
||||
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file },
|
||||
@ -286,14 +273,14 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ALL_HOTKEYS.includes($event.key) || this.dialogRef?.getState() === MatDialogState.OPEN) {
|
||||
if (!ALL_HOTKEYS.includes($event.key) || this.state.dialogRef?.getState() === MatDialogState.OPEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (['Escape'].includes($event.key)) {
|
||||
this.fullScreen = false;
|
||||
this.closeFullScreen();
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
|
||||
if (['f', 'F'].includes($event.key)) {
|
||||
@ -325,7 +312,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
this._loadingService.stop();
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
|
||||
closeFullScreen() {
|
||||
@ -402,15 +389,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return [oldAnnotations, newAnnotations];
|
||||
}
|
||||
|
||||
getActionsHelpModeKey(annotation: AnnotationWrapper): string {
|
||||
const type = annotation?.typeLabel?.split('.')[1];
|
||||
const typeValue = annotation?.typeValue;
|
||||
if (type === 'hint' && (typeValue === 'ocr' || typeValue === 'formula' || typeValue === 'image')) {
|
||||
return ActionsHelpModeKeys[`${type}-${typeValue}`];
|
||||
}
|
||||
return ActionsHelpModeKeys[type];
|
||||
}
|
||||
|
||||
#getAnnotationsToDraw(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
|
||||
const currentPage = this.pdf.currentPage;
|
||||
const currentPageAnnotations = this._annotationManager.get(a => a.getPageNumber() === currentPage);
|
||||
@ -456,7 +434,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
};
|
||||
await this._router.navigate([], extras);
|
||||
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
|
||||
#findAnnotationsToDraw(
|
||||
@ -646,7 +624,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
#highlightSelectedAnnotations(newAnnotations: AnnotationWrapper[]) {
|
||||
const annotationsIds = newAnnotations.map(annotation => annotation.id);
|
||||
const selected = this.listingService.selected.filter(a => annotationsIds.includes(a.id));
|
||||
const selected = this._listingService.selected.filter(a => annotationsIds.includes(a.id));
|
||||
const annotations = this._annotationManager.get(selected);
|
||||
this._annotationManager.select(annotations);
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ import { AnnotationWrapperComponent } from './components/annotation-wrapper/anno
|
||||
import { AnnotationReferenceComponent } from './components/annotation-reference/annotation-reference.component';
|
||||
import { ImportRedactionsDialogComponent } from './dialogs/import-redactions-dialog/import-redactions-dialog';
|
||||
import { DocumentUnloadedGuard } from './services/document-unloaded.guard';
|
||||
import { FilePreviewRightContainerComponent } from './components/right-container/file-preview-right-container.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -79,6 +80,7 @@ const components = [
|
||||
HighlightsSeparatorComponent,
|
||||
AnnotationReferenceComponent,
|
||||
FilePreviewScreenComponent,
|
||||
FilePreviewRightContainerComponent,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@ -8,13 +8,14 @@ import { boolFactory, getParam, LoadingService } 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';
|
||||
import { wipeFilesCache } from '@red/cache';
|
||||
import { wipeFilesCache } from '@iqser/cache';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { FilesService } from '@services/files/files.service';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { HttpEvent, HttpEventType, HttpProgressEvent, HttpResponse } from '@angular/common/http';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DictionariesMapService } from '../../../services/entity-services/dictionaries-map.service';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
const ONE_MEGABYTE = 1024 * 1024;
|
||||
|
||||
@ -42,6 +43,7 @@ export class FilePreviewStateService {
|
||||
readonly dossierTemplateId: string;
|
||||
readonly fileId: string = getParam(FILE_ID);
|
||||
dossier: Dossier;
|
||||
dialogRef: MatDialogRef<unknown>;
|
||||
file: File;
|
||||
#dossierDictionary: Dictionary;
|
||||
readonly #reloadBlob$ = new Subject();
|
||||
|
||||
@ -3,7 +3,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import packageInfo from '../../../../../package.json';
|
||||
import envConfig from '../../assets/config/config.json';
|
||||
import { CacheApiService, wipeAllCaches } from '@red/cache';
|
||||
import { CacheApiService, wipeAllCaches } from '@iqser/cache';
|
||||
import { Observable } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { AppConfig } from '@red/domain';
|
||||
|
||||
@ -2,7 +2,7 @@ import { inject, Inject, Injectable } from '@angular/core';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import jwt_decode from 'jwt-decode';
|
||||
import { ICreateUserRequest, IMyProfileUpdateRequest, IProfileUpdateRequest, IResetPasswordRequest, IUser, User } from '@red/domain';
|
||||
import { wipeCaches } from '@red/cache';
|
||||
import { wipeCaches } from '@iqser/cache';
|
||||
import { BASE_HREF } from '../tokens';
|
||||
import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs';
|
||||
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
{
|
||||
"files": ["**/*.ts"],
|
||||
"parserOptions": {
|
||||
"project": ["libs/red-cache/tsconfig.json"]
|
||||
"project": ["libs/iqser-cache/tsconfig.json"]
|
||||
},
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
@ -1,7 +1,7 @@
|
||||
# red-cache
|
||||
# iqser-cache
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test red-cache` to execute the unit tests.
|
||||
Run `nx test iqser-cache` to execute the unit tests.
|
||||
@ -41,9 +41,8 @@ export class CacheApiService {
|
||||
if (parseInt(expires, 10) > new Date().getTime()) {
|
||||
// console.log('[CACHE-API] Returning from cache: ', url);
|
||||
return this._toHttpResponse(response);
|
||||
} else {
|
||||
// console.log('[CACHE-API] cache expired: ', url);
|
||||
}
|
||||
// console.log('[CACHE-API] cache expired: ', url);
|
||||
} else {
|
||||
// console.log('[CACHE-API] Returning from cache: ', url);
|
||||
return this._toHttpResponse(response);
|
||||
@ -68,33 +67,8 @@ export class CacheApiService {
|
||||
// console.log('should cache', valueReference, string, response);
|
||||
return cache.put(request, response);
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
removeCache(cacheId: string): Promise<any> {
|
||||
if (this.cachesAvailable) {
|
||||
return caches.open(APP_LEVEL_CACHE).then(cache => cache.delete(cacheId));
|
||||
} else {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
deleteDynamicCache(cacheName: string): Promise<any> {
|
||||
if (this.cachesAvailable && DYNAMIC_CACHES.some(cache => cache.name === cacheName)) {
|
||||
return caches.delete(cacheName);
|
||||
} else {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
deleteDynamicCacheEntry(cacheName: string, cacheEntry: string): Promise<any> {
|
||||
if (this.cachesAvailable && DYNAMIC_CACHES.some(cache => cache.name === cacheName)) {
|
||||
return caches.open(cacheName).then(cache => cache.delete(cacheEntry));
|
||||
} else {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
getCachedValue(name: string): Promise<any> {
|
||||
@ -112,9 +86,8 @@ export class CacheApiService {
|
||||
return undefined;
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
_buildUrl(request: HttpRequest<any>) {
|
||||
3
libs/iqser-cache/src/lib/caches/index.ts
Normal file
3
libs/iqser-cache/src/lib/caches/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './cache-api.service';
|
||||
export * from './cache-utils';
|
||||
export * from './http-cache-interceptor';
|
||||
1
libs/iqser-cache/src/lib/index.ts
Normal file
1
libs/iqser-cache/src/lib/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './caches/index';
|
||||
@ -1,5 +0,0 @@
|
||||
export interface Cacheable {
|
||||
restoreFromCache(): Promise<any>;
|
||||
|
||||
storeToCache(): Promise<any>;
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
import { IdToObjectListCacheStoreService } from './id-to-object-list-cache-store.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class IdToObjectCacheRegisterService {
|
||||
constructor(private _idToObjectListCacheStoreService: IdToObjectListCacheStoreService) {}
|
||||
|
||||
registerCaches() {}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Observable, of } from 'rxjs';
|
||||
import { CacheApiService } from './cache-api.service';
|
||||
import { catchError, map, mergeMap } from 'rxjs/operators';
|
||||
|
||||
export interface IdToObject {
|
||||
id: string;
|
||||
object: any;
|
||||
}
|
||||
|
||||
export interface RegisteredCache {
|
||||
name: string;
|
||||
keyConversionFunction: (id: string, input: any) => string;
|
||||
cacheFunction: (ids: string[], ...params: any) => Observable<{ [key: string]: any }>;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class IdToObjectListCacheStoreService {
|
||||
private _cachesList: { [key: string]: RegisteredCache } = {};
|
||||
|
||||
constructor(private _cacheApiService: CacheApiService) {}
|
||||
|
||||
registerCache(
|
||||
name: string,
|
||||
cacheFunction: (ids: string[], ...params: any) => Observable<{ [key: string]: any }>,
|
||||
keyConversionFunction: (id: string, ...params: any) => string = id => id
|
||||
) {
|
||||
this._cachesList[name] = {
|
||||
name,
|
||||
keyConversionFunction,
|
||||
cacheFunction
|
||||
};
|
||||
}
|
||||
|
||||
invokeCache(name: string, ids: string[], ...params: any): Observable<{ [key: string]: any }> {
|
||||
const promises = [];
|
||||
const cache = this._cachesList[name];
|
||||
ids.map(id => this._toUrl(name, cache.keyConversionFunction(id, params))).forEach(url => {
|
||||
promises.push(this._cacheApiService.getCachedValue(url));
|
||||
});
|
||||
return from(Promise.all(promises))
|
||||
.pipe(catchError(() => of([])))
|
||||
.pipe(
|
||||
mergeMap((resolvedValues: IdToObject[]) => {
|
||||
const partialResult = {};
|
||||
resolvedValues
|
||||
.filter(v => !!v)
|
||||
.forEach(foundValue => {
|
||||
partialResult[foundValue.id] = foundValue.object;
|
||||
});
|
||||
|
||||
const existingIds = Object.keys(partialResult);
|
||||
const requestIds = ids.filter(el => !existingIds.includes(el));
|
||||
|
||||
if (requestIds.length > 0) {
|
||||
return cache.cacheFunction(requestIds, params).pipe(
|
||||
map(data => {
|
||||
// new items
|
||||
for (const key of Object.keys(data)) {
|
||||
const idToObject = {
|
||||
id: key,
|
||||
object: data[key]
|
||||
};
|
||||
// cache each new result
|
||||
this._cacheApiService.cacheValue(
|
||||
this._toUrl(name, cache.keyConversionFunction(key, params)),
|
||||
idToObject
|
||||
);
|
||||
}
|
||||
// add existing results to final result
|
||||
for (const existingKey of Object.keys(partialResult)) {
|
||||
data[existingKey] = partialResult[existingKey];
|
||||
}
|
||||
return data;
|
||||
})
|
||||
);
|
||||
} else {
|
||||
return of(partialResult);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
expireCache(name: string, id: string, ...params: any) {
|
||||
const cache = this._cachesList[name];
|
||||
const cacheUrl = this._toUrl(name, cache.keyConversionFunction(id, params));
|
||||
this._cacheApiService.removeCache(cacheUrl);
|
||||
}
|
||||
|
||||
private _toUrl(cacheName: string, id: string) {
|
||||
return `/${cacheName}/${id}`;
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 - 2030 by ACI Worldwide Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information
|
||||
* of ACI Worldwide Inc ("Confidential Information"). You shall
|
||||
* not disclose such Confidential Information and shall use it
|
||||
* only in accordance with the terms of the license agreement
|
||||
* you entered with ACI Worldwide Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
export * from './cache-api.service';
|
||||
export * from './cache-utils';
|
||||
export * from './cacheable';
|
||||
export * from './http-cache-interceptor';
|
||||
export * from './id-to-object-cache.register.service';
|
||||
export * from './id-to-object-list-cache-store.service';
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 - 2030 by ACI Worldwide Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information
|
||||
* of ACI Worldwide Inc ("Confidential Information"). You shall
|
||||
* not disclose such Confidential Information and shall use it
|
||||
* only in accordance with the terms of the license agreement
|
||||
* you entered with ACI Worldwide Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
export * from './caches/index';
|
||||
12
sonar.js
12
sonar.js
@ -2,12 +2,12 @@ const scanner = require('sonarqube-scanner');
|
||||
|
||||
scanner(
|
||||
{
|
||||
serverUrl : 'https://sonarqube.iqser.com',
|
||||
token : "362e7bc3a14436f2d6ee72c5ed379681d4b7963c",
|
||||
serverUrl: 'https://sonarqube.iqser.com',
|
||||
token: '362e7bc3a14436f2d6ee72c5ed379681d4b7963c',
|
||||
options: {
|
||||
'sonar.projectKey': 'RED_ui',
|
||||
'sonar.sources': 'apps/red-ui,libs/common-ui,libs/red-cache',
|
||||
}
|
||||
'sonar.sources': 'apps/red-ui,libs/common-ui,libs/iqser-cache',
|
||||
},
|
||||
},
|
||||
() => process.exit()
|
||||
)
|
||||
() => process.exit(),
|
||||
);
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
"@i18n/*": ["apps/red-ui/src/app/i18n/*"],
|
||||
"@iqser/common-ui": ["libs/common-ui/src/index.ts"],
|
||||
"@models/*": ["apps/red-ui/src/app/models/*"],
|
||||
"@red/cache": ["libs/red-cache/src/index.ts"],
|
||||
"@iqser/cache": ["libs/iqser-cache/src/index.ts"],
|
||||
"@red/domain": ["libs/red-domain/src/index.ts"],
|
||||
"@services/*": ["apps/red-ui/src/app/services/*"],
|
||||
"@shared/*": ["apps/red-ui/src/app/modules/shared/*"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user