[AAE-10768] Make the comments reusable (#7983)

* [AAE-10768] Refactor core comments

* [AAE-10768] Add models export in core comments refactor

* [AAE-10768] Add comments implementation inside process-services package

* [AAE-10768] Add task comments module to process module

* [AAE-10768] Add node comments module to content services

* [AAE-10768] Add id check to getComments and addComments in adf-core comments component

* [AAE-10768] Remove unused service files in process-comments module

* [AAE-10768] Remove unused service files in process-comments module

* [AAE-10768] Add testing logic to spec files

* [AAE-10768] Add comments components readme

* [AAE-10768] Add a mock service to inject into the comment stories file

* [AAE-10768] Add mock data for comments stories

* [AAE-10768] Add mock service to inject into comments stories

* [AAE-10768] Rename mock service and mock data

* [AAE-10768] change taskId with id into the comments test because taskId is never used

* [AAE-10768] Resolve pr suggestions

* [AAE-10768] Resolve task-comments pr suggestions

* [AAE-10768] Resolve comments pr suggestions

* [AAE-10768] Fix merge error in comments.component.html

* [AAE-10768] Add missing markdown files

* [AAE-10768] Remove events from md files

* [AAE-10768] Update upgrade50-60.md with renamed input property

Co-authored-by: Amedeo Lepore <amedeo.lepore@hyland.com>
This commit is contained in:
Diogo Bastos
2022-12-20 10:51:54 +00:00
committed by GitHub
parent 9077572199
commit 3864aaf9cb
43 changed files with 1667 additions and 356 deletions

View File

@@ -45,6 +45,7 @@ import { VersionCompatibilityModule } from './version-compatibility/version-comp
import { versionCompatibilityFactory } from './version-compatibility/version-compatibility-factory';
import { VersionCompatibilityService } from './version-compatibility/version-compatibility.service';
import { ContentPipeModule } from './pipes/content-pipe.module';
import { NodeCommentsModule } from './node-comments/node-comments.module';
@NgModule({
imports: [
@@ -73,7 +74,8 @@ import { ContentPipeModule } from './pipes/content-pipe.module';
TreeViewModule,
ContentTypeModule,
AspectListModule,
VersionCompatibilityModule
VersionCompatibilityModule,
NodeCommentsModule
],
providers: [
{
@@ -106,7 +108,8 @@ import { ContentPipeModule } from './pipes/content-pipe.module';
TreeViewModule,
AspectListModule,
ContentTypeModule,
VersionCompatibilityModule
VersionCompatibilityModule,
NodeCommentsModule
]
})
export class ContentModule {

View File

@@ -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';

View File

@@ -0,0 +1,209 @@
/*!
* @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 { CommentModel, EcmCompanyModel, EcmUserModel } from '@alfresco/adf-core';
export const fakeUser1 = {
enabled: true,
firstName: 'firstName',
lastName: 'lastName',
email: 'fake-email@dom.com',
emailNotificationsEnabled: true,
company: {},
id: 'fake-email@dom.com',
avatarId: '123-123-123'
};
export const fakeUser2 = {
enabled: true,
firstName: 'some',
lastName: 'one',
email: 'some-one@somegroup.com',
emailNotificationsEnabled: true,
company: {},
id: 'fake-email@dom.com',
avatarId: '001-001-001'
};
export const fakeContentComments = {
list: {
pagination: {
count: 4,
hasMoreItems: false,
totalItems: 4,
skipCount: 0,
maxItems: 100
},
entries: [{
entry: {
createdAt: '2018-03-27T10:55:45.725+0000',
createdBy: fakeUser1,
edited: false,
modifiedAt: '2018-03-27T10:55:45.725+0000',
canEdit: true,
modifiedBy: fakeUser1,
canDelete: true,
id: '35a0cea7-b6d0-4abc-9030-f4e461dd1ac7',
content: 'fake-message-1'
}
}, {
entry: {
createdAt: '2018-03-27T10:55:45.725+0000',
createdBy: fakeUser2,
edited: false,
modifiedAt: '2018-03-27T10:55:45.725+0000',
canEdit: true,
modifiedBy: fakeUser2,
canDelete: true,
id: '35a0cea7-b6d0-4abc-9030-f4e461dd1ac7',
content: 'fake-message-2'
}
}
]
}
};
export const fakeContentComment = {
entry: {
createdAt: '2018-03-29T11:49:51.735+0000',
createdBy: fakeUser1,
edited: false,
modifiedAt: '2018-03-29T11:49:51.735+0000',
canEdit: true,
modifiedBy: fakeUser1,
canDelete: true,
id: '4d07cdc5-f00c-4391-b39d-a842b12478b2',
content: 'fake-comment-message'
}
};
const fakeCompany: EcmCompanyModel = {
organization: '',
address1: '',
address2: '',
address3: '',
postcode: '',
telephone: '',
fax: '',
email: ''
};
const johnDoe: EcmUserModel = {
id: '1',
email: 'john.doe@alfresco.com',
firstName: 'John',
lastName: 'Doe',
company: fakeCompany,
enabled: true,
isAdmin: undefined,
avatarId: '001'
};
const janeEod: EcmUserModel = {
id: '2',
email: 'jane.eod@alfresco.com',
firstName: 'Jane',
lastName: 'Eod',
company: fakeCompany,
enabled: true,
isAdmin: undefined
};
const robertSmith: EcmUserModel = {
id: '3',
email: 'robert.smith@alfresco.com',
firstName: 'Robert',
lastName: 'Smith',
company: fakeCompany,
enabled: true,
isAdmin: undefined
};
export const testUser: EcmUserModel = {
id: '44',
email: 'test.user@hyland.com',
firstName: 'Test',
lastName: 'User',
company: fakeCompany,
enabled: true,
isAdmin: undefined,
avatarId: '044'
};
export const getDateXMinutesAgo = (minutes: number) => new Date(new Date().getTime() - minutes * 60000);
export const commentsNodeData: CommentModel[] = [
{
id: 1,
message: `I've done this component, is it cool?`,
created: getDateXMinutesAgo(30),
createdBy: johnDoe,
isSelected: false
},
{
id: 2,
message: 'Yeah',
created: getDateXMinutesAgo(15),
createdBy: janeEod,
isSelected: false
},
{
id: 3,
message: '+1',
created: getDateXMinutesAgo(12),
createdBy: robertSmith,
isSelected: false
},
{
id: 4,
message: 'ty',
created: new Date(),
createdBy: johnDoe,
isSelected: false
}
];
export const commentsTaskData: CommentModel[] = [
{
id: 1,
message: `I've done this task, what's next?`,
created: getDateXMinutesAgo(30),
createdBy: johnDoe,
isSelected: false
},
{
id: 2,
message: `I've assigned you another one 🤠`,
created: getDateXMinutesAgo(15),
createdBy: janeEod,
isSelected: false
},
{
id: 3,
message: '+1',
created: getDateXMinutesAgo(12),
createdBy: robertSmith,
isSelected: false
},
{
id: 4,
message: 'Cheers',
created: new Date(),
createdBy: johnDoe,
isSelected: false
}
];

View File

@@ -0,0 +1,5 @@
<adf-comments
[readOnly]="readOnly"
[id]="nodeId"
>
</adf-comments>

View File

@@ -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 { Component, Input, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'adf-node-comments',
templateUrl: './node-comments.component.html',
encapsulation: ViewEncapsulation.None
})
export class NodeCommentsComponent {
@Input()
nodeId: string;
@Input()
readOnly: boolean;
}

View File

@@ -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 { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NodeCommentsComponent } from './node-comments.component';
import { ADF_COMMENTS_SERVICE, CoreModule } from '@alfresco/adf-core';
import { NodeCommentsService } from './services/node-comments.service';
@NgModule({
imports: [
CommonModule,
CoreModule
],
declarations: [NodeCommentsComponent],
exports: [NodeCommentsComponent],
providers: [
{
provide: ADF_COMMENTS_SERVICE,
useClass: NodeCommentsService
}
]
})
export class NodeCommentsModule {}

View File

@@ -0,0 +1,22 @@
/*!
* @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 './node-comments.component';
export * from './services/node-comments.service';
export * from './node-comments.module';

View File

@@ -0,0 +1,88 @@
/*!
* @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 { TestBed } from '@angular/core/testing';
import { CommentModel, setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
import { fakeContentComment, fakeContentComments } from '../mocks/node-comments.mock';
import { TranslateModule } from '@ngx-translate/core';
import { NodeCommentsService } from './node-comments.service';
declare let jasmine: any;
describe('NodeCommentsService', () => {
let service: NodeCommentsService;
setupTestBed({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
});
beforeEach(() => {
service = TestBed.inject(NodeCommentsService);
jasmine.Ajax.install();
});
afterEach(() => {
jasmine.Ajax.uninstall();
});
describe('Node comments', () => {
it('should add a comment node ', (done) => {
service.add('999', 'fake-comment-message').subscribe(
(res: CommentModel) => {
expect(res).toBeDefined();
expect(res.id).not.toEqual(null);
expect(res.message).toEqual('fake-comment-message');
expect(res.created).not.toEqual(null);
expect(res.createdBy.email).toEqual('fake-email@dom.com');
expect(res.createdBy.firstName).toEqual('firstName');
expect(res.createdBy.lastName).toEqual('lastName');
done();
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeContentComment)
});
});
it('should return the nodes comments ', (done) => {
service.get('999').subscribe(
(res: CommentModel[]) => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].message).toEqual('fake-message-1');
expect(res[1].message).toEqual('fake-message-2');
done();
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeContentComments)
});
});
});
});

View File

@@ -0,0 +1,102 @@
/*!
* @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 { AlfrescoApiService, LogService, CommentModel } from '@alfresco/adf-core';
import { CommentEntry, CommentsApi, Comment } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Observable, from, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class NodeCommentsService {
private _commentsApi: CommentsApi;
get commentsApi(): CommentsApi {
this._commentsApi = this._commentsApi ?? new CommentsApi(this.apiService.getInstance());
return this._commentsApi;
}
constructor(
private apiService: AlfrescoApiService,
private logService: LogService
) {}
/**
* Gets all comments that have been added to a task.
*
* @param id ID of the target task
* @returns Details for each comment
*/
get(id: string): Observable<CommentModel[]> {
return from(this.commentsApi.listComments(id))
.pipe(
map((response) => {
const comments: CommentModel[] = [];
response.list.entries.forEach((comment: CommentEntry) => {
this.addToComments(comments, comment);
});
return comments;
}),
catchError(
(err: any) => this.handleError(err)
)
);
}
/**
* Adds a comment to a task.
*
* @param id ID of the target task
* @param message Text for the comment
* @returns Details about the comment
*/
add(id: string, message: string): Observable<CommentModel> {
return from(this.commentsApi.createComment(id, { content: message }))
.pipe(
map(
(response: CommentEntry) => this.newCommentModel(response.entry)
),
catchError(
(err: any) => this.handleError(err)
)
);
}
private addToComments(comments: CommentModel[], comment: CommentEntry): void {
const newComment: Comment = comment.entry;
comments.push(this.newCommentModel(newComment));
}
private newCommentModel(comment: Comment): CommentModel {
return new CommentModel({
id: comment.id,
message: comment.content,
created: comment.createdAt,
createdBy: comment.createdBy
});
}
private handleError(error: any) {
this.logService.error(error);
return throwError(error || 'Server error');
}
}

View File

@@ -35,6 +35,7 @@ export * from './lib/tree-view/index';
export * from './lib/group/index';
export * from './lib/aspect-list/index';
export * from './lib/content-type/index';
export * from './lib/node-comments/index';
export * from './lib/new-version-uploader';
export * from './lib/interfaces/index';
export * from './lib/version-compatibility/index';