[AAE-10767] Separate core card view logic from content-services and add documentation to reflect the changes (#7952)

This commit is contained in:
Diogo Bastos
2022-12-16 16:28:36 +01:00
committed by GitHub
parent 8d074e8b33
commit 02578dcdc5
27 changed files with 487 additions and 65 deletions
@@ -18,11 +18,12 @@
import { MinimalNode } from '@alfresco/js-api';
import { TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { AlfrescoApiService, CardViewUpdateService, NodesApiService, setupTestBed } from '@alfresco/adf-core';
import { AlfrescoApiService, NodesApiService, setupTestBed } from '@alfresco/adf-core';
import { EMPTY, of } from 'rxjs';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { NodeAspectService } from './node-aspect.service';
import { DialogAspectListService } from './dialog-aspect-list.service';
import { CardViewContentUpdateService } from '../../services/card-view-content-update.service';
describe('NodeAspectService', () => {
@@ -30,7 +31,7 @@ describe('NodeAspectService', () => {
let nodeAspectService: NodeAspectService;
let nodeApiService: NodesApiService;
let alfrescoApiService: AlfrescoApiService;
let cardViewUpdateService: CardViewUpdateService;
let cardViewContentUpdateService: CardViewContentUpdateService;
setupTestBed({
imports: [
@@ -44,7 +45,7 @@ describe('NodeAspectService', () => {
nodeAspectService = TestBed.inject(NodeAspectService);
nodeApiService = TestBed.inject(NodesApiService);
alfrescoApiService = TestBed.inject(AlfrescoApiService);
cardViewUpdateService = TestBed.inject(CardViewUpdateService);
cardViewContentUpdateService = TestBed.inject(CardViewContentUpdateService);
});
it('should call openAspectListDialog with correct parameters when selectorAutoFocusedOnClose is passed', () => {
@@ -89,7 +90,7 @@ describe('NodeAspectService', () => {
});
it('should send and update node aspect once the node has been updated', async () => {
await cardViewUpdateService.updatedAspect$.subscribe((nodeUpdated) => {
await cardViewContentUpdateService.updatedAspect$.subscribe((nodeUpdated) => {
expect(nodeUpdated.id).toBe('fake-node-id');
expect(nodeUpdated.aspectNames).toEqual(['a', 'b', 'c']);
});
@@ -16,8 +16,9 @@
*/
import { Injectable } from '@angular/core';
import { AlfrescoApiService, CardViewUpdateService, NodesApiService } from '@alfresco/adf-core';
import { AlfrescoApiService, NodesApiService } from '@alfresco/adf-core';
import { DialogAspectListService } from './dialog-aspect-list.service';
import { CardViewContentUpdateService } from '../../services/card-view-content-update.service';
@Injectable({
providedIn: 'root'
@@ -27,14 +28,14 @@ export class NodeAspectService {
constructor(private alfrescoApiService: AlfrescoApiService,
private nodesApiService: NodesApiService,
private dialogAspectListService: DialogAspectListService,
private cardViewUpdateService: CardViewUpdateService) {
private cardViewContentUpdateService: CardViewContentUpdateService) {
}
updateNodeAspects(nodeId: string, selectorAutoFocusedOnClose?: string) {
this.dialogAspectListService.openAspectListDialog(nodeId, selectorAutoFocusedOnClose).subscribe((aspectList) => {
this.nodesApiService.updateNode(nodeId, { aspectNames: [...aspectList] }).subscribe((updatedNode) => {
this.alfrescoApiService.nodeUpdated.next(updatedNode);
this.cardViewUpdateService.updateNodeAspect(updatedNode);
this.cardViewContentUpdateService.updateNodeAspect(updatedNode);
});
});
}
@@ -22,19 +22,20 @@ import { MinimalNode, Node } from '@alfresco/js-api';
import { ContentMetadataComponent } from './content-metadata.component';
import { ContentMetadataService } from '../../services/content-metadata.service';
import {
CardViewBaseItemModel, CardViewComponent, CardViewUpdateService, NodesApiService,
CardViewBaseItemModel, CardViewComponent, NodesApiService,
LogService, setupTestBed
} from '@alfresco/adf-core';
import { throwError, of } from 'rxjs';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { mockGroupProperties } from './mock-data';
import { TranslateModule } from '@ngx-translate/core';
import { CardViewContentUpdateService } from '../../../services/card-view-content-update.service';
describe('ContentMetadataComponent', () => {
let component: ContentMetadataComponent;
let fixture: ComponentFixture<ContentMetadataComponent>;
let contentMetadataService: ContentMetadataService;
let updateService: CardViewUpdateService;
let updateService: CardViewContentUpdateService;
let nodesApiService: NodesApiService;
let node: Node;
let folderNode: Node;
@@ -52,7 +53,7 @@ describe('ContentMetadataComponent', () => {
fixture = TestBed.createComponent(ContentMetadataComponent);
component = fixture.componentInstance;
contentMetadataService = TestBed.inject(ContentMetadataService);
updateService = TestBed.inject(CardViewUpdateService);
updateService = TestBed.inject(CardViewContentUpdateService);
nodesApiService = TestBed.inject(NodesApiService);
node = {
@@ -22,7 +22,6 @@ import {
CardViewItem,
NodesApiService,
LogService,
CardViewUpdateService,
AlfrescoApiService,
TranslationService,
AppConfigService,
@@ -32,6 +31,7 @@ import {
import { ContentMetadataService } from '../../services/content-metadata.service';
import { CardViewGroup, PresetConfig } from '../../interfaces/content-metadata.interfaces';
import { takeUntil, debounceTime, catchError, map } from 'rxjs/operators';
import { CardViewContentUpdateService } from '../../../services/card-view-content-update.service';
const DEFAULT_SEPARATOR = ', ';
@@ -97,7 +97,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
constructor(
private contentMetadataService: ContentMetadataService,
private cardViewUpdateService: CardViewUpdateService,
private cardViewContentUpdateService: CardViewContentUpdateService,
private nodesApiService: NodesApiService,
private logService: LogService,
private alfrescoApiService: AlfrescoApiService,
@@ -110,7 +110,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
}
ngOnInit() {
this.cardViewUpdateService.itemUpdated$
this.cardViewContentUpdateService.itemUpdated$
.pipe(
debounceTime(500),
takeUntil(this.onDestroy$))
@@ -122,7 +122,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
}
);
this.cardViewUpdateService.updatedAspect$.pipe(
this.cardViewContentUpdateService.updatedAspect$.pipe(
debounceTime(500),
takeUntil(this.onDestroy$))
.subscribe((node) => this.loadProperties(node));
@@ -201,14 +201,14 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
private updateNode() {
this.nodesApiService.updateNode(this.node.id, this.changedProperties).pipe(
catchError((err) => {
this.cardViewUpdateService.updateElement(this.targetProperty);
this.cardViewContentUpdateService.updateElement(this.targetProperty);
this.handleUpdateError(err);
return of(null);
}))
.subscribe((updatedNode) => {
if (updatedNode) {
if (this.hasContentTypeChanged(this.changedProperties)) {
this.cardViewUpdateService.updateNodeAspect(this.node);
this.cardViewContentUpdateService.updateNodeAspect(this.node);
}
this.revertChanges();
Object.assign(this.node, updatedNode);
@@ -0,0 +1,29 @@
/*!
* @license
* Copyright 2019 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 { CardViewBaseItemModel, UpdateNotification } from '@alfresco/adf-core';
import { MinimalNode } from '@alfresco/js-api';
import { Subject } from 'rxjs';
export interface BaseCardViewContentUpdate {
itemUpdated$: Subject<UpdateNotification>;
updatedAspect$: Subject<MinimalNode>;
update(property: CardViewBaseItemModel, newValue: any);
updateElement(notification: CardViewBaseItemModel);
updateNodeAspect(node: MinimalNode);
}
@@ -20,4 +20,5 @@ export * from './library-entity.interface';
export * from './restore-message-model.interface';
export * from './library-membership-error-event.interface';
export * from './library-membership-toggle-event.interface';
export * from './base-card-view-content-update.interface';
@@ -0,0 +1,38 @@
/*!
* @license
* Copyright 2019 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 { MinimalNode } from '@alfresco/js-api';
import { fakeAsync, TestBed } from '@angular/core/testing';
import { CardViewContentUpdateService } from './card-view-content-update.service';
describe('CardViewContentUpdateService', () => {
let cardViewContentUpdateService: CardViewContentUpdateService;
beforeEach(() => {
cardViewContentUpdateService = TestBed.inject(CardViewContentUpdateService);
});
it('should send updated node when aspect changed', fakeAsync(() => {
const fakeNode: MinimalNode = { id: 'Bigfoot'} as MinimalNode;
cardViewContentUpdateService.updatedAspect$.subscribe((node: MinimalNode) => {
expect(node.id).toBe('Bigfoot');
});
cardViewContentUpdateService.updateNodeAspect(fakeNode);
}));
});
@@ -0,0 +1,58 @@
/*!
* @license
* Copyright 2019 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 { UpdateNotification, CardViewBaseItemModel, CardViewUpdateService } from '@alfresco/adf-core';
import { MinimalNode } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { BaseCardViewContentUpdate } from '../interfaces/base-card-view-content-update.interface';
@Injectable({
providedIn: 'root'
})
export class CardViewContentUpdateService implements BaseCardViewContentUpdate {
itemUpdated$ = new Subject<UpdateNotification>();
updatedAspect$ = new Subject<MinimalNode>();
constructor(private cardViewUpdateService: CardViewUpdateService) {
this.linkVariables();
}
update(property: CardViewBaseItemModel, newValue: any) {
this.cardViewUpdateService.update(property, newValue);
}
updateElement(notification: CardViewBaseItemModel) {
this.cardViewUpdateService.updateElement(notification);
}
updateNodeAspect(node: MinimalNode) {
this.updatedAspect$.next(node);
}
private linkVariables() {
this.linkItemUpdated();
}
private linkItemUpdated() {
this.cardViewUpdateService.itemUpdated$.subscribe(res => {
this.itemUpdated$.next(res);
});
}
}
@@ -0,0 +1,18 @@
/*!
* @license
* Copyright 2019 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.
*/
export * from './public-api';
@@ -0,0 +1,18 @@
/*!
* @license
* Copyright 2019 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.
*/
export * from './card-view-content-update.service';
+1
View File
@@ -38,5 +38,6 @@ export * from './lib/content-type/index';
export * from './lib/new-version-uploader';
export * from './lib/interfaces/index';
export * from './lib/version-compatibility/index';
export * from './lib/services/index';
export * from './lib/content.module';
-9
View File
@@ -1,9 +0,0 @@
6.0.0-beta.1
- CheckAllowableOperationDirective: Moved from ADF Core to ADF content services
- LibraryFavoriteDirective: Moved from ADF Core to ADF content services
- LibraryMembershipDirective: Moved from ADF Core to ADF content services
- NodeDeleteDirective: Moved from ADF Core to ADF content services
- NodeFavoriteDirective: Moved from ADF Core to ADF content services
- NodeRestoreDirective: Moved from ADF Core to ADF content services
@@ -17,7 +17,6 @@
import {
Component,
ComponentFactoryResolver,
Input,
OnChanges,
SimpleChange,
@@ -67,8 +66,7 @@ export class CardViewItemDispatcherComponent implements OnChanges {
public ngOnInit;
public ngDoCheck;
constructor(private cardItemTypeService: CardItemTypeService,
private resolver: ComponentFactoryResolver) {
constructor(private cardItemTypeService: CardItemTypeService) {
const dynamicLifeCycleMethods = [
'ngOnInit',
'ngDoCheck',
@@ -102,8 +100,7 @@ export class CardViewItemDispatcherComponent implements OnChanges {
private loadComponent() {
const factoryClass = this.cardItemTypeService.resolveComponentType(this.property);
const factory = this.resolver.resolveComponentFactory(factoryClass);
this.componentReference = this.content.viewContainerRef.createComponent(factory);
this.componentReference = this.content.viewContainerRef.createComponent(factoryClass);
this.componentReference.instance.editable = this.editable;
this.componentReference.instance.property = this.property;
@@ -0,0 +1,31 @@
/*!
* @license
* Copyright 2019 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 { Subject } from 'rxjs';
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
import { UpdateNotification } from './update-notification.interface';
import { ClickNotification } from './click-notification.interface';
export interface BaseCardViewUpdate {
itemUpdated$: Subject<UpdateNotification>;
itemClicked$: Subject<ClickNotification>;
updateItem$: Subject<CardViewBaseItemModel>;
update(property: CardViewBaseItemModel, newValue: any);
clicked(property: CardViewBaseItemModel);
updateElement(notification: CardViewBaseItemModel);
}
@@ -16,7 +16,6 @@
*/
import { CardViewItemValidator } from './card-view-item-validator.interface';
import { Constraint } from '@alfresco/js-api';
export interface CardViewItemProperties {
label: string;
@@ -29,6 +28,12 @@ export interface CardViewItemProperties {
hint?: string;
validators?: CardViewItemValidator[];
data?: any;
constraints?: Constraint[];
constraints?: Array<{
id: string;
type?: string;
title?: string;
description?: string;
parameters?: { [key: string]: any };
}>;
multivalued?: boolean;
}
@@ -24,3 +24,6 @@ export * from './card-view-boolitem-properties.interface';
export * from './card-view-textitem-pipe-property.interface';
export * from './card-view-keyvaluepairsitem-properties.interface';
export * from './card-view-selectitem-properties.interface';
export * from './base-card-view-update.interface';
export * from './click-notification.interface';
export * from './update-notification.interface';
@@ -0,0 +1,20 @@
/*!
* @license
* Copyright 2019 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.
*/
export interface ClickNotification {
target: any;
}
@@ -0,0 +1,23 @@
/*!
* @license
* Copyright 2019 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 { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
export interface UpdateNotification {
target: CardViewBaseItemModel;
changed: any;
}
@@ -15,7 +15,6 @@
* limitations under the License.
*/
import { MinimalNode } from '@alfresco/js-api';
import { fakeAsync, TestBed } from '@angular/core/testing';
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
import { CardViewUpdateService, transformKeyToObject } from './card-view-update.service';
@@ -83,13 +82,5 @@ describe('CardViewUpdateService', () => {
);
cardViewUpdateService.clicked(property);
}));
it('should send updated node when aspect changed', fakeAsync(() => {
const fakeNode: MinimalNode = { id: 'Bigfoot'} as MinimalNode;
cardViewUpdateService.updatedAspect$.subscribe((node: MinimalNode) => {
expect(node.id).toBe('Bigfoot');
});
cardViewUpdateService.updateNodeAspect(fakeNode);
}));
});
});
@@ -15,20 +15,13 @@
* limitations under the License.
*/
import { MinimalNode } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { BaseCardViewUpdate } from '../interfaces/base-card-view-update.interface';
import { ClickNotification } from '../interfaces/click-notification.interface';
import { UpdateNotification } from '../interfaces/update-notification.interface';
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
export interface UpdateNotification {
target: CardViewBaseItemModel;
changed: any;
}
export interface ClickNotification {
target: any;
}
export const transformKeyToObject = (key: string, value): any => {
const objectLevels: string[] = key.split('.').reverse();
@@ -38,12 +31,11 @@ export const transformKeyToObject = (key: string, value): any => {
@Injectable({
providedIn: 'root'
})
export class CardViewUpdateService {
export class CardViewUpdateService implements BaseCardViewUpdate {
itemUpdated$ = new Subject<UpdateNotification>();
itemClicked$ = new Subject<ClickNotification>();
updateItem$ = new Subject<CardViewBaseItemModel>();
updatedAspect$ = new Subject<MinimalNode>();
update(property: CardViewBaseItemModel, newValue: any) {
this.itemUpdated$.next({
@@ -67,8 +59,4 @@ export class CardViewUpdateService {
this.updateItem$.next(notification);
}
updateNodeAspect(node: MinimalNode) {
this.updatedAspect$.next(node);
}
}