From c2d63bab7da993267912a5c1d115e90f3528a11a Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Mon, 5 Mar 2018 13:53:15 +0000 Subject: [PATCH 001/188] rollup-plugin-commonjs 8.3.0 pin up --- lib/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/package.json b/lib/package.json index a1aeae23eb..d15813a3d0 100644 --- a/lib/package.json +++ b/lib/package.json @@ -135,6 +135,7 @@ "rollup-plugin-cleanup": "^2.0.0", "rollup-plugin-license": "^0.5.0", "rollup-plugin-shift-header": "^1.0.1", + "rollup-plugin-commonjs": "8.3.0", "run-sequence": "1.2.2", "sass-loader": "6.0.5", "script-loader": "0.7.0", From 9b705d87ace228484cbc752bc502cf3eafeaf0f8 Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Mon, 5 Mar 2018 14:11:28 +0000 Subject: [PATCH 002/188] update ng-packagr 2.1.0 --- lib/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/package.json b/lib/package.json index d15813a3d0..700f0af818 100644 --- a/lib/package.json +++ b/lib/package.json @@ -78,7 +78,7 @@ "minimatch": "3.0.4", "moment": "2.20.1", "moment-es6": "^1.0.0", - "ng-packagr": "2.0.0", + "ng-packagr": "2.1.0", "ng2-charts": "1.6.0", "pdfjs-dist": "2.0.265", "raphael": "2.2.7", From 8f63af1fbdc6f67d5b4a9d088bbc5bc48fa13812 Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Mon, 5 Mar 2018 14:30:17 +0000 Subject: [PATCH 003/188] move ng-pkgr in dev --- lib/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/package.json b/lib/package.json index 700f0af818..30a747111c 100644 --- a/lib/package.json +++ b/lib/package.json @@ -78,7 +78,6 @@ "minimatch": "3.0.4", "moment": "2.20.1", "moment-es6": "^1.0.0", - "ng-packagr": "2.1.0", "ng2-charts": "1.6.0", "pdfjs-dist": "2.0.265", "raphael": "2.2.7", @@ -127,15 +126,16 @@ "markdownlint-cli": "^0.3.1", "merge-stream": "1.0.1", "nconf": "^0.10.0", + "ng-packagr": "2.0.0", "node-sass": "4.5.3", "null-loader": "0.1.1", "raw-loader": "0.5.1", "remap-istanbul": "0.6.3", "rimraf": "^2.6.2", "rollup-plugin-cleanup": "^2.0.0", + "rollup-plugin-commonjs": "8.3.0", "rollup-plugin-license": "^0.5.0", "rollup-plugin-shift-header": "^1.0.1", - "rollup-plugin-commonjs": "8.3.0", "run-sequence": "1.2.2", "sass-loader": "6.0.5", "script-loader": "0.7.0", From 69ac38713f28ad63534d8c12786b8aa0a5a4956b Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 6 Mar 2018 09:00:52 +0200 Subject: [PATCH 004/188] [ADF-2388, ADF-2375] PDF Viewer - show buffer thumbnail on pagechange (#3011) * disable thumbnails button until document is loaded * show buffer thumbnail on page change * correct value property * correct test --- .../pdfViewer-thumbnails.component.scss | 6 +-- .../pdfViewer-thumbnails.component.spec.ts | 37 ++++++++----- .../pdfViewer-thumbnails.component.ts | 9 +++- .../components/pdfViewer.component.html | 1 + .../components/pdfViewer.component.scss | 1 + .../components/pdfViewer.component.spec.ts | 52 +++++++++++++++++++ .../viewer/components/pdfViewer.component.ts | 13 +++++ .../viewer/components/viewer.component.scss | 2 +- 8 files changed, 99 insertions(+), 22 deletions(-) diff --git a/lib/core/viewer/components/pdfViewer-thumbnails.component.scss b/lib/core/viewer/components/pdfViewer-thumbnails.component.scss index 903fc56d03..30a1adb39a 100644 --- a/lib/core/viewer/components/pdfViewer-thumbnails.component.scss +++ b/lib/core/viewer/components/pdfViewer-thumbnails.component.scss @@ -9,16 +9,12 @@ position: relative; &__content { - top: 0; + top: 5px; left: 50%; height: 0; position: absolute; } - &__thumb:first-child { - margin-top: 15px; - } - &__thumb { cursor: pointer; display: block; diff --git a/lib/core/viewer/components/pdfViewer-thumbnails.component.spec.ts b/lib/core/viewer/components/pdfViewer-thumbnails.component.spec.ts index df68e9aa5d..05ca231f38 100644 --- a/lib/core/viewer/components/pdfViewer-thumbnails.component.spec.ts +++ b/lib/core/viewer/components/pdfViewer-thumbnails.component.spec.ts @@ -17,6 +17,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { PdfThumbListComponent } from './pdfViewer-thumbnails.component'; import { PdfThumbComponent } from './pdfViewer-thumb.component'; @@ -55,6 +56,9 @@ describe('PdfThumbListComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule + ], declarations: [ PdfThumbListComponent, PdfThumbComponent @@ -81,7 +85,7 @@ describe('PdfThumbListComponent', () => { fixture.detectChanges(); const renderedIds = component.renderItems.map(item => item.id); - const rangeIds = viewerMock._pages.slice(0, 7).map(item => item.id); + const rangeIds = viewerMock._pages.slice(0, 6).map(item => item.id); expect(renderedIds).toEqual(rangeIds); }); @@ -91,24 +95,23 @@ describe('PdfThumbListComponent', () => { fixture.detectChanges(); const renderedIds = component.renderItems.map(item => item.id); - const rangeIds = viewerMock._pages.slice(6, 14).map(item => item.id); + const rangeIds = viewerMock._pages.slice(5, 12).map(item => item.id); expect(renderedIds).toEqual(rangeIds); }); it('should render items containing current document page', () => { - fixture.nativeElement.scrollTop = 1700; fixture.detectChanges(); const renderedIds = component.renderItems.map(item => item.id); - expect(renderedIds).not.toContain(3); + expect(renderedIds).not.toContain(10); - viewerMock.eventBus.dispatch('pagechange', { pageNumber: 3 }); + component.scrollInto(10); const newRenderedIds = component.renderItems.map(item => item.id); - expect(newRenderedIds).toContain(3); + expect(newRenderedIds).toContain(10); }); it('should not change items if range contains current document page', () => { @@ -126,6 +129,19 @@ describe('PdfThumbListComponent', () => { expect(newRenderedIds).toContain(12); }); + it('should scroll thumbnail height amount to buffer thumbnail onPageChange event', () => { + spyOn(component, 'scrollInto'); + fixture.detectChanges(); + + expect(component.renderItems[component.renderItems.length - 1].id).toBe(6); + expect(fixture.debugElement.nativeElement.scrollTop).toBe(0); + + viewerMock.currentPageNumber = 6; + + expect(component.scrollInto).not.toHaveBeenCalled(); + expect(fixture.debugElement.nativeElement.scrollTop).toBe(129); + }); + it('should return current viewed page as selected', () => { fixture.nativeElement.scrollTop = 0; fixture.detectChanges(); @@ -136,17 +152,10 @@ describe('PdfThumbListComponent', () => { }); it('should go to selected page', () => { - fixture.nativeElement.scrollTop = 0; fixture.detectChanges(); - const renderedIds = component.renderItems.map(item => item.id); - - expect(renderedIds).not.toContain(12); - component.goTo(12); - const newRenderedIds = component.renderItems.map(item => item.id); - - expect(newRenderedIds).toContain(12); + expect(viewerMock.currentPageNumber).toBe(12); }); }); diff --git a/lib/core/viewer/components/pdfViewer-thumbnails.component.ts b/lib/core/viewer/components/pdfViewer-thumbnails.component.ts index 09e281ffff..762bf55676 100644 --- a/lib/core/viewer/components/pdfViewer-thumbnails.component.ts +++ b/lib/core/viewer/components/pdfViewer-thumbnails.component.ts @@ -35,7 +35,8 @@ export class PdfThumbListComponent implements OnInit, AfterViewInit, OnDestroy { renderItems = []; private items = []; - private itemHeight: number = 114; + private margin: number = 15; + private itemHeight: number = 114 + this.margin; @ContentChild(TemplateRef) template: any; @@ -87,7 +88,7 @@ export class PdfThumbListComponent implements OnInit, AfterViewInit, OnDestroy { return; } - this.element.nativeElement.scrollTop = Math.floor(index - 1 ) * this.itemHeight; + this.element.nativeElement.scrollTop = index * this.itemHeight; this.calculateItems(); } @@ -133,5 +134,9 @@ export class PdfThumbListComponent implements OnInit, AfterViewInit, OnDestroy { if (index < 0) { this.scrollInto(event.pageNumber); } + + if (index >= this.renderItems.length - 1) { + this.element.nativeElement.scrollTop += this.itemHeight; + } } } diff --git a/lib/core/viewer/components/pdfViewer.component.html b/lib/core/viewer/components/pdfViewer.component.html index 35a5f5ac83..f4a0692a15 100644 --- a/lib/core/viewer/components/pdfViewer.component.html +++ b/lib/core/viewer/components/pdfViewer.component.html @@ -37,6 +37,7 @@ diff --git a/lib/core/viewer/components/pdfViewer.component.scss b/lib/core/viewer/components/pdfViewer.component.scss index 720b71195c..66c80ff469 100644 --- a/lib/core/viewer/components/pdfViewer.component.scss +++ b/lib/core/viewer/components/pdfViewer.component.scss @@ -40,6 +40,7 @@ justify-content: flex-end; align-items: flex-end; display: flex; + color: mat-color($foreground, text, 0.54); } } diff --git a/lib/core/viewer/components/pdfViewer.component.spec.ts b/lib/core/viewer/components/pdfViewer.component.spec.ts index 7f9ea4e66b..ede7454035 100644 --- a/lib/core/viewer/components/pdfViewer.component.spec.ts +++ b/lib/core/viewer/components/pdfViewer.component.spec.ts @@ -437,4 +437,56 @@ describe('Test PdfViewer component', () => { }); }); }); + + describe('Viewer events', () => { + beforeEach(() => { + component.urlFile = require('../assets/fake-test-file.pdf'); + fixture.detectChanges(); + }); + + it('should emit pagechange event', (done) => { + component.ngOnChanges(null).then(() => { + fixture.detectChanges(); + return fixture.whenStable().then(() => { + expect(component.displayPage).toBe(1); + + const args = { + pageNumber: 6, + source: { + container: component.documentContainer + } + }; + + component.pdfViewer.eventBus.dispatch('pagechange', args); + fixture.detectChanges(); + + expect(component.displayPage).toBe(6); + expect(component.page).toBe(6); + done(); + }); + }); + }); + + it('should emit pagesloaded event', (done) => { + component.ngOnChanges(null).then(() => { + fixture.detectChanges(); + return fixture.whenStable().then(() => { + expect(component.isPanelDisabled).toBe(true); + + const args = { + pagesCount: 10, + source: { + container: component.documentContainer + } + }; + + component.pdfViewer.eventBus.dispatch('pagesloaded', args); + fixture.detectChanges(); + + expect(component.isPanelDisabled).toBe(false); + done(); + }); + }); + }); + }); }); diff --git a/lib/core/viewer/components/pdfViewer.component.ts b/lib/core/viewer/components/pdfViewer.component.ts index f6ca061220..82cdd3d169 100644 --- a/lib/core/viewer/components/pdfViewer.component.ts +++ b/lib/core/viewer/components/pdfViewer.component.ts @@ -67,6 +67,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { MIN_SCALE: number = 0.25; MAX_SCALE: number = 10.0; + isPanelDisabled = true; showThumbnails: boolean = false; pdfThumbnailsContext: { viewer: any } = { viewer: null }; @@ -78,6 +79,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { private logService: LogService) { // needed to preserve "this" context this.onPageChange = this.onPageChange.bind(this); + this.onPagesLoaded = this.onPagesLoaded.bind(this); } ngOnChanges(changes) { @@ -142,6 +144,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.documentContainer = document.getElementById('viewer-pdf-viewer'); this.documentContainer.addEventListener('pagechange', this.onPageChange, true); + this.documentContainer.addEventListener('pagesloaded', this.onPagesLoaded, true); this.pdfViewer = new PDFJS.PDFViewer({ container: this.documentContainer, @@ -159,6 +162,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { ngOnDestroy() { if (this.documentContainer) { this.documentContainer.removeEventListener('pagechange', this.onPageChange, true); + this.documentContainer.removeEventListener('pagesloaded', this.onPagesLoaded, true); } } @@ -369,6 +373,15 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.displayPage = event.pageNumber; } + /** + * Pages Loaded Event + * + * @param event + */ + onPagesLoaded(event) { + this.isPanelDisabled = false; + } + /** * Litener Keyboard Event * @param KeyboardEvent event diff --git a/lib/core/viewer/components/viewer.component.scss b/lib/core/viewer/components/viewer.component.scss index 51048dc377..5211893307 100644 --- a/lib/core/viewer/components/viewer.component.scss +++ b/lib/core/viewer/components/viewer.component.scss @@ -11,7 +11,7 @@ .adf-viewer { - .mat-toolbar, .mat-icon { + .mat-toolbar { color: mat-color($foreground, text, 0.54); } From eedb7a65db27b2b2980e8bfb6362fb3b16013cd3 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 6 Mar 2018 09:03:35 +0200 Subject: [PATCH 005/188] disable fullscreen for media types (#3026) --- lib/core/viewer/components/viewer.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/viewer/components/viewer.component.html b/lib/core/viewer/components/viewer.component.html index ac82762b10..55c5b6a75b 100644 --- a/lib/core/viewer/components/viewer.component.html +++ b/lib/core/viewer/components/viewer.component.html @@ -85,7 +85,7 @@ + + + + + + diff --git a/demo-shell/src/app/components/form/form-loading.component.scss b/demo-shell/src/app/components/form/form-loading.component.scss new file mode 100644 index 0000000000..3608df8b91 --- /dev/null +++ b/demo-shell/src/app/components/form/form-loading.component.scss @@ -0,0 +1,3 @@ +.form-container { + padding: 10px; +} diff --git a/demo-shell/src/app/components/form/form-loading.component.ts b/demo-shell/src/app/components/form/form-loading.component.ts new file mode 100644 index 0000000000..0d6d9deb72 --- /dev/null +++ b/demo-shell/src/app/components/form/form-loading.component.ts @@ -0,0 +1,60 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Inject, OnInit } from '@angular/core'; +import { FormModel, FormService, FormOutcomeEvent } from '@alfresco/adf-core'; +import { InMemoryFormService } from '../../services/in-memory-form.service'; +import { DemoForm } from './demo-form'; +import { FakeFormService } from './fake-form.service'; + +@Component({ + selector: 'app-form-loading', + templateUrl: 'form-loading.component.html', + styleUrls: ['form-loading.component.scss'], + providers: [ + { provide: FormService, useClass: FakeFormService }, + ] +}) +export class FormLoadingComponent implements OnInit { + + form: FormModel; + typeaheadFieldValue = ''; + selectFieldValue = ''; + radioButtonFieldValue = ''; + formattedData = {}; + + constructor(@Inject(FormService) private formService: InMemoryFormService) { + formService.executeOutcome.subscribe((formOutcomeEvent: FormOutcomeEvent) => { + formOutcomeEvent.preventDefault(); + }); + } + + ngOnInit() { + this.formattedData = {}; + const formDefinitionJSON: any = DemoForm.getSimpleFormDefinition(); + this.form = this.formService.parseForm(formDefinitionJSON); + } + + onLoadButtonClicked() { + this.formattedData = { + 'typeahedField': this.typeaheadFieldValue, + 'selectBox': this.selectFieldValue, + 'radioButton': this.radioButtonFieldValue + }; + } + +} diff --git a/lib/core/form/components/form.component.spec.ts b/lib/core/form/components/form.component.spec.ts index c4e894b3e1..981632a55c 100644 --- a/lib/core/form/components/form.component.spec.ts +++ b/lib/core/form/components/form.component.spec.ts @@ -822,14 +822,14 @@ describe('FormComponent', () => { let labelField = formFields.find(field => field.id === 'label'); let radioField = formFields.find(field => field.id === 'raduio'); expect(labelField.value).toBe('empty'); - expect(radioField.value).toBeNull(); + expect(radioField.value).toBe('option_1'); let formValues: any = {}; formValues.label = { - id: 'option_1', - name: 'test1' + id: 'option_2', + name: 'test2' }; - formValues.raduio = { id: 'option_1', name: 'Option 1' }; + formValues.raduio = { id: 'option_2', name: 'Option 2' }; let change = new SimpleChange(null, formValues, false); formComponent.data = formValues; formComponent.ngOnChanges({ 'data': change }); @@ -837,7 +837,25 @@ describe('FormComponent', () => { formFields = formComponent.form.getFormFields(); labelField = formFields.find(field => field.id === 'label'); radioField = formFields.find(field => field.id === 'raduio'); - expect(labelField.value).toBe('option_1'); - expect(radioField.value).toBe('option_1'); + expect(labelField.value).toBe('option_2'); + expect(radioField.value).toBe('option_2'); + }); + + it('should refresh radio buttons value when id is given to data', () => { + formComponent.form = new FormModel(fakeForm); + let formFields = formComponent.form.getFormFields(); + let radioFieldById = formFields.find(field => field.id === 'raduio'); + + expect(radioFieldById.value).toBe('option_2'); + + let formValues: any = {}; + formValues.raduio = 'option_3'; + let change = new SimpleChange(null, formValues, false); + formComponent.data = formValues; + formComponent.ngOnChanges({ 'data': change }); + + formFields = formComponent.form.getFormFields(); + radioFieldById = formFields.find(field => field.id === 'raduio'); + expect(radioFieldById.value).toBe('option_3'); }); }); diff --git a/lib/core/form/components/widgets/core/form-field-validator.spec.ts b/lib/core/form/components/widgets/core/form-field-validator.spec.ts index 03a601054c..c8099a7b55 100644 --- a/lib/core/form/components/widgets/core/form-field-validator.spec.ts +++ b/lib/core/form/components/widgets/core/form-field-validator.spec.ts @@ -82,9 +82,9 @@ describe('FormFieldValidator', () => { let field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.RADIO_BUTTONS, required: true, - value: 'one', options: [{ id: 'two', name: 'two' }] }); + field.value = 'one'; expect(validator.validate(field)).toBeFalsy(); }); diff --git a/lib/core/form/components/widgets/core/form-field.model.spec.ts b/lib/core/form/components/widgets/core/form-field.model.spec.ts index 2cdaa66045..95e8852cbe 100644 --- a/lib/core/form/components/widgets/core/form-field.model.spec.ts +++ b/lib/core/form/components/widgets/core/form-field.model.spec.ts @@ -266,8 +266,8 @@ describe('FormFieldModel', () => { let field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.RADIO_BUTTONS, options: [ - {id: 'opt1', value: 'Option 1'}, - {id: 'opt2', value: 'Option 2'} + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} ], value: 'opt2' }); @@ -319,8 +319,8 @@ describe('FormFieldModel', () => { id: 'radio-1', type: FormFieldTypes.RADIO_BUTTONS, options: [ - {id: 'opt1', value: 'Option 1'}, - {id: 'opt2', value: 'Option 2'} + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} ] }); @@ -334,8 +334,8 @@ describe('FormFieldModel', () => { id: 'radio-2', type: FormFieldTypes.RADIO_BUTTONS, options: [ - {id: 'opt1', value: 'Option 1'}, - {id: 'opt2', value: 'Option 2'} + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} ] }); diff --git a/lib/core/form/components/widgets/core/form-field.model.ts b/lib/core/form/components/widgets/core/form-field.model.ts index 4e4fd6a816..ec9cc3bd63 100644 --- a/lib/core/form/components/widgets/core/form-field.model.ts +++ b/lib/core/form/components/widgets/core/form-field.model.ts @@ -298,6 +298,8 @@ export class FormFieldModel extends FormWidgetModel { let emptyOption = json.options[0]; if (value === '' || value === emptyOption.id || value === emptyOption.name) { value = emptyOption.id; + } else if (value.id && value.name) { + value = value.id; } } } @@ -311,9 +313,12 @@ export class FormFieldModel extends FormWidgetModel { // Activiti has a bug with default radio button value where initial selection passed as `name` value // so try resolving current one with a fallback to first entry via name or id // TODO: needs to be reported and fixed at Activiti side - let entry: FormFieldOption[] = this.options.filter(opt => opt.id === value || opt.name === value); + let entry: FormFieldOption[] = this.options.filter(opt => + opt.id === value || opt.name === value || (value && (opt.id === value.id || opt.name === value.name))); if (entry.length > 0) { value = entry[0].id; + } else { + value = this.options[0] ? this.options[0].id : json.value; } } @@ -376,7 +381,7 @@ export class FormFieldModel extends FormWidgetModel { } break; case FormFieldTypes.TYPEAHEAD: - let taEntry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); + let taEntry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value || opt.name === this.value); if (taEntry.length > 0) { this.form.values[this.id] = taEntry[0]; } else if (this.options.length > 0) { diff --git a/lib/core/form/components/widgets/core/form.model.ts b/lib/core/form/components/widgets/core/form.model.ts index 87834dcb43..ab63af27a6 100644 --- a/lib/core/form/components/widgets/core/form.model.ts +++ b/lib/core/form/components/widgets/core/form.model.ts @@ -268,10 +268,6 @@ export class FormModel { if (data[field.id]) { field.json.value = data[field.id]; field.value = field.parseValue(field.json); - if (field.type === FormFieldTypes.DROPDOWN || - field.type === FormFieldTypes.RADIO_BUTTONS) { - field.value = data[field.id].id; - } } } } diff --git a/lib/core/form/components/widgets/typeahead/typeahead.widget.ts b/lib/core/form/components/widgets/typeahead/typeahead.widget.ts index 86f5b51e43..8af38a9ce6 100644 --- a/lib/core/form/components/widgets/typeahead/typeahead.widget.ts +++ b/lib/core/form/components/widgets/typeahead/typeahead.widget.ts @@ -67,7 +67,7 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit let fieldValue = this.field.value; if (fieldValue) { - let toSelect = options.find(item => item.id === fieldValue); + let toSelect = options.find(item => item.id === fieldValue || item.name.toLocaleLowerCase() === fieldValue.toLocaleLowerCase()); if (toSelect) { this.value = toSelect.name; } From 43ce4a195afa1b6718689aadd85bd0fba0473c90 Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Tue, 6 Mar 2018 10:23:55 +0000 Subject: [PATCH 013/188] update development documentation demo shell --- demo-shell/README.md | 41 +++++++---------------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/demo-shell/README.md b/demo-shell/README.md index cfb3603655..95a5186aeb 100644 --- a/demo-shell/README.md +++ b/demo-shell/README.md @@ -22,44 +22,24 @@ To simplify development and reduce the time to get the application started, we h The settings above address most common scenarios for running ACS on port 8080 and APS on port 9999 and allow you to skip the CORS configuration. -If you would like to change default proxy settings, please edit the `config/webpack.common.js` file. +If you would like to change default proxy settings, please edit the `proxy.conf.js` file. ## Application settings (server-side) -All server-side application settings are stored in the `app.config-dev.json` and `app.config-prod.json` files. +All server-side application settings are stored in the [src/app.config.json](src/app.config.json). By default the configuration files have the content similar to the following one: ```json { - "ecmHost": "http://localhost:3000/ecm", - "bpmHost": "http://localhost:3000/bpm", + "$schema": "../../lib/core/app-config/schema.json", + "ecmHost": "http://{hostname}:{port}", + "bpmHost": "http://{hostname}:{port}", "application": { - "name": "Alfresco" + "name": "Alfresco ADF Application" } } ``` -You can add any additional settings to the application configuration file if needed. - -Configuration files are picked based on environment settings (see `app.module.ts` for more details). - -```ts -let appConfigFile = 'app.config-dev.json'; -if (process.env.ENV === 'production') { - appConfigFile = 'app.config-prod.json'; -} - -@NgModule({ - imports: [ - ... - CoreModule.forRoot({ - appConfigFile: appConfigFile - }), - ... - ] -}) -``` - ## Development build ```sh @@ -85,17 +65,10 @@ This command builds project in `production` mode. All output is placed to `dist` folder and can be served to your preferred web server. You should need no additional files outside the `dist` folder. -### Important notes - -By default demo application is configured to use [wsrv](https://www.npmjs.com/package/wsrv) tool (lightweight web server) -to serve production build output. It will be running at `0.0.0.0` address with port `3000` and allow you to access your application -via network. However, you can use any web server of your choice in production. - ## Development branch build If you want to run the demo shell with the latest changes from the development branch, use the following command from the /script folder: ```sh -./npm-clean.sh -./start-linked.sh -install +npm run start:dev ``` From d867d5f4a9ef544bf717f80f29f85fefca2c203e Mon Sep 17 00:00:00 2001 From: siva kumar Date: Tue, 6 Mar 2018 19:29:25 +0530 Subject: [PATCH 014/188] [ADF-2412] Task List - refactoring. (#3034) * Removed initStream method. --- .../components/task-list.component.ts | 56 +++++++------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/lib/process-services/task-list/components/task-list.component.ts b/lib/process-services/task-list/components/task-list.component.ts index 808dac9255..592a8c4e4a 100644 --- a/lib/process-services/task-list/components/task-list.component.ts +++ b/lib/process-services/task-list/components/task-list.component.ts @@ -39,7 +39,6 @@ import { EventEmitter, Input, OnChanges, - OnInit, Output, SimpleChanges } from '@angular/core'; @@ -56,7 +55,7 @@ import { TaskListService } from './../services/tasklist.service'; templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.css'] }) -export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, PaginatedComponent { +export class TaskListComponent implements OnChanges, AfterContentInit, PaginatedComponent { requestNode: TaskQueryRequestRepresentationModel; @@ -159,7 +158,6 @@ export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, P * @memberOf TaskListComponent */ hasCustomDataSource: boolean = false; - isStreamLoaded = false; constructor(private taskListService: TaskListService, private appConfig: AppConfigService, @@ -176,39 +174,12 @@ export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, P }); } - initStream() { - if (!this.isStreamLoaded) { - this.isStreamLoaded = true; - this.taskListService.tasksList$.subscribe( - (tasks) => { - let instancesRow = this.createDataRow(tasks.data); - this.renderInstances(instancesRow); - this.selectTask(this.landingTaskId); - this.success.emit(tasks); - this.isLoading = false; - this.pagination.next({ - count: tasks.data.length, - maxItems: this.size, - skipCount: this.page * this.size, - totalItems: tasks.total - }); - }, (error) => { - this.error.emit(error); - this.isLoading = false; - }); - } - } - - ngOnInit() { - if (this.data === undefined) { - this.data = new ObjectDataTableAdapter(); - } - this.initStream(); - } - ngAfterContentInit() { this.loadLayoutPresets(); this.setupSchema(); + if (this.appId) { + this.reload(); + } } /** @@ -225,7 +196,6 @@ export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, P } ngOnChanges(changes: SimpleChanges) { - this.initStream(); if (this.isPropertyChanged(changes)) { this.reload(); } @@ -264,7 +234,23 @@ export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, P private load(requestNode: TaskQueryRequestRepresentationModel) { this.isLoading = true; - this.loadTasksByState().subscribe(); + this.loadTasksByState().subscribe( + (tasks) => { + let instancesRow = this.createDataRow(tasks.data); + this.renderInstances(instancesRow); + this.selectTask(this.landingTaskId); + this.success.emit(tasks); + this.isLoading = false; + this.pagination.next({ + count: tasks.data.length, + maxItems: this.size, + skipCount: this.page * this.size, + totalItems: tasks.total + }); + }, (error) => { + this.error.emit(error); + this.isLoading = false; + }); } private loadTasksByState(): Observable { From d8e5e55ffa0b26d607aaba076e75b34c069ca51c Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Tue, 6 Mar 2018 14:07:21 +0000 Subject: [PATCH 015/188] [ADF-2417] remove tag id as default value from demo shell (#3036) * remove tag id as default value from demo shell * fix export check script --- .../src/app/components/tag/tag.component.ts | 2 +- lib/config/export-check/export-2.2.0.json | 5882 +++++++++++++++++ .../export-check/export-check-config.json | 3 +- lib/package.json | 1 + 4 files changed, 5886 insertions(+), 2 deletions(-) create mode 100644 lib/config/export-check/export-2.2.0.json diff --git a/demo-shell/src/app/components/tag/tag.component.ts b/demo-shell/src/app/components/tag/tag.component.ts index 36d7a913f5..dd0d0c9b42 100644 --- a/demo-shell/src/app/components/tag/tag.component.ts +++ b/demo-shell/src/app/components/tag/tag.component.ts @@ -24,5 +24,5 @@ import { Component } from '@angular/core'; }) export class TagComponent { - nodeId = '74cd8a96-8a21-47e5-9b3b-a1b3e296787d'; + nodeId = ''; } diff --git a/lib/config/export-check/export-2.2.0.json b/lib/config/export-check/export-2.2.0.json new file mode 100644 index 0000000000..3c24d81d87 --- /dev/null +++ b/lib/config/export-check/export-2.2.0.json @@ -0,0 +1,5882 @@ +[ + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/collapsable/accordion.component.ts" + }, + "name": "AccordionComponent" + }, + { + "position": { + "line": 34, + "character": 8, + "fileName": "lib/core/collapsable/collapsable.module.ts" + }, + "name": "AccordionComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/collapsable/accordion-group.component.ts" + }, + "name": "AccordionGroupComponent" + }, + { + "position": { + "line": 35, + "character": 8, + "fileName": "lib/core/collapsable/collapsable.module.ts" + }, + "name": "AccordionGroupComponent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/form/services/activiti-alfresco.service.ts" + }, + "name": "ActivitiContentService" + }, + { + "position": { + "line": 18, + "character": 0, + "fileName": "lib/core/mock/AlfrescoApi.mock.ts" + }, + "name": "AlfrescoApiMock" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/services/alfresco-api.service.ts" + }, + "name": "AlfrescoApiService" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/amount/amount.widget.ts" + }, + "name": "AmountWidgetComponent" + }, + { + "position": { + "line": 68, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "AnalyticsComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/insights/analytics-process/components/analytics.component.ts" + }, + "name": "AnalyticsComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/insights/analytics-process/components/analytics-generator.component.ts" + }, + "name": "AnalyticsGeneratorComponent" + }, + { + "position": { + "line": 71, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "AnalyticsGeneratorComponent" + }, + { + "position": { + "line": 54, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "AnalyticsProcessModule" + }, + { + "position": { + "line": 41, + "character": 0, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "AnalyticsProcessModule" + }, + { + "position": { + "line": 72, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "AnalyticsReportHeatMapComponent" + }, + { + "position": { + "line": 69, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "AnalyticsReportListComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/insights/analytics-process/components/analytics-report-list.component.ts" + }, + "name": "AnalyticsReportListComponent" + }, + { + "position": { + "line": 70, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "AnalyticsReportParametersComponent" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/insights/analytics-process/components/analytics-report-parameters.component.ts" + }, + "name": "AnalyticsReportParametersComponent" + }, + { + "position": { + "line": 33, + "character": 0, + "fileName": "lib/insights/analytics-process/services/analytics.service.ts" + }, + "name": "AnalyticsService" + }, + { + "position": { + "line": 165, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "AppConfigModule" + }, + { + "position": { + "line": 228, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "AppConfigModule" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/app-config/app-config.module.ts" + }, + "name": "AppConfigModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/app-config/app-config.service.ts" + }, + "name": "AppConfigService" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/mock/app-config.service.mock.ts" + }, + "name": "AppConfigServiceMock" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/task-list/models/filter.model.ts" + }, + "name": "AppDefinitionRepresentationModel" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/process-services/app-list/apps-list.component.ts" + }, + "name": "AppsListComponent" + }, + { + "position": { + "line": 41, + "character": 8, + "fileName": "lib/process-services/app-list/apps-list.module.ts" + }, + "name": "AppsListComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/process-services/app-list/apps-list.module.ts" + }, + "name": "AppsListModule" + }, + { + "position": { + "line": 62, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "AppsListModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/apps-process.service.ts" + }, + "name": "AppsProcessService" + }, + { + "position": { + "line": 47, + "character": 8, + "fileName": "lib/process-services/content-widget/content-widget.module.ts" + }, + "name": "AttachFileWidgetComponent" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/process-services/content-widget/attach-file-widget.component.ts" + }, + "name": "AttachFileWidgetComponent" + }, + { + "position": { + "line": 48, + "character": 8, + "fileName": "lib/process-services/content-widget/content-widget.module.ts" + }, + "name": "AttachFolderWidgetComponent" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/process-services/content-widget/attach-folder-widget.component.ts" + }, + "name": "AttachFolderWidgetComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/process-services/attachment/create-task-attachment.component.ts" + }, + "name": "AttachmentComponent" + }, + { + "position": { + "line": 49, + "character": 8, + "fileName": "lib/process-services/attachment/attachment.module.ts" + }, + "name": "AttachmentComponent" + }, + { + "position": { + "line": 63, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "AttachmentModule" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/process-services/attachment/attachment.module.ts" + }, + "name": "AttachmentModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/mock/authentication.service.mock.ts" + }, + "name": "AuthenticationMock" + }, + { + "position": { + "line": 33, + "character": 0, + "fileName": "lib/core/services/authentication.service.ts" + }, + "name": "AuthenticationService" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/auth-guard.service.ts" + }, + "name": "AuthGuard" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/auth-guard-bpm.service.ts" + }, + "name": "AuthGuardBpm" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/services/auth-guard-ecm.service.ts" + }, + "name": "AuthGuardEcm" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/barChart.model.ts" + }, + "name": "BarChart" + }, + { + "position": { + "line": 18, + "character": 0, + "fileName": "lib/core/events/base.event.ts" + }, + "name": "BaseEvent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/events/base-ui.event.ts" + }, + "name": "BaseUIEvent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/editors/boolean/boolean.editor.ts" + }, + "name": "BooleanEditorComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/models/product-version.model.ts" + }, + "name": "BpmProductVersionModel" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/userinfo/services/bpm-user.service.ts" + }, + "name": "BpmUserService" + }, + { + "position": { + "line": 32, + "character": 8, + "fileName": "lib/content-services/breadcrumb/breadcrumb.module.ts" + }, + "name": "BreadcrumbComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/content-services/breadcrumb/breadcrumb.component.ts" + }, + "name": "BreadcrumbComponent" + }, + { + "position": { + "line": 82, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "BreadcrumbModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/breadcrumb/breadcrumb.module.ts" + }, + "name": "BreadcrumbModule" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/card-view/services/card-item-types.service.ts" + }, + "name": "CardItemTypeService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-baseitem.model.ts" + }, + "name": "CardViewBaseItemModel" + }, + { + "position": { + "line": 19, + "character": 4, + "fileName": "lib/core/card-view/public-api.ts" + }, + "name": "CardViewBoolItemComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/card-view/components/card-view-boolitem/card-view-boolitem.component.ts" + }, + "name": "CardViewBoolItemComponent" + }, + { + "position": { + "line": 72, + "character": 8, + "fileName": "lib/core/card-view/card-view.module.ts" + }, + "name": "CardViewBoolItemComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-boolitem.model.ts" + }, + "name": "CardViewBoolItemModel" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/card-view/components/card-view/card-view.component.ts" + }, + "name": "CardViewComponent" + }, + { + "position": { + "line": 71, + "character": 8, + "fileName": "lib/core/card-view/card-view.module.ts" + }, + "name": "CardViewComponent" + }, + { + "position": { + "line": 18, + "character": 4, + "fileName": "lib/core/card-view/public-api.ts" + }, + "name": "CardViewComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/card-view/directives/card-view-content-proxy.directive.ts" + }, + "name": "CardViewContentProxyDirective" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/card-view/components/card-view-dateitem/card-view-dateitem.component.ts" + }, + "name": "CardViewDateItemComponent" + }, + { + "position": { + "line": 73, + "character": 8, + "fileName": "lib/core/card-view/card-view.module.ts" + }, + "name": "CardViewDateItemComponent" + }, + { + "position": { + "line": 20, + "character": 4, + "fileName": "lib/core/card-view/public-api.ts" + }, + "name": "CardViewDateItemComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-dateitem.model.ts" + }, + "name": "CardViewDateItemModel" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-datetimeitem.model.ts" + }, + "name": "CardViewDatetimeItemModel" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-floatitem.model.ts" + }, + "name": "CardViewFloatItemModel" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-intitem.model.ts" + }, + "name": "CardViewIntItemModel" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/card-view/components/card-view-item-dispatcher/card-view-item-dispatcher.component.ts" + }, + "name": "CardViewItemDispatcherComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/card-view/validators/card-view-item-float.validator.ts" + }, + "name": "CardViewItemFloatValidator" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/card-view/validators/card-view-item-int.validator.ts" + }, + "name": "CardViewItemIntValidator" + }, + { + "position": { + "line": 74, + "character": 8, + "fileName": "lib/core/card-view/card-view.module.ts" + }, + "name": "CardViewMapItemComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/card-view/components/card-view-mapitem/card-view-mapitem.component.ts" + }, + "name": "CardViewMapItemComponent" + }, + { + "position": { + "line": 21, + "character": 4, + "fileName": "lib/core/card-view/public-api.ts" + }, + "name": "CardViewMapItemComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-mapitem.model.ts" + }, + "name": "CardViewMapItemModel" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/core/card-view/card-view.module.ts" + }, + "name": "CardViewModule" + }, + { + "position": { + "line": 169, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "CardViewModule" + }, + { + "position": { + "line": 232, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "CardViewModule" + }, + { + "position": { + "line": 22, + "character": 4, + "fileName": "lib/core/card-view/public-api.ts" + }, + "name": "CardViewTextItemComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/card-view/components/card-view-textitem/card-view-textitem.component.ts" + }, + "name": "CardViewTextItemComponent" + }, + { + "position": { + "line": 75, + "character": 8, + "fileName": "lib/core/card-view/card-view.module.ts" + }, + "name": "CardViewTextItemComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/card-view/models/card-view-textitem.model.ts" + }, + "name": "CardViewTextItemModel" + }, + { + "position": { + "line": 39, + "character": 0, + "fileName": "lib/core/card-view/services/card-view-update.service.ts" + }, + "name": "CardViewUpdateService" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/chart.model.ts" + }, + "name": "Chart" + }, + { + "position": { + "line": 76, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "CheckboxWidgetAanalyticsComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/checkbox/checkbox.widget.ts" + }, + "name": "CheckboxWidgetComponent" + }, + { + "position": { + "line": 85, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "ChecklistComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/process-services/task-list/components/checklist.component.ts" + }, + "name": "ChecklistComponent" + }, + { + "position": { + "line": 233, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "CollapsableModule" + }, + { + "position": { + "line": 170, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "CollapsableModule" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/collapsable/collapsable.module.ts" + }, + "name": "CollapsableModule" + }, + { + "position": { + "line": 45, + "character": 8, + "fileName": "lib/process-services/comments/comments.module.ts" + }, + "name": "CommentListComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/process-services/comments/comment-list.component.ts" + }, + "name": "CommentListComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/models/comment-process.model.ts" + }, + "name": "CommentProcessModel" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/services/comment-process.service.ts" + }, + "name": "CommentProcessService" + }, + { + "position": { + "line": 46, + "character": 8, + "fileName": "lib/process-services/comments/comments.module.ts" + }, + "name": "CommentsComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/comments/comments.component.ts" + }, + "name": "CommentsComponent" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/process-services/comments/comments.module.ts" + }, + "name": "CommentsModule" + }, + { + "position": { + "line": 57, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "CommentsModule" + }, + { + "position": { + "line": 157, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "CommonModule" + }, + { + "position": { + "line": 56, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "CommonModule" + }, + { + "position": { + "line": 220, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "CommonModule" + }, + { + "position": { + "line": 49, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "CommonModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/container-column.model.ts" + }, + "name": "ContainerColumnModel" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/container.model.ts" + }, + "name": "ContainerModel" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/container/container.widget.ts" + }, + "name": "ContainerWidgetComponent" + }, + { + "position": { + "line": 70, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "ContentActionComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/content-services/document-list/components/content-action/content-action.component.ts" + }, + "name": "ContentActionComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/content-services/document-list/components/content-action/content-action-list.component.ts" + }, + "name": "ContentActionListComponent" + }, + { + "position": { + "line": 71, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "ContentActionListComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/content-services/document-list/models/content-action.model.ts" + }, + "name": "ContentActionModel" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/document-list/components/content-column/content-column.component.ts" + }, + "name": "ContentColumnComponent" + }, + { + "position": { + "line": 68, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "ContentColumnComponent" + }, + { + "position": { + "line": 69, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "ContentColumnListComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/document-list/components/content-column/content-column-list.component.ts" + }, + "name": "ContentColumnListComponent" + }, + { + "position": { + "line": 63, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "ContentInfo" + }, + { + "position": { + "line": 21, + "character": 1, + "fileName": "lib/core/form/components/widgets/core/content-link.model.ts" + }, + "name": "ContentLinkModel" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/content-metadata/components/content-metadata-card/content-metadata-card.component.ts" + }, + "name": "ContentMetadataCardComponent" + }, + { + "position": { + "line": 41, + "character": 8, + "fileName": "lib/content-services/content-metadata/content-metadata.module.ts" + }, + "name": "ContentMetadataCardComponent" + }, + { + "position": { + "line": 40, + "character": 8, + "fileName": "lib/content-services/content-metadata/content-metadata.module.ts" + }, + "name": "ContentMetadataComponent" + }, + { + "position": { + "line": 31, + "character": 0, + "fileName": "lib/content-services/content-metadata/content-metadata.module.ts" + }, + "name": "ContentMetadataModule" + }, + { + "position": { + "line": 85, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "ContentMetadataModule" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/content-services/content-metadata/services/content-metadata.service.ts" + }, + "name": "ContentMetadataService" + }, + { + "position": { + "line": 39, + "character": 0, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "ContentModule" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/content-services/content-node-selector/content-node-dialog.service.ts" + }, + "name": "ContentNodeDialogService" + }, + { + "position": { + "line": 52, + "character": 8, + "fileName": "lib/content-services/content-node-selector/content-node-selector.module.ts" + }, + "name": "ContentNodeSelectorComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/content-services/content-node-selector/content-node-selector.component.ts" + }, + "name": "ContentNodeSelectorComponent" + }, + { + "position": { + "line": 33, + "character": 0, + "fileName": "lib/content-services/content-node-selector/content-node-selector.module.ts" + }, + "name": "ContentNodeSelectorModule" + }, + { + "position": { + "line": 84, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "ContentNodeSelectorModule" + }, + { + "position": { + "line": 43, + "character": 0, + "fileName": "lib/content-services/content-node-selector/content-node-selector-panel.component.ts" + }, + "name": "ContentNodeSelectorPanelComponent" + }, + { + "position": { + "line": 50, + "character": 8, + "fileName": "lib/content-services/content-node-selector/content-node-selector.module.ts" + }, + "name": "ContentNodeSelectorPanelComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/content-node-selector/content-node-selector.service.ts" + }, + "name": "ContentNodeSelectorService" + }, + { + "position": { + "line": 32, + "character": 0, + "fileName": "lib/core/services/content.service.ts" + }, + "name": "ContentService" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/content/content.widget.ts" + }, + "name": "ContentWidgetComponent" + }, + { + "position": { + "line": 86, + "character": 8, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "ContentWidgetComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/process-services/content-widget/content-widget.module.ts" + }, + "name": "ContentWidgetModule" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/context-menu/context-menu.directive.ts" + }, + "name": "ContextMenuDirective" + }, + { + "position": { + "line": 36, + "character": 8, + "fileName": "lib/core/context-menu/context-menu.module.ts" + }, + "name": "ContextMenuDirective" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/context-menu/context-menu-holder.component.ts" + }, + "name": "ContextMenuHolderComponent" + }, + { + "position": { + "line": 35, + "character": 8, + "fileName": "lib/core/context-menu/context-menu.module.ts" + }, + "name": "ContextMenuHolderComponent" + }, + { + "position": { + "line": 231, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ContextMenuModule" + }, + { + "position": { + "line": 168, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ContextMenuModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/context-menu/context-menu.module.ts" + }, + "name": "ContextMenuModule" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/context-menu/context-menu.service.ts" + }, + "name": "ContextMenuService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/services/cookie.service.ts" + }, + "name": "CookieService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/mock/cookie.service.mock.ts" + }, + "name": "CookieServiceMock" + }, + { + "position": { + "line": 74, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "CoreModule" + }, + { + "position": { + "line": 183, + "character": 0, + "fileName": "lib/core/core.module.ts" + }, + "name": "CoreModule" + }, + { + "position": { + "line": 48, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "CoreModule" + }, + { + "position": { + "line": 120, + "character": 0, + "fileName": "lib/core/core.module.ts" + }, + "name": "CoreModuleLazy" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/process-services/attachment/create-process-attachment.component.ts" + }, + "name": "CreateProcessAttachmentComponent" + }, + { + "position": { + "line": 48, + "character": 8, + "fileName": "lib/process-services/attachment/attachment.module.ts" + }, + "name": "CreateProcessAttachmentComponent" + }, + { + "position": { + "line": 47, + "character": 8, + "fileName": "lib/process-services/attachment/attachment.module.ts" + }, + "name": "CreateProcessAttachmentComponent" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/data-cell.event.ts" + }, + "name": "DataCellEvent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/data-cell.event.ts" + }, + "name": "DataCellEventModel" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/data-column/data-column.component.ts" + }, + "name": "DataColumnComponent" + }, + { + "position": { + "line": 32, + "character": 8, + "fileName": "lib/core/data-column/data-column.module.ts" + }, + "name": "DataColumnComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/data-column/data-column-list.component.ts" + }, + "name": "DataColumnListComponent" + }, + { + "position": { + "line": 33, + "character": 8, + "fileName": "lib/core/data-column/data-column.module.ts" + }, + "name": "DataColumnListComponent" + }, + { + "position": { + "line": 238, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "DataColumnModule" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/data-column/data-column.module.ts" + }, + "name": "DataColumnModule" + }, + { + "position": { + "line": 175, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "DataColumnModule" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/data-row-action.event.ts" + }, + "name": "DataRowActionEvent" + }, + { + "position": { + "line": 34, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/data-row-action.event.ts" + }, + "name": "DataRowActionModel" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/data/data-row-event.model.ts" + }, + "name": "DataRowEvent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/datatable/data/data-sorting.model.ts" + }, + "name": "DataSorting" + }, + { + "position": { + "line": 70, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "DataTableCellComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/datatable-cell.component.ts" + }, + "name": "DataTableCellComponent" + }, + { + "position": { + "line": 65, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "DataTableComponent" + }, + { + "position": { + "line": 45, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/datatable.component.ts" + }, + "name": "DataTableComponent" + }, + { + "position": { + "line": 176, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "DataTableModule" + }, + { + "position": { + "line": 239, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "DataTableModule" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "DataTableModule" + }, + { + "position": { + "line": 71, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "DateCellComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/date-cell.component.ts" + }, + "name": "DateCellComponent" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/editors/date/date.editor.ts" + }, + "name": "DateEditorComponent" + }, + { + "position": { + "line": 128, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "DateFieldValidator" + }, + { + "position": { + "line": 77, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "DateRangeWidgetComponent" + }, + { + "position": { + "line": 31, + "character": 0, + "fileName": "lib/core/form/components/widgets/date-time/date-time.widget.ts" + }, + "name": "DateTimeWidgetComponent" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/form/components/widgets/date/date.widget.ts" + }, + "name": "DateWidgetComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/services/deleted-nodes-api.service.ts" + }, + "name": "DeletedNodesApiService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/detailsTableChart.model.ts" + }, + "name": "DetailsTableChart" + }, + { + "position": { + "line": 222, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramAlfrescoPublishTaskComponent" + }, + { + "position": { + "line": 253, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramBoundaryEventComponent" + }, + { + "position": { + "line": 225, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramBoxPublishTaskComponent" + }, + { + "position": { + "line": 228, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramBusinessRuleTaskComponent" + }, + { + "position": { + "line": 220, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramCamelTaskComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/services/diagram-color.service.ts" + }, + "name": "DiagramColorService" + }, + { + "position": { + "line": 210, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/insights/diagram/components/diagram.component.ts" + }, + "name": "DiagramComponent" + }, + { + "position": { + "line": 248, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramContainerIconEventTaskComponent" + }, + { + "position": { + "line": 214, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramContainerServiceTaskComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramElement.model.ts" + }, + "name": "DiagramElementModel" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramElementProperty.model.ts" + }, + "name": "DiagramElementPropertyModel" + }, + { + "position": { + "line": 213, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramEndEventComponent" + }, + { + "position": { + "line": 211, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramEventComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramEventDefinition.model.ts" + }, + "name": "DiagramEventDefinitionModel" + }, + { + "position": { + "line": 234, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramEventGatewayComponent" + }, + { + "position": { + "line": 257, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramEventSubprocessComponent" + }, + { + "position": { + "line": 231, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramExclusiveGatewayComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramFlowElement.model.ts" + }, + "name": "DiagramFlowElementModel" + }, + { + "position": { + "line": 230, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramGatewayComponent" + }, + { + "position": { + "line": 224, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramGoogleDrivePublishTaskComponent" + }, + { + "position": { + "line": 241, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconAlfrescoPublishTaskComponent" + }, + { + "position": { + "line": 244, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconBoxPublishTaskComponent" + }, + { + "position": { + "line": 247, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconBusinessRuleTaskComponent" + }, + { + "position": { + "line": 239, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconCamelTaskComponent" + }, + { + "position": { + "line": 250, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconErrorComponent" + }, + { + "position": { + "line": 243, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconGoogleDrivePublishTaskComponent" + }, + { + "position": { + "line": 238, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconManualTaskComponent" + }, + { + "position": { + "line": 252, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconMessageComponent" + }, + { + "position": { + "line": 240, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconMuleTaskComponent" + }, + { + "position": { + "line": 245, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconReceiveTaskComponent" + }, + { + "position": { + "line": 242, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconRestCallTaskComponent" + }, + { + "position": { + "line": 246, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconScriptTaskComponent" + }, + { + "position": { + "line": 236, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconSendTaskComponent" + }, + { + "position": { + "line": 235, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconServiceTaskComponent" + }, + { + "position": { + "line": 251, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconSignalComponent" + }, + { + "position": { + "line": 249, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconTimerComponent" + }, + { + "position": { + "line": 237, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIconUserTaskComponent" + }, + { + "position": { + "line": 232, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramInclusiveGatewayComponent" + }, + { + "position": { + "line": 255, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramIntermediateCatchingEventComponent" + }, + { + "position": { + "line": 261, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramLaneComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramLaneElement.model.ts" + }, + "name": "DiagramLaneElementModel" + }, + { + "position": { + "line": 260, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramLanesComponent" + }, + { + "position": { + "line": 219, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramManualTaskComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagram.model.ts" + }, + "name": "DiagramModel" + }, + { + "position": { + "line": 221, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramMuleTaskComponent" + }, + { + "position": { + "line": 233, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramParallelGatewayComponent" + }, + { + "position": { + "line": 259, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramPoolComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramPoolElement.model.ts" + }, + "name": "DiagramPoolElementModel" + }, + { + "position": { + "line": 258, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramPoolsComponent" + }, + { + "position": { + "line": 226, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramReceiveTaskComponent" + }, + { + "position": { + "line": 223, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramRestCallTaskComponent" + }, + { + "position": { + "line": 227, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramScriptTaskComponent" + }, + { + "position": { + "line": 217, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramSendTaskComponent" + }, + { + "position": { + "line": 229, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramSequenceFlowComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/components/diagram-sequence-flow.component.ts" + }, + "name": "DiagramSequenceFlowComponent" + }, + { + "position": { + "line": 216, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramServiceTaskComponent" + }, + { + "position": { + "line": 53, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "DiagramsModule" + }, + { + "position": { + "line": 118, + "character": 0, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramsModule" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/insights/diagram/services/diagrams.service.ts" + }, + "name": "DiagramsService" + }, + { + "position": { + "line": 212, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramStartEventComponent" + }, + { + "position": { + "line": 256, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramSubprocessComponent" + }, + { + "position": { + "line": 215, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramTaskComponent" + }, + { + "position": { + "line": 254, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramThrowEventComponent" + }, + { + "position": { + "line": 262, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramTooltipComponent" + }, + { + "position": { + "line": 218, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "DiagramUserTaskComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/diagram/diagramWayPoint.model.ts" + }, + "name": "DiagramWayPointModel" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/content-services/dialogs/dialog.module.ts" + }, + "name": "DialogModule" + }, + { + "position": { + "line": 86, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "DialogModule" + }, + { + "position": { + "line": 158, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "DirectiveModule" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "DirectiveModule" + }, + { + "position": { + "line": 221, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "DirectiveModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/discovery-api.service.ts" + }, + "name": "DiscoveryApiService" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/display-text/display-text.widget.ts" + }, + "name": "DisplayTextWidgetComponentComponent" + }, + { + "position": { + "line": 49, + "character": 0, + "fileName": "lib/content-services/document-list/models/content-action.model.ts" + }, + "name": "DocumentActionModel" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/content-services/document-list/services/document-actions.service.ts" + }, + "name": "DocumentActionsService" + }, + { + "position": { + "line": 60, + "character": 0, + "fileName": "lib/content-services/document-list/components/document-list.component.ts" + }, + "name": "DocumentListComponent" + }, + { + "position": { + "line": 67, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "DocumentListComponent" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "DocumentListModule" + }, + { + "position": { + "line": 78, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "DocumentListModule" + }, + { + "position": { + "line": 31, + "character": 0, + "fileName": "lib/content-services/document-list/services/document-list.service.ts" + }, + "name": "DocumentListService" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/form/components/widgets/document/document.widget.ts" + }, + "name": "DocumentWidgetComponent" + }, + { + "position": { + "line": 46, + "character": 8, + "fileName": "lib/content-services/dialogs/dialog.module.ts" + }, + "name": "DownloadZipDialogComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/content-services/dialogs/download-zip.dialog.ts" + }, + "name": "DownloadZipDialogComponent" + }, + { + "position": { + "line": 33, + "character": 8, + "fileName": "lib/content-services/breadcrumb/breadcrumb.module.ts" + }, + "name": "DropdownBreadcrumbComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/content-services/breadcrumb/dropdown-breadcrumb.component.ts" + }, + "name": "DropdownBreadcrumbComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.ts" + }, + "name": "DropdownEditorComponent" + }, + { + "position": { + "line": 34, + "character": 8, + "fileName": "lib/content-services/site-dropdown/sites-dropdown.module.ts" + }, + "name": "DropdownSitesComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/content-services/site-dropdown/sites-dropdown.component.ts" + }, + "name": "DropdownSitesComponent" + }, + { + "position": { + "line": 73, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "DropdownWidgetAanalyticsComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/dropdown/dropdown.widget.ts" + }, + "name": "DropdownWidgetComponent" + }, + { + "position": { + "line": 75, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "DurationWidgetComponent" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/services/dynamic-component-mapper.service.ts" + }, + "name": "DynamicComponentMapper" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/services/dynamic-component-mapper.service.ts" + }, + "name": "DynamicComponentResolver" + }, + { + "position": { + "line": 32, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.model.ts" + }, + "name": "DynamicTableModel" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.ts" + }, + "name": "DynamicTableWidgetComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/models/ecm-company.model.ts" + }, + "name": "EcmCompanyModel" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/form/services/ecm-model.service.ts" + }, + "name": "EcmModelService" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/core/models/product-version.model.ts" + }, + "name": "EcmProductVersionModel" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/userinfo/services/ecm-user.service.ts" + }, + "name": "EcmUserService" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/document-list/components/empty-folder/empty-folder-content.directive.ts" + }, + "name": "EmptyFolderContentDirective" + }, + { + "position": { + "line": 72, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "EmptyFolderContentDirective" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/empty-list.component.ts" + }, + "name": "EmptyListBodyDirective" + }, + { + "position": { + "line": 68, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "EmptyListBodyDirective" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/empty-list.component.ts" + }, + "name": "EmptyListComponent" + }, + { + "position": { + "line": 66, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "EmptyListComponent" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/empty-list.component.ts" + }, + "name": "EmptyListFooterDirective" + }, + { + "position": { + "line": 69, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "EmptyListFooterDirective" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/empty-list.component.ts" + }, + "name": "EmptyListHeaderDirective" + }, + { + "position": { + "line": 67, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "EmptyListHeaderDirective" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/content-services/search/components/empty-search-result.component.ts" + }, + "name": "EmptySearchResultComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/error-message.model.ts" + }, + "name": "ErrorMessageModel" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/error/error.component.ts" + }, + "name": "ErrorWidgetComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/mock/event.mock.ts" + }, + "name": "EventMock" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/services/favorites-api.service.ts" + }, + "name": "FavoritesApiService" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/content-services/upload/directives/file-draggable.directive.ts" + }, + "name": "FileDraggableDirective" + }, + { + "position": { + "line": 47, + "character": 8, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "FileDraggableDirective" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/core/models/file.model.ts" + }, + "name": "FileModel" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/filesize-cell.component.ts" + }, + "name": "FileSizeCellComponent" + }, + { + "position": { + "line": 72, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "FileSizeCellComponent" + }, + { + "position": { + "line": 48, + "character": 8, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "FileSizePipe" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/pipes/file-size.pipe.ts" + }, + "name": "FileSizePipe" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/events/file.event.ts" + }, + "name": "FileUploadCompleteEvent" + }, + { + "position": { + "line": 37, + "character": 0, + "fileName": "lib/core/events/file.event.ts" + }, + "name": "FileUploadDeleteEvent" + }, + { + "position": { + "line": 45, + "character": 0, + "fileName": "lib/core/events/file.event.ts" + }, + "name": "FileUploadErrorEvent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/events/file.event.ts" + }, + "name": "FileUploadEvent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/upload/components/file-uploading-dialog.component.ts" + }, + "name": "FileUploadingDialogComponent" + }, + { + "position": { + "line": 50, + "character": 8, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "FileUploadingDialogComponent" + }, + { + "position": { + "line": 51, + "character": 8, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "FileUploadingListComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/content-services/upload/components/file-uploading-list.component.ts" + }, + "name": "FileUploadingListComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/upload/components/file-uploading-list-row.component.ts" + }, + "name": "FileUploadingListRowComponent" + }, + { + "position": { + "line": 52, + "character": 8, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "FileUploadingListRowComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/utils/file-utils.ts" + }, + "name": "FileUtils" + }, + { + "position": { + "line": 85, + "character": 0, + "fileName": "lib/process-services/task-list/models/filter.model.ts" + }, + "name": "FilterParamRepresentationModel" + }, + { + "position": { + "line": 45, + "character": 0, + "fileName": "lib/process-services/task-list/models/filter.model.ts" + }, + "name": "FilterParamsModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/process-list/models/filter-process.model.ts" + }, + "name": "FilterProcessRepresentationModel" + }, + { + "position": { + "line": 59, + "character": 0, + "fileName": "lib/process-services/task-list/models/filter.model.ts" + }, + "name": "FilterRepresentationModel" + }, + { + "position": { + "line": 479, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "FixedValueFieldValidator" + }, + { + "position": { + "line": 56, + "character": 0, + "fileName": "lib/content-services/document-list/models/content-action.model.ts" + }, + "name": "FolderActionModel" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/content-services/document-list/services/folder-actions.service.ts" + }, + "name": "FolderActionsService" + }, + { + "position": { + "line": 34, + "character": 8, + "fileName": "lib/content-services/folder-directive/folder-directive.module.ts" + }, + "name": "FolderCreateDirective" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/content-services/folder-directive/folder-create.directive.ts" + }, + "name": "FolderCreateDirective" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/content-services/dialogs/folder.dialog.ts" + }, + "name": "FolderDialogComponent" + }, + { + "position": { + "line": 47, + "character": 8, + "fileName": "lib/content-services/dialogs/dialog.module.ts" + }, + "name": "FolderDialogComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/content-services/folder-directive/folder-directive.module.ts" + }, + "name": "FolderDirectiveModule" + }, + { + "position": { + "line": 87, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "FolderDirectiveModule" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/content-services/folder-directive/folder-edit.directive.ts" + }, + "name": "FolderEditDirective" + }, + { + "position": { + "line": 35, + "character": 8, + "fileName": "lib/content-services/folder-directive/folder-directive.module.ts" + }, + "name": "FolderEditDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/process-services/task-list/models/form.model.ts" + }, + "name": "Form" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/form/components/form.component.ts" + }, + "name": "FormComponent" + }, + { + "position": { + "line": 88, + "character": 8, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "FormComponent" + }, + { + "position": { + "line": 18, + "character": 9, + "fileName": "lib/core/form/events/index.ts" + }, + "name": "FormErrorEvent" + }, + { + "position": { + "line": 17, + "character": 9, + "fileName": "lib/core/form/events/index.ts" + }, + "name": "FormEvent" + }, + { + "position": { + "line": 87, + "character": 8, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "FormFieldComponent" + }, + { + "position": { + "line": 19, + "character": 9, + "fileName": "lib/core/form/events/index.ts" + }, + "name": "FormFieldEvent" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field.model.ts" + }, + "name": "FormFieldModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-types.ts" + }, + "name": "FormFieldTypes" + }, + { + "position": { + "line": 89, + "character": 8, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "FormListComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/form/components/form-list.component.ts" + }, + "name": "FormListComponent" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form.model.ts" + }, + "name": "FormModel" + }, + { + "position": { + "line": 171, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "FormModule" + }, + { + "position": { + "line": 234, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "FormModule" + }, + { + "position": { + "line": 48, + "character": 0, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "FormModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-outcome-event.model.ts" + }, + "name": "FormOutcomeEvent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-outcome.model.ts" + }, + "name": "FormOutcomeModel" + }, + { + "position": { + "line": 42, + "character": 0, + "fileName": "lib/core/form/services/form-rendering.service.ts" + }, + "name": "FormRenderingService" + }, + { + "position": { + "line": 37, + "character": 0, + "fileName": "lib/core/form/services/form.service.ts" + }, + "name": "FormService" + }, + { + "position": { + "line": 50, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "FormsModule" + }, + { + "position": { + "line": 58, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "FormsModule" + }, + { + "position": { + "line": 222, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "FormsModule" + }, + { + "position": { + "line": 159, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "FormsModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-widget.model.ts" + }, + "name": "FormWidgetModel" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/functional-group/functional-group.widget.ts" + }, + "name": "FunctionalGroupWidgetComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/heatMapChart.model.ts" + }, + "name": "HeatMapChart" + }, + { + "position": { + "line": 44, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "HighlightDirective" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/directives/highlight.directive.ts" + }, + "name": "HighlightDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/pipes/text-highlight.pipe.ts" + }, + "name": "HighlightPipe" + }, + { + "position": { + "line": 49, + "character": 8, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "HighlightPipe" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/services/highlight-transform.service.ts" + }, + "name": "HighlightTransformService" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/settings/host-settings.component.ts" + }, + "name": "HostSettingsComponent" + }, + { + "position": { + "line": 37, + "character": 8, + "fileName": "lib/core/settings/host-settings.module.ts" + }, + "name": "HostSettingsComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/settings/host-settings.module.ts" + }, + "name": "HostSettingsModule" + }, + { + "position": { + "line": 225, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "HostSettingsModule" + }, + { + "position": { + "line": 162, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "HostSettingsModule" + }, + { + "position": { + "line": 161, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "HttpClientModule" + }, + { + "position": { + "line": 224, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "HttpClientModule" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/hyperlink/hyperlink.widget.ts" + }, + "name": "HyperlinkWidgetComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/viewer/components/imgViewer.component.ts" + }, + "name": "ImgViewerComponent" + }, + { + "position": { + "line": 67, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ImgViewerComponent" + }, + { + "position": { + "line": 35, + "character": 8, + "fileName": "lib/core/pagination/pagination.module.ts" + }, + "name": "InfinitePaginationComponent" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/core/pagination/infinite-pagination.component.ts" + }, + "name": "InfinitePaginationComponent" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer-layout.component.ts" + }, + "name": "InfoDrawerButtonsDirective" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer.component.ts" + }, + "name": "InfoDrawerComponent" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer-layout.component.ts" + }, + "name": "InfoDrawerContentDirective" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer-layout.component.ts" + }, + "name": "InfoDrawerLayoutComponent" + }, + { + "position": { + "line": 174, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "InfoDrawerModule" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer.module.ts" + }, + "name": "InfoDrawerModule" + }, + { + "position": { + "line": 237, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "InfoDrawerModule" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer.component.ts" + }, + "name": "InfoDrawerTabComponent" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/info-drawer/info-drawer-layout.component.ts" + }, + "name": "InfoDrawerTitleDirective" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/pipes/user-initial.pipe.ts" + }, + "name": "InitialUsernamePipe" + }, + { + "position": { + "line": 52, + "character": 8, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "InitialUsernamePipe" + }, + { + "position": { + "line": 37, + "character": 0, + "fileName": "lib/core/form/components/widgets/text/text-mask.component.ts" + }, + "name": "InputMaskDirective" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "InsightsModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/language-menu/language-menu.component.ts" + }, + "name": "LanguageMenuComponent" + }, + { + "position": { + "line": 32, + "character": 8, + "fileName": "lib/core/language-menu/language-menu.module.ts" + }, + "name": "LanguageMenuComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/language-menu/language-menu.module.ts" + }, + "name": "LanguageMenuModule" + }, + { + "position": { + "line": 236, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "LanguageMenuModule" + }, + { + "position": { + "line": 173, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "LanguageMenuModule" + }, + { + "position": { + "line": 80, + "character": 0, + "fileName": "lib/core/models/product-version.model.ts" + }, + "name": "LicenseModel" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/social/like.component.ts" + }, + "name": "LikeComponent" + }, + { + "position": { + "line": 32, + "character": 8, + "fileName": "lib/content-services/social/social.module.ts" + }, + "name": "LikeComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/lineChart.model.ts" + }, + "name": "LineChart" + }, + { + "position": { + "line": 76, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "LoadingContentTemplateDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/directives/loading-template.directive.ts" + }, + "name": "LoadingContentTemplateDirective" + }, + { + "position": { + "line": 73, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "LocationCellComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/datatable/components/datatable/location-cell.component.ts" + }, + "name": "LocationCellComponent" + }, + { + "position": { + "line": 46, + "character": 0, + "fileName": "lib/core/login/components/login.component.ts" + }, + "name": "LoginComponent" + }, + { + "position": { + "line": 44, + "character": 12, + "fileName": "lib/core/login/login.module.ts" + }, + "name": "LoginComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/login/models/login-error.event.ts" + }, + "name": "LoginErrorEvent" + }, + { + "position": { + "line": 45, + "character": 12, + "fileName": "lib/core/login/login.module.ts" + }, + "name": "LoginFooterDirective" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/login/directives/login-footer.directive.ts" + }, + "name": "LoginFooterDirective" + }, + { + "position": { + "line": 46, + "character": 12, + "fileName": "lib/core/login/login.module.ts" + }, + "name": "LoginHeaderDirective" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/login/directives/login-header.directive.ts" + }, + "name": "LoginHeaderDirective" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/login/login.module.ts" + }, + "name": "LoginModule" + }, + { + "position": { + "line": 235, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "LoginModule" + }, + { + "position": { + "line": 172, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "LoginModule" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/login/models/login-submit.event.ts" + }, + "name": "LoginSubmitEvent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/login/models/login-success.event.ts" + }, + "name": "LoginSuccessEvent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/directives/logout.directive.ts" + }, + "name": "LogoutDirective" + }, + { + "position": { + "line": 45, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "LogoutDirective" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/services/log.service.ts" + }, + "name": "LogService" + }, + { + "position": { + "line": 164, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "MaterialModule" + }, + { + "position": { + "line": 227, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "MaterialModule" + }, + { + "position": { + "line": 52, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "MaterialModule" + }, + { + "position": { + "line": 207, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MaxDateFieldValidator" + }, + { + "position": { + "line": 295, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MaxDateTimeFieldValidator" + }, + { + "position": { + "line": 368, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MaxLengthFieldValidator" + }, + { + "position": { + "line": 424, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MaxValueFieldValidator" + }, + { + "position": { + "line": 69, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "MediaPlayerComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/viewer/components/mediaPlayer.component.ts" + }, + "name": "MediaPlayerComponent" + }, + { + "position": { + "line": 51, + "character": 8, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "MimeTypeIconPipe" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/pipes/mime-type-icon.pipe.ts" + }, + "name": "MimeTypeIconPipe" + }, + { + "position": { + "line": 160, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MinDateFieldValidator" + }, + { + "position": { + "line": 248, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MinDateTimeFieldValidator" + }, + { + "position": { + "line": 342, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MinLengthFieldValidator" + }, + { + "position": { + "line": 394, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "MinValueFieldValidator" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/utils/momentDateAdapter.ts" + }, + "name": "MomentDateAdapter" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/multiBarChart.model.ts" + }, + "name": "MultiBarChart" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/multiline-text/multiline-text.widget.ts" + }, + "name": "MultilineTextWidgetComponentComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/content-node-selector/name-location-cell/name-location-cell.component.ts" + }, + "name": "NameLocationCellComponent" + }, + { + "position": { + "line": 51, + "character": 8, + "fileName": "lib/content-services/content-node-selector/content-node-selector.module.ts" + }, + "name": "NameLocationCellComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/directives/no-content-template.directive.ts" + }, + "name": "NoContentTemplateDirective" + }, + { + "position": { + "line": 74, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "NoContentTemplateDirective" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/content-services/document-list/services/node-actions.service.ts" + }, + "name": "NodeActionsService" + }, + { + "position": { + "line": 46, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "NodeDeleteDirective" + }, + { + "position": { + "line": 51, + "character": 0, + "fileName": "lib/core/directives/node-delete.directive.ts" + }, + "name": "NodeDeleteDirective" + }, + { + "position": { + "line": 88, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "NodeDownloadDirective" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/content-services/directives/node-download.directive.ts" + }, + "name": "NodeDownloadDirective" + }, + { + "position": { + "line": 32, + "character": 9, + "fileName": "lib/content-services/index.ts" + }, + "name": "NodeDownloadDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/document-list/components/node.event.ts" + }, + "name": "NodeEntityEvent" + }, + { + "position": { + "line": 32, + "character": 0, + "fileName": "lib/content-services/document-list/components/node.event.ts" + }, + "name": "NodeEntryEvent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/directives/node-favorite.directive.ts" + }, + "name": "NodeFavoriteDirective" + }, + { + "position": { + "line": 47, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "NodeFavoriteDirective" + }, + { + "position": { + "line": 42, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "NodeMinimal" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "NodeMinimalEntry" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/pipes/node-name-tooltip.pipe.ts" + }, + "name": "NodeNameTooltipPipe" + }, + { + "position": { + "line": 53, + "character": 8, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "NodeNameTooltipPipe" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "NodePaging" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "NodePagingList" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/directives/node-permission.directive.ts" + }, + "name": "NodePermissionDirective" + }, + { + "position": { + "line": 48, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "NodePermissionDirective" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/directives/node-restore.directive.ts" + }, + "name": "NodeRestoreDirective" + }, + { + "position": { + "line": 49, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "NodeRestoreDirective" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/nodes-api.service.ts" + }, + "name": "NodesApiService" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/form/services/node.service.ts" + }, + "name": "NodeService" + }, + { + "position": { + "line": 73, + "character": 8, + "fileName": "lib/content-services/document-list/document-list.module.ts" + }, + "name": "NoPermissionContentDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/document-list/components/no-permission/no-permission-content.directive.ts" + }, + "name": "NoPermissionContentDirective" + }, + { + "position": { + "line": 75, + "character": 8, + "fileName": "lib/core/datatable/datatable.module.ts" + }, + "name": "NoPermissionTemplateDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/datatable/directives/no-permission-template.directive.ts" + }, + "name": "NoPermissionTemplateDirective" + }, + { + "position": { + "line": 80, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "NoTaskDetailsTemplateDirective" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/process-services/task-list/components/no-task-detail-template.directive.ts" + }, + "name": "NoTaskDetailsTemplateDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/services/notification.service.ts" + }, + "name": "NotificationService" + }, + { + "position": { + "line": 87, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "NumberFieldValidator" + }, + { + "position": { + "line": 74, + "character": 8, + "fileName": "lib/insights/analytics-process/analytics-process.module.ts" + }, + "name": "NumberWidgetAanlyticsComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/number/number.widget.ts" + }, + "name": "NumberWidgetComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/datatable/data/object-datacolumn.model.ts" + }, + "name": "ObjectDataColumn" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/datatable/data/object-datarow.model.ts" + }, + "name": "ObjectDataRow" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/core/datatable/data/object-datatable-adapter.ts" + }, + "name": "ObjectDataTableAdapter" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/utils/object-utils.ts" + }, + "name": "ObjectUtils" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/services/page-title.service.ts" + }, + "name": "PageTitleService" + }, + { + "position": { + "line": 34, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "Pagination" + }, + { + "position": { + "line": 36, + "character": 8, + "fileName": "lib/core/pagination/pagination.module.ts" + }, + "name": "PaginationComponent" + }, + { + "position": { + "line": 35, + "character": 0, + "fileName": "lib/core/pagination/pagination.component.ts" + }, + "name": "PaginationComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/pagination/pagination.module.ts" + }, + "name": "PaginationModule" + }, + { + "position": { + "line": 229, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "PaginationModule" + }, + { + "position": { + "line": 166, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "PaginationModule" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/report/parameterValue.model.ts" + }, + "name": "ParameterValueModel" + }, + { + "position": { + "line": 76, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "PathElementEntity" + }, + { + "position": { + "line": 70, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "PathInfoEntity" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/viewer/components/pdfViewer-thumb.component.ts" + }, + "name": "PdfThumbComponent" + }, + { + "position": { + "line": 71, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "PdfThumbComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/viewer/components/pdfViewer-thumbnails.component.ts" + }, + "name": "PdfThumbListComponent" + }, + { + "position": { + "line": 72, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "PdfThumbListComponent" + }, + { + "position": { + "line": 70, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "PdfViewerComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/viewer/components/pdfViewer.component.ts" + }, + "name": "PdfViewerComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/process-services/people/components/people/people.component.ts" + }, + "name": "PeopleComponent" + }, + { + "position": { + "line": 53, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/services/people-content.service.ts" + }, + "name": "PeopleContentService" + }, + { + "position": { + "line": 59, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleListComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/people/components/people-list/people-list.component.ts" + }, + "name": "PeopleListComponent" + }, + { + "position": { + "line": 64, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "PeopleModule" + }, + { + "position": { + "line": 33, + "character": 0, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleModule" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/services/people-process.service.ts" + }, + "name": "PeopleProcessService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/people/directives/people-search-action-label.directive.ts" + }, + "name": "PeopleSearchActionLabelDirective" + }, + { + "position": { + "line": 58, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleSearchActionLabelDirective" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/people/components/people-search/people-search.component.ts" + }, + "name": "PeopleSearchComponent" + }, + { + "position": { + "line": 54, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleSearchComponent" + }, + { + "position": { + "line": 55, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleSearchFieldComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/process-services/people/components/people-search-field/people-search-field.component.ts" + }, + "name": "PeopleSearchFieldComponent" + }, + { + "position": { + "line": 57, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleSearchTitleDirective" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/people/directives/people-search-title.directive.ts" + }, + "name": "PeopleSearchTitleDirective" + }, + { + "position": { + "line": 56, + "character": 8, + "fileName": "lib/process-services/people/people.module.ts" + }, + "name": "PeopleSelectorComponent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/process-services/people/components/people-selector/people-selector.component.ts" + }, + "name": "PeopleSelectorComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/form/components/widgets/people/people.widget.ts" + }, + "name": "PeopleWidgetComponent" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/content-services/document-list/models/permissions.model.ts" + }, + "name": "PermissionModel" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/core/models/permissions.enum.ts" + }, + "name": "PermissionsEnum" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/content-services/document-list/models/permissions-style.model.ts" + }, + "name": "PermissionStyleModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/pieChart.model.ts" + }, + "name": "PieChart" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "PipeModule" + }, + { + "position": { + "line": 156, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "PipeModule" + }, + { + "position": { + "line": 219, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "PipeModule" + }, + { + "position": { + "line": 46, + "character": 8, + "fileName": "lib/process-services/attachment/attachment.module.ts" + }, + "name": "ProcessAttachmentListComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/process-services/attachment/process-attachment-list.component.ts" + }, + "name": "ProcessAttachmentListComponent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/process-services/process-list/components/process-audit.directive.ts" + }, + "name": "ProcessAuditDirective" + }, + { + "position": { + "line": 79, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessAuditDirective" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/comments/process-comments.component.ts" + }, + "name": "ProcessCommentsComponent" + }, + { + "position": { + "line": 44, + "character": 8, + "fileName": "lib/process-services/comments/comments.module.ts" + }, + "name": "ProcessCommentsComponent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/form/services/process-content.service.ts" + }, + "name": "ProcessContentService" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/process-services/process-list/models/process-definition.model.ts" + }, + "name": "ProcessDefinitionRepresentation" + }, + { + "position": { + "line": 48, + "character": 0, + "fileName": "lib/process-services/process-list/models/filter-process.model.ts" + }, + "name": "ProcessFilterParamRepresentationModel" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/process-services/process-list/models/process-instance-filter.model.ts" + }, + "name": "ProcessFilterRequestRepresentation" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/process-services/process-list/components/process-filters.component.ts" + }, + "name": "ProcessFiltersComponent" + }, + { + "position": { + "line": 77, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessFiltersComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/process-services/process-list/services/process-filter.service.ts" + }, + "name": "ProcessFilterService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/process-list/models/process-instance.model.ts" + }, + "name": "ProcessInstance" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/process-services/process-list/components/process-instance-details.component.ts" + }, + "name": "ProcessInstanceDetailsComponent" + }, + { + "position": { + "line": 78, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessInstanceDetailsComponent" + }, + { + "position": { + "line": 80, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessInstanceHeaderComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/process-services/process-list/components/process-instance-header.component.ts" + }, + "name": "ProcessInstanceHeaderComponent" + }, + { + "position": { + "line": 76, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessInstanceListComponent" + }, + { + "position": { + "line": 52, + "character": 0, + "fileName": "lib/process-services/process-list/components/process-list.component.ts" + }, + "name": "ProcessInstanceListComponent" + }, + { + "position": { + "line": 81, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessInstanceTasksComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/process-services/process-list/components/process-instance-tasks.component.ts" + }, + "name": "ProcessInstanceTasksComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/process-list/models/process-instance-variable.model.ts" + }, + "name": "ProcessInstanceVariable" + }, + { + "position": { + "line": 60, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "ProcessListModule" + }, + { + "position": { + "line": 42, + "character": 0, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "ProcessListModule" + }, + { + "position": { + "line": 31, + "character": 0, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "ProcessModule" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/process-services/process-list/services/process.service.ts" + }, + "name": "ProcessService" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/task-list/services/process-upload.service.ts" + }, + "name": "ProcessUploadService" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.ts" + }, + "name": "RadioButtonsWidgetComponent" + }, + { + "position": { + "line": 263, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelCircleDirective" + }, + { + "position": { + "line": 268, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelCrossDirective" + }, + { + "position": { + "line": 267, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelFlowArrowDirective" + }, + { + "position": { + "line": 278, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconAlfrescoPublishDirective" + }, + { + "position": { + "line": 281, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconBoxPublishDirective" + }, + { + "position": { + "line": 284, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconBusinessRuleDirective" + }, + { + "position": { + "line": 276, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconCamelDirective" + }, + { + "position": { + "line": 286, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconErrorDirective" + }, + { + "position": { + "line": 280, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconGoogleDrivePublishDirective" + }, + { + "position": { + "line": 275, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconManualDirective" + }, + { + "position": { + "line": 288, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconMessageDirective" + }, + { + "position": { + "line": 277, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconMuleDirective" + }, + { + "position": { + "line": 282, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconReceiveDirective" + }, + { + "position": { + "line": 279, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconRestCallDirective" + }, + { + "position": { + "line": 283, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconScriptDirective" + }, + { + "position": { + "line": 273, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconSendDirective" + }, + { + "position": { + "line": 272, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconServiceDirective" + }, + { + "position": { + "line": 287, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconSignalDirective" + }, + { + "position": { + "line": 285, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconTimerDirective" + }, + { + "position": { + "line": 274, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelIconUserDirective" + }, + { + "position": { + "line": 266, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelMultilineTextDirective" + }, + { + "position": { + "line": 271, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelPentagonDirective" + }, + { + "position": { + "line": 269, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelPlusDirective" + }, + { + "position": { + "line": 264, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelRectDirective" + }, + { + "position": { + "line": 270, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelRhombusDirective" + }, + { + "position": { + "line": 265, + "character": 8, + "fileName": "lib/insights/diagram/diagram.module.ts" + }, + "name": "RaphaelTextDirective" + }, + { + "position": { + "line": 31, + "character": 8, + "fileName": "lib/content-services/social/social.module.ts" + }, + "name": "RatingComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/social/rating.component.ts" + }, + "name": "RatingComponent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/content-services/social/services/rating.service.ts" + }, + "name": "RatingService" + }, + { + "position": { + "line": 160, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ReactiveFormsModule" + }, + { + "position": { + "line": 223, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ReactiveFormsModule" + }, + { + "position": { + "line": 59, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "ReactiveFormsModule" + }, + { + "position": { + "line": 51, + "character": 8, + "fileName": "lib/insights/insights.module.ts" + }, + "name": "ReactiveFormsModule" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/models/redirection.model.ts" + }, + "name": "RedirectionModel" + }, + { + "position": { + "line": 454, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "RegExFieldValidator" + }, + { + "position": { + "line": 32, + "character": 0, + "fileName": "lib/core/services/renditions.service.ts" + }, + "name": "RenditionsService" + }, + { + "position": { + "line": 17, + "character": 0, + "fileName": "lib/insights/diagram/models/report/reportDateRange.model.ts" + }, + "name": "ReportDateRange" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/report/reportDefinition.model.ts" + }, + "name": "ReportDefinitionModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/report/reportParameterDetails.model.ts" + }, + "name": "ReportParameterDetailsModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/report/reportParameters.model.ts" + }, + "name": "ReportParametersModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/report/reportQuery.model.ts" + }, + "name": "ReportQuery" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/form-field-validator.ts" + }, + "name": "RequiredFieldValidator" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/editors/row.editor.ts" + }, + "name": "RowEditorComponent" + }, + { + "position": { + "line": 34, + "character": 0, + "fileName": "lib/content-services/search/components/search.component.ts" + }, + "name": "SearchComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/services/search-configuration.service.ts" + }, + "name": "SearchConfigurationService" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/content-services/search/components/search-control.component.ts" + }, + "name": "SearchControlComponent" + }, + { + "position": { + "line": 42, + "character": 0, + "fileName": "lib/content-services/search/search.module.ts" + }, + "name": "SearchModule" + }, + { + "position": { + "line": 80, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "SearchModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/search.service.ts" + }, + "name": "SearchService" + }, + { + "position": { + "line": 46, + "character": 0, + "fileName": "lib/content-services/search/components/search-trigger.directive.ts" + }, + "name": "SearchTriggerDirective" + }, + { + "position": { + "line": 42, + "character": 8, + "fileName": "lib/process-services/app-list/apps-list.module.ts" + }, + "name": "SelectAppsDialogComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/process-services/app-list/select-apps-dialog-component.ts" + }, + "name": "SelectAppsDialogComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/services/settings.service.ts" + }, + "name": "SettingsService" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/content-services/document-list/data/share-data-row.model.ts" + }, + "name": "ShareDataRow" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/document-list/data/share-datatable-adapter.ts" + }, + "name": "ShareDataTableAdapter" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/services/shared-links-api.service.ts" + }, + "name": "SharedLinksApiService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/sidebar/sidebar-action-menu.component.ts" + }, + "name": "SidebarActionMenuComponent" + }, + { + "position": { + "line": 155, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "SideBarActionModule" + }, + { + "position": { + "line": 218, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "SideBarActionModule" + }, + { + "position": { + "line": 43, + "character": 0, + "fileName": "lib/core/sidebar/sidebar-action-menu.component.ts" + }, + "name": "SidebarMenuDirective" + }, + { + "position": { + "line": 45, + "character": 0, + "fileName": "lib/core/sidebar/sidebar-action-menu.component.ts" + }, + "name": "SidebarMenuExpandIconDirective" + }, + { + "position": { + "line": 44, + "character": 0, + "fileName": "lib/core/sidebar/sidebar-action-menu.component.ts" + }, + "name": "SidebarMenuTitleIconDirective" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/site-dropdown/sites-dropdown.module.ts" + }, + "name": "SitesDropdownModule" + }, + { + "position": { + "line": 81, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "SitesDropdownModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/services/sites.service.ts" + }, + "name": "SitesService" + }, + { + "position": { + "line": 75, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "SocialModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/social/social.module.ts" + }, + "name": "SocialModule" + }, + { + "position": { + "line": 41, + "character": 0, + "fileName": "lib/core/form/components/start-form.component.ts" + }, + "name": "StartFormComponent" + }, + { + "position": { + "line": 90, + "character": 8, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "StartFormComponent" + }, + { + "position": { + "line": 91, + "character": 8, + "fileName": "lib/core/form/form.module.ts" + }, + "name": "StartFormCustomButtonDirective" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/process-services/process-list/components/start-process.component.ts" + }, + "name": "StartProcessInstanceComponent" + }, + { + "position": { + "line": 82, + "character": 8, + "fileName": "lib/process-services/process-list/process-list.module.ts" + }, + "name": "StartProcessInstanceComponent" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/process-services/task-list/components/start-task.component.ts" + }, + "name": "StartTaskComponent" + }, + { + "position": { + "line": 87, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "StartTaskComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/task-list/models/start-task.model.ts" + }, + "name": "StartTaskModel" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/services/storage.service.ts" + }, + "name": "StorageService" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/insights/diagram/models/chart/tableChart.model.ts" + }, + "name": "TableChart" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/core/tab.model.ts" + }, + "name": "TabModel" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/form/components/widgets/tabs/tabs.widget.ts" + }, + "name": "TabsWidgetComponent" + }, + { + "position": { + "line": 37, + "character": 8, + "fileName": "lib/content-services/tag/tag.module.ts" + }, + "name": "TagActionsComponent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/content-services/tag/tag-actions.component.ts" + }, + "name": "TagActionsComponent" + }, + { + "position": { + "line": 38, + "character": 8, + "fileName": "lib/content-services/tag/tag.module.ts" + }, + "name": "TagListComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/tag/tag-list.component.ts" + }, + "name": "TagListComponent" + }, + { + "position": { + "line": 28, + "character": 0, + "fileName": "lib/content-services/tag/tag.module.ts" + }, + "name": "TagModule" + }, + { + "position": { + "line": 76, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "TagModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/tag/tag-node-list.component.ts" + }, + "name": "TagNodeListComponent" + }, + { + "position": { + "line": 39, + "character": 8, + "fileName": "lib/content-services/tag/tag.module.ts" + }, + "name": "TagNodeListComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/content-services/tag/services/tag.service.ts" + }, + "name": "TagService" + }, + { + "position": { + "line": 45, + "character": 8, + "fileName": "lib/process-services/attachment/attachment.module.ts" + }, + "name": "TaskAttachmentListComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/process-services/attachment/task-attachment-list.component.ts" + }, + "name": "TaskAttachmentListComponent" + }, + { + "position": { + "line": 84, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "TaskAuditDirective" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/process-services/task-list/components/task-audit.directive.ts" + }, + "name": "TaskAuditDirective" + }, + { + "position": { + "line": 83, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "TaskDetailsComponent" + }, + { + "position": { + "line": 47, + "character": 0, + "fileName": "lib/process-services/task-list/components/task-details.component.ts" + }, + "name": "TaskDetailsComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/process-services/task-list/models/task-details.event.ts" + }, + "name": "TaskDetailsEvent" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/process-services/task-list/models/task-details.model.ts" + }, + "name": "TaskDetailsModel" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/process-services/task-list/components/task-filters.component.ts" + }, + "name": "TaskFiltersComponent" + }, + { + "position": { + "line": 81, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "TaskFiltersComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/process-services/task-list/services/task-filter.service.ts" + }, + "name": "TaskFilterService" + }, + { + "position": { + "line": 86, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "TaskHeaderComponent" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/process-services/task-list/components/task-header.component.ts" + }, + "name": "TaskHeaderComponent" + }, + { + "position": { + "line": 53, + "character": 0, + "fileName": "lib/process-services/task-list/components/task-list.component.ts" + }, + "name": "TaskListComponent" + }, + { + "position": { + "line": 82, + "character": 8, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "TaskListComponent" + }, + { + "position": { + "line": 61, + "character": 8, + "fileName": "lib/process-services/process.module.ts" + }, + "name": "TaskListModule" + }, + { + "position": { + "line": 44, + "character": 0, + "fileName": "lib/process-services/task-list/task-list.module.ts" + }, + "name": "TaskListModule" + }, + { + "position": { + "line": 30, + "character": 0, + "fileName": "lib/process-services/task-list/services/tasklist.service.ts" + }, + "name": "TaskListService" + }, + { + "position": { + "line": 109, + "character": 0, + "fileName": "lib/process-services/task-list/models/filter.model.ts" + }, + "name": "TaskQueryRequestRepresentationModel" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/process-services/task-list/services/task-upload.service.ts" + }, + "name": "TaskUploadService" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/form/components/widgets/dynamic-table/editors/text/text.editor.ts" + }, + "name": "TextEditorComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/text/text.widget.ts" + }, + "name": "TextWidgetComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/services/thumbnail.service.ts" + }, + "name": "ThumbnailService" + }, + { + "position": { + "line": 50, + "character": 8, + "fileName": "lib/core/pipes/pipe.module.ts" + }, + "name": "TimeAgoPipe" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/core/pipes/time-ago.pipe.ts" + }, + "name": "TimeAgoPipe" + }, + { + "position": { + "line": 36, + "character": 8, + "fileName": "lib/core/toolbar/toolbar.module.ts" + }, + "name": "ToolbarComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/toolbar/toolbar.component.ts" + }, + "name": "ToolbarComponent" + }, + { + "position": { + "line": 38, + "character": 8, + "fileName": "lib/core/toolbar/toolbar.module.ts" + }, + "name": "ToolbarDividerComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/toolbar/toolbar-divider.component.ts" + }, + "name": "ToolbarDividerComponent" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/toolbar/toolbar.module.ts" + }, + "name": "ToolbarModule" + }, + { + "position": { + "line": 230, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ToolbarModule" + }, + { + "position": { + "line": 167, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ToolbarModule" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/toolbar/toolbar-title.component.ts" + }, + "name": "ToolbarTitleComponent" + }, + { + "position": { + "line": 37, + "character": 8, + "fileName": "lib/core/toolbar/toolbar.module.ts" + }, + "name": "ToolbarTitleComponent" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/services/translate-loader.service.ts" + }, + "name": "TranslateLoaderService" + }, + { + "position": { + "line": 240, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "TranslateModule" + }, + { + "position": { + "line": 177, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "TranslateModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/core/mock/traslation.service.mock.ts" + }, + "name": "TranslationMock" + }, + { + "position": { + "line": 38, + "character": 0, + "fileName": "lib/core/services/translation.service.ts" + }, + "name": "TranslationService" + }, + { + "position": { + "line": 68, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "TxtViewerComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/viewer/components/txtViewer.component.ts" + }, + "name": "TxtViewerComponent" + }, + { + "position": { + "line": 26, + "character": 0, + "fileName": "lib/core/form/components/widgets/typeahead/typeahead.widget.ts" + }, + "name": "TypeaheadWidgetComponent" + }, + { + "position": { + "line": 74, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "UnknownFormatComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/viewer/components/unknown-format/unknown-format.component.ts" + }, + "name": "UnknownFormatComponent" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/form/components/widgets/unknown/unknown.widget.ts" + }, + "name": "UnknownWidgetComponent" + }, + { + "position": { + "line": 44, + "character": 0, + "fileName": "lib/content-services/upload/components/upload-button.component.ts" + }, + "name": "UploadButtonComponent" + }, + { + "position": { + "line": 49, + "character": 8, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "UploadButtonComponent" + }, + { + "position": { + "line": 22, + "character": 0, + "fileName": "lib/core/directives/upload.directive.ts" + }, + "name": "UploadDirective" + }, + { + "position": { + "line": 50, + "character": 8, + "fileName": "lib/core/directives/directive.module.ts" + }, + "name": "UploadDirective" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/content-services/upload/components/upload-drag-area.component.ts" + }, + "name": "UploadDragAreaComponent" + }, + { + "position": { + "line": 48, + "character": 8, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "UploadDragAreaComponent" + }, + { + "position": { + "line": 31, + "character": 0, + "fileName": "lib/content-services/upload/upload.module.ts" + }, + "name": "UploadModule" + }, + { + "position": { + "line": 79, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "UploadModule" + }, + { + "position": { + "line": 32, + "character": 0, + "fileName": "lib/core/services/upload.service.ts" + }, + "name": "UploadService" + }, + { + "position": { + "line": 29, + "character": 0, + "fileName": "lib/core/form/components/widgets/upload/upload.widget.ts" + }, + "name": "UploadWidgetComponent" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/process-services/task-list/models/user-event.model.ts" + }, + "name": "UserEventModel" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/process-services/task-list/models/user-group.model.ts" + }, + "name": "UserGroupModel" + }, + { + "position": { + "line": 58, + "character": 0, + "fileName": "lib/content-services/document-list/models/document-library.model.ts" + }, + "name": "UserInfo" + }, + { + "position": { + "line": 24, + "character": 0, + "fileName": "lib/core/userinfo/components/user-info.component.ts" + }, + "name": "UserInfoComponent" + }, + { + "position": { + "line": 42, + "character": 8, + "fileName": "lib/core/userinfo/userinfo.module.ts" + }, + "name": "UserInfoComponent" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/core/userinfo/userinfo.module.ts" + }, + "name": "UserInfoModule" + }, + { + "position": { + "line": 226, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "UserInfoModule" + }, + { + "position": { + "line": 163, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "UserInfoModule" + }, + { + "position": { + "line": 33, + "character": 0, + "fileName": "lib/core/services/user-preferences.service.ts" + }, + "name": "UserPreferencesService" + }, + { + "position": { + "line": 23, + "character": 0, + "fileName": "lib/core/models/user-process.model.ts" + }, + "name": "UserProcessModel" + }, + { + "position": { + "line": 22, + "character": 9, + "fileName": "lib/core/form/events/index.ts" + }, + "name": "ValidateDynamicTableRowEvent" + }, + { + "position": { + "line": 21, + "character": 9, + "fileName": "lib/core/form/events/index.ts" + }, + "name": "ValidateFormEvent" + }, + { + "position": { + "line": 20, + "character": 9, + "fileName": "lib/core/form/events/index.ts" + }, + "name": "ValidateFormFieldEvent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/content-services/version-manager/version-list.component.ts" + }, + "name": "VersionListComponent" + }, + { + "position": { + "line": 37, + "character": 8, + "fileName": "lib/content-services/version-manager/version-manager.module.ts" + }, + "name": "VersionListComponent" + }, + { + "position": { + "line": 36, + "character": 8, + "fileName": "lib/content-services/version-manager/version-manager.module.ts" + }, + "name": "VersionManagerComponent" + }, + { + "position": { + "line": 21, + "character": 0, + "fileName": "lib/content-services/version-manager/version-manager.component.ts" + }, + "name": "VersionManagerComponent" + }, + { + "position": { + "line": 83, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "VersionManagerModule" + }, + { + "position": { + "line": 27, + "character": 0, + "fileName": "lib/content-services/version-manager/version-manager.module.ts" + }, + "name": "VersionManagerModule" + }, + { + "position": { + "line": 58, + "character": 0, + "fileName": "lib/core/models/product-version.model.ts" + }, + "name": "VersionModel" + }, + { + "position": { + "line": 118, + "character": 0, + "fileName": "lib/core/models/product-version.model.ts" + }, + "name": "VersionModuleModel" + }, + { + "position": { + "line": 102, + "character": 0, + "fileName": "lib/core/models/product-version.model.ts" + }, + "name": "VersionStatusModel" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/content-services/version-manager/version-upload.component.ts" + }, + "name": "VersionUploadComponent" + }, + { + "position": { + "line": 35, + "character": 8, + "fileName": "lib/content-services/version-manager/version-manager.module.ts" + }, + "name": "VersionUploadComponent" + }, + { + "position": { + "line": 32, + "character": 0, + "fileName": "lib/core/viewer/components/viewer.component.ts" + }, + "name": "ViewerComponent" + }, + { + "position": { + "line": 66, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerComponent" + }, + { + "position": { + "line": 73, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerExtensionDirective" + }, + { + "position": { + "line": 20, + "character": 0, + "fileName": "lib/core/viewer/directives/viewer-extension.directive.ts" + }, + "name": "ViewerExtensionDirective" + }, + { + "position": { + "line": 40, + "character": 0, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerModule" + }, + { + "position": { + "line": 217, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ViewerModule" + }, + { + "position": { + "line": 154, + "character": 8, + "fileName": "lib/core/core.module.ts" + }, + "name": "ViewerModule" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/viewer/components/viewer-more-actions.component.ts" + }, + "name": "ViewerMoreActionsComponent" + }, + { + "position": { + "line": 78, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerMoreActionsComponent" + }, + { + "position": { + "line": 77, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerOpenWithComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/viewer/components/viewer-open-with.component.ts" + }, + "name": "ViewerOpenWithComponent" + }, + { + "position": { + "line": 76, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerSidebarComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/viewer/components/viewer-sidebar.component.ts" + }, + "name": "ViewerSidebarComponent" + }, + { + "position": { + "line": 79, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerToolbarActionsComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/viewer/components/viewer-toolbar-actions.component.ts" + }, + "name": "ViewerToolbarActionsComponent" + }, + { + "position": { + "line": 19, + "character": 0, + "fileName": "lib/core/viewer/components/viewer-toolbar.component.ts" + }, + "name": "ViewerToolbarComponent" + }, + { + "position": { + "line": 75, + "character": 8, + "fileName": "lib/core/viewer/viewer.module.ts" + }, + "name": "ViewerToolbarComponent" + }, + { + "position": { + "line": 41, + "character": 0, + "fileName": "lib/content-services/webscript/webscript.component.ts" + }, + "name": "WebscriptComponent" + }, + { + "position": { + "line": 34, + "character": 8, + "fileName": "lib/content-services/webscript/webscript.module.ts" + }, + "name": "WebscriptComponent" + }, + { + "position": { + "line": 77, + "character": 8, + "fileName": "lib/content-services/content.module.ts" + }, + "name": "WebScriptModule" + }, + { + "position": { + "line": 25, + "character": 0, + "fileName": "lib/content-services/webscript/webscript.module.ts" + }, + "name": "WebScriptModule" + }, + { + "position": { + "line": 38, + "character": 0, + "fileName": "lib/core/form/components/widgets/widget.component.ts" + }, + "name": "WidgetComponent" + } +] \ No newline at end of file diff --git a/lib/config/export-check/export-check-config.json b/lib/config/export-check/export-check-config.json index 191cfec510..ba0cb48d26 100644 --- a/lib/config/export-check/export-check-config.json +++ b/lib/config/export-check/export-check-config.json @@ -2,6 +2,7 @@ "export-last-version": "export-new.json", "export-versions": [ "export-2.0.0.json", - "export-2.1.0.json" + "export-2.1.0.json", + "export-2.2.0.json" ] } diff --git a/lib/package.json b/lib/package.json index 30a747111c..e2abe24322 100644 --- a/lib/package.json +++ b/lib/package.json @@ -95,6 +95,7 @@ "angular2-template-loader": "0.6.2", "autoprefixer": "6.5.4", "bundlesize": "^0.15.3", + "chalk": "^2.3.2", "codelyzer": "4.0.0", "copy-webpack-plugin": "4.0.1", "css-loader": "0.25.0", From 0f64af39d9cd1f6c6653ac8f57b2309dd86ddd39 Mon Sep 17 00:00:00 2001 From: Vito Date: Tue, 6 Mar 2018 15:54:44 +0000 Subject: [PATCH 016/188] [ADF-645] added claim and unclaim event for task details action (#3038) * [ADF-645] added claim and unclaim event for task details action * [ADF-645] added new events to documentation --- docs/task-details.component.md | 2 ++ .../components/task-details.component.html | 2 +- .../components/task-details.component.spec.ts | 14 ++++++++++++++ .../task-list/components/task-details.component.ts | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/task-details.component.md b/docs/task-details.component.md index b1d7596e62..0d822b52b7 100644 --- a/docs/task-details.component.md +++ b/docs/task-details.component.md @@ -46,6 +46,8 @@ Shows the details of the task id passed in input | error | `EventEmitter` | Emitted when an error occurs. | | executeOutcome | `EventEmitter` | Emitted when any outcome is executed. Default behaviour can be prevented via `event.preventDefault()`. | | assignTask | `EventEmitter` | Emitted when a task is assigned. | +| claimedTask | `EventEmitter` | Emitted when a task is claimed. | +| unClaimedTask | `EventEmitter` | Emitted when a task is unclaimed. | ## Details diff --git a/lib/process-services/task-list/components/task-details.component.html b/lib/process-services/task-list/components/task-details.component.html index fbb59c934a..d91272b024 100644 --- a/lib/process-services/task-list/components/task-details.component.html +++ b/lib/process-services/task-list/components/task-details.component.html @@ -69,7 +69,7 @@ [taskDetails]="taskDetails" [formName]="taskFormName" (claim)="onClaimAction($event)" - (unclaim)="onClaimAction($event)"> + (unclaim)="onUnclaimAction($event)"> { expect(getTaskDetailsSpy).not.toHaveBeenCalled(); }); + it('should send a claim task event when a task is claimed', async(() => { + component.claimedTask.subscribe((taskId) => { + expect(taskId).toBe('FAKE-TASK-CLAIM'); + }); + component.onClaimAction('FAKE-TASK-CLAIM'); + })); + + it('should send a unclaim task event when a task is unclaimed', async(() => { + component.claimedTask.subscribe((taskId) => { + expect(taskId).toBe('FAKE-TASK-UNCLAIM'); + }); + component.onUnclaimAction('FAKE-TASK-UNCLAIM'); + })); + it('should set a placeholder message when taskId not initialised', () => { fixture.detectChanges(); expect(fixture.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.MESSAGES.NONE'); diff --git a/lib/process-services/task-list/components/task-details.component.ts b/lib/process-services/task-list/components/task-details.component.ts index b1ed92a6e7..46aa58ccd0 100644 --- a/lib/process-services/task-list/components/task-details.component.ts +++ b/lib/process-services/task-list/components/task-details.component.ts @@ -160,6 +160,14 @@ export class TaskDetailsComponent implements OnInit, OnChanges { @Output() assignTask: EventEmitter = new EventEmitter(); + /** Emitted when a task is claimed. */ + @Output() + claimedTask: EventEmitter = new EventEmitter(); + + /** Emitted when a task is unclaimed. */ + @Output() + unClaimedTask: EventEmitter = new EventEmitter(); + taskDetails: TaskDetailsModel; taskFormName: string = null; @@ -375,6 +383,12 @@ export class TaskDetailsComponent implements OnInit, OnChanges { } onClaimAction(taskId: string): void { + this.claimedTask.emit(taskId); + this.loadDetails(taskId); + } + + onUnclaimAction(taskId: string): void { + this.unClaimedTask.emit(taskId); this.loadDetails(taskId); } From 52df355e9067940e9c73ec81ba28ffa9fbbad636 Mon Sep 17 00:00:00 2001 From: Vito Date: Tue, 6 Mar 2018 16:28:30 +0000 Subject: [PATCH 017/188] [ADF-2373] added filtering for membership on site dropdown (#3031) * [ADF-2373] added filtering for membership on site dropdown * [ADF-2373] added test for new site service method * [ADF-2373] added filtering for site membering to the sites dropdown * [ADF-2373] added another check into sites tests * [ADF-2373] added a fix for the site dropdown tests * [ADF-2373] fixed broken test check * [ADF-2373] added PR review changes --- .../app/components/files/files.component.html | 2 +- docs/sites-dropdown.component.md | 1 + .../sites-dropdown.component.spec.ts | 168 +++++++++++++++++- .../site-dropdown/sites-dropdown.component.ts | 56 ++++-- .../version-manager.component.ts | 1 - .../version-upload.component.ts | 1 - lib/core/services/sites.service.ts | 4 + 7 files changed, 213 insertions(+), 20 deletions(-) diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index 459ec8b8da..2cc49fea9a 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -29,7 +29,7 @@
- +
diff --git a/docs/sites-dropdown.component.md b/docs/sites-dropdown.component.md index 2c57598042..103c3f7dc8 100644 --- a/docs/sites-dropdown.component.md +++ b/docs/sites-dropdown.component.md @@ -24,6 +24,7 @@ Displays a dropdown menu to show and interact with the sites of the current user | siteList | [SitePaging](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/SitePaging.md) | null | A custom list of sites to be displayed by the dropdown. If no value is given, the sites of the current user are displayed by default. A list of objects only with properties 'title' and 'guid' is enough to be able to display the dropdown. | | placeholder | string | 'DROPDOWN.PLACEHOLDER_LABEL' | The placeholder text/the key from translation files for the placeholder text to be shown by default | | value | string | null | Id of the select site | +| relations | string | null | This parameter will allow to perform sites query filtering the results.It could have two possible values: **members** and **containers**. When **members** is used the site list will be filtered with only the sites where the user is a member of. | ### Events diff --git a/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts b/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts index d1a6758611..c1cf5dc65e 100644 --- a/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts +++ b/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts @@ -18,7 +18,9 @@ import { DebugElement } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { DropdownSitesComponent } from './sites-dropdown.component'; +import { DropdownSitesComponent, Relations } from './sites-dropdown.component'; +import { SitesService, LogService } from '@alfresco/adf-core'; +import { Observable } from 'rxjs/Observable'; declare let jasmine: any; @@ -29,13 +31,16 @@ describe('DropdownSitesComponent', () => { let debug: DebugElement; let element: HTMLElement; let sitesList: any; + let siteListWitMembers: any; + let siteService: SitesService; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ DropdownSitesComponent - ] + ], + providers: [SitesService, LogService] }).compileComponents(); })); @@ -44,6 +49,7 @@ describe('DropdownSitesComponent', () => { debug = fixture.debugElement; element = fixture.nativeElement; component = fixture.componentInstance; + siteService = TestBed.get(SitesService); sitesList = { 'list': { @@ -80,6 +86,126 @@ describe('DropdownSitesComponent', () => { ] } }; + + siteListWitMembers = { + 'list': { + 'entries': [{ + 'entry': { + 'visibility': 'MODERATED', + 'guid': 'b4cff62a-664d-4d45-9302-98723eac1319', + 'description': 'This is a Sample Alfresco Team site.', + 'id': 'MODERATED-SITE', + 'preset': 'site-dashboard', + 'title': 'FAKE-MODERATED-SITE' + }, + 'relations': { + 'members': { + 'list': { + 'pagination': { + 'count': 3, + 'hasMoreItems': false, + 'skipCount': 0, + 'maxItems': 100 + }, + 'entries': [ + { + 'entry': { + 'role': 'SiteManager', + 'person': { + 'firstName': 'Administrator', + 'emailNotificationsEnabled': true, + 'company': {}, + 'id': 'admin', + 'enabled': true, + 'email': 'admin@alfresco.com' + }, + 'id': 'admin' + } + }, + { + 'entry': { + 'role': 'SiteCollaborator', + 'person': { + 'lastName': 'Beecher', + 'userStatus': 'Helping to design the look and feel of the new web site', + 'jobTitle': 'Graphic Designer', + 'statusUpdatedAt': '2011-02-15T20:20:13.432+0000', + 'mobile': '0112211001100', + 'emailNotificationsEnabled': true, + 'description': 'Alice is a demo user for the sample Alfresco Team site.', + 'telephone': '0112211001100', + 'enabled': false, + 'firstName': 'Alice', + 'skypeId': 'abeecher', + 'avatarId': '198500fc-1e99-4f5f-8926-248cea433366', + 'location': 'Tilbury, UK', + 'company': { + 'organization': 'Moresby, Garland and Wedge', + 'address1': '200 Butterwick Street', + 'address2': 'Tilbury', + 'address3': 'UK', + 'postcode': 'ALF1 SAM1' + }, + 'id': 'abeecher', + 'email': 'abeecher@example.com' + }, + 'id': 'abeecher' + } + } + ] + } + } + } + }, { + 'entry': { + 'visibility': 'PUBLIC', + 'guid': 'b4cff62a-664d-4d45-9302-98723eac1319', + 'description': 'This is a Sample Alfresco Team site.', + 'id': 'PUBLIC-SITE', + 'preset': 'site-dashboard', + 'title': 'FAKE-SITE-PUBLIC' + } + }, { + 'entry': { + 'visibility': 'PRIVATE', + 'guid': 'b4cff62a-664d-4d45-9302-98723eac1319', + 'description': 'This is a Sample Alfresco Team site.', + 'id': 'MEMBER-SITE', + 'preset': 'site-dashboard', + 'title': 'FAKE-PRIVATE-SITE-MEMBER' + }, + 'relations': { + 'members': { + 'list': { + 'pagination': { + 'count': 3, + 'hasMoreItems': false, + 'skipCount': 0, + 'maxItems': 100 + }, + 'entries': [ + { + 'entry': { + 'role': 'SiteManager', + 'person': { + 'firstName': 'Administrator', + 'emailNotificationsEnabled': true, + 'company': {}, + 'id': 'admin', + 'enabled': true, + 'email': 'admin@alfresco.com' + }, + 'id': 'test' + } + } + ] + } + } + } + } + ] + } + }; }); describe('Rendering tests', () => { @@ -280,5 +406,43 @@ describe('DropdownSitesComponent', () => { }); }); + it('should show only sites which logged user is member of when member relation is set', async(() => { + spyOn(siteService, 'getEcmCurrentLoggedUserName').and.returnValue('test'); + spyOn(siteService, 'getSites').and.returnValue(Observable.of(siteListWitMembers)); + component.relations = Relations.Members; + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let options: any = debug.queryAll(By.css('mat-option')); + expect(options[1].nativeElement.innerText).toContain('FAKE-SITE-PUBLIC'); + expect(options[2].nativeElement.innerText).toContain('FAKE-PRIVATE-SITE-MEMBER'); + expect(options[3]).toBeUndefined(); + }); + }); + })); + + it('should show all the sites if no relation is set', async(() => { + spyOn(siteService, 'getEcmCurrentLoggedUserName').and.returnValue('test'); + spyOn(siteService, 'getSites').and.returnValue(Observable.of(siteListWitMembers)); + component.siteList = null; + component.relations = null; + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let options: any = debug.queryAll(By.css('mat-option')); + expect(options[1].nativeElement.innerText).toContain('FAKE-MODERATED-SITE'); + expect(options[2].nativeElement.innerText).toContain('FAKE-SITE-PUBLIC'); + expect(options[3].nativeElement.innerText).toContain('FAKE-PRIVATE-SITE-MEMBER'); + }); + }); + })); + }); }); diff --git a/lib/content-services/site-dropdown/sites-dropdown.component.ts b/lib/content-services/site-dropdown/sites-dropdown.component.ts index e57964c7da..e5052eb42e 100644 --- a/lib/content-services/site-dropdown/sites-dropdown.component.ts +++ b/lib/content-services/site-dropdown/sites-dropdown.component.ts @@ -16,9 +16,14 @@ */ import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; -import { SitesService } from '@alfresco/adf-core'; +import { SitesService, LogService } from '@alfresco/adf-core'; import { SitePaging, SiteEntry } from 'alfresco-js-api'; +export enum Relations { + Members = 'members', + Containers = 'containers' +} + @Component({ selector: 'adf-sites-dropdown', styleUrls: ['./sites-dropdown.component.scss'], @@ -48,6 +53,9 @@ export class DropdownSitesComponent implements OnInit { @Input() placeholder: string = 'DROPDOWN.PLACEHOLDER_LABEL'; + @Input() + relations: string; + /** Emitted when the user selects a site. When the default option is selected, * an empty model is emitted. */ @@ -58,14 +66,14 @@ export class DropdownSitesComponent implements OnInit { public MY_FILES_VALUE = '-my-'; - constructor(private sitesService: SitesService) { + constructor(private sitesService: SitesService, + private logService: LogService) { } ngOnInit() { if (!this.siteList) { this.setDefaultSiteList(); } - } selectedSite(event: any) { @@ -73,24 +81,42 @@ export class DropdownSitesComponent implements OnInit { } private setDefaultSiteList() { - this.sitesService.getSites().subscribe((result) => { - this.siteList = result; + let extendedOptions = null; + if (this.relations) { + extendedOptions = { relations: [this.relations] }; + } + this.sitesService.getSites(extendedOptions).subscribe((result) => { - if (!this.hideMyFiles) { - let myItem = { entry: { id: '-my-', guid: '-my-', title: 'DROPDOWN.MY_FILES_OPTION' } }; + this.siteList = this.relations === Relations.Members ? this.filteredResultsByMember(result) : result; - this.siteList.list.entries.unshift(myItem); + if (!this.hideMyFiles) { + let myItem = { entry: { id: '-my-', guid: '-my-', title: 'DROPDOWN.MY_FILES_OPTION' } }; - if (!this.value) { - this.value = '-my-'; - } + this.siteList.list.entries.unshift(myItem); + + if (!this.value) { + this.value = '-my-'; } + } - this.selected = this.siteList.list.entries.find(site => site.entry.id === this.value); - }, - (error) => { + this.selected = this.siteList.list.entries.find(site => site.entry.id === this.value); + }, + (error) => { + this.logService.error(error); + }); + } + + private filteredResultsByMember(sites: SitePaging): SitePaging { + const loggedUserName = this.sitesService.getEcmCurrentLoggedUserName(); + sites.list.entries = sites.list.entries.filter( (site) => this.isCurrentUserMember(site, loggedUserName)); + return sites; + } + + private isCurrentUserMember(site, loggedUserName): boolean { + return site.entry.visibility === 'PUBLIC' || + !!site.relations.members.list.entries.find((member) => { + return member.entry.id === loggedUserName; }); - } } diff --git a/lib/content-services/version-manager/version-manager.component.ts b/lib/content-services/version-manager/version-manager.component.ts index 5a29e2fd33..85e6868cbe 100644 --- a/lib/content-services/version-manager/version-manager.component.ts +++ b/lib/content-services/version-manager/version-manager.component.ts @@ -48,4 +48,3 @@ export class VersionManagerComponent { this.uploadError.emit(event); } } - diff --git a/lib/content-services/version-manager/version-upload.component.ts b/lib/content-services/version-manager/version-upload.component.ts index 0538382e35..58e01d0da9 100644 --- a/lib/content-services/version-manager/version-upload.component.ts +++ b/lib/content-services/version-manager/version-upload.component.ts @@ -46,4 +46,3 @@ export class VersionUploadComponent { } } - diff --git a/lib/core/services/sites.service.ts b/lib/core/services/sites.service.ts index 071a5e5437..feaa6b3db6 100644 --- a/lib/core/services/sites.service.ts +++ b/lib/core/services/sites.service.ts @@ -81,6 +81,10 @@ export class SitesService { return this.getSite(siteId, { relations: ['members'] }); } + getEcmCurrentLoggedUserName(): string { + return this.apiService.getInstance().ecmAuth.username; + } + private handleError(error: Response): any { console.error(error); return Observable.throw(error || 'Server error'); From e37eb3c7cbf94c46b67b6dcc8ed2ae377a881af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Popovics=20Andr=C3=A1s?= Date: Tue, 6 Mar 2018 22:56:28 +0100 Subject: [PATCH 018/188] Fix mobile styles (#3040) --- demo-shell/src/app/app.component.scss | 15 +++++++++++++++ .../src/app/components/files/files.component.scss | 8 ++++++++ 2 files changed, 23 insertions(+) diff --git a/demo-shell/src/app/app.component.scss b/demo-shell/src/app/app.component.scss index b554b878f8..f46c8c01f6 100644 --- a/demo-shell/src/app/app.component.scss +++ b/demo-shell/src/app/app.component.scss @@ -33,3 +33,18 @@ width: 52px; } } + +@media (max-width: 425px) { + adf-content-node-selector { + .adf-content-node-selector-content-list { + .adf-data-table-cell { + display: none; + } + + .adf-data-table-cell:first-child, + .adf-data-table-cell:nth-child(2) { + display: table-cell; + } + } + } +} diff --git a/demo-shell/src/app/components/files/files.component.scss b/demo-shell/src/app/components/files/files.component.scss index 198feeded8..8438978db8 100644 --- a/demo-shell/src/app/components/files/files.component.scss +++ b/demo-shell/src/app/components/files/files.component.scss @@ -146,4 +146,12 @@ adf-document-list ::ng-deep .adf-datatable-selected > svg { width: 100%; } } + + file-uploading-dialog ::ng-deep .upload-dialog { + width: 80%; + + & ::ng-deep adf-file-uploading-list ::ng-deep adf-file-uploading-list-row .adf-file-uploading-row__group { + min-width: 0; + } + } } From 4b9daeb1c82429e9d61e420158137be52d408946 Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Tue, 6 Mar 2018 22:01:22 +0000 Subject: [PATCH 019/188] [ADF-2447] Added review checker tool (#3039) --- lib/config/DocProcessor/ReviewCheckerGuide.md | 27 ++++ lib/config/DocProcessor/commitStoplist.json | 1 + lib/config/DocProcessor/libsearch.js | 31 ++++ lib/config/DocProcessor/reviewChecker.js | 95 +++++++++++ lib/config/DocProcessor/reviewChecker.ts | 152 ++++++++++++++++++ lib/config/DocProcessor/stoplist.js | 29 ++++ lib/config/DocProcessor/stoplist.ts | 31 ++++ lib/config/DocProcessor/tools/index.js | 27 +--- 8 files changed, 367 insertions(+), 26 deletions(-) create mode 100644 lib/config/DocProcessor/ReviewCheckerGuide.md create mode 100644 lib/config/DocProcessor/commitStoplist.json create mode 100644 lib/config/DocProcessor/libsearch.js create mode 100644 lib/config/DocProcessor/reviewChecker.js create mode 100644 lib/config/DocProcessor/reviewChecker.ts create mode 100644 lib/config/DocProcessor/stoplist.js create mode 100644 lib/config/DocProcessor/stoplist.ts diff --git a/lib/config/DocProcessor/ReviewCheckerGuide.md b/lib/config/DocProcessor/ReviewCheckerGuide.md new file mode 100644 index 0000000000..ba890ece76 --- /dev/null +++ b/lib/config/DocProcessor/ReviewCheckerGuide.md @@ -0,0 +1,27 @@ +# Review checker guide + +The review checker tool queries the Github repo to look for recent +commits to the component source files. The dates of these commits +are compared against against a review date stored in the Markdown doc +file for each component. The time and the number of commits since the +last review are then combined into a "score" that gives an indication +of how urgently the doc file needs a review. + +## Review date metadata + +The review date is kept in the YAML metadata section at the top of each +Markdown file. The key is "Last reviewed" and the date is in the form +YYYY-MM-DD. + +## Commit message stoplist + +The checker will ignore any commits that match regular expressions stored +in the `commitStoplist.json` file in the `DocProcessor` folder. You could +use this, for example, to filter out JIRA tasks that don't involve any +changes in functionality (and therefore don't need documenting). + +## Output format + +The script sends comma-separated text to the command line. You can copy/paste +this into a spreadsheet or redirect the output to a text file with a ".csv" +suffix. \ No newline at end of file diff --git a/lib/config/DocProcessor/commitStoplist.json b/lib/config/DocProcessor/commitStoplist.json new file mode 100644 index 0000000000..cd9793875a --- /dev/null +++ b/lib/config/DocProcessor/commitStoplist.json @@ -0,0 +1 @@ +["ADF-1769"] \ No newline at end of file diff --git a/lib/config/DocProcessor/libsearch.js b/lib/config/DocProcessor/libsearch.js new file mode 100644 index 0000000000..ba6c63a5db --- /dev/null +++ b/lib/config/DocProcessor/libsearch.js @@ -0,0 +1,31 @@ +var fs = require("fs"); +var path = require("path"); + +module.exports = searchLibraryRecursive; + +var angFilenameRegex = /([a-zA-Z0-9\-]+)\.((component)|(directive)|(model)|(pipe)|(service)|(widget))\.ts/; +var searchFolderOmitRegex = /(config)|(mock)|(i18n)|(assets)|(styles)/; + +// Search source folders for .ts files to discover all components, directives, etc. +function searchLibraryRecursive(srcData, folderPath) { + var items = fs.readdirSync(folderPath); + + for (var i = 0; i < items.length; i++) { + var itemPath = path.resolve(folderPath, items[i]); + var info = fs.statSync(itemPath); + + if (info.isFile() && (items[i].match(angFilenameRegex))) { + var nameNoSuffix = path.basename(items[i], '.ts'); + + var displayPath = itemPath.replace(/\\/g, '/'); + displayPath = displayPath.substr(displayPath.indexOf("lib") + 4); + + // Type == "component", "directive", etc. + var itemType = nameNoSuffix.split('.')[1]; + + srcData[nameNoSuffix] = { "path": displayPath, "type": itemType }; + } else if (info.isDirectory() && !items[i].match(searchFolderOmitRegex)) { + searchLibraryRecursive(srcData, itemPath); + } + } +} \ No newline at end of file diff --git a/lib/config/DocProcessor/reviewChecker.js b/lib/config/DocProcessor/reviewChecker.js new file mode 100644 index 0000000000..028ee3f15a --- /dev/null +++ b/lib/config/DocProcessor/reviewChecker.js @@ -0,0 +1,95 @@ +"use strict"; +exports.__esModule = true; +var path = require("path"); +var fs = require("fs"); +var process = require("process"); +var graphql_request_1 = require("graphql-request"); +var remark = require("remark"); +var frontMatter = require("remark-frontmatter"); +var yaml = require("js-yaml"); +var moment = require("moment"); +var Rx_1 = require("rxjs/Rx"); +var libsearch = require("./libsearch"); +var stoplist_1 = require("./stoplist"); +var adf20StartDate = "2017-11-20"; +var commitWeight = 0.1; +var scoreTimeBase = 60; +var rootFolder = "."; +var stoplistFilePath = path.resolve("config", "DocProcessor", "commitStoplist.json"); +var angFilePattern = /(component)|(directive)|(model)|(pipe)|(service)|(widget)/; +var srcData = {}; +var stoplist = new stoplist_1.Stoplist(stoplistFilePath); +var docsFolderPath = path.resolve("..", "docs"); +libsearch(srcData, path.resolve(rootFolder)); +/* +let keys = Object.keys(srcData); + +for (let i = 0; i < keys.length; i++) { + console.log(keys[i]); +} +*/ +var authToken = process.env.graphAuthToken; +var client = new graphql_request_1.GraphQLClient('https://api.github.com/graphql', { + headers: { + Authorization: 'Bearer ' + authToken + } +}); +var query = "query commitHistory($path: String) {\n repository(name: \"alfresco-ng2-components\", owner: \"alfresco\") {\n ref(qualifiedName: \"development\") {\n target {\n ... on Commit {\n history(first: 15, path: $path) {\n nodes {\n pushedDate\n message\n }\n }\n }\n }\n }\n }\n}"; +var docFiles = getDocFileNames(docsFolderPath); +var docNames = Rx_1.Observable.from(docFiles); +console.log("'Name','Review date','Commits since review','Score'"); +docNames.subscribe(function (x) { + var key = path.basename(x, ".md"); + if (!srcData[key]) + return; + var vars = { + "path": "lib/" + srcData[key].path + }; + client.request(query, vars).then(function (data) { + var nodes = data["repository"].ref.target.history.nodes; + var lastReviewDate = getDocReviewDate(key + ".md"); + var numUsefulCommits = extractCommitInfo(nodes, lastReviewDate, stoplist); + var dateString = lastReviewDate.format("YYYY-MM-DD"); + var score = priorityScore(lastReviewDate, numUsefulCommits).toPrecision(3); + console.log("'" + key + "','" + dateString + "','" + numUsefulCommits + "','" + score + "'"); + }); +}); +function priorityScore(reviewDate, numCommits) { + var daysSinceReview = moment().diff(reviewDate, 'days'); + var commitScore = 2 + numCommits * commitWeight; + return Math.pow(commitScore, daysSinceReview / scoreTimeBase); +} +function getDocReviewDate(docFileName) { + var mdFilePath = path.resolve(docsFolderPath, docFileName); + var mdText = fs.readFileSync(mdFilePath); + var tree = remark().use(frontMatter, ["yaml"]).parse(mdText); + var lastReviewDate = moment(adf20StartDate); + if (tree.children[0].type == "yaml") { + var metadata = yaml.load(tree.children[0].value); + if (metadata["Last reviewed"]) + lastReviewDate = moment(metadata["Last reviewed"]); + } + return lastReviewDate; +} +function extractCommitInfo(commitNodes, cutOffDate, stoplist) { + var numUsefulCommits = 0; + commitNodes.forEach(function (element) { + if (!stoplist.isRejected(element.message)) { + var abbr = element.message.substr(0, 15); + var commitDate = moment(element.pushedDate); + if (commitDate.isAfter(cutOffDate)) { + numUsefulCommits++; + } + } + }); + return numUsefulCommits; +} +function getDocFileNames(folderPath) { + var files = fs.readdirSync(folderPath); + files = files.filter(function (filename) { + return (path.extname(filename) === ".md") && + (filename !== "README.md") && + (filename.match(angFilePattern)); + }); + return files; +} diff --git a/lib/config/DocProcessor/reviewChecker.ts b/lib/config/DocProcessor/reviewChecker.ts new file mode 100644 index 0000000000..d15db187d2 --- /dev/null +++ b/lib/config/DocProcessor/reviewChecker.ts @@ -0,0 +1,152 @@ +import * as path from "path"; +import * as fs from "fs"; +import * as process from "process" + +import { GraphQLClient } from "graphql-request"; +import * as remark from "remark"; +import * as frontMatter from "remark-frontmatter"; +import * as yaml from "js-yaml"; +import * as moment from "moment"; +import { Observable } from 'rxjs/Rx'; + +import * as libsearch from "./libsearch"; +import { Stoplist } from "./stoplist"; +import { last } from "rxjs/operator/last"; + + +const adf20StartDate = "2017-11-20"; + +const commitWeight = 0.1; +const scoreTimeBase = 60; + +const rootFolder = "."; +const stoplistFilePath = path.resolve("config", "DocProcessor", "commitStoplist.json"); + +const angFilePattern = /(component)|(directive)|(model)|(pipe)|(service)|(widget)/; + +let srcData = {}; +let stoplist = new Stoplist(stoplistFilePath); + +let docsFolderPath = path.resolve("..", "docs"); + +libsearch(srcData, path.resolve(rootFolder)); + +/* +let keys = Object.keys(srcData); + +for (let i = 0; i < keys.length; i++) { + console.log(keys[i]); +} +*/ + +const authToken = process.env.graphAuthToken; + +const client = new GraphQLClient('https://api.github.com/graphql', { + headers: { + Authorization: 'Bearer ' + authToken + } +}); + +const query = `query commitHistory($path: String) { + repository(name: "alfresco-ng2-components", owner: "alfresco") { + ref(qualifiedName: "development") { + target { + ... on Commit { + history(first: 15, path: $path) { + nodes { + pushedDate + message + } + } + } + } + } + } +}`; + +let docFiles = getDocFileNames(docsFolderPath); + +let docNames = Observable.from(docFiles); + +console.log("'Name','Review date','Commits since review','Score'"); + +docNames.subscribe(x => { + let key = path.basename(x, ".md"); + + if (!srcData[key]) + return; + + let vars = { + "path": "lib/" + srcData[key].path + }; + + client.request(query, vars).then(data => { + let nodes = data["repository"].ref.target.history.nodes; + + let lastReviewDate = getDocReviewDate(key + ".md"); + + let numUsefulCommits = extractCommitInfo(nodes, lastReviewDate, stoplist); + let dateString = lastReviewDate.format("YYYY-MM-DD"); + let score = priorityScore(lastReviewDate, numUsefulCommits).toPrecision(3); + + console.log(`'${key}','${dateString}','${numUsefulCommits}','${score}'`); + }); +}); + + +function priorityScore(reviewDate, numCommits) { + let daysSinceReview = moment().diff(reviewDate, 'days'); + let commitScore = 2 + numCommits * commitWeight; + return Math.pow(commitScore, daysSinceReview / scoreTimeBase); +} + + +function getDocReviewDate(docFileName) { + let mdFilePath = path.resolve(docsFolderPath, docFileName); + + let mdText = fs.readFileSync(mdFilePath); + let tree = remark().use(frontMatter, ["yaml"]).parse(mdText); + + let lastReviewDate = moment(adf20StartDate); + + if (tree.children[0].type == "yaml") { + let metadata = yaml.load(tree.children[0].value); + + if (metadata["Last reviewed"]) + lastReviewDate = moment(metadata["Last reviewed"]); + } + + return lastReviewDate; +} + + +function extractCommitInfo(commitNodes, cutOffDate, stoplist) { + let numUsefulCommits = 0; + + commitNodes.forEach(element => { + if (!stoplist.isRejected(element.message)) { + let abbr = element.message.substr(0, 15); + + let commitDate = moment(element.pushedDate); + + if (commitDate.isAfter(cutOffDate)) { + numUsefulCommits++; + } + } + }); + + return numUsefulCommits; +} + + +function getDocFileNames(folderPath) { + let files = fs.readdirSync(folderPath); + + files = files.filter(filename => + (path.extname(filename) === ".md") && + (filename !== "README.md") && + (filename.match(angFilePattern)) + ); + + return files; +} \ No newline at end of file diff --git a/lib/config/DocProcessor/stoplist.js b/lib/config/DocProcessor/stoplist.js new file mode 100644 index 0000000000..188a4e1e1d --- /dev/null +++ b/lib/config/DocProcessor/stoplist.js @@ -0,0 +1,29 @@ +"use strict"; +exports.__esModule = true; +var fs = require("fs"); +/* "Stoplist" of regular expressions to match against strings. */ +var Stoplist = /** @class */ (function () { + function Stoplist(slFilePath) { + var listExpressions = JSON.parse(fs.readFileSync(slFilePath, 'utf8')); + this.regexes = []; + if (listExpressions) { + for (var i = 0; i < listExpressions.length; i++) { + this.regexes.push(new RegExp(listExpressions[i])); + } + } + else { + this.regexes = []; + } + } + // Check if an item is covered by the stoplist and reject it if so. + Stoplist.prototype.isRejected = function (itemName) { + for (var i = 0; i < this.regexes.length; i++) { + if (this.regexes[i].test(itemName)) { + return true; + } + } + return false; + }; + return Stoplist; +}()); +exports.Stoplist = Stoplist; diff --git a/lib/config/DocProcessor/stoplist.ts b/lib/config/DocProcessor/stoplist.ts new file mode 100644 index 0000000000..84798f315e --- /dev/null +++ b/lib/config/DocProcessor/stoplist.ts @@ -0,0 +1,31 @@ +import * as fs from "fs"; + +/* "Stoplist" of regular expressions to match against strings. */ +export class Stoplist { + regexes: RegExp[]; + + constructor(slFilePath: string) { + let listExpressions = JSON.parse(fs.readFileSync(slFilePath, 'utf8')); + this.regexes = []; + + if (listExpressions) { + for (var i = 0; i < listExpressions.length; i++) { + this.regexes.push(new RegExp(listExpressions[i])); + } + } else { + this.regexes = []; + } + } + + // Check if an item is covered by the stoplist and reject it if so. + isRejected(itemName: string) { + for (var i = 0; i < this.regexes.length; i++) { + if (this.regexes[i].test(itemName)) { + return true; + } + } + + return false; + } + +} \ No newline at end of file diff --git a/lib/config/DocProcessor/tools/index.js b/lib/config/DocProcessor/tools/index.js index dcb011823c..1b010edcde 100644 --- a/lib/config/DocProcessor/tools/index.js +++ b/lib/config/DocProcessor/tools/index.js @@ -8,7 +8,7 @@ var yaml = require("js-yaml"); var unist = require("../unistHelpers"); var ngHelpers = require("../ngHelpers"); - +var searchLibraryRecursive = require("../libsearch"); module.exports = { "initPhase": initPhase, @@ -147,31 +147,6 @@ function rejectItemViaStoplist(stoplist, itemName) { } -// Search source folders for .ts files to discover all components, directives, etc. -function searchLibraryRecursive(srcData, folderPath) { - var items = fs.readdirSync(folderPath); - - for (var i = 0; i < items.length; i++) { - var itemPath = path.resolve(folderPath, items[i]); - var info = fs.statSync(itemPath); - - if (info.isFile() && (items[i].match(angFilenameRegex))) { - var nameNoSuffix = path.basename(items[i], '.ts'); - - var displayPath = itemPath.replace(/\\/g, '/'); - displayPath = displayPath.substr(displayPath.indexOf("lib") + 4); - - // Type == "component", "directive", etc. - var itemType = nameNoSuffix.split('.')[1]; - - srcData[nameNoSuffix] = { "path": displayPath, "type": itemType }; - } else if (info.isDirectory() && !items[i].match(searchFolderOmitRegex)) { - searchLibraryRecursive(srcData, itemPath); - } - } -} - - function prepareIndexSections(aggData) { var srcNames = Object.keys(aggData.srcData); var sections = initEmptySections(); From 232404aef3b6e23264679f11f635b7a7fe7dd899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Popovics=20Andr=C3=A1s?= Date: Wed, 7 Mar 2018 12:55:41 +0100 Subject: [PATCH 020/188] Fix dark theme for viewing pdf files also. (#3042) --- lib/core/viewer/components/pdfViewer.component.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/core/viewer/components/pdfViewer.component.scss b/lib/core/viewer/components/pdfViewer.component.scss index 66c80ff469..be8e4a9948 100644 --- a/lib/core/viewer/components/pdfViewer.component.scss +++ b/lib/core/viewer/components/pdfViewer.component.scss @@ -1,4 +1,5 @@ @mixin adf-pdf-viewer-theme($theme) { + $background: map-get($theme, background); $foreground: map-get($theme, foreground); .adf-viewer-content-container { @@ -67,7 +68,7 @@ .adf-toolbar .mat-toolbar { max-height: 48px; - background-color: mat-color($primary, default-contrast, 1); + background-color: mat-color($background, card); border-width: 0; border-radius: 2px; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.24), 0 0 2px 0 rgba(0, 0, 0, 0.12); @@ -80,6 +81,8 @@ & > input { border: 1px solid mat-color($foreground, text, 0.07); + background-color: mat-color($background, card); + color: inherit; font-size: 14px; padding: 0; height: 24px; From 6afdbcad7c41a1a9259110e95fae933adad4e312 Mon Sep 17 00:00:00 2001 From: Vito Date: Wed, 7 Mar 2018 14:11:36 +0000 Subject: [PATCH 021/188] [ADF-2358] Always enabling copy action (#3044) --- .../app/components/files/files.component.html | 2 +- .../document-list.component.spec.ts | 21 +++++++++++++++++++ .../components/document-list.component.ts | 5 +++-- lib/core/models/permissions.enum.ts | 1 + lib/core/services/content.service.spec.ts | 5 +++++ lib/core/services/content.service.ts | 4 ++++ 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index 2cc49fea9a..ff581fd2c5 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -251,7 +251,7 @@ { }); + it('should not disable the action if there is copy permission', () => { + let documentMenu = new ContentActionModel({ + disableWithNoPermission: true, + permission: 'copy', + target: 'document', + title: 'FileAction' + }); + + documentList.actions = [ + documentMenu + ]; + + let nodeFile = { entry: { isFile: true, name: 'xyz', allowableOperations: ['create', 'update'] } }; + + let actions = documentList.getNodeActions(nodeFile); + expect(actions.length).toBe(1); + expect(actions[0].title).toEqual('FileAction'); + expect(actions[0].disabled).toBeFalsy(); + + }); + it('should disable the action if there is no permission for the folder and disableWithNoPermission true', () => { let documentMenu = new ContentActionModel({ disableWithNoPermission: true, diff --git a/lib/content-services/document-list/components/document-list.component.ts b/lib/content-services/document-list/components/document-list.component.ts index 29bea2d3d9..bf50a7530a 100644 --- a/lib/content-services/document-list/components/document-list.component.ts +++ b/lib/content-services/document-list/components/document-list.component.ts @@ -24,7 +24,8 @@ import { DisplayMode, ObjectDataColumn, PaginatedComponent, - PaginationQueryParams + PaginationQueryParams, + PermissionsEnum } from '@alfresco/adf-core'; import { AlfrescoApiService, AppConfigService, DataColumnListComponent, UserPreferencesService } from '@alfresco/adf-core'; import { @@ -420,7 +421,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte } checkPermission(node: any, action: ContentActionModel): ContentActionModel { - if (action.permission) { + if (action.permission && action.permission !== PermissionsEnum.COPY) { if (this.hasPermissions(node)) { let permissions = node.entry.allowableOperations; let findPermission = permissions.find(permission => permission === action.permission); diff --git a/lib/core/models/permissions.enum.ts b/lib/core/models/permissions.enum.ts index d2e2cc7429..42035ed551 100644 --- a/lib/core/models/permissions.enum.ts +++ b/lib/core/models/permissions.enum.ts @@ -19,6 +19,7 @@ export class PermissionsEnum extends String { static DELETE: string = 'delete'; static UPDATE: string = 'update'; static CREATE: string = 'create'; + static COPY: string = 'copy'; static UPDATEPERMISSIONS: string = 'updatePermissions'; static NOT_DELETE: string = '!delete'; static NOT_UPDATE: string = '!update'; diff --git a/lib/core/services/content.service.spec.ts b/lib/core/services/content.service.spec.ts index ddf11b57d6..1e9428723e 100644 --- a/lib/core/services/content.service.spec.ts +++ b/lib/core/services/content.service.spec.ts @@ -151,6 +151,11 @@ describe('ContentService', () => { expect(contentService.hasPermission(permissionNode, null)).toBeFalsy(); }); + it('should havePermission return true if permission parameter is copy', () => { + let permissionNode = null; + expect(contentService.hasPermission(permissionNode, 'copy')).toBeTruthy(); + }); + describe('Download blob', () => { it('Should use native msSaveOrOpenBlob if the browser is IE', (done) => { diff --git a/lib/core/services/content.service.ts b/lib/core/services/content.service.ts index b8edafc6ad..8a3de5099c 100644 --- a/lib/core/services/content.service.ts +++ b/lib/core/services/content.service.ts @@ -213,6 +213,10 @@ export class ContentService { } } + if (permission === PermissionsEnum.COPY) { + hasPermission = true; + } + return hasPermission; } From 1fade9b23bd32fdf77f2cbf6aa35f865e1b1a32a Mon Sep 17 00:00:00 2001 From: Deepak Paul Date: Thu, 8 Mar 2018 15:32:41 +0530 Subject: [PATCH 022/188] [ADF-2320] Complete button is visible on an involved task (#3033) * * [ADF-2320] Conditionally showing Complete button for task without form * * [ADF-2320] Refactored the coditions --- .../components/task-details.component.html | 4 +-- .../components/task-details.component.spec.ts | 31 +++++++++++++++++-- .../components/task-details.component.ts | 6 +++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/process-services/task-list/components/task-details.component.html b/lib/process-services/task-list/components/task-details.component.html index d91272b024..39a387b172 100644 --- a/lib/process-services/task-list/components/task-details.component.html +++ b/lib/process-services/task-list/components/task-details.component.html @@ -28,7 +28,7 @@ [showTitle]="showFormTitle" [showRefreshButton]="showFormRefreshButton" [showCompleteButton]="showFormCompleteButton" - [disableCompleteButton]="!isCompleteButtonVisible()" + [disableCompleteButton]="!isCompleteButtonEnabled()" [showSaveButton]="isSaveButtonVisible()" [readOnly]="readOnlyForm" [fieldValidators]="fieldValidators" @@ -45,7 +45,7 @@ {{ 'ADF_TASK_LIST.DETAILS.MESSAGES.CLAIM' | translate }}
diff --git a/lib/process-services/task-list/components/task-details.component.spec.ts b/lib/process-services/task-list/components/task-details.component.spec.ts index c481946788..357dcda125 100644 --- a/lib/process-services/task-list/components/task-details.component.spec.ts +++ b/lib/process-services/task-list/components/task-details.component.spec.ts @@ -24,7 +24,7 @@ import { Observable } from 'rxjs/Observable'; import { FormModule, FormModel, FormOutcomeEvent, FormOutcomeModel, FormService } from '@alfresco/adf-core'; import { CommentProcessService, LogService } from '@alfresco/adf-core'; -import { PeopleProcessService, UserProcessModel } from '@alfresco/adf-core'; +import { PeopleProcessService, UserProcessModel, AuthenticationService } from '@alfresco/adf-core'; import { TaskDetailsModel } from '../models/task-details.model'; import { noDataMock, taskDetailsMock, taskFormMock, tasksMock } from '../../mock'; import { TaskListService } from './../services/tasklist.service'; @@ -52,6 +52,7 @@ describe('TaskDetailsComponent', () => { let completeTaskSpy: jasmine.Spy; let logService: LogService; let commentProcessService: CommentProcessService; + let authService: AuthenticationService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -67,7 +68,8 @@ describe('TaskDetailsComponent', () => { providers: [ TaskListService, PeopleProcessService, - CommentProcessService + CommentProcessService, + AuthenticationService ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); @@ -83,6 +85,7 @@ describe('TaskDetailsComponent', () => { service = fixture.debugElement.injector.get(TaskListService); formService = fixture.debugElement.injector.get(FormService); commentProcessService = TestBed.get(CommentProcessService); + authService = TestBed.get(AuthenticationService); getTaskDetailsSpy = spyOn(service, 'getTaskDetails').and.returnValue(Observable.of(taskDetailsMock)); spyOn(formService, 'getTaskForm').and.returnValue(Observable.of(taskFormMock)); @@ -146,6 +149,30 @@ describe('TaskDetailsComponent', () => { }); })); + it('should display complete button when task without form is assigned to current user', async(() => { + spyOn(authService, 'getBpmUsername').and.returnValue(taskDetailsMock.assignee.email); + taskDetailsMock.formKey = undefined; + component.taskId = '123'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + const completeBtn = fixture.nativeElement.querySelector('button'); + expect(completeBtn).toBeDefined(); + expect(completeBtn.disabled).toBeFalsy(); + expect(completeBtn.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.COMPLETE'); + }); + })); + + it('should not display complete button when task without form is not assigned to current user', async(() => { + spyOn(authService, 'getBpmUsername').and.returnValue(''); + component.taskId = '123'; + taskDetailsMock.formKey = undefined; + fixture.detectChanges(); + fixture.whenStable().then(() => { + const completeBtn = fixture.nativeElement.querySelector('.activiti-task-details__action-button'); + expect(completeBtn).toBeNull(); + }); + })); + describe('change detection', () => { let change = new SimpleChange('123', '456', true); diff --git a/lib/process-services/task-list/components/task-details.component.ts b/lib/process-services/task-list/components/task-details.component.ts index 46aa58ccd0..fb755113fe 100644 --- a/lib/process-services/task-list/components/task-details.component.ts +++ b/lib/process-services/task-list/components/task-details.component.ts @@ -292,10 +292,14 @@ export class TaskDetailsComponent implements OnInit, OnChanges { return this.taskDetails.assignee.email === this.authService.getBpmUsername(); } - isCompleteButtonVisible(): boolean { + isCompleteButtonEnabled(): boolean { return this.isAssignedToMe() || this.canInitiatorComplete(); } + isCompleteButtonVisible(): boolean { + return !this.hasFormKey() && this.isTaskActive() && this.isCompleteButtonEnabled(); + } + canInitiatorComplete(): boolean { return this.taskDetails.initiatorCanCompleteTask; } From 499c3cd66ed2cebc126d34842c9215230154b757 Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Thu, 8 Mar 2018 10:11:13 +0000 Subject: [PATCH 023/188] [ADF-2458] Updated doc to standard format (#3047) --- docs/process.service.md | 500 +++--------------- .../process-list/services/process.service.ts | 56 +- 2 files changed, 116 insertions(+), 440 deletions(-) diff --git a/docs/process.service.md b/docs/process.service.md index 94cc655dd0..b0a8f453b4 100644 --- a/docs/process.service.md +++ b/docs/process.service.md @@ -4,9 +4,62 @@ Status: Active --- # Process Service -Manage Process Instances, Process Variables, and Process Audit Log. +Manages Process Instances, Process Variables, and Process Audit Log. -## Importing +## Methods + +- `getProcessInstances(requestNode: ProcessFilterParamRepresentationModel, processDefinitionKey?: string): Observable` + Get process instances for a filter and optionally a process definition. + - `requestNode` - Filter for instances + - `processDefinitionKey` - (Optional) Limits returned instances to a process definition +- `fetchProcessAuditPdfById(processId: string): Observable` + Fetches the Process Audit information as a pdf + - `processId` - ID of the target process +- `fetchProcessAuditJsonById(processId: string): Observable` + Fetches the Process Audit information in a json format. + - `processId` - ID of the target process +- `getProcess(processInstanceId: string): Observable` + Gets Process Instance metadata. + - `processInstanceId` - ID of the target process +- `getProcessTasks(processInstanceId: string, state?: string): Observable` + Gets task instances for a process instance. + - `processInstanceId` - ID of the process instance + - `state` - (Optional) Task state filter (can be "active" or "completed") +- `getProcessDefinitions(appId?: number): Observable` + Gets process definitions associated with an app. + - `appId` - (Optional) ID of a target app +- `getProcessDefinitionVersions(appId?: number): Observable` + Gets the versions of process definitions associated with an app. + - `appId` - (Optional) ID of a target app +- `startProcess(processDefinitionId: string, name: string, outcome?: string, startFormValues?: FormValues, variables?: ProcessInstanceVariable[]): Observable` + Starts a process based on a process definition, name, form values or variables. + - `processDefinitionId` - Process definition ID + - `name` - Process name + - `outcome` - (Optional) Process outcome + - `startFormValues` - (Optional) Values for the start form + - `variables` - (Optional) Array of process instance variables +- `cancelProcess(processInstanceId: string): Observable` + Cancels a process instance. + - `processInstanceId` - ID of process to cancel +- `getProcessInstanceVariables(processInstanceId: string): Observable` + Gets the variables for a process instance. + - `processInstanceId` - ID of the target process +- `createOrUpdateProcessInstanceVariables(processInstanceId: string, variables: ProcessInstanceVariable[]): Observable` + Creates or updates variables for a process instance. + - `processInstanceId` - ID of the target process + - `variables` - Variables to update +- `deleteProcessInstanceVariable(processInstanceId: string, variableName: string): Observable` + Deletes a variable for a process instance. + - `processInstanceId` - ID of the target process + - `variableName` - Name of the variable to delete + +## Details + +Parameter and return value classes are defined in the Alfresco JS API. See the +[Activiti REST API](https://github.com/Alfresco/alfresco-js-api/tree/master/src/alfresco-activiti-rest-api) +pages for further information. + +### Importing ```ts import { ProcessService, ProcessInstance, ProcessInstanceVariable, @@ -18,57 +71,12 @@ export class SomePageComponent implements OnInit { } ``` -## Methods +### Example of starting a process -#### getProcess(processInstanceId: string): Observable`` +When starting a process, you can choose to pass in form field values or process variables +but not both in the same call. -Get Process Instance metadata for passed in Process Instance ID: - -```ts -const processInstanceId = '11337'; -this.processService.getProcess(processInstanceId).subscribe( (processInstance: ProcessInstance) => { - console.log('ProcessInstance: ', processInstance); - }, error => { - console.log('Error: ', error); - }); -``` - -The `processInstanceId` refers to a process instance ID for a running process in APS. -The returned `processInstance` object is of type `ProcessInstance` and looks like in this sample: - - businessKey: null - ended: null - graphicalNotationDefined: true - id: "11337" - name: "Invoice Approval 2 started from ADF client" - processDefinitionCategory: "http://www.activiti.org/processdef" - processDefinitionDeploymentId: "18" - processDefinitionDescription: "This is a simple invoice approval process that allows a person to assign a dedicated approver for the the invoice. It will then be routed to the Accounting department for payment preparation. Once payment is prepared the invoice will be stored in a specific folder and an email notification will be sent." - processDefinitionId: "InvoiceApprovalProcess:2:21" - processDefinitionKey: "InvoiceApprovalProcess" - processDefinitionName: "Invoice Approval Process" - processDefinitionVersion: 2 - startFormDefined: true - started: Tue Oct 10 2017 10:35:42 GMT+0100 (BST) {} - startedBy: {id: 1, firstName: null, lastName: "Administrator", email: "admin@app.activiti.com"} - suspended: false - tenantId: "tenant_1" - variables: - 0: {name: "initiator", type: "string", value: "1"} - 1: {name: "approver", type: "long", value: 2002} - 2: {name: "companyemail", type: "string", value: "martin.bergljung@xxxxx.com"} - 3: {name: "invoicetobeapproved", value: null} - 4: {name: "invoiceFileName", type: "string", value: " - [Alfresco_Enterprise_Edition_3_3_Windows_Simple_Install.pdf]"} - 5: {name: "comments", value: null} - 6: {name: "form8outcome", type: "string", value: "Reject"} - -#### startProcess(processDefinitionId: string, name: string, outcome?: string, startFormValues?: any, variables?: ProcessInstanceVariable\[]): Observable`` - -Start a process based on passed in Process Definition, name, form values or variables. - -When starting you can choose to pass in form field values or process variables (you cannot pass in both). -Here is an example of how to pass in form field values, these correspond to the -start form that has been defined for the process: +In this example, values are supplied to the start form that has been defined for the process: ```ts const processDefinitionId = 'InvoiceApprovalProcess:2:21'; @@ -87,33 +95,11 @@ this.processService.startProcess(processDefinitionId, name, outcome, startFormVa }); ``` -A `ProcessInstance` object is returned for a successfully started process: +A `ProcessInstance` object is returned for a successfully started process. This implements the +[ProcessInstanceRepresentation interface](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/ProcessInstanceRepresentation.md). - businessKey: null - ended: null - graphicalNotationDefined: true - id: "75001" - name: "Sample Invoice Process" - processDefinitionCategory: "http://www.activiti.org/processdef" - processDefinitionDeploymentId: "18" - processDefinitionDescription: "This is a simple invoice approval process that allows a person to assign a dedicated approver for the the invoice. It will then be routed to the Accounting department for payment preparation. Once payment is prepared the invoice will be stored in a specific folder and an email notification will be sent." - processDefinitionId: "InvoiceApprovalProcess:2:21" - processDefinitionKey: "InvoiceApprovalProcess" - processDefinitionName: "Invoice Approval Process" - processDefinitionVersion: 2 - startFormDefined: false - started: Thu Nov 09 2017 08:15:37 GMT+0000 (GMT) {} - startedBy: {id: 1, firstName: null, lastName: "Administrator", email: "admin@app.activiti.com"} - tenantId: "tenant_1" - variables: - 0: {name: "approver", value: null} - 1: {name: "companyemail", type: "string", value: "someone@acme.com"} - 2: {name: "initiator", type: "string", value: "1"} - 3: {name: "invoicetobeapproved", value: null} - -We can see here that the form field values have been converted to process variables. - -To start the process with process variables instead of form field values do: +You can start the process with process variables instead of form field values using +code like the following: ```ts const processDefinitionId = 'InvoiceApprovalProcess:2:21'; @@ -132,7 +118,7 @@ this.processService.startProcess(processDefinitionId, name, null, null, variable }); ``` -If you want to start a process that has no start form and no process variables, then do: +You can also start a process that has no start form and no process variables: ```ts const processDefinitionId = 'SimpleProcess:1:2'; @@ -144,361 +130,3 @@ this.processService.startProcess(processDefinitionId, name) console.log('Error: ', error); }); ``` - -#### cancelProcess(processInstanceId: string): Observable`` - -Cancel a process instance by passing in its process instance ID: - -```ts -const processInstanceId = '75012'; -this.processService.cancelProcess(processInstanceId) - .subscribe( response => { - console.log('Response: ', response); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is just `null` if the process instance was cancelled successfully. -Once a Process Instance is cancelled it will show up under processes with status -`completed`. - -You typically get the `processInstanceId` when you start a process. It is then -contained in the `ProcessInstance.id` response. - -#### createOrUpdateProcessInstanceVariables(processDefinitionId: string, variables: ProcessInstanceVariable\[]): Observable`` - -Create or update variables for a Process Instance: - -```ts -const processInstanceId = '75001'; -const variables: ProcessInstanceVariable[] = [ - {name: 'sampleVar1', value: 'hello'}, - {name: 'sampleVar2', value: 'bye'} -]; -this.processService.createOrUpdateProcessInstanceVariables(processInstanceId, variables) - .subscribe( response => { - console.log('Response: ', response); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is an array of the successfully created `ProcessInstanceVariable`: - - Response: - 0: {name: "sampleVar1", type: "string", value: "hello", scope: "global"} - 1: {name: "sampleVar2", type: "string", value: "bye", scope: "global"} - -If a variable already exist, then its value will be updated. - -**Note**. you need to pass in a Process Instance ID here, not a Process Definition ID. - -#### deleteProcessInstanceVariable(processInstanceId: string, variableName: string): Observable`` - -Delete a variable for a Process Instance: - -```ts -const processInstanceId = '75001'; -const variableName = 'sampleVar1'; -this.processService.deleteProcessInstanceVariable(processInstanceId, variableName) - .subscribe( response => { - console.log('Response: ', response); -}, error => { - console.log('Error: ', error); -}); -``` - -The response will be `null` if the variable was successfully deleted from the Process Instance. - -**Note**. you need to pass in a Process Instance ID here, not a Process Definition ID. - -#### getProcessInstanceVariables(processDefinitionId: string): Observable`` - -Get all the variables for a Process Instance: - -```ts -const processInstanceId = '75001'; -this.processService.getProcessInstanceVariables(processInstanceId) - .subscribe( (procVars: ProcessInstanceVariable[]) => { - console.log('procVars: ', procVars); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is an array of `ProcessInstanceVariable`: - - procVars: - 0: {name: "approver", scope: "global", value: null, valueUrl: null} - 1: {name: "companyemail", scope: "global", value: "someone@acme.com", valueUrl: null} - 2: {name: "initiator", scope: "global", value: "1", valueUrl: null} - 3: {name: "sampleVar2", scope: "global", value: "bye", valueUrl: null} - 4: {name: "invoicetobeapproved", scope: "global", value: null, valueUrl: null} - 5: {name: "invoiceFileName", scope: "global", value: " - [UNKNOWN]", valueUrl: null} - -**Note**. you need to pass in a Process Instance ID here, not a Process Definition ID. - -#### getProcessDefinitions(appId?: number): Observable`` - -Get Process Definitions associated with a Process App: - -```ts -const processAppId = 2; -this.processService.getProcessDefinitions(processAppId) - .subscribe( (procDefs: ProcessDefinitionRepresentation[]) => { - console.log('ProceDefs: ', procDefs); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is an array of `ProcessDefinitionRepresentation` objects looking like in this example: - - 0: - category: "http://www.activiti.org/processdef" - deploymentId: "18" - description: "This is a simple invoice approval process that allows a person to assign a dedicated approver for the the invoice. It will then be routed to the Accounting department for payment preparation. Once payment is prepared the invoice will be stored in a specific folder and an email notification will be sent." - hasStartForm: true - id: "InvoiceApprovalProcess:2:21" - key: "InvoiceApprovalProcess" - metaDataValues: [] - name: "Invoice Approval Process" - tenantId: "tenant_1" - version: 2 - -If you wanted a list of all available process definitions call the method without specifying the -process application ID: - -```ts -this.processService.getProcessDefinitions() - .subscribe( (procDefs: ProcessDefinitionRepresentation[]) => { - console.log('ProceDefs: ', procDefs); -}, error => { - console.log('Error: ', error); -}); -``` - -#### getProcessInstances(requestNode: ProcessFilterParamRepresentationModel, processDefinitionKey?: string): Observable`` - -Get Process Instances for passed in filter and optionally Process Definition: - -```ts -const processDefKey = 'InvoiceApprovalProcess'; -const filterRunningAsc = new ProcessFilterParamRepresentationModel({ -'state': 'running', -'sort': 'created-asc', -}); -this.processService.getProcessInstances(filterRunningAsc, processDefKey) - .subscribe( (processInstances: ProcessInstance[]) => { - console.log('Process Instances: ', processInstances); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is an array of `ProcessInstance` objects as in this example: - - 0: {id: "7501", name: "Invoice Approval Process - October 9th 2017", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:3:2511", tenantId: "tenant_1", …} - 1: {id: "7520", name: "Invoice Approval Process - October 9th 2017", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:2:21", tenantId: "tenant_1", …} - 2: {id: "8206", name: "Invoice Approval Process - October 9th 2017", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:2:21", tenantId: "tenant_1", …} - 3: {id: "8302", name: "Invoice Approval Process - October 9th 2017", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:2:21", tenantId: "tenant_1", …} - 4: {id: "11337", name: "Invoice Approval 2 started from ADF client", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:2:21", tenantId: "tenant_1", …} - 5: {id: "11437", name: "Invoice Approval Process - October 10th 2017", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:2:21", tenantId: "tenant_1", …} - 6: {id: "67143", name: "Sample Invoice Approval 2017-10-26", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:5:62514", tenantId: "tenant_1", …} - 7: {id: "75001", name: "Sample Invoice Process", businessKey: null, processDefinitionId: "InvoiceApprovalProcess:2:21", tenantId: "tenant_1", …} - -You can also narrow down the search via other properties in the `ProcessFilterParamRepresentationModel`, such as -`processDefinitionId` and `appDefinitionId`. -The number of Process Instances that are returned can be controlled with the `page` and `size` properties. - -#### getProcessTasks(processInstanceId: string, state?: string): Observable`` - -Get Task Instances for passed in Process Instance, optionally filter by task state: - -```ts -const processInstanceId = '75001'; -this.processService.getProcessTasks(processInstanceId) - .subscribe( (taskInstances: TaskDetailsModel[]) => { - console.log('Task Instances: ', taskInstances); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is an array of `TaskDetailsModel` objects as in this example: - - { - "size":1, - "total":1, - "start":0, - "data":[ - {"id":"75010", - "name":"Approve Invoice - [Invoice 123]", - "description":null, - "category":null, - "assignee":{"id":1,"firstName":null,"lastName":"Administrator","email":"admin@app.activiti.com"}, - "created":"2017-11-09T08:15:37.427+0000", - "dueDate":null, - "endDate":null, - "duration":null, - "priority":50, - "parentTaskId":null, - "parentTaskName":null, - "processInstanceId":"75001", - "processInstanceName":null, - "processDefinitionId":"InvoiceApprovalProcess:2:21", - "processDefinitionName":"Invoice Approval Process", - "processDefinitionDescription":"This is a simple invoice approval process that allows a person to assign a dedicated approver for the the invoice. It will then be routed to the Accounting department for payment preparation. Once payment is prepared the invoice will be stored in a specific folder and an email notification will be sent.", - "processDefinitionKey":"InvoiceApprovalProcess", - "processDefinitionCategory":"http://www.activiti.org/processdef", - "processDefinitionVersion":2, - "processDefinitionDeploymentId":"18", - "formKey":"8", - "processInstanceStartUserId":null, - "initiatorCanCompleteTask":false, - "adhocTaskCanBeReassigned":false, - "taskDefinitionKey":"approveInvoice", - "executionId":"75001", - "memberOfCandidateGroup":false, - "memberOfCandidateUsers":false, - "managerOfCandidateGroup":false - } - ] - } - -You can also filter by task state, which can be `active` or `completed`: - -```ts -const processInstanceId = '75001'; -const taskState = 'active'; -this.processService.getProcessTasks(processInstanceId, taskState) - .subscribe( (taskInstances: TaskDetailsModel[]) => { - console.log('Task Instances: ', taskInstances); -}, error => { - console.log('Error: ', error); -}); -``` - -#### fetchProcessAuditJsonById(processId: string): Observable`` - -Fetch Process Audit log as JSON for a Process Instance ID: - -```ts -const processInstanceId = '75001'; -this.processService.fetchProcessAuditJsonById(processInstanceId) - .subscribe( auditJson => { - console.log('Process Audit: ', auditJson); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is JSON object with the Process Instance audit log: - - { - "processInstanceId": "75001", - "processInstanceName": "Sample Invoice Process", - "processDefinitionName": "Invoice Approval Process", - "processDefinitionVersion": "2", - "processInstanceStartTime": "Thu Nov 09 08:15:37 GMT 2017", - "processInstanceEndTime": null, - "processInstanceDurationInMillis": null, - "processInstanceInitiator": " Administrator", - "entries": [ - { - "index": 1, - "type": "startForm", - "selectedOutcome": null, - "formData": [ - { - "fieldName": "Approver", - "fieldId": "approver", - "value": "" - }, - { - "fieldName": "Company Email", - "fieldId": "companyemail", - "value": "someone@acme.com" - }, - { - "fieldName": "Invoice to be approved", - "fieldId": "invoicetobeapproved", - "value": "" - } - ], - "taskName": null, - "taskAssignee": null, - "activityId": null, - "activityName": null, - "activityType": null, - "startTime": null, - "endTime": null, - "durationInMillis": null - }, - { - "index": 2, - "type": "activityExecuted", - "selectedOutcome": null, - "formData": [], - "taskName": null, - "taskAssignee": null, - "activityId": "startInvoiceProcess", - "activityName": "Start Invoice Process", - "activityType": "startEvent", - "startTime": "Thu Nov 09 08:15:37 GMT 2017", - "endTime": "Thu Nov 09 08:15:37 GMT 2017", - "durationInMillis": 37 - }, - { - "index": 3, - "type": "activityExecuted", - "selectedOutcome": null, - "formData": [], - "taskName": null, - "taskAssignee": null, - "activityId": "approveInvoice", - "activityName": "Approve Invoice", - "activityType": "userTask", - "startTime": "Thu Nov 09 08:15:37 GMT 2017", - "endTime": null, - "durationInMillis": null - }, - { - "index": 4, - "type": "taskCreated", - "selectedOutcome": null, - "formData": [], - "taskName": "Approve Invoice - [UNKNOWN]", - "taskAssignee": " Administrator", - "activityId": null, - "activityName": null, - "activityType": null, - "startTime": "Thu Nov 09 08:15:37 GMT 2017", - "endTime": null, - "durationInMillis": null - } - ], - "decisionInfo": { - "calculatedValues": [], - "appliedRules": [] - } - } - -#### fetchProcessAuditPdfById(processId: string): Observable`` - -Fetch Process Audit log as a PDF for a Process Instance ID: - -```ts -const processInstanceId = '75001'; -this.processService.fetchProcessAuditPdfById(processInstanceId) - .subscribe( auditPdf => { - console.log('Process Audit log BLOB: ', auditPdf); -}, error => { - console.log('Error: ', error); -}); -``` - -The response is a BLOB as follows: - - Process Audit log BLOB: Blob {size: 124511, type: "text/xml"} diff --git a/lib/process-services/process-list/services/process.service.ts b/lib/process-services/process-list/services/process.service.ts index fbf3e3b9f4..23df2a381e 100644 --- a/lib/process-services/process-list/services/process.service.ts +++ b/lib/process-services/process-list/services/process.service.ts @@ -34,6 +34,11 @@ export class ProcessService { constructor(private alfrescoApiService: AlfrescoApiService) { } + /** + * Get process instances for a filter and optionally a process definition. + * @param requestNode Filter for instances + * @param processDefinitionKey Limits returned instances to a process definition + */ getProcessInstances(requestNode: ProcessFilterParamRepresentationModel, processDefinitionKey?: string): Observable { return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.processApi.getProcessInstances(requestNode)) .map((res: any) => { @@ -48,8 +53,8 @@ export class ProcessService { } /** - * fetch the Process Audit information as a pdf - * @param processId - the process id + * Fetches the Process Audit information as a pdf + * @param processId ID of the target process */ fetchProcessAuditPdfById(processId: string): Observable { return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.processApi.getProcessAuditPdf(processId)) @@ -57,19 +62,28 @@ export class ProcessService { } /** - * fetch the Process Audit information in a json format - * @param processId - the process id + * Fetches the Process Audit information in a json format. + * @param processId ID of the target process */ fetchProcessAuditJsonById(processId: string): Observable { return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.processApi.getProcessAuditJson(processId)) .catch(err => this.handleProcessError(err)); } + /** + * Gets Process Instance metadata. + * @param processInstanceId ID of the target process + */ getProcess(processInstanceId: string): Observable { return Observable.fromPromise(this.alfrescoApiService.getInstance().activiti.processApi.getProcessInstance(processInstanceId)) .catch(err => this.handleProcessError(err)); } + /** + * Gets task instances for a process instance. + * @param processInstanceId ID of the process instance + * @param state Task state filter (can be "active" or "completed") + */ getProcessTasks(processInstanceId: string, state?: string): Observable { let taskOpts = state ? { processInstanceId: processInstanceId, @@ -86,6 +100,10 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Gets process definitions associated with an app. + * @param appId ID of a target app + */ getProcessDefinitions(appId?: number): Observable { let opts = appId ? { latest: true, @@ -101,6 +119,10 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Gets the versions of process definitions associated with an app. + * @param appId ID of a target app + */ getProcessDefinitionVersions(appId?: number): Observable { const opts = appId ? { appDefinitionId: appId } : {}; @@ -112,6 +134,14 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Starts a process based on a process definition, name, form values or variables. + * @param processDefinitionId Process definition ID + * @param name Process name + * @param outcome Process outcome + * @param startFormValues Values for the start form + * @param variables Array of process instance variables + */ startProcess(processDefinitionId: string, name: string, outcome?: string, startFormValues?: FormValues, variables?: ProcessInstanceVariable[]): Observable { let startRequest: any = { name: name, @@ -133,6 +163,10 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Cancels a process instance. + * @param processInstanceId ID of process to cancel + */ cancelProcess(processInstanceId: string): Observable { return Observable.fromPromise( this.alfrescoApiService.getInstance().activiti.processApi.deleteProcessInstance(processInstanceId) @@ -140,6 +174,10 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Gets the variables for a process instance. + * @param processInstanceId ID of the target process + */ getProcessInstanceVariables(processInstanceId: string): Observable { return Observable.fromPromise( this.alfrescoApiService.getInstance().activiti.processInstanceVariablesApi.getProcessInstanceVariables(processInstanceId) @@ -148,6 +186,11 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Creates or updates variables for a process instance. + * @param processInstanceId ID of the target process + * @param variables Variables to update + */ createOrUpdateProcessInstanceVariables(processInstanceId: string, variables: ProcessInstanceVariable[]): Observable { return Observable.fromPromise( this.alfrescoApiService.getInstance().activiti.processInstanceVariablesApi.createOrUpdateProcessInstanceVariables(processInstanceId, variables) @@ -155,6 +198,11 @@ export class ProcessService { .catch(err => this.handleProcessError(err)); } + /** + * Deletes a variable for a process instance. + * @param processInstanceId ID of the target process + * @param variableName Name of the variable to delete + */ deleteProcessInstanceVariable(processInstanceId: string, variableName: string): Observable { return Observable.fromPromise( this.alfrescoApiService.getInstance().activiti.processInstanceVariablesApi.deleteProcessInstanceVariable(processInstanceId, variableName) From f8f79b3f31c018e23da7360d0e15f6999dfbd093 Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Thu, 8 Mar 2018 12:58:35 +0200 Subject: [PATCH 024/188] [ADF-2421] Unable to copy / move a file from Recent or Favorites when user has only granular permissions on the file (#3041) * [ADF-2421] Unable to copy / move a file from Recent or Favorites when user has only granular permissions on the file * [ADF-2421] refactor code * [ADF-2421] refactor to simplify code --- .../document-list.component.spec.ts | 32 +++++++++++++++++++ .../components/document-list.component.ts | 3 ++ 2 files changed, 35 insertions(+) diff --git a/lib/content-services/document-list/components/document-list.component.spec.ts b/lib/content-services/document-list/components/document-list.component.spec.ts index 99909f5e67..8bc27e01b1 100644 --- a/lib/content-services/document-list/components/document-list.component.spec.ts +++ b/lib/content-services/document-list/components/document-list.component.spec.ts @@ -959,6 +959,38 @@ describe('DocumentList', () => { documentList.loadFolderByNodeId('123'); }); + it('should reset noPermission on loading folder by node id', () => { + documentList.noPermission = true; + fixture.detectChanges(); + + documentList.loadFolderByNodeId('-trashcan-'); + fixture.detectChanges(); + + expect(documentList.noPermission).toBeFalsy(); + }); + + it('should reset noPermission upon reload', () => { + documentList.noPermission = true; + fixture.detectChanges(); + + documentList.reload(); + fixture.detectChanges(); + + expect(documentList.noPermission).toBeFalsy(); + }); + + it('should reload contents if node data changes after previously got noPermission error', () => { + spyOn(documentList.data, 'loadPage').and.callThrough(); + + documentList.noPermission = true; + fixture.detectChanges(); + + documentList.ngOnChanges({ node: new SimpleChange(null, {list: {entities: {}}}, true) }); + + expect(documentList.data.loadPage).toHaveBeenCalled(); + expect(documentList.noPermission).toBeFalsy(); + }); + xit('should load previous page if there are no other elements in multi page table', (done) => { documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692'; documentList.folderNode = new NodeMinimal(); diff --git a/lib/content-services/document-list/components/document-list.component.ts b/lib/content-services/document-list/components/document-list.component.ts index bf50a7530a..64f07db716 100644 --- a/lib/content-services/document-list/components/document-list.component.ts +++ b/lib/content-services/document-list/components/document-list.component.ts @@ -337,6 +337,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte } else if (this.data) { if (changes.node && changes.node.currentValue) { this.resetSelection(); + this.data.loadPage(changes.node.currentValue); this.pagination.next(changes.node.currentValue.list.pagination); } else if (changes.rowFilter) { @@ -557,6 +558,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte loadFolderNodesByFolderNodeId(id: string, maxItems: number, skipCount: number, merge: boolean = false): Promise { return new Promise((resolve, reject) => { this.resetSelection(); + this.documentListService .getFolder(null, { maxItems: maxItems, @@ -581,6 +583,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte resetSelection() { this.dataTable.resetSelection(); this.selection = []; + this.noPermission = false; } private isSkipCountChanged(changePage: SimpleChanges) { From f0dcaa02fbf8ffda9001eff42836790f3c783131 Mon Sep 17 00:00:00 2001 From: Vito Date: Thu, 8 Mar 2018 18:05:00 +0000 Subject: [PATCH 025/188] =?UTF-8?q?[ADF-2361]=20added=20breadcrumb=20trans?= =?UTF-8?q?form=20function=20to=20the=20breadcrumb=20comp=E2=80=A6=20(#305?= =?UTF-8?q?0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ADF-2361] added breadcrumb transform function to the breadcrumb component * [ADF-2361] added PR review changes --- docs/breadcrumb.component.md | 1 + .../breadcrumb/breadcrumb.component.spec.ts | 24 +++++++++++++++++++ .../breadcrumb/breadcrumb.component.ts | 21 +++++++++++++--- ...content-node-selector-panel.component.html | 1 + ...tent-node-selector-panel.component.spec.ts | 5 ++-- .../content-node-selector-panel.component.ts | 2 +- 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/breadcrumb.component.md b/docs/breadcrumb.component.md index 3097013461..1acfaed233 100644 --- a/docs/breadcrumb.component.md +++ b/docs/breadcrumb.component.md @@ -25,6 +25,7 @@ Indicates the current position within a navigation hierarchy. | root | `string` | `null` | (optional) Name of the root element of the breadcrumb. You can use this property to rename "Company Home" to "Personal Files" for example. You can use an i18n resource key for the property value. | | rootId | `string` | `null` | (optional) The id of the root element. You can use this property to set a custom element the breadcrumb should start with. | | target | `DocumentListComponent` | | (optional) Document List component to operate with. The list will update when the breadcrumb is clicked. | +| transform | (node) => any | null | Action to be performed to the chosen/folder node before building the breadcrumb UI. Can be useful when custom formatting is needed to the breadcrumb, so changing the node's path elements that help build the breadcrumb can be done through this function. | ### Events diff --git a/lib/content-services/breadcrumb/breadcrumb.component.spec.ts b/lib/content-services/breadcrumb/breadcrumb.component.spec.ts index ad240556f8..0bb40a4bc4 100644 --- a/lib/content-services/breadcrumb/breadcrumb.component.spec.ts +++ b/lib/content-services/breadcrumb/breadcrumb.component.spec.ts @@ -205,4 +205,28 @@ describe('Breadcrumb', () => { expect(route[0].id).toBe('custom-id'); expect(route[0].name).toBe('custom-name'); }); + + it('should apply the transformation function when there is one', () => { + const node: any = { + id: null, + name: null, + path: { + elements: [ + { id: 'element-1-id', name: 'element-1-name' }, + { id: 'element-2-id', name: 'element-2-name' }, + { id: 'element-3-id', name: 'element-3-name' } + ] + } + }; + component.transform = ((transformNode) => { + transformNode.id = 'test-id'; + transformNode.name = 'test-name'; + return transformNode; + }); + let change = new SimpleChange(null, node, true); + component.ngOnChanges({'folderNode': change}); + expect(component.route.length).toBe(4); + expect(component.route[3].id).toBe('test-id'); + expect(component.route[3].name).toBe('test-name'); + }); }); diff --git a/lib/content-services/breadcrumb/breadcrumb.component.ts b/lib/content-services/breadcrumb/breadcrumb.component.ts index 9679c7690e..c6301bb2c1 100644 --- a/lib/content-services/breadcrumb/breadcrumb.component.ts +++ b/lib/content-services/breadcrumb/breadcrumb.component.ts @@ -15,7 +15,14 @@ * limitations under the License. */ -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core'; +import { Component, + EventEmitter, + Input, + OnChanges, + Output, + SimpleChanges, + ViewEncapsulation, + OnInit } from '@angular/core'; import { MinimalNodeEntryEntity, PathElementEntity } from 'alfresco-js-api'; import { DocumentListComponent } from '../document-list'; @@ -28,7 +35,7 @@ import { DocumentListComponent } from '../document-list'; 'class': 'adf-breadcrumb' } }) -export class BreadcrumbComponent implements OnChanges { +export class BreadcrumbComponent implements OnInit, OnChanges { /** Active node, builds UI based on folderNode.path.elements collection. */ @Input() @@ -53,6 +60,9 @@ export class BreadcrumbComponent implements OnChanges { @Input() target: DocumentListComponent; + @Input() + transform: (node) => any; + route: PathElementEntity[] = []; get hasRoot(): boolean { @@ -63,9 +73,14 @@ export class BreadcrumbComponent implements OnChanges { @Output() navigate: EventEmitter = new EventEmitter(); + ngOnInit() { + this.transform = this.transform ? this.transform : null ; + } + ngOnChanges(changes: SimpleChanges): void { if (changes.folderNode) { - const node: MinimalNodeEntryEntity = changes.folderNode.currentValue; + let node: MinimalNodeEntryEntity = null; + node = this.transform ? this.transform(changes.folderNode.currentValue) : changes.folderNode.currentValue; this.route = this.parseRoute(node); } } diff --git a/lib/content-services/content-node-selector/content-node-selector-panel.component.html b/lib/content-services/content-node-selector/content-node-selector-panel.component.html index e3a3233421..a632e7dd46 100644 --- a/lib/content-services/content-node-selector/content-node-selector-panel.component.html +++ b/lib/content-services/content-node-selector/content-node-selector-panel.component.html @@ -40,6 +40,7 @@ class="adf-content-node-selector-content-breadcrumb" (navigate)="clear()" [target]="documentList" + [transform]="breadcrumbTransform" [folderNode]="breadcrumbFolderNode" data-automation-id="content-node-selector-content-breadcrumb"> diff --git a/lib/content-services/content-node-selector/content-node-selector-panel.component.spec.ts b/lib/content-services/content-node-selector/content-node-selector-panel.component.spec.ts index a7ea7a4385..8763dc671b 100644 --- a/lib/content-services/content-node-selector/content-node-selector-panel.component.spec.ts +++ b/lib/content-services/content-node-selector/content-node-selector-panel.component.spec.ts @@ -261,7 +261,7 @@ describe('ContentNodeSelectorComponent', () => { }); it('should make changes to breadcrumb\'s folderNode if breadcrumbTransform is defined', (done) => { - const transformedFolderNode = { path: { elements: [{id: 'testId', name: 'testName'}] } }; + const transformedFolderNode = { id: 'trans-node', name: 'trans-node-name', path: { elements: [{id: 'testId', name: 'testName'}] } }; component.breadcrumbTransform = (() => { return transformedFolderNode; }); @@ -272,7 +272,8 @@ describe('ContentNodeSelectorComponent', () => { expect(component.breadcrumbTransform).not.toBeNull(); const breadcrumb = fixture.debugElement.query(By.directive(DropdownBreadcrumbComponent)); - expect(breadcrumb.componentInstance.folderNode).toBe(transformedFolderNode); + expect(breadcrumb.componentInstance.route[0].name).toBe('testName'); + expect(breadcrumb.componentInstance.route[0].id).toBe('testId'); done(); }); }); diff --git a/lib/content-services/content-node-selector/content-node-selector-panel.component.ts b/lib/content-services/content-node-selector/content-node-selector-panel.component.ts index 3cbdfc4f7c..3f8f9de4fd 100644 --- a/lib/content-services/content-node-selector/content-node-selector-panel.component.ts +++ b/lib/content-services/content-node-selector/content-node-selector-panel.component.ts @@ -174,7 +174,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit { folderNode = this.documentList.folderNode; } - return this.breadcrumbTransform ? this.breadcrumbTransform(folderNode) : folderNode; + return folderNode; } /** From 8a70e026cd853dfdeb7c2f269c909cd7e4164c0b Mon Sep 17 00:00:00 2001 From: Vito Date: Thu, 8 Mar 2018 19:39:13 +0000 Subject: [PATCH 026/188] [ADF-1814] added delete event to mobile menu (#3052) --- demo-shell/src/app/components/files/files.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index ff581fd2c5..d56f2bce22 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -156,7 +156,9 @@ From 606009cac2e67d7ed9d40c063550bcd8c0da0e92 Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Thu, 8 Mar 2018 19:41:38 +0000 Subject: [PATCH 027/188] [ADF-2456] Fixed property table formatting (#3051) --- docs/document-list.component.md | 22 +++++++++---------- lib/config/DocProcessor/docProcessor.js | 4 ++-- lib/config/DocProcessor/tools/tscProps.js | 11 ++++++++-- lib/config/DocProcessor/tools/tscProps.ts | 14 +++++++++--- .../components/document-list.component.ts | 8 ++++--- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/docs/document-list.component.md b/docs/document-list.component.md index f38c5a6165..cb5982ca86 100644 --- a/docs/document-list.component.md +++ b/docs/document-list.component.md @@ -2,6 +2,7 @@ Added: v2.0.0 Status: Active --- + # Document List component Displays the documents from a repository. @@ -51,20 +52,22 @@ Displays the documents from a repository. ``` ### Properties - + | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | +| display | `string` | `DisplayMode.List` | Change the display mode of the table. Can be "list" or "gallery". | | permissionsStyle | `PermissionStyleModel[]` | `[]` | Define a set of CSS styles styles to apply depending on the permission of the user on that node. See the Permission Style model page for further details and examples. | | locationFormat | `string` | `'/'` | The default route for all the location-based columns (if declared). | | navigate | `boolean` | `true` | Toggles navigation to folder content or file preview | -| navigationMode | `string` | `DocumentListComponent.DOUBLE_CLICK_NAVIGATION` | User interaction for folder navigation or file preview. Valid values are "click" and "dblclick". | +| showHeader | `boolean` | `true` | Toggles the header | +| navigationMode | `string` | See description | User interaction for folder navigation or file preview. Valid values are "click" and "dblclick". Default value: "dblclick" | | thumbnails | `boolean` | `false` | Show document thumbnails rather than icons | | selectionMode | `string` | `'single'` | Row selection mode. Can be null, `single` or `multiple`. For `multiple` mode, you can use Cmd (macOS) or Ctrl (Win) modifier key to toggle selection for multiple rows. | | multiselect | `boolean` | `false` | Toggles multiselect mode | | contentActions | `boolean` | `false` | Toggles content actions for each row | | contentActionsPosition | `string` | `'right'` | Position of the content actions dropdown menu. Can be set to "left" or "right". | | contextMenuActions | `boolean` | `false` | Toggles context menus for each row | -| emptyFolderImageUrl | `string` | `'./assets/images/empty_doc_lib.svg'` | Custom image for empty folder | +| emptyFolderImageUrl | `string` | See description | Custom image for empty folder. Default value: './assets/images/empty_doc_lib.svg' | | allowDropFiles | `boolean` | `false` | Toggle file drop support for rows (see Upload Directive for further details | | sorting | `string[]` | | Defines default sorting. The format is an array of 2 strings `[key, direction]` i.e. `['name', 'desc']` or `['name', 'asc']`. Set this value only if you want to override the default sorting detected by the component based on columns. | | rowStyle | `string` | | The inline style to apply to every row. See the Angular NgStyle docs for more details and usage examples. | @@ -78,19 +81,17 @@ Displays the documents from a repository. | maxItems | `number` | | Default value is stored into user preference settings | | skipCount | `number` | `0` | Number of elements to skip over for pagination purposes | | enableInfiniteScrolling | `boolean` | `false` | Set document list to work in infinite scrolling mode | -| showHeader | `boolean` | `true` | Toggles header visibility | -| display | string | 'list' | change the display mode can be one of the values provided by the enum : **list**, **gallery** | ### Events | Name | Type | Description | | ---- | ---- | ----------- | -| nodeClick | `EventEmitter` | Emitted when the user clicks a list node | -| nodeDblClick | `EventEmitter` | Emitted when the user double-clicks a list node | -| folderChange | `EventEmitter` | Emitted when the current display folder changes | +| nodeClick | `EventEmitter` | Emitted when the user clicks a list node | +| nodeDblClick | `EventEmitter` | Emitted when the user double-clicks a list node | +| folderChange | `EventEmitter` | Emitted when the current display folder changes | | preview | `EventEmitter` | Emitted when the user acts upon files with either single or double click (depends on `navigation-mode`). Useful for integration with the Viewer component. | -| ready | `EventEmitter` | Emitted when the Document List has loaded all items and is ready for use | -| error | `EventEmitter` | Emitted when the API fails to get the Document List data | +| ready | `EventEmitter` | Emitted when the Document List has loaded all items and is ready for use | +| error | `EventEmitter` | Emitted when the API fails to get the Document List data | ## Details @@ -147,7 +148,6 @@ If you want to enable the card view mode you need to set to 'gallery' the input ![card-view](docassets/images/document-list-card-view.png) - ### Pagination strategy The Document List by default supports 2 type of pagination, the **finite** and the **infinite** pagination. diff --git a/lib/config/DocProcessor/docProcessor.js b/lib/config/DocProcessor/docProcessor.js index ee19af12b5..d408e409d5 100644 --- a/lib/config/DocProcessor/docProcessor.js +++ b/lib/config/DocProcessor/docProcessor.js @@ -51,7 +51,7 @@ function updatePhase(srcFolder, destFolder, filenames, aggData) { var pathname = path.resolve(srcFolder, filenames[i]); var src = fs.readFileSync(pathname); - var tree = remark().parse(src) + var tree = remark().use(frontMatter, ["yaml"]).parse(src) var modified = false; @@ -60,7 +60,7 @@ function updatePhase(srcFolder, destFolder, filenames, aggData) { }); if (modified) - fs.writeFileSync(path.resolve(destFolder, filenames[i]), remark().data("settings", {paddedTable: false}).stringify(tree)); + fs.writeFileSync(path.resolve(destFolder, filenames[i]), remark().use(frontMatter, {type: 'yaml', fence: '---'}).data("settings", {paddedTable: false}).stringify(tree)); //console.log(JSON.stringify(tree)); } } diff --git a/lib/config/DocProcessor/tools/tscProps.js b/lib/config/DocProcessor/tools/tscProps.js index eb6a3bd3f2..3aaaa1fb72 100644 --- a/lib/config/DocProcessor/tools/tscProps.js +++ b/lib/config/DocProcessor/tools/tscProps.js @@ -6,6 +6,8 @@ var heading = require("mdast-util-heading-range"); var remark = require("remark"); var unist = require("../unistHelpers"); var typescript_1 = require("typescript"); +// Max number of characters in the text for the default value column. +var maxDefaultTextLength = 20; function initPhase(aggData) { } exports.initPhase = initPhase; @@ -284,15 +286,20 @@ function buildPropsTable(props, includeInitializer) { for (var i = 0; i < props.length; i++) { var pName = props[i].name; var pType = props[i].type; - var pDefault = props[i].initializer || ""; var pDesc = props[i].docText || ""; if (pDesc) { pDesc = pDesc.replace(/[\n\r]+/, " "); } var descCellContent = remark().parse(pDesc).children; + var pDefault = props[i].initializer || ""; var defaultCellContent; if (pDefault) { - defaultCellContent = unist.makeInlineCode(pDefault); + if (pDefault.length > maxDefaultTextLength) { + defaultCellContent = unist.makeText("See description"); + console.log("Warning: property \"" + pName + "\" default value substituted (> " + maxDefaultTextLength + " chars)"); + } + else + defaultCellContent = unist.makeInlineCode(pDefault); } else { defaultCellContent = unist.makeText(""); diff --git a/lib/config/DocProcessor/tools/tscProps.ts b/lib/config/DocProcessor/tools/tscProps.ts index 99b685a58b..514a59d533 100644 --- a/lib/config/DocProcessor/tools/tscProps.ts +++ b/lib/config/DocProcessor/tools/tscProps.ts @@ -1,7 +1,6 @@ import * as ts from "typescript"; import * as fs from "fs"; import * as path from "path"; -import * as program from "commander"; import * as heading from "mdast-util-heading-range"; import * as remark from "remark"; @@ -9,6 +8,10 @@ import * as remark from "remark"; import * as unist from "../unistHelpers"; import { JsxEmit, isClassDeclaration, PropertyDeclaration } from "typescript"; + +// Max number of characters in the text for the default value column. +const maxDefaultTextLength = 20; + export function initPhase(aggData) { } @@ -397,7 +400,6 @@ function buildPropsTable(props: PropData[], includeInitializer: boolean = true) for (var i = 0; i < props.length; i++) { var pName = props[i].name; var pType = props[i].type; - var pDefault = props[i].initializer || ""; var pDesc = props[i].docText || ""; if (pDesc) { @@ -406,10 +408,16 @@ function buildPropsTable(props: PropData[], includeInitializer: boolean = true) var descCellContent = remark().parse(pDesc).children; + var pDefault = props[i].initializer || ""; + var defaultCellContent; if (pDefault) { - defaultCellContent = unist.makeInlineCode(pDefault); + if (pDefault.length > maxDefaultTextLength) { + defaultCellContent = unist.makeText("See description"); + console.log(`Warning: property "${pName}" default value substituted (> ${maxDefaultTextLength} chars)`); + } else + defaultCellContent = unist.makeInlineCode(pDefault); } else { defaultCellContent = unist.makeText(""); } diff --git a/lib/content-services/document-list/components/document-list.component.ts b/lib/content-services/document-list/components/document-list.component.ts index 64f07db716..294e399bf4 100644 --- a/lib/content-services/document-list/components/document-list.component.ts +++ b/lib/content-services/document-list/components/document-list.component.ts @@ -73,7 +73,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte @ContentChild(DataColumnListComponent) columnList: DataColumnListComponent; - /* change the display mode of the table list or gallery */ + /** Change the display mode of the table. Can be "list" or "gallery". */ @Input() display: string = DisplayMode.List; @@ -96,7 +96,9 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte @Input() showHeader: boolean = true; - /** User interaction for folder navigation or file preview. Valid values are "click" and "dblclick". */ + /** User interaction for folder navigation or file preview. + * Valid values are "click" and "dblclick". Default value: "dblclick" + */ @Input() navigationMode: string = DocumentListComponent.DOUBLE_CLICK_NAVIGATION; // click|dblclick @@ -126,7 +128,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte @Input() contextMenuActions: boolean = false; - /** Custom image for empty folder */ + /** Custom image for empty folder. Default value: './assets/images/empty_doc_lib.svg' */ @Input() emptyFolderImageUrl: string = './assets/images/empty_doc_lib.svg'; From ae489f6737dba2aa562a6e455cda5ad6a73bf4a8 Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Fri, 9 Mar 2018 12:16:05 +0000 Subject: [PATCH 028/188] [ADF-2240] fix e2e and test in demo shell (#3035) * fix e2e and test in demo shell * test single run demo shell conf * fix script e2e * fix test lint problems * remove async from nested test * fix pdf test * modify url load pdf strategy test * SimpleChange import * pdf viewer test fix * remove force closing * refactor pdf viewer -remove promise approach -add event rendered -add destroy worker * increment timeout * use proxy files * remove require * fix viewer component test * remove last require * prefer use of done for txt viewer test --- demo-shell/.angular-cli.json | 8 - demo-shell/e2e/app.e2e-spec.ts | 16 +- demo-shell/e2e/app.po.ts | 12 +- demo-shell/package.json | 2 +- demo-shell/src/app/app.component.spec.ts | 43 +- demo-shell/src/polyfills.ts | 4 + demo-shell/src/tsconfig.spec.json | 42 +- demo-shell/tslint.json | 1 - lib/config/karma.conf-all.js | 8 +- .../components/search-trigger.directive.ts | 2 +- .../components/search.component.spec.ts | 35 +- .../datatable/data-row-action.event.ts | 22 +- lib/core/models/product-version.model.ts | 46 +- .../components/pdfViewer.component.spec.ts | 671 +++++++++--------- .../viewer/components/pdfViewer.component.ts | 75 +- .../components/txtViewer.component.spec.ts | 4 +- .../components/viewer.component.spec.ts | 10 +- .../task-list/models/filter.model.ts | 48 +- scripts/README.md | 1 + scripts/start.sh | 18 +- tslint.json | 1 - 21 files changed, 566 insertions(+), 503 deletions(-) diff --git a/demo-shell/.angular-cli.json b/demo-shell/.angular-cli.json index 0b378c281f..fc67e939c3 100644 --- a/demo-shell/.angular-cli.json +++ b/demo-shell/.angular-cli.json @@ -149,14 +149,6 @@ { "project": "src/tsconfig.app.json", "exclude": "**/node_modules/**/*" - }, - { - "project": "src/tsconfig.spec.json", - "exclude": "**/node_modules/**/*" - }, - { - "project": "e2e/tsconfig.e2e.json", - "exclude": "**/node_modules/**/*" } ], "test": { diff --git a/demo-shell/e2e/app.e2e-spec.ts b/demo-shell/e2e/app.e2e-spec.ts index cd3f2ce792..5cbdd1f59f 100644 --- a/demo-shell/e2e/app.e2e-spec.ts +++ b/demo-shell/e2e/app.e2e-spec.ts @@ -1,14 +1,14 @@ import { MyappPage } from './app.po'; describe('myapp App', () => { - let page: MyappPage; + let page: MyappPage; - beforeEach(() => { - page = new MyappPage(); - }); + beforeEach(() => { + page = new MyappPage(); + }); - it('should display message saying app works', () => { - page.navigateTo(); - expect(page.getParagraphText()).toEqual('app works!'); - }); + it('should display toolbar', () => { + page.navigateTo(); + expect(page.getToolbar()).toBeDefined(); + }); }); diff --git a/demo-shell/e2e/app.po.ts b/demo-shell/e2e/app.po.ts index ecb0bc31b9..73e3ccb8a1 100644 --- a/demo-shell/e2e/app.po.ts +++ b/demo-shell/e2e/app.po.ts @@ -1,11 +1,11 @@ import { browser, element, by } from 'protractor'; export class MyappPage { - navigateTo() { - return browser.get('/'); - } + navigateTo() { + return browser.get('/'); + } - getParagraphText() { - return element(by.css('app-root h1')).getText(); - } + getToolbar() { + return element(by.tagName('adf-toolbar')); + } } diff --git a/demo-shell/package.json b/demo-shell/package.json index af4e8f40bc..334490be82 100644 --- a/demo-shell/package.json +++ b/demo-shell/package.json @@ -14,7 +14,7 @@ "build:dist": "npm run validate-config && npm run style:dev && npm run server-versions && rimraf dist && node --max_old_space_size=30000 node_modules/.bin/ng build --prod --build-optimizer=false --aot=false --app dist", "style:dev": "npm run webpack -- --config config/webpack.style.js --progress --profile --bail", "copy:dev": "node ./config/dev-copy-watch.js", - "test": "ng test", + "test": " npm run clean-lib-angular && ng test --single-run", "lint": "ng lint", "e2e": "ng e2e", "validate-config": "ajv validate -s ../lib/core/app-config/schema.json -d ./src/app.config.json --errors=text --verbose", diff --git a/demo-shell/src/app/app.component.spec.ts b/demo-shell/src/app/app.component.spec.ts index c740bcd745..91a015b61e 100644 --- a/demo-shell/src/app/app.component.spec.ts +++ b/demo-shell/src/app/app.component.spec.ts @@ -1,32 +1,25 @@ import { TestBed, async } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AdfModule } from './adf.module'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ - AppComponent - ], - }).compileComponents(); - })); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + RouterTestingModule, + AdfModule + ], + declarations: [ + AppComponent + ] + }).compileComponents(); + })); - it('should create the app', async(() => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - })); - - it(`should have as title 'app works!'`, async(() => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('app works!'); - })); - - it('should render title in a h1 tag', async(() => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('app works!'); - })); + it('should create the app', async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); }); diff --git a/demo-shell/src/polyfills.ts b/demo-shell/src/polyfills.ts index 229e7fbf23..b7944674fa 100644 --- a/demo-shell/src/polyfills.ts +++ b/demo-shell/src/polyfills.ts @@ -60,6 +60,10 @@ import 'zone.js/dist/zone'; // Included with Angular CLI. * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 */ import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +import 'intl/locale-data/jsonp/en'; /** * Support custom event in IE11 diff --git a/demo-shell/src/tsconfig.spec.json b/demo-shell/src/tsconfig.spec.json index 510e3f1fda..62ecc00647 100644 --- a/demo-shell/src/tsconfig.spec.json +++ b/demo-shell/src/tsconfig.spec.json @@ -2,19 +2,41 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/spec", - "module": "commonjs", - "target": "es5", - "baseUrl": "", + "module": "es2015", + "rootDir": "..", + "baseUrl": ".", + "skipLibCheck": false, "types": [ "jasmine", "node" - ] + ], + "paths": { + "alfresco-js-api": [ + "../node_modules/alfresco-js-api/dist/alfresco-js-api.js" + ], + "rxjs/*": [ + "../node_modules/rxjs/*" + ], + "@angular/*": [ + "../node_modules/@angular/*" + ], + "@alfresco/adf-core": [ + "../../lib/core" + ], + "@alfresco/adf-content-services": [ + "../../lib/content-services" + ], + "@alfresco/adf-process-services": [ + "../../lib/process-services" + ], + "@alfresco/adf-insights": [ + "../../lib/insights" + ] + } }, - "files": [ - "test.ts" + "exclude": [ ], - "include": [ - "**/*.spec.ts", - "**/*.d.ts" - ] + "angularCompilerOptions": { + "skipTemplateCodegen": false + } } diff --git a/demo-shell/tslint.json b/demo-shell/tslint.json index 71d1f7d829..2afece4c98 100644 --- a/demo-shell/tslint.json +++ b/demo-shell/tslint.json @@ -99,7 +99,6 @@ "variable-declaration": "nospace" } ], - "typeof-compare": true, "unified-signatures": true, "variable-name": false, "whitespace": [ diff --git a/lib/config/karma.conf-all.js b/lib/config/karma.conf-all.js index 540f03f4fe..34b13a7430 100644 --- a/lib/config/karma.conf-all.js +++ b/lib/config/karma.conf-all.js @@ -44,7 +44,9 @@ module.exports = function (config) { {pattern: config.component + '/**/*.ts', included: false, served: true, watched: false}, - {pattern: './config/app.config.json', included: false, served: true, watched: false} + {pattern: './config/app.config.json', included: false, served: true, watched: false}, + {pattern: './core/viewer/assets/fake-test-file.pdf', included: false, served: true, watched: false}, + {pattern: './core/viewer/assets/fake-test-file.txt', included: false, served: true, watched: false} ], webpack: (config.mode === 'coverage') ? webpackCoverage(config) : webpackTest(config), @@ -59,7 +61,9 @@ module.exports = function (config) { port: 9876, proxies: { - '/app.config.json': '/base/config/app.config.json' + '/app.config.json': '/base/config/app.config.json', + '/fake-test-file.pdf': '/base/core/viewer/assets/fake-test-file.pdf', + '/fake-test-file.txt': '/base/core/viewer/assets/fake-test-file.txt' }, // level of logging diff --git a/lib/content-services/search/components/search-trigger.directive.ts b/lib/content-services/search/components/search-trigger.directive.ts index c8c196d9be..4c9b16eb68 100644 --- a/lib/content-services/search/components/search-trigger.directive.ts +++ b/lib/content-services/search/components/search-trigger.directive.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -/* tslint:disable:no-input-rename */ +/* tslint:disable: no-input-rename no-use-before-declare no-input-rename */ import { ENTER, ESCAPE } from '@angular/cdk/keycodes'; import { diff --git a/lib/content-services/search/components/search.component.spec.ts b/lib/content-services/search/components/search.component.spec.ts index 133a157edc..1671b2537b 100644 --- a/lib/content-services/search/components/search.component.spec.ts +++ b/lib/content-services/search/components/search.component.spec.ts @@ -59,7 +59,7 @@ describe('SearchComponent', () => { fixture.destroy(); }); - it('should clear results straight away when a new search term is entered', async(() => { + it('should clear results straight away when a new search term is entered', (done) => { spyOn(searchService, 'search') .and.returnValues(Observable.of(result), Observable.of(differentResult)); @@ -75,11 +75,12 @@ describe('SearchComponent', () => { fixture.detectChanges(); optionShowed = element.querySelectorAll('#autocomplete-search-result-list > li').length; expect(optionShowed).toBe(1); + done(); }); }); - })); + }); - it('should display the returned search results', async(() => { + it('should display the returned search results', (done) => { spyOn(searchService, 'search') .and.returnValue(Observable.of(result)); @@ -89,10 +90,11 @@ describe('SearchComponent', () => { fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#result_option_0').textContent.trim()).toBe('MyDoc'); + done(); }); - })); + }); - it('should emit error event when search call fail', async(() => { + it('should emit error event when search call fail', (done) => { spyOn(searchService, 'search') .and.returnValue(Observable.fromPromise(Promise.reject({ status: 402 }))); component.setSearchWordTo('searchTerm'); @@ -101,10 +103,11 @@ describe('SearchComponent', () => { fixture.detectChanges(); let message: HTMLElement = element.querySelector('#component-result-message'); expect(message.textContent).toBe('ERROR'); + done(); }); - })); + }); - it('should be able to hide the result panel', async(() => { + it('should be able to hide the result panel', (done) => { spyOn(searchService, 'search') .and.returnValues(Observable.of(result), Observable.of(differentResult)); @@ -120,9 +123,10 @@ describe('SearchComponent', () => { fixture.detectChanges(); let elementList = element.querySelector('#adf-search-results-content'); expect(elementList.classList).toContain('adf-search-hide'); + done(); }); }); - })); + }); }); describe('search node', () => { @@ -131,7 +135,7 @@ describe('SearchComponent', () => { fixture.destroy(); }); - it('should perform a search based on the query node given', async(() => { + it('should perform a search based on the query node given', (done) => { spyOn(searchService, 'searchByQueryBody') .and.callFake((searchObj) => fakeNodeResultSearch(searchObj)); let fakeSearchNode: QueryBody = { @@ -151,10 +155,11 @@ describe('SearchComponent', () => { expect(optionShowed).toBe(1); let folderOption: HTMLElement = element.querySelector('#result_option_0'); expect(folderOption.textContent.trim()).toBe('MyFolder'); + done(); }); - })); + }); - it('should perform a search with a defaultNode if no searchnode is given', async(() => { + it('should perform a search with a defaultNode if no searchnode is given', (done) => { spyOn(searchService, 'search') .and.returnValue(Observable.of(result)); component.setSearchWordTo('searchTerm'); @@ -165,10 +170,11 @@ describe('SearchComponent', () => { expect(optionShowed).toBe(1); let folderOption: HTMLElement = element.querySelector('#result_option_0'); expect(folderOption.textContent.trim()).toBe('MyDoc'); + done(); }); - })); + }); - it('should perform a search with the searchNode given', async(() => { + it('should perform a search with the searchNode given', (done) => { spyOn(searchService, 'searchByQueryBody') .and.callFake((searchObj) => fakeNodeResultSearch(searchObj)); let fakeSearchNode: QueryBody = { @@ -188,7 +194,8 @@ describe('SearchComponent', () => { expect(optionShowed).toBe(1); let folderOption: HTMLElement = element.querySelector('#result_option_0'); expect(folderOption.textContent.trim()).toBe('TEST_DOC'); + done(); }); - })); + }); }); }); diff --git a/lib/core/datatable/components/datatable/data-row-action.event.ts b/lib/core/datatable/components/datatable/data-row-action.event.ts index 1949df6d90..ce9e327283 100644 --- a/lib/core/datatable/components/datatable/data-row-action.event.ts +++ b/lib/core/datatable/components/datatable/data-row-action.event.ts @@ -18,6 +18,17 @@ import { BaseEvent } from '../../../events'; import { DataRow } from '../../data/data-row.model'; +export class DataRowActionModel { + + row: DataRow; + action: any; + + constructor(row: DataRow, action: any) { + this.row = row; + this.action = action; + } +} + export class DataRowActionEvent extends BaseEvent { // backwards compatibility with 1.2.0 and earlier @@ -31,14 +42,3 @@ export class DataRowActionEvent extends BaseEvent { } } - -export class DataRowActionModel { - - row: DataRow; - action: any; - - constructor(row: DataRow, action: any) { - this.row = row; - this.action = action; - } -} diff --git a/lib/core/models/product-version.model.ts b/lib/core/models/product-version.model.ts index 526f1904a0..95a656d76a 100644 --- a/lib/core/models/product-version.model.ts +++ b/lib/core/models/product-version.model.ts @@ -33,29 +33,6 @@ export class BpmProductVersionModel { } } -export class EcmProductVersionModel { - edition: string; - version: VersionModel; - license: LicenseModel; - status: VersionStatusModel; - modules: VersionModuleModel[] = []; - - constructor(obj?: any) { - if (obj && obj.entry && obj.entry.repository) { - this.edition = obj.entry.repository.edition || null; - this.version = new VersionModel(obj.entry.repository.version); - this.license = new LicenseModel(obj.entry.repository.license); - this.status = new VersionStatusModel(obj.entry.repository.status); - if (obj.entry.repository.modules) { - obj.entry.repository.modules.forEach((module) => { - this.modules.push(new VersionModuleModel(module)); - }); - } - } - } - -} - export class VersionModel { major: string; minor: string; @@ -139,3 +116,26 @@ export class VersionModuleModel { } } } + +export class EcmProductVersionModel { + edition: string; + version: VersionModel; + license: LicenseModel; + status: VersionStatusModel; + modules: VersionModuleModel[] = []; + + constructor(obj?: any) { + if (obj && obj.entry && obj.entry.repository) { + this.edition = obj.entry.repository.edition || null; + this.version = new VersionModel(obj.entry.repository.version); + this.license = new LicenseModel(obj.entry.repository.license); + this.status = new VersionStatusModel(obj.entry.repository.status); + if (obj.entry.repository.modules) { + obj.entry.repository.modules.forEach((module) => { + this.modules.push(new VersionModuleModel(module)); + }); + } + } + } + +} diff --git a/lib/core/viewer/components/pdfViewer.component.spec.ts b/lib/core/viewer/components/pdfViewer.component.spec.ts index ede7454035..aa130e5a7d 100644 --- a/lib/core/viewer/components/pdfViewer.component.spec.ts +++ b/lib/core/viewer/components/pdfViewer.component.spec.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import { Component, SimpleChange, ViewChild } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { AlfrescoApiService, @@ -28,36 +29,48 @@ import { RenderingQueueServices } from '../services/rendering-queue.services'; import { PdfViewerComponent } from './pdfViewer.component'; import { PdfThumbListComponent } from './pdfViewer-thumbnails.component'; import { PdfThumbComponent } from './pdfViewer-thumb.component'; +import { RIGHT_ARROW, LEFT_ARROW } from '@angular/cdk/keycodes'; -declare var require: any; +@Component({ + template: ` + + + ` +}) +class UrlTestComponent { -describe('Test PdfViewer component', () => { + @ViewChild(PdfViewerComponent) + pdfViewerComponent: PdfViewerComponent; - let component: PdfViewerComponent; - let fixture: ComponentFixture; - let element: HTMLElement; + urlFile: any; - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - ToolbarModule, - MaterialModule - ], - declarations: [ - PdfViewerComponent, - PdfThumbListComponent, - PdfThumbComponent - ], - providers: [ - SettingsService, - AuthenticationService, - AlfrescoApiService, - RenderingQueueServices - ] - }).compileComponents(); - })); + constructor() { + this.urlFile = './fake-test-file.pdf'; + } +} - function createFakeBlob(): Blob { +@Component({ + template: ` + + + ` +}) +class BlobTestComponent { + + @ViewChild(PdfViewerComponent) + pdfViewerComponent: PdfViewerComponent; + + blobFile: any; + + constructor() { + this.blobFile = this.createFakeBlob(); + } + + createFakeBlob(): Blob { let pdfData = atob( 'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' + 'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' + @@ -75,418 +88,408 @@ describe('Test PdfViewer component', () => { return new Blob([pdfData], { type: 'application/pdf' }); } - beforeEach(() => { +} + +describe('Test PdfViewer component', () => { + + let component: PdfViewerComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + let change: any; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + ToolbarModule, + MaterialModule + ], + declarations: [ + PdfViewerComponent, + PdfThumbListComponent, + PdfThumbComponent, + UrlTestComponent, + BlobTestComponent + ], + providers: [ + SettingsService, + AuthenticationService, + AlfrescoApiService, + RenderingQueueServices + ] + }).compileComponents(); + })); + + beforeEach((done) => { fixture = TestBed.createComponent(PdfViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; component.showToolbar = true; + component.inputPage('1'); + component.currentScale = 1; + + fixture.detectChanges(); + + fixture.whenStable().then(() => { + done(); + }); + }); + + it('should Loader be present', () => { + expect(element.querySelector('.loader-container')).not.toBeNull(); + }); + + describe('Required values', () => { + it('should thrown an error If urlfile is not present', () => { + change = new SimpleChange(null, null, true); + + expect(() => { + component.ngOnChanges({ 'urlFile': change }); + }).toThrow(new Error('Attribute urlFile or blobFile is required')); + }); + + it('should If blobFile is not present thrown an error ', () => { + change = new SimpleChange(null, null, true); + + expect(() => { + component.ngOnChanges({ 'blobFile': change }); + }).toThrow(new Error('Attribute urlFile or blobFile is required')); + }); }); describe('View with url file', () => { - beforeEach(() => { - component.urlFile = require('../assets/fake-test-file.pdf'); - fixture.detectChanges(); + + let fixtureUrlTestComponent: ComponentFixture; + let elementUrlTestComponent: HTMLElement; + + beforeEach((done) => { + fixtureUrlTestComponent = TestBed.createComponent(UrlTestComponent); + elementUrlTestComponent = fixtureUrlTestComponent.nativeElement; + + fixtureUrlTestComponent.detectChanges(); + + fixtureUrlTestComponent.whenStable().then(() => { + done(); + }); }); - it('should thrown an error If urlfile is not present', () => { - component.urlFile = undefined; + it('should Canvas be present', (done) => { + fixtureUrlTestComponent.detectChanges(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(elementUrlTestComponent.querySelector('.pdfViewer')).not.toBeNull(); + expect(elementUrlTestComponent.querySelector('.viewer-pdf-viewer')).not.toBeNull(); + done(); + }); + }, 5000); - fixture.detectChanges(); + it('should Next an Previous Buttons be present', (done) => { + fixtureUrlTestComponent.detectChanges(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(elementUrlTestComponent.querySelector('#viewer-previous-page-button')).not.toBeNull(); + expect(elementUrlTestComponent.querySelector('#viewer-next-page-button')).not.toBeNull(); + done(); + }); + }, 5000); - expect(() => { - component.ngOnChanges(null); - }).toThrow(new Error('Attribute urlFile or blobFile is required')); - }); + it('should Input Page elements be present', (done) => { - it('should Canvas be present', () => { - expect(element.querySelector('.pdfViewer')).not.toBeNull(); - expect(element.querySelector('.viewer-pdf-viewer')).not.toBeNull(); - }); + fixtureUrlTestComponent.detectChanges(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(elementUrlTestComponent.querySelector('.viewer-pagenumber-input')).toBeDefined(); + expect(elementUrlTestComponent.querySelector('.viewer-total-pages')).toBeDefined(); - it('should Loader be present', () => { - expect(element.querySelector('.loader-container')).not.toBeNull(); - }); + expect(elementUrlTestComponent.querySelector('#viewer-previous-page-button')).not.toBeNull(); + expect(elementUrlTestComponent.querySelector('#viewer-next-page-button')).not.toBeNull(); + done(); + }); + }, 5000); - it('should Next an Previous Buttons be present', () => { - expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull(); - expect(element.querySelector('#viewer-next-page-button')).not.toBeNull(); - }); - - it('should Input Page elements be present', () => { - expect(element.querySelector('.viewer-pagenumber-input')).toBeDefined(); - expect(element.querySelector('.viewer-total-pages')).toBeDefined(); - - expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull(); - expect(element.querySelector('#viewer-next-page-button')).not.toBeNull(); - }); - - it('should Toolbar be hide if showToolbar is false', () => { + it('should Toolbar be hide if showToolbar is false', (done) => { component.showToolbar = false; - fixture.detectChanges(); - - expect(element.querySelector('.viewer-toolbar-command')).toBeNull(); - expect(element.querySelector('.viewer-toolbar-pagination')).toBeNull(); - }); + fixtureUrlTestComponent.detectChanges(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(elementUrlTestComponent.querySelector('.viewer-toolbar-command')).toBeNull(); + expect(elementUrlTestComponent.querySelector('.viewer-toolbar-pagination')).toBeNull(); + done(); + }); + }, 5000); }); describe('View with blob file', () => { - beforeEach(() => { - component.urlFile = undefined; - component.blobFile = createFakeBlob(); + let fixtureBlobTestComponent: ComponentFixture; + let componentBlobTestComponent: BlobTestComponent; + let elementBlobTestComponent: HTMLElement; - fixture.detectChanges(); + beforeEach((done) => { + fixtureBlobTestComponent = TestBed.createComponent(BlobTestComponent); + componentBlobTestComponent = fixtureBlobTestComponent.componentInstance; + elementBlobTestComponent = fixtureBlobTestComponent.nativeElement; + + fixtureBlobTestComponent.detectChanges(); + + componentBlobTestComponent.pdfViewerComponent.rendered.subscribe(() => { + done(); + }); }); - it('should If blobFile is not present thrown an error ', () => { - component.blobFile = undefined; - expect(() => { - component.ngOnChanges(null); - }).toThrow(new Error('Attribute urlFile or blobFile is required')); - }); + it('should Canvas be present', (done) => { + fixtureBlobTestComponent.detectChanges(); - it('should Canvas be present', () => { - expect(element.querySelector('.pdfViewer')).not.toBeNull(); - expect(element.querySelector('.viewer-pdf-viewer')).not.toBeNull(); - }); + fixtureBlobTestComponent.whenStable().then(() => { + expect(elementBlobTestComponent.querySelector('.pdfViewer')).not.toBeNull(); + expect(elementBlobTestComponent.querySelector('.viewer-pdf-viewer')).not.toBeNull(); + done(); + }; + }, 5000); - it('should Loader be present', () => { - expect(element.querySelector('.loader-container')).not.toBeNull(); - }); + it('should Next an Previous Buttons be present', (done) => { + fixtureBlobTestComponent.detectChanges(); - it('should Next an Previous Buttons be present', () => { - expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull(); - expect(element.querySelector('#viewer-next-page-button')).not.toBeNull(); - }); + fixtureBlobTestComponent.whenStable().then(() => { + expect(elementBlobTestComponent.querySelector('#viewer-previous-page-button')).not.toBeNull(); + expect(elementBlobTestComponent.querySelector('#viewer-next-page-button')).not.toBeNull(); + done(); + }; + }, 5000); - it('should Input Page elements be present', () => { - expect(element.querySelector('.viewer-pagenumber-input')).toBeDefined(); - expect(element.querySelector('.viewer-total-pages')).toBeDefined(); + it('should Input Page elements be present', (done) => { + fixtureBlobTestComponent.detectChanges(); - expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull(); - expect(element.querySelector('#viewer-next-page-button')).not.toBeNull(); - }); + fixtureBlobTestComponent.whenStable().then(() => { + expect(elementBlobTestComponent.querySelector('.viewer-pagenumber-input')).toBeDefined(); + expect(elementBlobTestComponent.querySelector('.viewer-total-pages')).toBeDefined(); - it('should Toolbar be hide if showToolbar is false', () => { - component.showToolbar = false; + expect(elementBlobTestComponent.querySelector('#viewer-previous-page-button')).not.toBeNull(); + expect(elementBlobTestComponent.querySelector('#viewer-next-page-button')).not.toBeNull(); + done(); + }; + }, 5000); - fixture.detectChanges(); + it('should Toolbar be hide if showToolbar is false', (done) => { + componentBlobTestComponent.pdfViewerComponent.showToolbar = false; - expect(element.querySelector('.viewer-toolbar-command')).toBeNull(); - expect(element.querySelector('.viewer-toolbar-pagination')).toBeNull(); - }); + fixtureBlobTestComponent.detectChanges(); + + fixtureBlobTestComponent.whenStable().then(() => { + expect(elementBlobTestComponent.querySelector('.viewer-toolbar-command')).toBeNull(); + expect(elementBlobTestComponent.querySelector('.viewer-toolbar-pagination')).toBeNull(); + done(); + }; + }, 5000); }); describe('User interaction', () => { - beforeEach(async(() => { - component.urlFile = require('../assets/fake-test-file.pdf'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - component.inputPage('1'); + let fixtureUrlTestComponent: ComponentFixture; + let componentUrlTestComponent: UrlTestComponent; + let elementUrlTestComponent: HTMLElement; + + beforeEach((done) => { + fixtureUrlTestComponent = TestBed.createComponent(UrlTestComponent); + componentUrlTestComponent = fixtureUrlTestComponent.componentInstance; + elementUrlTestComponent = fixtureUrlTestComponent.nativeElement; + + fixtureUrlTestComponent.detectChanges(); + + componentUrlTestComponent.pdfViewerComponent.rendered.subscribe(() => { + done(); }); - })); + }); it('should Total number of pages be loaded', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(component.totalPages).toEqual(6); - done(); - }); - }); - }); + fixtureUrlTestComponent.detectChanges(); - it('should right arrow move to the next page', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(component.displayPage).toBe(1); - EventMock.keyDown(39); - fixture.detectChanges(); - expect(component.displayPage).toBe(2); - done(); - }); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.totalPages).toBe(6); + done(); }); - }); + }, 5000); it('should nextPage move to the next page', (done) => { - let nextPageButton: any = element.querySelector('#viewer-next-page-button'); + let nextPageButton: any = elementUrlTestComponent.querySelector('#viewer-next-page-button'); + nextPageButton.click(); - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { + fixtureUrlTestComponent.detectChanges(); - expect(component.displayPage).toBe(1); - nextPageButton.click(); - fixture.detectChanges(); - expect(component.displayPage).toBe(2); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(2); + done(); + }); + }, 5000); + + it('should event RIGHT_ARROW keyboard change pages', (done) => { + EventMock.keyDown(RIGHT_ARROW); + + fixtureUrlTestComponent.detectChanges(); + + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(2); + done(); + }); + }, 5000); + + it('should event LEFT_ARROW keyboard change pages', (done) => { + component.inputPage('2'); + + fixtureUrlTestComponent.detectChanges(); + + fixtureUrlTestComponent.whenStable().then(() => { + EventMock.keyDown(LEFT_ARROW); + + fixtureUrlTestComponent.detectChanges(); + + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(1); done(); }); }); - }); - - it('should event keyboard change pages', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - - expect(component.displayPage).toBe(1); - EventMock.keyDown(39); - EventMock.keyDown(39); - EventMock.keyDown(37); - fixture.detectChanges(); - expect(component.displayPage).toBe(2); - done(); - }); - }); - }); + }, 5000); it('should previous page move to the previous page', (done) => { - let previousPageButton: any = element.querySelector('#viewer-previous-page-button'); - let nextPageButton: any = element.querySelector('#viewer-next-page-button'); + let previousPageButton: any = elementUrlTestComponent.querySelector('#viewer-previous-page-button'); + let nextPageButton: any = elementUrlTestComponent.querySelector('#viewer-next-page-button'); - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { + nextPageButton.click(); + nextPageButton.click(); + previousPageButton.click(); + fixtureUrlTestComponent.detectChanges(); - expect(component.displayPage).toBe(1); - nextPageButton.click(); - nextPageButton.click(); - previousPageButton.click(); - fixture.detectChanges(); - expect(component.displayPage).toBe(2); - done(); - }); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(2); + done(); }); - }); + }, 5000); it('should previous page not move to the previous page if is page 1', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { + component.previousPage(); + fixtureUrlTestComponent.detectChanges(); - expect(component.displayPage).toBe(1); - component.previousPage(); - fixture.detectChanges(); - expect(component.displayPage).toBe(1); - done(); - }); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(1); + done(); }); - }); + }, 5000); it('should Input page move to the inserted page', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { + componentUrlTestComponent.pdfViewerComponent.inputPage('2'); + fixtureUrlTestComponent.detectChanges(); - expect(component.displayPage).toBe(1); - component.inputPage('2'); - fixture.detectChanges(); - expect(component.displayPage).toBe(2); - done(); - }); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(2); + done(); }); - }); - }); + }, 5000); - describe('Zoom', () => { + describe('Zoom', () => { - beforeEach(async(() => { - component.urlFile = require('../assets/fake-test-file.pdf'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - component.inputPage('1'); - component.currentScale = 1; - }); - })); + it('should zoom in increment the scale value', () => { + let zoomInButton: any = elementUrlTestComponent.querySelector('#viewer-zoom-in-button'); - it('should zoom in increment the scale value', (done) => { - let zoomInButton: any = element.querySelector('#viewer-zoom-in-button'); - - component.ngOnChanges(null).then(() => { - let zoomBefore = component.currentScale; + let zoomBefore = componentUrlTestComponent.pdfViewerComponent.currentScale; zoomInButton.click(); - expect(component.currentScaleMode).toBe('auto'); - let currentZoom = component.currentScale; + expect(componentUrlTestComponent.pdfViewerComponent.currentScaleMode).toBe('auto'); + let currentZoom = componentUrlTestComponent.pdfViewerComponent.currentScale; expect(zoomBefore < currentZoom).toBe(true); - done(); - }); - }); + }, 5000); - it('should zoom out decrement the scale value', (done) => { - let zoomOutButton: any = element.querySelector('#viewer-zoom-out-button'); + it('should zoom out decrement the scale value', () => { + let zoomOutButton: any = elementUrlTestComponent.querySelector('#viewer-zoom-out-button'); - component.ngOnChanges(null).then(() => { - let zoomBefore = component.currentScale; + let zoomBefore = componentUrlTestComponent.pdfViewerComponent.currentScale; zoomOutButton.click(); - expect(component.currentScaleMode).toBe('auto'); - let currentZoom = component.currentScale; + expect(componentUrlTestComponent.pdfViewerComponent.currentScaleMode).toBe('auto'); + let currentZoom = componentUrlTestComponent.pdfViewerComponent.currentScale; expect(zoomBefore > currentZoom).toBe(true); - done(); - }); + }, 5000); + + it('should it-in button toggle page-fit and auto scale mode', () => { + let itPage: any = elementUrlTestComponent.querySelector('#viewer-scale-page-button'); + + expect(componentUrlTestComponent.pdfViewerComponent.currentScaleMode).toBe('auto'); + itPage.click(); + expect(componentUrlTestComponent.pdfViewerComponent.currentScaleMode).toBe('page-fit'); + itPage.click(); + expect(componentUrlTestComponent.pdfViewerComponent.currentScaleMode).toBe('auto'); + }, 5000); }); - it('should fit-in button toggle page-fit and auto scale mode', (done) => { - let fitPage: any = element.querySelector('#viewer-scale-page-button'); + describe('Resize interaction', () => { - component.ngOnChanges(null).then(() => { - expect(component.currentScaleMode).toBe('auto'); - fitPage.click(); - expect(component.currentScaleMode).toBe('page-fit'); - fitPage.click(); - expect(component.currentScaleMode).toBe('auto'); - done(); - }); + it('should resize event trigger setScaleUpdatePages', () => { + spyOn(componentUrlTestComponent.pdfViewerComponent, 'onResize'); + EventMock.resizeMobileView(); + expect(componentUrlTestComponent.pdfViewerComponent.onResize).toHaveBeenCalled(); + }, 5000); }); - }); - describe('Resize interaction', () => { + describe('Thumbnails', () => { - beforeEach(async(() => { - component.urlFile = require('../assets/fake-test-file.pdf'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - component.inputPage('1'); - component.currentScale = 1; - }); - })); + it('should have own context', () => { + expect(componentUrlTestComponent.pdfViewerComponent.pdfThumbnailsContext.viewer).not.toBeNull(); + }, 5000); - it('should resize event trigger setScaleUpdatePages', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { + it('should open thumbnails panel', (done) => { + expect(elementUrlTestComponent.querySelector('.adf-pdf-viewer__thumbnails')).toBeNull(); - spyOn(component, 'onResize'); - EventMock.resizeMobileView(); - expect(component.onResize).toHaveBeenCalled(); + componentUrlTestComponent.pdfViewerComponent.toggleThumbnails(); + fixtureUrlTestComponent.detectChanges(); + + fixtureUrlTestComponent.whenStable().then(() => { + expect(elementUrlTestComponent.querySelector('.adf-pdf-viewer__thumbnails')).not.toBeNull(); done(); }); - }); - }); - }); - - describe('scroll interaction', () => { - - beforeEach(async(() => { - component.urlFile = require('../assets/fake-test-file.pdf'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - component.inputPage('1'); - component.currentScale = 1; - }); - })); - - it('should scroll page return the current page', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - - expect(component.displayPage).toBe(1); - - component.inputPage('2'); - fixture.detectChanges(); - expect(component.displayPage).toBe(2); - - component.pdfViewer.currentPageNumber = 6; - fixture.detectChanges(); - expect(component.displayPage).toBe(6); - expect(component.page).toBe(6); - done(); - }); - }); - }); - }); - - describe('Thumbnails', () => { - beforeEach(async () => { - component.urlFile = require('../assets/fake-test-file.pdf'); - component.showThumbnails = false; - fixture.detectChanges(); - fixture.whenStable().then(() => { - component.inputPage('1'); - }); + }, 5000); }); - it('should have own context', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(component.pdfThumbnailsContext.viewer).not.toBeNull(); - done(); - }); - }); - }); - - it('should open thumbnails panel', (done) => { - expect(element.querySelector('.adf-pdf-viewer__thumbnails')).toBeNull(); - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - component.toggleThumbnails(); - fixture.detectChanges(); - - expect(element.querySelector('.adf-pdf-viewer__thumbnails')).not.toBeNull(); - done(); - }); - }); - }); - }); - - describe('Viewer events', () => { - beforeEach(() => { - component.urlFile = require('../assets/fake-test-file.pdf'); - fixture.detectChanges(); - }); - - it('should emit pagechange event', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - return fixture.whenStable().then(() => { - expect(component.displayPage).toBe(1); + describe('Viewer events', () => { + it('should react on the emit of pagechange event', (done) => { + fixtureUrlTestComponent.detectChanges(); + fixtureUrlTestComponent.whenStable().then(() => { const args = { pageNumber: 6, source: { - container: component.documentContainer + container: componentUrlTestComponent.pdfViewerComponent.documentContainer } }; - component.pdfViewer.eventBus.dispatch('pagechange', args); - fixture.detectChanges(); + componentUrlTestComponent.pdfViewerComponent.pdfViewer.eventBus.dispatch('pagechange', args); + fixtureUrlTestComponent.detectChanges(); - expect(component.displayPage).toBe(6); - expect(component.page).toBe(6); - done(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.displayPage).toBe(6); + expect(componentUrlTestComponent.pdfViewerComponent.page).toBe(6); + done(); + }); }); - }); - }); + }, 5000); - it('should emit pagesloaded event', (done) => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - return fixture.whenStable().then(() => { - expect(component.isPanelDisabled).toBe(true); + it('should react on the emit of pagesloaded event', (done) => { + fixtureUrlTestComponent.detectChanges(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.isPanelDisabled = false; const args = { pagesCount: 10, source: { - container: component.documentContainer + container: componentUrlTestComponent.pdfViewerComponent.documentContainer } }; - component.pdfViewer.eventBus.dispatch('pagesloaded', args); - fixture.detectChanges(); + componentUrlTestComponent.pdfViewerComponent.pdfViewer.eventBus.dispatch('pagesloaded', args); + fixtureUrlTestComponent.detectChanges(); - expect(component.isPanelDisabled).toBe(false); - done(); + fixtureUrlTestComponent.whenStable().then(() => { + expect(componentUrlTestComponent.pdfViewerComponent.isPanelDisabled).toBe(false); + done(); + }); }); - }); + }, 5000); }); + }); }); diff --git a/lib/core/viewer/components/pdfViewer.component.ts b/lib/core/viewer/components/pdfViewer.component.ts index 82cdd3d169..649e56b134 100644 --- a/lib/core/viewer/components/pdfViewer.component.ts +++ b/lib/core/viewer/components/pdfViewer.component.ts @@ -15,7 +15,17 @@ * limitations under the License. */ -import { Component, TemplateRef, HostListener, Input, OnChanges, OnDestroy, ViewEncapsulation } from '@angular/core'; +import { + Component, + TemplateRef, + HostListener, + Output, + Input, + OnChanges, + OnDestroy, + ViewEncapsulation, + EventEmitter +} from '@angular/core'; import { LogService } from '../../services/log.service'; import { RenderingQueueServices } from '../services/rendering-queue.services'; @@ -52,6 +62,13 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { @Input() thumbnailsTemplate: TemplateRef = null; + @Output() + rendered = new EventEmitter(); + + @Output() + error = new EventEmitter(); + + loadingTask: any; currentPdfDocument: any; page: number; displayPage: number; @@ -80,37 +97,39 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { // needed to preserve "this" context this.onPageChange = this.onPageChange.bind(this); this.onPagesLoaded = this.onPagesLoaded.bind(this); + this.onPagerendered = this.onPagerendered.bind(this); } ngOnChanges(changes) { + let blobFile = changes['blobFile']; + + if (blobFile && blobFile.currentValue) { + let reader = new FileReader(); + reader.onload = () => { + this.executePdf(reader.result); + }; + reader.readAsArrayBuffer(blobFile.currentValue); + } + + let urlFile = changes['urlFile']; + if (urlFile && urlFile.currentValue) { + this.executePdf(urlFile.currentValue); + } + if (!this.urlFile && !this.blobFile) { throw new Error('Attribute urlFile or blobFile is required'); } - - if (this.urlFile) { - return new Promise((resolve, reject) => { - this.executePdf(this.urlFile, resolve, reject); - }); - } else { - return new Promise((resolve, reject) => { - let reader = new FileReader(); - reader.onload = () => { - this.executePdf(reader.result, resolve, reject); - }; - reader.readAsArrayBuffer(this.blobFile); - }); - } } - executePdf(src, resolve, reject) { - let loadingTask = this.getPDFJS().getDocument(src); + executePdf(src) { + this.loadingTask = this.getPDFJS().getDocument(src); - loadingTask.onProgress = (progressData) => { + this.loadingTask.onProgress = (progressData) => { let level = progressData.loaded / progressData.total; this.loadingPercent = Math.round(level * 100); }; - loadingTask.then((pdfDocument) => { + this.loadingTask.then((pdfDocument) => { this.currentPdfDocument = pdfDocument; this.totalPages = pdfDocument.numPages; this.page = 1; @@ -119,13 +138,12 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.currentPdfDocument.getPage(1).then(() => { this.scalePage('auto'); - resolve(); }, (error) => { - reject(error); + this.error.emit(); }); }, (error) => { - reject(error); + this.error.emit(); }); } @@ -145,6 +163,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.documentContainer = document.getElementById('viewer-pdf-viewer'); this.documentContainer.addEventListener('pagechange', this.onPageChange, true); this.documentContainer.addEventListener('pagesloaded', this.onPagesLoaded, true); + this.documentContainer.addEventListener('textlayerrendered', this.onPagerendered, true); this.pdfViewer = new PDFJS.PDFViewer({ container: this.documentContainer, @@ -163,6 +182,11 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { if (this.documentContainer) { this.documentContainer.removeEventListener('pagechange', this.onPageChange, true); this.documentContainer.removeEventListener('pagesloaded', this.onPagesLoaded, true); + this.documentContainer.removeEventListener('textlayerrendered', this.onPagerendered, true); + } + + if (this.loadingTask) { + this.loadingTask.destroy(); } } @@ -373,6 +397,13 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.displayPage = event.pageNumber; } + /** + * Page Rendered Event + */ + onPagerendered() { + this.rendered.emit(); + } + /** * Pages Loaded Event * diff --git a/lib/core/viewer/components/txtViewer.component.spec.ts b/lib/core/viewer/components/txtViewer.component.spec.ts index 674805a76c..a21b164347 100644 --- a/lib/core/viewer/components/txtViewer.component.spec.ts +++ b/lib/core/viewer/components/txtViewer.component.spec.ts @@ -24,8 +24,6 @@ import { } from '../../services'; import { TxtViewerComponent } from './txtViewer.component'; -declare var require: any; - describe('Text View component', () => { let component: TxtViewerComponent; @@ -54,7 +52,7 @@ describe('Text View component', () => { it('Should text container be present with urlfile', (done) => { fixture.detectChanges(); - let urlFile = require('../assets/fake-test-file.txt'); + let urlFile = './fake-test-file.txt'; let change = new SimpleChange(null, urlFile, true); component.ngOnChanges({ 'urlFile': change }).then(() => { diff --git a/lib/core/viewer/components/viewer.component.spec.ts b/lib/core/viewer/components/viewer.component.spec.ts index b9554fb27d..fb78a4a462 100644 --- a/lib/core/viewer/components/viewer.component.spec.ts +++ b/lib/core/viewer/components/viewer.component.spec.ts @@ -127,8 +127,6 @@ class ViewerWithCustomOpenWithComponent {} }) class ViewerWithCustomMoreActionsComponent {} -declare var require: any; - describe('ViewerComponent', () => { let component: ViewerComponent; @@ -593,7 +591,7 @@ describe('ViewerComponent', () => { })); it('should extension file txt be loaded', async(() => { - component.urlFile = require('../assets/fake-test-file.txt'); + component.urlFile = 'fake-test-file.txt'; component.ngOnChanges(null); fixture.detectChanges(); @@ -678,18 +676,18 @@ describe('ViewerComponent', () => { }); })); - it('should display the txt viewer if the file identified by mimetype is a txt when the filename has wrong extension', async(() => { + it('should display the txt viewer if the file identified by mimetype is a txt when the filename has wrong extension', (done) => { component.urlFile = 'content.bin'; component.mimeType = 'text/plain'; - component.urlFile = require('../assets/fake-test-file.txt'); fixture.detectChanges(); component.ngOnChanges(null); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-txt-viewer')).not.toBeNull(); + done(); }); - })); + }); it('should display the media player if the file identified by mimetype is a media when the filename has no extension', async(() => { component.urlFile = 'content'; diff --git a/lib/process-services/task-list/models/filter.model.ts b/lib/process-services/task-list/models/filter.model.ts index 1f5fedf125..70387670eb 100644 --- a/lib/process-services/task-list/models/filter.model.ts +++ b/lib/process-services/task-list/models/filter.model.ts @@ -57,6 +57,30 @@ export class FilterParamsModel { } } +export class FilterParamRepresentationModel { + processDefinitionId: string; + processDefinitionKey: string; + name: string; + state: string; + sort: string; + assignment: string; + dueAfter: Date; + dueBefore: Date; + + constructor(obj?: any) { + if (obj) { + this.processDefinitionId = obj.processDefinitionId || null; + this.processDefinitionKey = obj.processDefinitionKey || null; + this.name = obj.name || null; + this.state = obj.state || null; + this.sort = obj.sort || null; + this.assignment = obj.assignment || null; + this.dueAfter = obj.dueAfter || null; + this.dueBefore = obj.dueBefore || null; + } + } +} + export class FilterRepresentationModel implements UserTaskFilterRepresentation { id: number; appId: number; @@ -83,30 +107,6 @@ export class FilterRepresentationModel implements UserTaskFilterRepresentation { } } -export class FilterParamRepresentationModel { - processDefinitionId: string; - processDefinitionKey: string; - name: string; - state: string; - sort: string; - assignment: string; - dueAfter: Date; - dueBefore: Date; - - constructor(obj?: any) { - if (obj) { - this.processDefinitionId = obj.processDefinitionId || null; - this.processDefinitionKey = obj.processDefinitionKey || null; - this.name = obj.name || null; - this.state = obj.state || null; - this.sort = obj.sort || null; - this.assignment = obj.assignment || null; - this.dueAfter = obj.dueAfter || null; - this.dueBefore = obj.dueBefore || null; - } - } -} - export class TaskQueryRequestRepresentationModel implements TaskQueryRequestRepresentation { appDefinitionId: string; processInstanceId: string; diff --git a/scripts/README.md b/scripts/README.md index cd93d73f43..ea0b607d45 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -52,6 +52,7 @@ All the commands before can be used in combination | -u or --update | run the update of the node_modules packages on the demo shell | | -c or --clean | clean the demo shell folder before starting it | | -t or --test | run the tests on the demo-shell | +| --e2e | execute e2e test | | -r or --registry | Start the demo using an alternative npm registry | | -v or --version | Use the version defined in the pacakge.json . Download from npm and Install a different version of the lib (this option is not compatible with -dev) | | -si or --skipinstall | skip the install of the node_modules | diff --git a/scripts/start.sh b/scripts/start.sh index 9bafc3cfcc..16be00280e 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -12,6 +12,7 @@ eval EXEC_GIT_NPM_INSTALL_JSAPI=false eval EXEC_VERSION_JSAPI=false eval EXEC_START=true eval EXEC_TEST=false +eval EXEC_E2E=false eval JSAPI_VERSION="" eval NG2_COMPONENTS_VERSION="" eval GIT_ISH="" @@ -28,6 +29,7 @@ show_help() { echo "-dev or -develop start the demo shell using the relative lib folder to link the components" echo "-dist create the disbuild the demo shell in dist mode" echo "-t or -test execute test" + echo "--e2e execute e2e test" echo "-u or -update start the demo shell and update the dependencies" echo "-c or -clean clean the demo shell and reinstall the dependencies" echo "-r or -registry to download the packages from an alternative npm registry example -registry 'http://npm.local.me:8080/' " @@ -57,7 +59,11 @@ disable_start() { } enable_test() { - EXEC_TEST=false + EXEC_TEST=true +} + +enable_e2e() { + EXEC_E2E=true } enable_js_api_git_link() { @@ -113,6 +119,7 @@ while [[ $1 == -* ]]; do -u|--update) update; shift;; -c|--clean) clean; shift;; -t|--test) enable_test; shift;; + --e2e) enable_e2e; shift;; -r|--registry) change_registry $2; shift 2;; -v|--version) version_component $2; shift 2;; -si|--skipinstall) install; shift;; @@ -186,8 +193,13 @@ if $EXEC_VERSION_JSAPI == true; then fi if $EXEC_TEST == true; then - echo "====== Demo shell Test=====" - npm run test + echo "====== Demo shell Test =====" + npm install && npm run test +fi + +if $EXEC_E2E == true; then + echo "====== Demo shell e2e =====" + npm run e2e fi if $EXEC_START == true; then diff --git a/tslint.json b/tslint.json index d9d1e66e41..063d77a307 100644 --- a/tslint.json +++ b/tslint.json @@ -126,7 +126,6 @@ "no-string-literal": false, "no-string-throw": true, "prefer-const": false, - "typeof-compare": true, "unified-signatures": true, "whitespace": [ true, From e627613bc580d7ba4b09e9b9305127c5e65aaa58 Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Fri, 9 Mar 2018 12:59:45 +0000 Subject: [PATCH 029/188] fast stop appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 67cd48a44b..89e4221079 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -54,4 +54,4 @@ install: # Don't actually build. build: off matrix: - fast_finish: false + fast_finish: true From 487147ca22c9efa2be6117ceb9856e307f323684 Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Fri, 9 Mar 2018 13:47:44 +0000 Subject: [PATCH 030/188] [ADF-2451] Reviewed docs for components (#3055) --- docs/document-list.component.md | 202 ++++++++++++++++++-------------- docs/viewer.component.md | 98 +++++++++------- 2 files changed, 166 insertions(+), 134 deletions(-) diff --git a/docs/document-list.component.md b/docs/document-list.component.md index cb5982ca86..758c86c9b6 100644 --- a/docs/document-list.component.md +++ b/docs/document-list.component.md @@ -1,6 +1,7 @@ --- Added: v2.0.0 Status: Active +Last reviewed: 2018-03-09 --- # Document List component @@ -95,21 +96,24 @@ Displays the documents from a repository. ## Details -The properties currentFolderId, folderNode and node are the entry initialization properties of the document list. They cannot be used together, so choose the one that suits your use case best. +The properties `currentFolderId`, `folderNode` and `node` set the initial folder shown by +the Document List. They cannot be used together, so choose the one that suits your use case +best. ### DOM Events Below are the DOM events the DocumentList component emits. -All of them are `bubbling`, meaning you can handle them in any component up the parent hierarchy, even if DocumentList is wrapped by another component(s). +All of them are *bubbling*, meaning you can handle them in any component up the parent hierarchy, even if the DocumentList is wrapped by one or more other components. | Name | Description | | ---- | ----------- | -| node-click | Raised when user clicks the node | -| node-dblclick | Raised when user double-clicks the node | -| node-select | Raised when user selects a node | -| node-unselect | Raised when user unselects a node | +| node-click | Emitted when user clicks the node | +| node-dblclick | Emitted when user double-clicks the node | +| node-select | Emitted when user selects a node | +| node-unselect | Emitted when user unselects a node | -Every event is represented by a [CustomEvent](https://developer.mozilla.org/en/docs/Web/API/CustomEvent) instance, having at least the following properties as part of the `Event.detail` property value: +Every event is represented by a [CustomEvent](https://developer.mozilla.org/en/docs/Web/API/CustomEvent) instance. Each event will +have at least the following properties as part of the `Event.detail` property value: ```ts { @@ -118,7 +122,8 @@ Every event is represented by a [CustomEvent](https://developer.mozilla.org/en/d } ``` -Please refer to the [DataTable](datatable.component.md) documentation to find details about additional DOM events the DocumentList component bubbles up from the DataTable. +See the [DataTable](datatable.component.md) documentation for further details about +the other DOM events that the Document List component bubbles up from the DataTable. Below is a basic example of handling DOM events in the parent elements. @@ -137,7 +142,12 @@ Below is a basic example of handling DOM events in the parent elements. ### Card view -If you want to enable the card view mode you need to set to 'gallery' the input parameter [display] : +The Document List has an option to display items as "cards" instead of the +standard view: + +![card-view](docassets/images/document-list-card-view.png) + +Set the `[display]` property to "gallery" to enable card view mode: ```html ``` -![card-view](docassets/images/document-list-card-view.png) + ### Pagination strategy -The Document List by default supports 2 type of pagination, the **finite** and the **infinite** pagination. +The Document List by default supports 2 types of pagination: **finite** and **infinite**: -- With the **finite** pagination you must provide document list with 2 parameters : maxItems and skipCount. -- With the **infinite** pagination you must provide documentlist with 3 parameters : enableInfiniteScrolling, maxItems and skipCount. +- With **finite** pagination, the Document List needs 2 parameters: `maxItems` and `skipCount`. These set the maximum number of items shown in a single page and the start +offset of the first item in the page (ie, the number of items you need to skip to get there). +- You can enable **infinite** pagination by setting the same parameters plus an extra third +parameter: `enableInfiniteScrolling`. ### Data Sources -For the Document List data sources you can use one of the following options: +You can use any of the following options to set the folder that the Document List will display: #### Node ID @@ -171,9 +183,9 @@ You can use one of the well-known reserved aliases: - `-shared-` - `-my-` -#### DocumentList aliases +#### Document List aliases -The DocumentList component also provides support for the following reserved aliases you can use: +The Document List component also provides support for the following reserved aliases: - `-trashcan-`, - `-sharedlinks-` @@ -182,16 +194,16 @@ The DocumentList component also provides support for the following reserved alia - `-favorites-` - `-recent-` -Note that due to specific origin of the data the sources above do not support navigation. -You may want handling single and double clicks yourself to perform navigation to other sources. +Note that due to the nature of the data, these sources do not support navigation. +You may want to handle single and double clicks yourself to perform navigation to other sources. -DocumentList component supports default presets for all the custom sources mentioned earlier. -If you don't provide any custom column definition utilizing "data-columns" component, -then a default preset will be automatically used at runtime. +The Document List component supports default presets for all the custom sources mentioned earlier. +If you don't provide any custom column definition with the [Data Column](#custom-columns) +component then a default preset will be automatically used at runtime. -Some of the presets use the Location columns that allow you to navigate to the parent folder of the node, -for instance navigating from the "Favorite" node to the folder containing it. -There's a possibility to set the default location format using "locationFormat" property, to avoid re-defining entire columns layout. +Some of the presets use the Location columns that allow you to navigate to the parent folder of the node +(eg, navigating from the "Favorite" node to the folder that contains it). +You can set the default location format using the `locationFormat` property to avoid redefining the entire column layout. The default column layout for non-reserved views is: @@ -301,15 +313,19 @@ Default layout: ### Setting default folder -You can set current folder path by assigning a value for `currentFolderId` property. -It can be either one of the well-known locations as **-root-**, **-shared-** or **-my-** or a node ID (guid). +You can set the current folder path by assigning a value to the `currentFolderId` property. +It can be either one of the well-known locations (such as **-root-**, **-shared-** or **-my-**), +or a node ID (guid). -There may be scenarios when it is needed to set default path based on relative string value rather than node ID. -For example when folder name or path is static but its underlying ID is not (i.e. created manually by admin). -In this case you can use `alfresco-js-api` to get node details based on its relative path. +There may be scenarios where you need to set the default path based on a relative string value rather than a node ID. +This might happen, for example, when the folder name or path is static but its underlying ID +is not (i.e. created manually by admin). +In this case you can use the `alfresco-js-api` to get the details of a node based on its +relative path. -Let's try setting default folder to `/Sites/swsdp/documentLibrary` without knowing it's ID beforehand. -For the sake of simplicity example below shows only main points you may need to pay attention to: +The example below shows how to set the default folder to `/Sites/swsdp/documentLibrary` +without knowing its ID beforehand. For the sake of simplicity, the example below shows only the main +points you should pay attention to: ```ts import { ChangeDetectorRef } from '@angular/core'; @@ -340,8 +356,8 @@ export class FilesComponent implements OnInit { } ``` -We've added `console.log(node)` for the `getNodeInfo` callback just for study and debug purposes. -It helps examining other valuable information you can have access to if needed: +The `console.log(node)` for the `getNodeInfo` callback is just for study and debug purposes. +It is useful for examining other information that you can access if necessary: ![documentLibrary](docassets/images/documentLibrary.png) @@ -349,7 +365,7 @@ It helps examining other valuable information you can have access to if needed: ### Calling DocumentList api directly -Typically you will be binding DocumentList properties to your application/component class properties: +Typically you will bind Document List properties to your application/component class properties: ```html ``` -with the underlying class being implemented similar to the following one: +...with the underlying class implemented as in the following example: ```ts @Component(...) @@ -368,12 +384,12 @@ export class MyAppComponent { } ``` -However there may be scenarios that require you direct access to DocumentList apis. -You can get reference to the DocumentList instance by means of Angular **Component Interaction** API. -See more details in [Parent calls a ViewChild](https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-view-child) -section of the official docs. +However there may be scenarios where you need direct access to the Document List APIs. +You can get a reference to the Document List instance using the Angular **Component Interaction** API. +See the [Parent calls a ViewChild](https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-view-child) +section of the Angular docs for more information. -Here's an example of getting reference: +Below is an example of getting a reference: ```html ``` -Note the `#documentList` ID we've just added to be able referencing this component later on. +Note that the `#documentList` ID allows the component to be referenced elsewhere. ```ts import { ViewChild, AfterViewInit } from '@angular/core'; @@ -402,11 +418,11 @@ export class MyAppComponent implements AfterViewInit { } ``` -Example above should produce the following browser console output: +The example above should produce the following browser console output: ![view-child](docassets/images/viewchild.png) -Now you are able to access DocumentList properties or to call methods directly. +Now you can access Document List properties or call methods directly: ```ts // print currently displayed folder node object to console @@ -414,13 +430,19 @@ console.log(documentList.folderNode); ``` **Important note**: -It is important accessing child components at least at the `AfterViewInit` state. -Any UI click (buttons, links, etc.) event handlers are absolutely fine. This cannot be `ngOnInit` event though. -You can get more details in [Component lifecycle hooks](https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html) article. +You must not access child components any earlier in the component lifecycle than +the `AfterViewInit` state. Any UI click (buttons, links, etc.) event handlers are fine but +an earlier event like `ngOnInit` is not. +See the Angular +[Component lifecycle hooks](https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html) +documentation for a full explanation of the component lifecycle. ### Underlying node object -DocumentList component assigns an instance of `MinimalNode` type (`alfresco-js-api`) as a data context of each row. +The Document List component assigns an instance of +[MinimalNode](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/MinimalNode.md] +(defined in the [Alfresco JS API](https://github.com/Alfresco/alfresco-js-api)) as the data context +for each row. You can make use of the properties of this object when defining custom columns: ```js export interface MinimalNode { @@ -440,8 +462,6 @@ export interface MinimalNode { } ``` -_See more details in [alfresco-js-api](https://github.com/Alfresco/alfresco-js-api/blob/master/index.d.ts) repository._ - Binding to nested properties is also supported. You can define a column key as a property path similar to the following: ```text @@ -465,10 +485,10 @@ Here's a short example: ### Custom columns -It is possible to reorder, extend or completely redefine data columns displayed by the component. +You can reorder, extend or completely redefine data columns displayed by the component. By default, special `$thumbnail` and `displayName` columns are rendered. -A custom set of columns can look like the following: +A custom set of columns might look like the following: ```html @@ -500,7 +520,8 @@ A custom set of columns can look like the following: ![Custom columns](docassets/images/custom-columns.png) -You can also use HTML-based schema declaration used by DataTable, TaskList and other components: +You can also use the HTML-based schema declaration used by +[DataTable](datatable.component.md), [Task List](task-list.component.md) and other components: ```html @@ -518,21 +539,23 @@ You can also add tooltips, styling, automatic column title translation and other ### Date Column -For `date` column type the [DatePipe](https://angular.io/docs/ts/latest/api/common/DatePipe-class.html) formatting is used. -For a full list of available `format` values please refer to [DatePipe](https://angular.io/docs/ts/latest/api/common/DatePipe-class.html) documentation. +For the `date` column type, the Angular [DatePipe](https://angular.io/docs/ts/latest/api/common/DatePipe-class.html) formatting is used. +See the [DatePipe](https://angular.io/docs/ts/latest/api/common/DatePipe-class.html) documentation +for a full list of `format` values it supports. -ADF also supports additional `timeAgo` value for the `format` property. -That triggers the date values to be rendered using popular ["Time from now"](https://momentjs.com/docs/#/displaying/fromnow/) format. +ADF also supports an additional `timeAgo` value for the `format` property. +This renders date values using the popular +["Time from now"](https://momentjs.com/docs/#/displaying/fromnow/) format. ### Location Column -This column is used to display a clickable location link pointing to the parent path of the node. +This column displays a clickable location link pointing to the parent path of the node. **Important note**: -_For granular permissions, the Location Column may or may not render link location_ +_For granular permissions, the Location Column may or may not the render link location_ -You are going to use it with custom navigation or when displaying content from the sources like: +You would normally use this with custom navigation or when displaying content from sources like: - Sites - My Sites @@ -541,10 +564,12 @@ You are going to use it with custom navigation or when displaying content from t - Favorites - Trashcan -or any other location that needs nagivating to the node parent folder easily. +...or any other location where the user needs to be able to navigate to the node parent +folder easily. -Note that the parent node is evaluated automatically, -the generated link will be pointing to URL based on the `format` property value with the node `id` value appended: +Note that the parent node is evaluated automatically. +The generated link will have a URL based on the `format` property value with the node `id` +value appended: ```text //:id @@ -573,7 +598,8 @@ All links rendered in the column above will have an address mapped to `/files`: You can add actions to a dropdown menu for each item shown in a Document List. Several built-in actions are available (**delete**, **download**, **copy** and **move**) but -you can also define your own actions. See the [Content Action component](content-action.component.md) +you can also define your own actions. See the +[Content Action component](content-action.component.md) for more information and examples. You can also use the [Context Menu directive](context-menu.directive.md) from the @@ -598,15 +624,10 @@ This single extra line in the template enables context menu items for documents ### Navigation mode -By default DocumentList component uses 'double-click' mode for navigation. -That means user will see the contents of the folder by double-clicking its name -or icon (similar to Google Drive behaviour). However it is possible switching to -other modes, like single-click navigation for example. - -The following navigation modes are supported: - -- **click** -- **dblclick** +By default, the Document List component uses 'double-click' mode for navigation. +That means that the user will see the contents of the folder when they double-click its name +or icon (in a similar manner to Google Drive). However, there is also a single-click mode that +may be sometimes be useful. The following example switches navigation to single clicks: @@ -620,8 +641,9 @@ The following example switches navigation to single clicks: ### Custom row filter -You can create a custom row filter implementation that returns `true` if row should be displayed or `false` to hide it. -Typical row filter implementation is a function that receives `ShareDataRow` as parameter: +You can create a custom row filter function that returns `true` if the row should be +displayed or `false` if it should be hidden. +A typical row filter implementation receives a `ShareDataRow` object as a parameter: ```ts myFilter(row: ShareDataRow): boolean { @@ -650,7 +672,7 @@ export class View1 { constructor() { - // This filter will make document list show only folders + // This filter will make the document list show only folders this.folderFilter = (row: ShareDataRow) => { let node = row.node.entry; @@ -667,12 +689,12 @@ export class View1 { ### Custom image resolver -You can create a custom image resolver implementation and take full control over how folder/file icons and thumbnails -are resolved and what document list should display. +You can create a custom image resolver function to manage the way folder/file icons and thumbnails +are resolved (ie, which image is shown for which item). -**Image resolvers are executed only for columns of the `image` type.** +**Note:** Image resolvers are executed only for columns of the `image` type. -Typical image resolver implementation is a function that receives `DataRow` and `DataColumn` as parameters: +A typical image resolver implementation receives `DataRow` and `DataColumn` objects as parameters: ```ts myImageResolver(row: DataRow, col: DataColumn): string { @@ -680,7 +702,8 @@ myImageResolver(row: DataRow, col: DataColumn): string { } ``` -Your function can return `null` or `false` values to fallback to default image resolving behavior. +Your function can return `null` or `false` values to fall back to the default image +resolving behavior. _Note that for the sake of simplicity the example code below was reduced to the main points of interest only._ @@ -733,11 +756,11 @@ export class View1 { ### Custom 'empty folder' template -By default DocumentList provides the following content for the empty folder: +By default, the Document List provides the following content for the empty folder: ![Default empty folder](docassets/images/empty-folder-template-default.png) -This can be changed by means of the custom html template: +However, you can change this by defining your own custom HTML template: ```html @@ -749,17 +772,18 @@ This can be changed by means of the custom html template: ``` -That will give the following output: +This will give the following output: ![Custom empty folder](docassets/images/empty-folder-template-custom.png) ### Custom 'permission denied' template -By default DocumentList provides the following content for permission denied: +By default, the Document List shows the following content when permission +is denied: ![Default no permission](docassets/images/no-permission-default.png) -This can be changed by means of the custom html template: +You can change this by defining your own custom HTML template: ```html @@ -771,14 +795,10 @@ This can be changed by means of the custom html template: ``` -That will give the following output: +This will give the following output: ![Custom no permission](docassets/images/no-permission-custom.png) - - - - ## See also - [Datatable component](datatable.component.md) @@ -796,4 +816,4 @@ That will give the following output: - [Dropdown breadcrumb component](dropdown-breadcrumb.component.md) - [Permissions style model](permissions-style.model.md) - [Version manager component](version-manager.component.md) - +- [Viewer component](viewer.component.md) diff --git a/docs/viewer.component.md b/docs/viewer.component.md index 15e6797851..edd5c25676 100644 --- a/docs/viewer.component.md +++ b/docs/viewer.component.md @@ -1,6 +1,7 @@ --- Added: v2.0.0 Status: Active +Last reviewed: 2018-03-07 --- # Viewer component @@ -14,19 +15,25 @@ See it live: [Viewer Quickstart](https://embed.plnkr.co/iTuG1lFIXfsP95l6bDW6/) - [Properties](#properties) - [Events](#events) + - [Keyboard shortcuts](#keyboard-shortcuts) - [Details](#details) - - [Integrating with DocumentList component](#integrating-with-documentlist-component) + - [Integrating with the Document List component](#integrating-with-the-document-list-component) + - [Custom file parameters](#custom-file-parameters) - [Supported file formats](#supported-file-formats) - - [Content renditions](#content-renditions) + - [Content Renditions](#content-renditions) - [Configuring PDF.js library](#configuring-pdfjs-library) - [Custom toolbar](#custom-toolbar) + - [Custom toolbar buttons](#custom-toolbar-buttons) - [Custom sidebar](#custom-sidebar) + - [Custom thumbnails](#custom-thumbnails) - [Custom "Open With" menu](#custom-open-with-menu) - [Custom "More actions" menu](#custom-more-actions-menu) - [Extending the Viewer](#extending-the-viewer) +- [See also](#see-also) + ## Basic usage Using with node id: @@ -70,11 +77,11 @@ Using with file url: | canNavigateBefore | `boolean` | `true` | Toggles the "before" ("<") button. Requires `allowNavigate` to be enabled. | | canNavigateNext | `boolean` | `true` | Toggles the next (">") button. Requires `allowNavigate` to be enabled. | | allowSidebar | `boolean` | `false` | Toggles the sidebar. | +| allowThumbnails | `boolean` | `true` | Toggles PDF thumbnails. | | showSidebar | `boolean` | `false` | Toggles sidebar visibility. Requires `allowSidebar` to be set to `true`. | | sidebarPosition | `string` | `'right'` | The position of the sidebar. Can be `left` or `right`. | | sidebarTemplate | `TemplateRef` | `null` | The template for the sidebar. The template context contains the loaded node data. | -| allowThumbnails | `boolean` | `true` | Enables pdf viewer thumbnails. | -| thumbnailsTemplate | `TemplateRef` | `null` | Custom template content for thumbnails. | +| thumbnailsTemplate | `TemplateRef` | `null` | The template for the pdf thumbnails. | | mimeType | `string` | | MIME type of the file content (when not determined by the filename extension). | | fileName | `string` | | Content filename. | | downloadUrl | `string` | `null` | URL to download. | @@ -84,14 +91,14 @@ Using with file url: | Name | Type | Description | | ---- | ---- | ----------- | -| goBack | `EventEmitter>` | Emitted when user clicks the 'Back' button. | -| download | `EventEmitter>` | Emitted when user clicks the 'Download' button. | -| print | `EventEmitter>` | Emitted when user clicks the 'Print' button. | -| share | `EventEmitter>` | Emitted when user clicks the 'Share' button. | -| showViewerChange | `EventEmitter` | Emitted when the viewer is shown or hidden. | -| extensionChange | `EventEmitter` | Emitted when the filename extension changes. | -| navigateBefore | `EventEmitter<{}>` | Emitted when user clicks 'Navigate Before' ("<") button. | -| navigateNext | `EventEmitter<{}>` | Emitted when user clicks 'Navigate Next' (">") button. | +| goBack | `EventEmitter>` | Emitted when user clicks the 'Back' button. | +| download | `EventEmitter>` | Emitted when user clicks the 'Download' button. | +| print | `EventEmitter>` | Emitted when user clicks the 'Print' button. | +| share | `EventEmitter>` | Emitted when user clicks the 'Share' button. | +| showViewerChange | `EventEmitter` | Emitted when the viewer is shown or hidden. | +| extensionChange | `EventEmitter` | Emitted when the filename extension changes. | +| navigateBefore | `EventEmitter<{}>` | Emitted when user clicks 'Navigate Before' ("<") button. | +| navigateNext | `EventEmitter<{}>` | Emitted when user clicks 'Navigate Next' (">") button. | ### Keyboard shortcuts @@ -104,9 +111,10 @@ Using with file url: ## Details -### Integrating with DocumentList component +### Integrating with the Document List component -Below is the most simple integration of Viewer and DocumentList components within your custom component: +Below is the most simple integration of the Viewer and +[Document List](document-list.component.md) components within your custom component: ```html ``` -And the component controller class implementation can look like the following: +The component controller class implementation might look like the following: ```ts export class OverlayViewerComponent { @@ -199,21 +207,23 @@ The Viewer component consists of separate Views that handle particular types of ### Content Renditions -For those extensions and mime types that cannot be natively displayed in the browser, the Viewer will try to fetch corresponding rendition by utilising the [renditions service api](https://community.alfresco.com/docs/DOC-5879-rendition-service). +For those extensions and mime types that cannot be natively displayed in the browser, the Viewer will try to fetch the corresponding rendition using the [renditions service api](https://community.alfresco.com/docs/DOC-5879-rendition-service). For the full list of supported types please refer to: [File types that support preview and thumbnail generation](http://docs.alfresco.com/5.2/references/valid-transformations-preview.html). ### Configuring PDF.js library -In order to configure your webpack-enabled application with the PDF.js library please follow the next steps. +Configure your webpack-enabled application with the PDF.js library as follows. -Install pdfjs-dist +1. Install pdfjs-dist ```sh npm install pdfjs-dist ``` -Update `vendors.ts` by appending the following: +2. Update `vendors.ts` by appending the following code. This will enable the viewer component + and compatibility mode for all browsers. It will also configure the web worker for the PDF.js + library to render PDF files in the background: ```ts // PDF.js @@ -223,10 +233,7 @@ pdfjsLib.PDFJS.workerSrc = './pdf.worker.js'; require('pdfjs-dist/web/pdf_viewer.js'); ``` -The code above enables the "viewer" component and "compatibility" mode for all the browsers. -It also configures the web worker for PDF.js library to render PDF files in the background. - -Update the `plugins` section of the `webpack.common.js` file with the next lines: +3. Update the `plugins` section of the `webpack.common.js` file with the following lines: ```js new CopyWebpackPlugin([ @@ -238,11 +245,11 @@ new CopyWebpackPlugin([ ]) ``` -The Viewer component now should be able displaying PDF files. +The Viewer component now should be able to display PDF files. ### Custom toolbar -You can replace standard viewer toolbar with your custom implementation. +You can replace the standard viewer toolbar with your own custom implementation: ```html @@ -252,12 +259,13 @@ You can replace standard viewer toolbar with your custom implementation. ``` -Everything you put inside the "adf-viewer-toolbar" tags is going to be rendered instead of the toolbar. +Everything you put inside the "adf-viewer-toolbar" tags will be rendered instead of the +standard toolbar. ### Custom toolbar buttons -If you are okay with the custom toolbar behaviour but want to add some extra buttons, -you can do that like in the following example: +If you are happy with the custom toolbar's behaviour but want to add some extra buttons +then you can do so as shown in the following example: ```html @@ -275,19 +283,19 @@ you can do that like in the following example: ``` -You should now see the following result at runtime: +The result should look like this: ![Custom Toolbar Actions](docassets/images/viewer-toolbar-actions.png) ### Custom sidebar The Viewer component also supports custom sidebar components and layouts. -The `allowSidebar` property should be set to `true` to enable this feature. +Set the `allowSidebar` property to `true` to enable this feature. -Custom sidebar for the viewer can be injected in two different ways: +The custom sidebar can be injected in two different ways: - using transclusion -- using template **(only works when using the viewer with fileNodeId)** +- using a template **(only works when using the viewer with fileNodeId)** #### Using transclusion @@ -299,7 +307,7 @@ Custom sidebar for the viewer can be injected in two different ways: ``` -Everything you put inside the "adf-viewer-sidebar" tags is going to be rendered. +Everything you put inside the "adf-viewer-sidebar" tags will be rendered. #### Using template injection (only works when using the viewer with fileNodeId) @@ -312,8 +320,8 @@ Everything you put inside the "adf-viewer-sidebar" tags is going to be rendered. ### Custom thumbnails -By default, the pdf viewer comes with its own thumbnails list but this can be replaced -by providing a custom template and binding to context property `viewer` to access PDFJS.PDFViewer +The PDF viewer comes with its own default list of thumbnails but you can replace this +by providing a custom template and binding to the context property `viewer` to access the PDFJS.PDFViewer instance. ![PDF thumbnails](docassets/images/pdf-thumbnails.png) @@ -344,7 +352,8 @@ export class CustomThumbnailsComponent { ### Custom "Open With" menu -You can enable custom "Open With" menu by providing at least one action inside the "adf-viewer-open-with" tag: +You can enable a custom "Open With" menu by providing at least one action inside the +`adf-viewer-open-with` tag: ```html @@ -371,7 +380,7 @@ You can enable custom "Open With" menu by providing at least one action inside t ### Custom "More actions" menu -You can enable custom "More actions" menu by providing at least one action inside the "adf-viewer-more-actions" tag: +You can enable a custom "More actions" menu by providing at least one action inside the `adf-viewer-more-actions` tag: ```html @@ -398,10 +407,9 @@ You can enable custom "More actions" menu by providing at least one action insid ### Extending the Viewer -If you want to handle other file formats that are not yet supported by the Viewer component, -you can define your own custom handler. - -Below you can find an example with the use of `adf-viewer-extension` if you can handle 3d files +You can define your own custom handle to handle other file formats that are not yet supported by +the Viewer component. Below is an example that shows how to use the `adf-viewer-extension` +to handle 3D data files: ```html @@ -418,9 +426,9 @@ Below you can find an example with the use of `adf-viewer-extension` if you can ``` -Note: you need adding `ng2-3d-editor` dependency to your `package.json` file to make the example above work. +Note: you need to add the `ng2-3d-editor` dependency to your `package.json` file to make the example above work. -It is possible to define multiple `adf-viewer-extension` templates: +You can define multiple `adf-viewer-extension` templates if required: ```html @@ -442,3 +450,7 @@ It is possible to define multiple `adf-viewer-extension` templates: ``` + +## See also + +- [Document List component](document-list.component.md) \ No newline at end of file From 16a8fa8cd81c7a8b2086d9c5fe8db9364066c498 Mon Sep 17 00:00:00 2001 From: camorra-skk Date: Fri, 9 Mar 2018 19:19:20 +0530 Subject: [PATCH 031/188] [ADF-2457] Comment component - Hide the table header (#3053) * Added showHeader input property in adf-datatable to hide header in comment-list component. --- .../comments/comment-list.component.html | 1 + .../comments/comment-list.component.spec.ts | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/lib/process-services/comments/comment-list.component.html b/lib/process-services/comments/comment-list.component.html index 8416624b3f..bbc4b5aff5 100644 --- a/lib/process-services/comments/comment-list.component.html +++ b/lib/process-services/comments/comment-list.component.html @@ -1,5 +1,6 @@ diff --git a/lib/process-services/comments/comment-list.component.spec.ts b/lib/process-services/comments/comment-list.component.spec.ts index 87c4e4162d..81c029ad3b 100644 --- a/lib/process-services/comments/comment-list.component.spec.ts +++ b/lib/process-services/comments/comment-list.component.spec.ts @@ -133,4 +133,13 @@ describe('CommentListComponent', () => { expect(elements[0].innerText).toContain(commentList.getUserShortName(testComment.createdBy)); expect(fixture.nativeElement.querySelector('#comment-user-icon:empty')).toBeNull(); }); + + it('should hide the datatable header in comment-list as showHeader is false', (done) => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('.adf-datatable-header')).toBe(null); + done(); + }); + }); }); From 4ee7cc08703167b4a4ca16fa98d3f5c42667a537 Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Fri, 9 Mar 2018 22:39:59 +0000 Subject: [PATCH 032/188] [ADF-2463] Update doc tools to work with subfolders (#3056) * [ADF-2463] Updated main doc tool and index tool to handle subfolders * [ADF-2463] Updated version index tool for subfolders --- lib/config/DocProcessor/docProcessor.js | 48 +++++++++++++------ lib/config/DocProcessor/tools/index.js | 12 +++-- lib/config/DocProcessor/tools/versionIndex.js | 15 ++++-- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/lib/config/DocProcessor/docProcessor.js b/lib/config/DocProcessor/docProcessor.js index d408e409d5..4fb795b541 100644 --- a/lib/config/DocProcessor/docProcessor.js +++ b/lib/config/DocProcessor/docProcessor.js @@ -23,9 +23,9 @@ function initPhase(aggData) { } -function readPhase(srcFolder, filenames, aggData) { +function readPhase(filenames, aggData) { for (var i = 0; i < filenames.length; i++) { - var pathname = path.resolve(srcFolder, filenames[i]); + var pathname = filenames[i];//path.resolve(srcFolder, filenames[i]); var src = fs.readFileSync(pathname); var tree = remark().use(frontMatter, ["yaml"]).parse(src); @@ -46,9 +46,9 @@ function aggPhase(aggData) { } -function updatePhase(srcFolder, destFolder, filenames, aggData) { +function updatePhase(filenames, aggData) { for (var i = 0; i < filenames.length; i++) { - var pathname = path.resolve(srcFolder, filenames[i]); + var pathname = filenames[i]; // path.resolve(srcFolder, filenames[i]); var src = fs.readFileSync(pathname); var tree = remark().use(frontMatter, ["yaml"]).parse(src) @@ -60,8 +60,9 @@ function updatePhase(srcFolder, destFolder, filenames, aggData) { }); if (modified) - fs.writeFileSync(path.resolve(destFolder, filenames[i]), remark().use(frontMatter, {type: 'yaml', fence: '---'}).data("settings", {paddedTable: false}).stringify(tree)); - //console.log(JSON.stringify(tree)); + fs.writeFileSync(filenames[i], remark().use(frontMatter, {type: 'yaml', fence: '---'}).data("settings", {paddedTable: false}).stringify(tree)); + + //console.log(JSON.stringify(tree)); } } @@ -91,8 +92,24 @@ function loadToolConfig(configFilePath) { } +function getAllDocFilePaths(docFolder, files) { + var items = fs.readdirSync(docFolder); + + for (var i = 0; i < items.length; i++) { + var itemPath = path.resolve(docFolder, items[i]); + var itemInfo = fs.statSync(itemPath); + + if (itemInfo.isFile()){ + files.push(itemPath); + } else if (itemInfo.isDirectory()) { + getAllDocFilePaths(itemPath, files); + } + } +} + + program -.usage("[options] [dest]") +.usage("[options] ") .parse(process.argv); if (program.args.length === 0) { @@ -104,6 +121,7 @@ if (program.args.length === 0) { var sourcePath = path.resolve(program.args[0]); var sourceInfo = fs.statSync(sourcePath); +/* var destPath; var destInfo; @@ -119,19 +137,21 @@ if (sourceInfo.isDirectory() && !destInfo.isDirectory()) { console.log("Error: The argument must be a directory"); return 0; } +*/ var toolModules = loadToolModules(); var toolList = loadToolConfig(path.resolve(__dirname, configFileName)); -var files; +var files = []; if (sourceInfo.isDirectory()) { - files = fs.readdirSync(sourcePath); + getAllDocFilePaths(sourcePath, files); } else if (sourceInfo.isFile()) { - files = [ path.basename(sourcePath) ]; - sourcePath = path.dirname(sourcePath); - destPath = path.dirname(destPath); + files = [ sourcePath ]; + //files = [ path.basename(sourcePath) ]; + //sourcePath = path.dirname(sourcePath); + //destPath = path.dirname(destPath); } files = files.filter(filename => @@ -145,13 +165,13 @@ console.log("Initialising..."); initPhase(aggData); console.log("Analysing Markdown files..."); -readPhase(sourcePath, files, aggData); +readPhase(files, aggData); console.log("Computing aggregate data..."); aggPhase(aggData); console.log("Updating Markdown files..."); -updatePhase(sourcePath, destPath, files, aggData); +updatePhase(files, aggData); diff --git a/lib/config/DocProcessor/tools/index.js b/lib/config/DocProcessor/tools/index.js index 1b010edcde..38462ebe29 100644 --- a/lib/config/DocProcessor/tools/index.js +++ b/lib/config/DocProcessor/tools/index.js @@ -39,7 +39,7 @@ function initPhase(aggData) { aggData.srcData = {}; aggData.mdFileDesc = []; aggData.mdFileStatus = []; - + aggData.mdFilePath = []; searchLibraryRecursive(aggData.srcData, path.resolve(rootFolder)); //console.log(JSON.stringify(aggData.srcData)); @@ -50,7 +50,7 @@ function readPhase(tree, pathname, aggData) { var itemName = path.basename(pathname, ".md"); // Look for the first paragraph in the file by skipping other items. - // Should usually be a position 1 in the tree. + // Should usually be at position 1 in the tree. var s; var briefDesc; @@ -80,6 +80,10 @@ function readPhase(tree, pathname, aggData) { } } + + var linkPath = pathname.replace(/\\/g, '/'); + linkPath = linkPath.substr(linkPath.indexOf("docs") + 5); + aggData.mdFilePath[itemName] = linkPath; } function aggPhase(aggData) { @@ -159,6 +163,7 @@ function prepareIndexSections(aggData) { var briefDesc = aggData.mdFileDesc[itemName]; var displayName = ngHelpers.ngNameToDisplayName(itemName); + var pathname = aggData.mdFilePath[itemName]; var status = ""; @@ -169,6 +174,7 @@ function prepareIndexSections(aggData) { sections[libName][srcData.type].documented.push({ "displayName": displayName, "mdName": itemName + ".md", + "mdPath": pathname, "srcPath": srcData.path, "briefDesc": briefDesc, "status": status @@ -280,7 +286,7 @@ function makeMDUndocumentedListItem(docItem) { function makeMDDocumentedTableRow(docItem) { - var mdFileLink = unist.makeLink(unist.makeText(docItem.displayName), docItem.mdName); + var mdFileLink = unist.makeLink(unist.makeText(docItem.displayName), docItem.mdPath); var srcFileLink = unist.makeLink(unist.makeText("Source"), "../lib/" + docItem.srcPath); var desc = docItem.briefDesc; diff --git a/lib/config/DocProcessor/tools/versionIndex.js b/lib/config/DocProcessor/tools/versionIndex.js index a67df3f5c5..50ed416a3d 100644 --- a/lib/config/DocProcessor/tools/versionIndex.js +++ b/lib/config/DocProcessor/tools/versionIndex.js @@ -31,7 +31,7 @@ function initPhase(aggData) { function readPhase(tree, pathname, aggData) { - var compName = path.basename(pathname, ".md"); + var compName = pathname; //path.basename(pathname, ".md"); var angNameRegex = /([a-zA-Z0-9\-]+)\.((component)|(directive)|(model)|(pipe)|(service)|(widget))/; if (!compName.match(angNameRegex)) @@ -86,13 +86,20 @@ function aggPhase(aggData) { for (var i = 0; i < keys.length; i++) { var version = keys[i]; var versionItems = aggData.versions[version]; - versionItems.sort(); + versionItems.sort((a, b) => { + var aa = path.basename(a, ".md"); + var bb = path.basename(b, ".md"); + + return aa.localeCompare(bb); + }); var versListItems = []; for (var v = 0; v < versionItems.length; v++) { - var displayName = ngHelpers.ngNameToDisplayName(versionItems[v]); - var pageLink = versionItems[v] + ".md"; + var displayName = ngHelpers.ngNameToDisplayName(path.basename(versionItems[v], ".md")); + var pageLink = versionItems[v];// + ".md"; + pageLink = pageLink.replace(/\\/g, '/'); + pageLink = pageLink.substr(pageLink.indexOf("docs") + 5); versListItems.push( unist.makeListItem( From 8859d3466e0524d12de457e388e46569e28fb4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Popovics=20Andr=C3=A1s?= Date: Fri, 9 Mar 2018 23:55:24 +0100 Subject: [PATCH 033/188] [ADF-2368] Version manager update (#3058) * Add auto file renaming in FE side * Add error handling, file type restriction * Documentation * Fix ts-lint error * Test the service * Fix fdescribe... --- .../file-view/file-view.component.html | 2 +- .../file-view/file-view.component.ts | 5 ++ ...sion-manager-dialog-adapter.component.html | 2 +- ...ersion-manager-dialog-adapter.component.ts | 6 ++ demo-shell/src/app/material.module.ts | 2 + docs/upload-button.component.md | 41 ++++++++++++- lib/content-services/i18n/en.json | 6 ++ .../components/upload-button.component.ts | 11 ++-- .../upload-version-button.component.ts | 58 +++++++++++++++++++ lib/content-services/upload/public-api.ts | 1 + lib/content-services/upload/upload.module.ts | 3 + .../version-upload.component.html | 5 +- lib/core/models/file.model.ts | 1 + lib/core/services/upload.service.spec.ts | 14 +++++ lib/core/services/upload.service.ts | 5 ++ 15 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 lib/content-services/upload/components/upload-version-button.component.ts diff --git a/demo-shell/src/app/components/file-view/file-view.component.html b/demo-shell/src/app/components/file-view/file-view.component.html index 398f8fe312..595347e39a 100644 --- a/demo-shell/src/app/components/file-view/file-view.component.html +++ b/demo-shell/src/app/components/file-view/file-view.component.html @@ -9,7 +9,7 @@ - + diff --git a/demo-shell/src/app/components/file-view/file-view.component.ts b/demo-shell/src/app/components/file-view/file-view.component.ts index d86bec404b..66b77c8101 100644 --- a/demo-shell/src/app/components/file-view/file-view.component.ts +++ b/demo-shell/src/app/components/file-view/file-view.component.ts @@ -18,6 +18,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AlfrescoApiService } from '@alfresco/adf-core'; +import { MatSnackBar } from '@angular/material'; @Component({ selector: 'app-file-view', @@ -30,6 +31,7 @@ export class FileViewComponent implements OnInit { constructor( private router: Router, private route: ActivatedRoute, + private snackBar: MatSnackBar, private apiService: AlfrescoApiService) {} ngOnInit() { @@ -51,4 +53,7 @@ export class FileViewComponent implements OnInit { }); } + uploadError(errorMessage: string) { + this.snackBar.open(errorMessage, '', { duration: 4000 }); + } } diff --git a/demo-shell/src/app/components/files/version-manager-dialog-adapter.component.html b/demo-shell/src/app/components/files/version-manager-dialog-adapter.component.html index 062fbf32a4..0be206cf1b 100644 --- a/demo-shell/src/app/components/files/version-manager-dialog-adapter.component.html +++ b/demo-shell/src/app/components/files/version-manager-dialog-adapter.component.html @@ -1,6 +1,6 @@
{{'VERSION.DIALOG.TITLE' | translate}}
- +