@hmcts/media-viewer
Version:
1,464 lines (1,449 loc) • 558 kB
JavaScript
import * as i5 from 'rpx-xui-translation';
import { RpxTranslationModule } from 'rpx-xui-translation';
import * as i0 from '@angular/core';
import { Injectable, Component, ViewChild, HostListener, Directive, Input, ViewEncapsulation, Pipe, EventEmitter, Output, ViewChildren, NgModule } from '@angular/core';
import * as i4 from '@angular/common';
import { DatePipe, CommonModule } from '@angular/common';
import * as i2 from '@angular/forms';
import { UntypedFormControl, FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i1$1 from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http';
import { BehaviorSubject, Subject, of, combineLatest, asyncScheduler, filter as filter$1, take as take$1, delay } from 'rxjs';
import { take, distinctUntilChanged, filter, auditTime, tap, throttleTime, map, catchError, switchMap, concatMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
import * as i1 from '@ngrx/store';
import { createFeatureSelector, createSelector, select, StoreModule } from '@ngrx/store';
import { v4 } from 'uuid';
import moment from 'moment-timezone';
import 'pdfjs-dist/build/pdf.mjs';
import * as pdfjsViewer from 'pdfjs-dist/web/pdf_viewer.mjs';
import { PDFLinkService } from 'pdfjs-dist/web/pdf_viewer.mjs';
import * as pdfjs from 'pdfjs-dist';
import 'pdfjs-dist/build/pdf.worker';
import { some } from 'lodash';
import * as i4$1 from 'ngx-chips';
import { TagInputModule } from 'ngx-chips';
import * as i3 from '@angular/router';
import { RouterModule } from '@angular/router';
import * as i4$2 from 'mutable-div';
import { MutableDivModule } from 'mutable-div';
import { SelectionModel, ArrayDataSource } from '@angular/cdk/collections';
import * as i3$1 from '@angular/cdk/tree';
import { NestedTreeControl, CdkTreeModule } from '@angular/cdk/tree';
import * as i4$3 from '@angular/cdk/drag-drop';
import { DragDropModule } from '@angular/cdk/drag-drop';
import * as i5$1 from '@angular/cdk/scrolling';
import * as i8 from '@angular/cdk/overlay';
import { ConnectionPositionPair, OverlayModule } from '@angular/cdk/overlay';
import * as i5$2 from '@angular/cdk/a11y';
import { A11yModule } from '@angular/cdk/a11y';
import * as i8$1 from '@swimlane/ngx-datatable';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import * as i1$2 from '@ngrx/effects';
import { createEffect, ofType, EffectsModule } from '@ngrx/effects';
var ResponseType;
(function (ResponseType) {
ResponseType["SUCCESS"] = "SUCCESS";
ResponseType["FAILURE"] = "FAILURE";
ResponseType["UNSUPPORTED"] = "UNSUPPORTED";
})(ResponseType || (ResponseType = {}));
class ViewerException {
constructor(exceptionType, detail) {
this.exceptionType = exceptionType;
this.detail = detail;
}
}
const SET_DOCUMENT_ID = '[Document] Set Document Id';
const POSITION_UPDATED = '[Document] Position Updated';
const ADD_PAGES = '[Document] Add Pages';
const CONVERT = '[Document] Convert';
const CONVERT_SUCCESS = '[Document] Convert Success';
const CONVERT_FAIL = '[Document] Convert Fail';
const CLEAR_CONVERT_DOC_URL = '[Document] Clear Convert Doc Url';
const LOAD_ROTATION = '[Document] Load Rotation';
const LOAD_ROTATION_SUCCESS = '[Document] Load Rotation Success';
const LOAD_ROTATION_FAIL = '[Document] Load Rotation Fail';
const SAVE_ROTATION = '[Document] Save Rotation';
const SAVE_ROTATION_SUCCESS = '[Document] Save Rotation Success';
const SAVE_ROTATION_FAIL = '[Document] Save Rotation Fail';
class SetDocumentId {
constructor(payload) {
this.payload = payload;
this.type = SET_DOCUMENT_ID;
}
}
class AddPages {
constructor(payload) {
this.payload = payload;
this.type = ADD_PAGES;
}
}
class PdfPositionUpdate {
constructor(payload) {
this.payload = payload;
this.type = POSITION_UPDATED;
}
}
class Convert {
constructor(payload) {
this.payload = payload;
this.type = CONVERT;
}
}
class ConvertSuccess {
constructor(payload) {
this.payload = payload;
this.type = CONVERT_SUCCESS;
}
}
class ConvertFailure {
constructor(payload) {
this.payload = payload;
this.type = CONVERT_FAIL;
}
}
class ClearConvertDocUrl {
constructor() {
this.type = CLEAR_CONVERT_DOC_URL;
}
}
class LoadRotation {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ROTATION;
}
}
class LoadRotationSuccess {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ROTATION_SUCCESS;
}
}
class LoadRotationFailure {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ROTATION_FAIL;
}
}
class SaveRotation {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ROTATION;
}
}
class SaveRotationSuccess {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ROTATION_SUCCESS;
}
}
class SaveRotationFailure {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ROTATION_FAIL;
}
}
const UPDATE_TAGS = '[Tags] Update Tags';
const ADD_FILTER_TAGS = '[Tags] Add Filter Tags';
const CLEAR_FILTER_TAGS = '[Tags] Clear Filter Tags';
class UpdateTags {
constructor(payload) {
this.payload = payload;
this.type = UPDATE_TAGS;
}
}
class AddFilterTags {
constructor(payload) {
this.payload = payload;
this.type = ADD_FILTER_TAGS;
}
}
class ClearFilterTags {
constructor() {
this.type = CLEAR_FILTER_TAGS;
}
}
const SET_CASE_ID = '[Icp] Set Case Id';
const LOAD_ICP_SESSION = '[Icp] Load Session';
const LOAD_ICP_SESSION_FAIL = '[Icp] Load Session Failure';
const JOIN_ICP_SOCKET_SESSION = '[Icp] Join Socket Session';
const ICP_SOCKET_SESSION_JOINED = '[Icp] Socket Session Joined';
const LEAVE_ICP_SOCKET_SESSION = '[Icp] Leave Socket Session';
const ICP_PRESENTER_UPDATED = '[Icp] Presenter Updated';
const ICP_PARTICIPANT_LIST_UPDATED = '[Icp] Participant List Updated';
class SetCaseId {
constructor(payload) {
this.payload = payload;
this.type = SET_CASE_ID;
}
}
class LoadIcpSession {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ICP_SESSION;
}
}
class LoadIcpSessionFailure {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ICP_SESSION_FAIL;
}
}
class JoinIcpSocketSession {
constructor(payload) {
this.payload = payload;
this.type = JOIN_ICP_SOCKET_SESSION;
}
}
class IcpSocketSessionJoined {
constructor(payload) {
this.payload = payload;
this.type = ICP_SOCKET_SESSION_JOINED;
}
}
class LeaveIcpSocketSession {
constructor() {
this.type = LEAVE_ICP_SOCKET_SESSION;
}
}
class IcpPresenterUpdated {
constructor(payload) {
this.payload = payload;
this.type = ICP_PRESENTER_UPDATED;
}
}
class IcpParticipantListUpdated {
constructor(payload) {
this.payload = payload;
this.type = ICP_PARTICIPANT_LIST_UPDATED;
}
}
const initialDocumentState = {
convertedDocument: undefined,
documentId: undefined,
pdfPosition: undefined,
pages: {},
hasDifferentPageSize: false,
rotation: undefined,
rotationLoaded: false,
loading: false,
loaded: false
};
function docReducer(state = initialDocumentState, action) {
switch (action.type) {
case CONVERT_SUCCESS: {
const convertedDocument = {
url: action.payload,
error: undefined
};
return {
...state,
convertedDocument
};
}
case CONVERT_FAIL: {
const convertedDocument = {
url: undefined,
error: action.payload
};
return {
...state,
convertedDocument
};
}
case CLEAR_CONVERT_DOC_URL: {
const convertedDocument = undefined;
return {
...state,
convertedDocument
};
}
case LOAD_ROTATION: {
return {
...state,
rotationLoaded: false
};
}
case LOAD_ROTATION_SUCCESS: {
const metadata = action.payload;
const rotation = metadata ? metadata.rotationAngle : 0;
return {
...state,
rotation,
rotationLoaded: true
};
}
case LOAD_ROTATION_FAIL: {
return {
...state,
rotation: 0,
rotationLoaded: true
};
}
case SAVE_ROTATION_SUCCESS: {
const metadata = action.payload;
const rotation = metadata.rotationAngle;
return {
...state,
rotation
};
}
case SET_DOCUMENT_ID: {
return {
...state,
documentId: action.payload
};
}
case ADD_PAGES: {
const payload = action.payload;
let pages = {};
let pageHeight;
let pageWidth;
let hasDifferentPageSize = state.hasDifferentPageSize;
const pageNumberInput = document.getElementById('pageNumber');
const pageIndex = pageNumberInput?.value ? parseInt(pageNumberInput.value, 10) - 1 : 0;
const loadedPage = payload[pageIndex]?.div['attributes']?.style?.value ?? '';
payload.forEach(page => {
const sizingValue = page.div?.['attributes']?.style?.value ?? '';
const widthMatch = sizingValue.match(/width:\s*round\(down,\s*var\(--scale-factor\)\s*\*\s*([\d.]+)([a-z%]+)?,.*var\(--scale-round-x, ([\d.]+)([a-z%]+)?\)\)/);
const heightMatch = sizingValue.match(/height:\s*round\(down,\s*var\(--scale-factor\)\s*\*\s*([\d.]+)([a-z%]+)?,.*var\(--scale-round-y, ([\d.]+)([a-z%]+)?\)\)/);
const scaleRoundXMatch = loadedPage.match(/--scale-round-x:\s*([\d.]+)([a-z%]+)?/);
const scaleRoundYMatch = loadedPage.match(/--scale-round-y:\s*([\d.]+)([a-z%]+)?/);
// You can now use widthUnit, heightUnit, scaleRoundXUnit, scaleRoundYUnit as needed
const scaleFactor = page.viewportScale ?? 1;
const scaleRoundX = scaleRoundXMatch ? parseFloat(scaleRoundXMatch[1]) : 1;
const scaleRoundY = scaleRoundYMatch ? parseFloat(scaleRoundYMatch[1]) : 1;
const baseWidth = widthMatch ? parseFloat(widthMatch[1]) : undefined;
const baseHeight = heightMatch ? parseFloat(heightMatch[1]) : undefined;
function roundDown(value, step) {
return Math.floor(value / step) * step;
}
const computedWidth = baseWidth !== undefined
? roundDown(scaleFactor * baseWidth, scaleRoundX)
: page.div['clientWidth'];
const computedHeight = baseHeight !== undefined
? roundDown(scaleFactor * baseHeight, scaleRoundY)
: page.div['clientHeight'];
if (!hasDifferentPageSize && pageHeight && pageWidth &&
(pageHeight !== computedHeight || pageWidth !== computedWidth)) {
hasDifferentPageSize = true;
}
else {
pageHeight = computedHeight;
pageWidth = computedWidth;
}
const styles = {
left: page.div['offsetLeft'],
height: computedHeight,
width: computedWidth
};
const scaleRotation = {
scale: page.scale,
rotation: page.rotation
};
const p = {
styles,
scaleRotation,
viewportScale: page.viewportScale
};
pages = {
...pages,
[page.id]: p
};
});
return {
...state,
pages,
hasDifferentPageSize
};
}
case POSITION_UPDATED: {
const pdfPosition = action.payload;
return {
...state,
pdfPosition
};
}
}
return state;
}
const getDocPages = (state) => state.pages;
const getDocId = (state) => state.documentId;
const getPdfPos = (state) => state.pdfPosition;
const getHasDifferentPageSizes = (state) => state.hasDifferentPageSize;
const getRotation$1 = (state) => state.rotation;
const rotationLoaded$1 = (state) => state.rotationLoaded;
const getConvertedDocument$1 = (state) => state.convertedDocument;
const LOAD_ANNOTATION_SET = '[Annotations] Load Annotation Set';
const LOAD_ANNOTATION_SET_SUCCESS = '[Annotations] Load Annotation Set Success';
const LOAD_ANNOTATION_SET_FAIL = '[Annotations] Load Annotation Set Fail';
const SAVE_ANNOTATION_SET = '[Annotations] Save Annotation Set';
const SAVE_ANNOTATION_SET_SUCCESS = '[Annotations] Save Annotation Set Success';
const SAVE_ANNOTATION_SET_FAIL = '[Annotations] Save Annotation Set Fail';
const SAVE_ANNOTATION = '[Annotations] Save Annotation';
const SAVE_ANNOTATION_SUCCESS = '[Annotations] Save Annotation Success';
const SAVE_ANNOTATION_FAIL = '[Annotations] Save Annotation Fail';
const ADD_OR_EDIT_COMMENT = '[Annotations] Add or Edit Comment';
const DELETE_ANNOTATION = '[Annotations] Delete Annotation';
const DELETE_ANNOTATION_SUCCESS = '[Annotations] Delete Annotation Success';
const DELETE_ANNOTATION_FAIL = '[Annotations] Delete Annotation Fail';
const SELECT_ANNOTATION = '[Annotations] Select Annotation';
const SEARCH_COMMENT = '[Comments] Search Comments';
const APPLY_COMMENT_SUMMARY_FILTER = '[Comments] Apply Comment Summary Filter';
const CLEAR_COMMENT_SUMMARY_FILTER = '[Comments] Clear Comment Summary Filter';
class LoadAnnotationSet {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ANNOTATION_SET;
}
}
class SaveAnnotationSet {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ANNOTATION_SET;
}
}
class LoadAnnotationSetSucess {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ANNOTATION_SET_SUCCESS;
}
}
class SaveAnnotationSetSuccess {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ANNOTATION_SET_SUCCESS;
}
}
class LoadAnnotationSetFail {
constructor(payload) {
this.payload = payload;
this.type = LOAD_ANNOTATION_SET_FAIL;
}
}
class SaveAnnotationSetFail {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ANNOTATION_SET_FAIL;
}
}
class SaveAnnotation {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ANNOTATION;
}
}
class SaveAnnotationSuccess {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ANNOTATION_SUCCESS;
}
}
class SaveAnnotationFail {
constructor(payload) {
this.payload = payload;
this.type = SAVE_ANNOTATION_FAIL;
}
}
class AddOrEditComment {
constructor(payload) {
this.payload = payload;
this.type = ADD_OR_EDIT_COMMENT;
}
}
class DeleteAnnotation {
constructor(payload) {
this.payload = payload;
this.type = DELETE_ANNOTATION;
}
}
class DeleteAnnotationSuccess {
constructor(payload) {
this.payload = payload;
this.type = DELETE_ANNOTATION_SUCCESS;
}
}
class DeleteAnnotationFail {
constructor(payload) {
this.payload = payload;
this.type = DELETE_ANNOTATION_FAIL;
}
}
class SelectedAnnotation {
constructor(payload) {
this.payload = payload;
this.type = SELECT_ANNOTATION;
}
}
class SearchComment {
constructor(payload) {
this.payload = payload;
this.type = SEARCH_COMMENT;
}
}
class ApplyCommentSymmaryFilter {
constructor(payload) {
this.payload = payload;
this.type = APPLY_COMMENT_SUMMARY_FILTER;
}
}
class ClearCommentSummaryFilters {
constructor() {
this.type = CLEAR_COMMENT_SUMMARY_FILTER;
}
}
/*
@dynamic
marking class as dynamic to stop compiler throwing error for lambda in static function
see https://github.com/angular/angular/issues/19698#issuecomment-338340211
*/
class StoreUtils {
static groupByKeyEntities(annotations, key) {
return annotations.reduce((h, obj) => Object.assign(h, { [obj[key]]: (h[obj[key]] || []).concat(obj) }), {});
}
static generateCommentsEntities(annotations) {
return annotations.reduce((commentEntities, annotation) => {
if (annotation.comments.length) {
const comment = {
...annotation.comments[0] || '',
tags: [...annotation.tags || []]
};
return {
...commentEntities,
[annotation.id]: comment
};
}
return {
...commentEntities
};
}, {});
}
static genTagNameEntities(annotations) {
const filterAnnoWithoutCommentsTags = annotations.filter(a => (a.comments.length && a.tags.length));
const allTags = filterAnnoWithoutCommentsTags.map(anno => this.groupByKeyEntities(anno.tags, 'name'));
const groupedByName = allTags.reduce((tagEntitiy, tagItem) => {
return {
...tagEntitiy,
...tagItem
};
}, {});
return this.genNameEnt(annotations, groupedByName);
}
static genNameEnt(annos, groupedByName) {
return Object.keys(groupedByName).reduce((tagNameEnt, key) => {
const readyAnno = annos.filter(anno => anno.tags.find(tag => tag.name === key))
.map(anno => anno.id)
.reduce((obj, anno) => ({ ...obj, [anno]: anno }), {});
return {
...tagNameEnt,
[key]: readyAnno
};
}, {});
}
static generateAnnotationEntities(anno) {
return anno.reduce((annoEntities, annotation) => {
const annot = {
...annotation,
positionTop: annotation.rectangles[0].y // todo remove this
};
return {
...annoEntities,
[annotation.id]: annot
};
}, {});
}
static generateRedactionEntities(redactions) {
return redactions.reduce((redactEntities, redaction) => {
return {
...redactEntities,
[redaction.redactionId]: redaction
};
}, {});
}
static resetCommentEntSelect(ent) {
return Object.keys(ent).reduce((object, key) => {
object[key] = {
...ent[key],
editable: false,
selected: false
};
return object;
}, {});
}
static filterCommentsSummary(comments, filters) {
if (Object.keys(filters).length) {
const tagFilterApplied = Object.keys(filters.tagFilters)
.filter(key => filters.tagFilters[key] === true).length;
const dateFilterApplied = (filters.dateRangeFrom || filters.dateRangeTo);
const filteredComments = comments.filter(comment => {
let hasTagFilter = false;
let hasDateFilter = false;
// check tags
if (filters.hasOwnProperty('tagFilters')) {
Object.keys(filters.tagFilters).forEach(filter => {
const label = filters.tagFilters[filter];
if (label) {
return comment.tags.forEach(tag => {
if (tag.name === filter && !hasTagFilter) {
hasTagFilter = true;
}
});
}
});
}
// check for dates
if (dateFilterApplied) {
const commentDate = moment(comment.lastModifiedDate);
const dateFrom = filters.dateRangeFrom !== null ? moment(filters.dateRangeFrom) : undefined;
const dateTo = filters.dateRangeTo !== null ? moment(filters.dateRangeTo) : undefined;
if (dateTo && dateFrom) {
if (commentDate > dateFrom && commentDate < dateTo) {
hasDateFilter = true;
}
}
if (dateTo && !dateFrom) {
if (commentDate <= dateTo) {
hasDateFilter = true;
}
}
if (dateFrom && !dateTo) {
if (commentDate > dateFrom) {
hasDateFilter = true;
}
}
}
return (hasTagFilter || hasDateFilter);
});
return (tagFilterApplied || dateFilterApplied) ? filteredComments : comments;
}
else {
return comments;
}
}
}
const initialState = {
annotationSet: {},
annotationEntities: {},
commentEntities: {},
annotationPageEntities: {},
selectedAnnotation: null,
commentSearchQueries: { commentSearch: '' },
commentSummaryFilters: { hasFilter: false, filters: {} },
loading: false,
loaded: false,
};
function reducer(state = initialState, action) {
switch (action.type) {
case LOAD_ANNOTATION_SET: {
const annotationSet = {
...state.annotationSet,
documentId: action.payload
};
return {
...initialState,
annotationSet,
loading: true
};
}
case LOAD_ANNOTATION_SET_SUCCESS:
case LOAD_ANNOTATION_SET_FAIL: {
const annotationSet = action.payload.status === 200 ? action.payload.body :
{
...state.annotationSet,
annotations: [],
id: v4()
};
const annotationEntities = StoreUtils.generateAnnotationEntities(annotationSet.annotations);
const annotationPageEntities = StoreUtils.groupByKeyEntities(annotationSet.annotations, 'page');
const commentEntities = StoreUtils.generateCommentsEntities(annotationSet.annotations);
return {
...state,
annotationSet,
annotationEntities,
annotationPageEntities,
commentEntities,
loading: false,
loaded: true
};
}
case SAVE_ANNOTATION_SET_SUCCESS: {
const anno = action.payload.annotations;
const annEntities = {
...state.annotationEntities,
...anno
};
const annotArray = Object.keys(annEntities).map(key => annEntities[key]);
const annotationEntities = StoreUtils.generateAnnotationEntities(annotArray);
const annotationPageEntities = StoreUtils.groupByKeyEntities(annotArray, 'page');
const commentEntities = StoreUtils.generateCommentsEntities(annotArray);
const selectedAnnotation = {
...state.selectedAnnotation,
...anno,
editable: false
};
return {
...state,
annotationEntities,
annotationPageEntities,
commentEntities,
selectedAnnotation,
loading: false,
loaded: true
};
}
case SAVE_ANNOTATION_SUCCESS: {
const anno = action.payload;
const annEntities = {
...state.annotationEntities,
[anno.id]: anno
};
const annotArray = Object.keys(annEntities).map(key => annEntities[key]);
const annotationEntities = StoreUtils.generateAnnotationEntities(annotArray);
const annotationPageEntities = StoreUtils.groupByKeyEntities(annotArray, 'page');
const commentEntities = StoreUtils.generateCommentsEntities(annotArray);
const selectedAnnotation = {
...state.selectedAnnotation,
annotationId: anno.id,
editable: false
};
return {
...state,
annotationEntities,
annotationPageEntities,
commentEntities,
selectedAnnotation,
loading: false,
loaded: true
};
}
case DELETE_ANNOTATION_SUCCESS: {
const id = action.payload;
const page = state.annotationEntities[id].page;
const annotationEntities = {
...state.annotationEntities
};
delete annotationEntities[id];
const pageAnnotationsRemoved = [
...state.annotationPageEntities[page].filter(anno => anno.id !== id)
];
const annotationPageEntities = {
...state.annotationPageEntities,
[page]: pageAnnotationsRemoved
};
const commentEntities = {
...state.commentEntities
};
if (state.commentEntities[id]) {
delete commentEntities[id];
}
return {
...state,
annotationEntities,
annotationPageEntities,
commentEntities
};
}
case ADD_OR_EDIT_COMMENT: {
const comment = {
[action.payload.annotationId]: action.payload
};
const comments = {
...state.commentEntities,
...comment
};
return {
...state,
commentEntities: comments
};
}
case SELECT_ANNOTATION: {
const payload = action.payload;
const commentEntity = {
...state.commentEntities[payload.annotationId],
editable: payload.editable,
selected: payload.selected
};
const resetCommentEntSelect = StoreUtils.resetCommentEntSelect({ ...state.commentEntities });
const commentEntities = payload.annotationId && state.commentEntities[payload.annotationId] ? {
...resetCommentEntSelect,
[payload.annotationId]: commentEntity
} : { ...resetCommentEntSelect };
return {
...state,
commentEntities,
selectedAnnotation: action.payload
};
}
case SEARCH_COMMENT: {
const commentSearchQueries = {
...state.commentSearchQueries,
commentSearch: action.payload
};
const commentEntities = StoreUtils.resetCommentEntSelect({ ...state.commentEntities });
return {
...state,
commentEntities,
commentSearchQueries
};
}
case APPLY_COMMENT_SUMMARY_FILTER: {
const payload = action.payload;
const hasTagFilter = () => {
let isFiltered = false;
if (payload.tagFilters) {
Object.keys(payload.tagFilters).map(filter => {
if (payload.tagFilters[filter] && !isFiltered) {
isFiltered = true;
}
});
}
return isFiltered;
};
const hasFilter = (hasTagFilter() || !!payload.dateRangeFrom || !!payload.dateRangeTo);
const commentSummaryFilters = {
hasFilter,
filters: payload
};
return {
...state,
commentSummaryFilters: commentSummaryFilters
};
}
case CLEAR_COMMENT_SUMMARY_FILTER: {
return {
...state,
commentSummaryFilters: { ...initialState.commentSummaryFilters }
};
}
}
return state;
}
const getAnnoSet = (state) => state.annotationSet;
const getCommentEnts = (state) => state.commentEntities;
const getAnnoPageEnt = (state) => state.annotationPageEntities;
const getAnnoEnt = (state) => state.annotationEntities;
const getSelectedAnno = (state) => state.selectedAnnotation;
const commentSearchQ = (state) => state.commentSearchQueries;
const getSummaryFilters = (state) => state.commentSummaryFilters;
const initialTagState = {
tagNameEnt: {},
annotations: [],
filteredPageEntities: {},
filteredComments: {},
formFilterState: {},
filters: []
};
function tagsReducer(state = initialTagState, action) {
switch (action.type) {
case LOAD_ANNOTATION_SET: {
return {
...state,
...initialTagState
};
}
case LOAD_ANNOTATION_SET_SUCCESS: {
const annotations = action.payload.body.annotations;
const tagNameEnt = StoreUtils.genTagNameEntities(annotations);
return {
...state,
tagNameEnt,
annotations
};
}
case SAVE_ANNOTATION_SUCCESS: {
const payload = action.payload;
const anno = [...state.annotations].filter(a => a.id !== payload.id) || [];
const annotations = [...anno, payload];
const tagNameEnt = StoreUtils.genTagNameEntities(annotations);
return {
...state,
annotations,
tagNameEnt
};
}
case DELETE_ANNOTATION_SUCCESS: {
const id = action.payload;
const annotations = [...state.annotations].filter(a => a.id !== id);
const tagNameEnt = StoreUtils.genTagNameEntities(annotations);
const filteredPageEntities = StoreUtils.groupByKeyEntities(annotations, 'page');
const filteredComments = {
...state.filteredComments
};
delete filteredComments[id];
return {
...state,
annotations,
tagNameEnt,
filteredComments,
filteredPageEntities,
filters: []
};
}
case ADD_FILTER_TAGS: {
const formFilterState = action.payload;
const filters = Object.keys(formFilterState).reduce((arr, key) => {
return formFilterState[key] ? [...arr, key] : arr;
}, []);
const filteredComments = filters.reduce((obj, f) => {
return {
...obj,
...state.tagNameEnt[f]
};
}, {});
const annotations = Object.keys(filteredComments).map(key => state.annotations.filter(a => a.id === key)[0]);
const filteredPageEntities = StoreUtils.groupByKeyEntities(annotations, 'page');
return {
...state,
filters,
filteredComments,
filteredPageEntities,
};
}
case CLEAR_FILTER_TAGS: {
return {
...state,
filters: [],
filteredComments: {},
filteredPageEntities: {},
};
}
}
return state;
}
const getTagNameEnt = (state) => state.tagNameEnt;
const getFilters = (state) => state.filters;
const getFilteredComments = (state) => state.filteredComments;
const getFilteredPageEnt = (state) => state.filteredPageEntities;
const LOAD_BOOKMARKS = '[Bookmarks] Load Bookmarks';
const LOAD_BOOKMARKS_SUCCESS = '[Bookmarks] Load Bookmarks Success';
const LOAD_BOOKMARKS_FAIL = '[Bookmarks] Load Bookmarks Failure';
const CREATE_BOOKMARK = '[Bookmarks] Create Bookmark';
const CREATE_BOOKMARK_SUCCESS = '[Bookmarks] Create Bookmark Success';
const CREATE_BOOKMARK_FAIL = '[Bookmarks] Create Bookmark Failure';
const DELETE_BOOKMARK = '[Bookmarks] Delete Bookmark';
const DELETE_BOOKMARK_SUCCESS = '[Bookmarks] Delete Bookmark Success';
const DELETE_BOOKMARK_FAIL = '[Bookmarks] Delete Bookmark Failure';
const MOVE_BOOKMARK = '[Bookmarks] Move Bookmark';
const MOVE_BOOKMARK_SUCCESS = '[Bookmarks] Move Bookmark Success';
const MOVE_BOOKMARK_FAIL = '[Bookmarks] Move Bookmark Failure';
const UPDATE_BOOKMARK = '[Bookmarks] Update Bookmark';
const UPDATE_BOOKMARK_SUCCESS = '[Bookmarks] Update Bookmark Success';
const UPDATE_BOOKMARK_FAIL = '[Bookmarks] Update Bookmark Failure';
const UPDATE_BOOKMARK_SCROLL_TOP = '[Bookmarks] Update Bookmark Scroll Top';
class LoadBookmarks {
constructor() {
this.type = LOAD_BOOKMARKS;
}
}
class LoadBookmarksSuccess {
constructor(payload) {
this.payload = payload;
this.type = LOAD_BOOKMARKS_SUCCESS;
}
}
class LoadBookmarksFailure {
constructor(payload) {
this.payload = payload;
this.type = LOAD_BOOKMARKS_FAIL;
}
}
class CreateBookmark {
constructor(payload) {
this.payload = payload;
this.type = CREATE_BOOKMARK;
}
}
class CreateBookmarkSuccess {
constructor(payload) {
this.payload = payload;
this.type = CREATE_BOOKMARK_SUCCESS;
}
}
class CreateBookmarkFailure {
constructor(payload) {
this.payload = payload;
this.type = CREATE_BOOKMARK_FAIL;
}
}
class DeleteBookmark {
constructor(payload) {
this.payload = payload;
this.type = DELETE_BOOKMARK;
}
}
class DeleteBookmarkSuccess {
constructor(payload) {
this.payload = payload;
this.type = DELETE_BOOKMARK_SUCCESS;
}
}
class DeleteBookmarkFailure {
constructor(payload) {
this.payload = payload;
this.type = DELETE_BOOKMARK_FAIL;
}
}
class MoveBookmark {
constructor(payload) {
this.payload = payload;
this.type = MOVE_BOOKMARK;
}
}
class MoveBookmarkSuccess {
constructor(payload) {
this.payload = payload;
this.type = MOVE_BOOKMARK_SUCCESS;
}
}
class MoveBookmarkFailure {
constructor(payload) {
this.payload = payload;
this.type = MOVE_BOOKMARK_FAIL;
}
}
class UpdateBookmark {
constructor(payload) {
this.payload = payload;
this.type = UPDATE_BOOKMARK;
}
}
class UpdateBookmarkSuccess {
constructor(payload) {
this.payload = payload;
this.type = UPDATE_BOOKMARK_SUCCESS;
}
}
class UpdateBookmarkFailure {
constructor(payload) {
this.payload = payload;
this.type = UPDATE_BOOKMARK_FAIL;
}
}
class UpdateBookmarkScrollTop {
constructor(payload) {
this.payload = payload;
this.type = UPDATE_BOOKMARK_SCROLL_TOP;
}
}
const getBookmarkChildren = (bookmarks) => {
if (bookmarks) {
return bookmarks.reduce((childIds, bookmark) => {
if (bookmark.children && bookmark.children.length > 0) {
return [...childIds, bookmark.id, ...getBookmarkChildren(bookmark.children)];
}
return [...childIds, bookmark.id];
}, []);
}
else {
return [];
}
};
const generateBookmarkEntities = (bookmarks) => {
return bookmarks.reduce((bookmarkEntities, bookmark) => Object.assign(bookmarkEntities, { [bookmark.id]: bookmark }), {});
};
const indexEntities = (entities) => {
const entityIds = Object.keys(entities);
for (let index = 0; entityIds.length > 0; index++) {
let keysToRemove = [];
entityIds.forEach(key => {
if (!entities[key].previous || !entityIds.includes(entities[key].previous.toString())) {
entities[key].index = index;
keysToRemove.push(key);
}
});
keysToRemove.forEach(key => entityIds.splice(entityIds.indexOf(key), 1));
keysToRemove = [];
}
};
const generateBookmarkNodes = (entities) => {
const bookmarkEntities = JSON.parse(JSON.stringify(entities));
indexEntities(bookmarkEntities);
return Object.keys(bookmarkEntities).reduce((nodes, bookmarkId) => {
const bookmarkEntity = bookmarkEntities[bookmarkId];
if (bookmarkEntity.parent) {
const parentEntity = bookmarkEntities[bookmarkEntity.parent];
if (!parentEntity.children) {
parentEntity.children = [];
}
parentEntity.children[bookmarkEntity.index] = bookmarkEntity;
}
else {
nodes[bookmarkEntity.index] = bookmarkEntity;
}
return nodes;
}, []);
};
const initialBookmarksState = {
bookmarks: [],
bookmarkEntities: {},
bookmarkPageEntities: {},
editableBookmark: undefined,
loaded: false,
loading: false,
scrollTop: null,
};
function bookmarksReducer(state = initialBookmarksState, action) {
switch (action.type) {
case LOAD_BOOKMARKS: {
return {
...state,
loading: true
};
}
case LOAD_BOOKMARKS_SUCCESS:
case LOAD_BOOKMARKS_FAIL: {
const bookmarks = action.payload.status === 200 ? action.payload.body : [];
const bookmarkEntities = generateBookmarkEntities(bookmarks);
const bookmarkPageEntities = StoreUtils.groupByKeyEntities(bookmarks, 'pageNumber');
return {
...state,
bookmarks,
bookmarkEntities,
bookmarkPageEntities,
loaded: true
};
}
case CREATE_BOOKMARK_SUCCESS: {
const bookmark = action.payload;
const bookmarkEntities = {
...state.bookmarkEntities,
[bookmark.id]: bookmark,
};
const bookmarkArray = Object.keys(bookmarkEntities).map(key => bookmarkEntities[key]);
const bookmarkPageEntities = StoreUtils.groupByKeyEntities(bookmarkArray, 'pageNumber');
const editableBookmark = bookmark.id;
return {
...state,
bookmarkEntities,
editableBookmark,
bookmarkPageEntities,
loading: false,
loaded: true
};
}
case MOVE_BOOKMARK_SUCCESS: {
const movedBookmarks = generateBookmarkEntities(action.payload);
const bookmarkEntities = {
...state.bookmarkEntities,
...movedBookmarks
};
return {
...state,
bookmarkEntities,
loading: false,
loaded: true
};
}
case DELETE_BOOKMARK_SUCCESS: {
const bookmarkIds = action.payload;
const bookmarkEntities = { ...state.bookmarkEntities };
const bookmarkPageEntities = { ...state.bookmarkPageEntities };
const removeBookmarksByPage = {};
bookmarkIds.forEach(bookmarkId => {
if (removeBookmarksByPage[bookmarkEntities[bookmarkId].pageNumber] !== undefined &&
removeBookmarksByPage[bookmarkEntities[bookmarkId].pageNumber].length > 0) {
removeBookmarksByPage[bookmarkEntities[bookmarkId].pageNumber].push(bookmarkId);
}
else {
removeBookmarksByPage[bookmarkEntities[bookmarkId].pageNumber] = [bookmarkId];
}
delete bookmarkEntities[bookmarkId];
});
Object.entries(removeBookmarksByPage).forEach(([pageNumber, bmrkIds]) => {
bookmarkPageEntities[pageNumber]
= bookmarkPageEntities[pageNumber].filter(bookmark => !bmrkIds.includes(bookmark.id));
});
return {
...state,
bookmarkEntities,
bookmarkPageEntities,
loading: false,
loaded: true
};
}
case UPDATE_BOOKMARK_SUCCESS: {
const bookmark = action.payload;
const bookmarkEntities = {
...state.bookmarkEntities,
[bookmark.id]: { ...bookmark }
};
const bookmarkArray = Object.keys(bookmarkEntities).map(key => bookmarkEntities[key]);
const bookmarkPageEntities = StoreUtils.groupByKeyEntities(bookmarkArray, 'pageNumber');
const editableBookmark = undefined;
return {
...state,
bookmarkEntities,
editableBookmark,
bookmarkPageEntities,
loading: false,
loaded: true
};
}
case UPDATE_BOOKMARK_SCROLL_TOP: {
const scrollTop = action.payload;
return {
...state,
scrollTop: scrollTop
};
}
}
return state;
}
const getBookmarks = (state) => state.bookmarks;
const getBookmarkEnts = (state) => state.bookmarkEntities;
const getBookmarkPageEnt = (state) => state.bookmarkPageEntities;
const getEditBookmark = (state) => state.editableBookmark;
const getScrollTop$1 = (state) => state.scrollTop;
const LOAD_REDACTIONS = '[Redaction] Load Redaction';
const LOAD_REDACTION_SUCCESS = '[Redaction] Load Redaction Success';
const LOAD_REDACTION_FAIL = '[Redaction] Load Redaction Fail';
const SAVE_REDACTION = '[Redaction] Save Redaction';
const SAVE_REDACTION_SUCCESS = '[Redaction] Save Redaction Success';
const SAVE_REDACTION_FAIL = '[Redaction] Save Redaction Fail';
const SAVE_BULK_REDACTION = '[Redaction] Save bulk Redaction';
const SAVE_BULK_REDACTION_SUCCESS = '[Redaction] Save bulk Redaction Success';
const SAVE_BULK_REDACTION_FAIL = '[Redaction] Save bulk Redaction Fail';
const DELETE_REDACTION = '[Redaction] Delete Redaction';
const DELETE_REDACTION_SUCCESS = '[Redaction] Delete Redaction Success';
const DELETE_REDACTION_FAIL = '[Redaction] Delete Redaction Fail';
const SELECT_REDACTION = '[Redaction] Select Redaction';
const REDACT = '[Redaction] Redact';
const REDACT_SUCCESS = '[Redaction] Redact Success';
const REDACT_FAIL = '[Redaction] Redact Fail';
const RESET_REDACTED_DOCUMENT = '[Redaction] Reset Redacted Document';
const UNMARK_ALL = '[Redaction] Unmark All';
const UNMARK_ALL_SUCCESS = '[Redaction] Unmark All Success';
class LoadRedactions {
constructor(payload) {
this.payload = payload;
this.type = LOAD_REDACTIONS;
}
}
class LoadRedactionSuccess {
constructor(payload) {
this.payload = payload;
this.type = LOAD_REDACTION_SUCCESS;
}
}
class LoadRedactionFailure {
constructor(payload) {
this.payload = payload;
this.type = LOAD_REDACTION_FAIL;
}
}
class SaveRedaction {
constructor(payload) {
this.payload = payload;
this.type = SAVE_REDACTION;
}
}
class SaveRedactionSuccess {
constructor(payload) {
this.payload = payload;
this.type = SAVE_REDACTION_SUCCESS;
}
}
class SaveRedactionFailure {
constructor(payload) {
this.payload = payload;
this.type = SAVE_REDACTION_FAIL;
}
}
class SaveBulkRedactionFailure {
constructor(payload) {
this.payload = payload;
this.type = SAVE_BULK_REDACTION_FAIL;
}
}
class SaveBulkRedaction {
constructor(payload) {
this.payload = payload;
this.type = SAVE_BULK_REDACTION;
}
}
class SaveBulkRedactionSuccess {
constructor(payload) {
this.payload = payload;
this.type = SAVE_BULK_REDACTION_SUCCESS;
}
}
class DeleteRedaction {
constructor(payload) {
this.payload = payload;
this.type = DELETE_REDACTION;
}
}
class DeleteRedactionSuccess {
constructor(payload) {
this.payload = payload;
this.type = DELETE_REDACTION_SUCCESS;
}
}
class DeleteRedactionFailure {
constructor(payload) {
this.payload = payload;
this.type = DELETE_REDACTION_FAIL;
}
}
class SelectRedaction {
constructor(payload) {
this.payload = payload;
this.type = SELECT_REDACTION;
}
}
class Redact {
constructor(payload) {
this.payload = payload;
this.type = REDACT;
}
}
class RedactSuccess {
constructor(payload) {
this.payload = payload;
this.type = REDACT_SUCCESS;
}
}
class RedactFailure {
constructor(payload) {
this.payload = payload;
this.type = REDACT_FAIL;
}
}
class ResetRedactedDocument {
constructor() {
this.type = RESET_REDACTED_DOCUMENT;
}
}
class UnmarkAll {
constructor(payload) {
this.payload = payload;
this.type = UNMARK_ALL;
}
}
class UnmarkAllSuccess {
constructor() {
this.type = UNMARK_ALL_SUCCESS;
}
}
const initialRedactionState = {
redactionEntities: {},
redactionPageEntities: {},
selectedRedaction: {},
redactedDocumentInfo: undefined,
documentId: undefined
};
function redactionReducer(state = initialRedactionState, action) {
switch (action.type) {
case LOAD_REDACTIONS: {
return {
...state,
...initialRedactionState
};
}
case LOAD_REDACTION_SUCCESS: {
const payload = action.payload;
if (payload) {
const redactionEntities = StoreUtils.generateRedactionEntities(payload);
const redactionPageEntities = StoreUtils.groupByKeyEntities(payload, 'page');
return {
...state,
redactionEntities,
redactionPageEntities
};
}
return {
...state
};
}
case SAVE_REDACTION_SUCCESS: {
const { payload } = action;
const redactionEntities = {
...state.redactionEntities,
[payload.redactionId]: payload
};
const redactionArray = Object.keys(redactionEntities).map(key => redactionEntities[key]);
const redactionPageEntities = StoreUtils.groupByKeyEntities(redactionArray, 'page');
return {
...state,
redactionEntities,
redactionPageEntities
};
}
case SAVE_BULK_REDACTION_SUCCESS: {
const payloadResult = Object.assign({}, ...action.payload.searchRedactions.map((x) => ({ [x.redactionId]: x })));
const redactionEntities = {
...state.redactionEntities,
...payloadResult
};
const redactionArray = Object.keys(redactionEntities).map(key => redactionEntities[key]);
const redactionPageEntities = StoreUtils.groupByKeyEntities(redactionArray, 'page');
return {
...state,
redactionEntities,
redactionPageEntities
};
}
case SELECT_REDACTION:
case SELECT_ANNOTATION: {
return {
...state,
selectedRedaction: action.payload
};
}
case DELETE_REDACTION_SUCCESS: {
const page = action.payload.page;
const id = action.payload.redactionId;
const redactionEntities = {
...state.redactionEntities
};
delete redactionEntities[id];
const pageRedactionRemoved = [
...state.redactionPageEntities[page].filter(redaction => redaction.redactionId !== id)
];
const redactionPageEntities = {
...state.redactionPageEntities,
[page]: pageRedactionRemoved
};
return {
...state,
redactionPageEntities,
redactionEntities,
};
}
case REDACT_SUCCESS: {
const redactedDocumentInfo = action.payload;
return {
...state,
...initialRedactionState,
redactedDocumentInfo
};
}
case RESET_REDACTED_DOCUMENT: {
return {
...state,
redactedDocumentInfo: undefined
};
}
case UNMARK_ALL_SUCCESS: {
return {
...state,
...initialRedactionState
};
}
}
return state;
}
const getRedactionEnt$1 = (state) => state.redactionEntities;
const getPageEnt = (state) => state.redactionPageEntities;
const getSelectedRedaction = (state) => state.selectedRedaction;
const getRedactedDocInfo = (state) => state.redactedDocumentInfo;
const initialIcpSessionState = {
session: null,
presenter: null,
client: null,
participants: []
};
function icpReducer(state = initialIcpSessionState, action) {
switch (action.type) {
case SET_CASE_ID: {
const caseId = action.payload;
const session = { ...state.sess