Compare commits

...
Author SHA1 Message Date
VitoAlbano 4bdb7f86c1 [ci:force] 2025-01-24 13:05:27 +00:00
VitoAlbano b59c25ba26 [ 2025-01-24 13:05:01 +00:00
VitoAlbano 46ff46c7f4 [AAE-26767] - Fixed lint 2025-01-24 13:05:01 +00:00
VitoAlbano 665cc9e201 [AAE-26767] - Fixed lint 2025-01-24 13:05:01 +00:00
DominikIwanek fa017e24d7 Change dialog label padding 2025-01-24 13:05:01 +00:00
swapnil-verma-gl 87ba1a4476 [ACS-9084] Fixed incorrect color for notification bell icon (#10513) 2025-01-24 13:05:01 +00:00
DominikIwanek 5a91b6b3c9 Fix ACA pipeline 2025-01-24 13:05:01 +00:00
DominikIwanek f89d56acbf Update package.json 2025-01-24 13:05:01 +00:00
AleksanderSklorz 926710a82c [ACS-9075] Fixed incorrect buttons labels color (#10489) 2025-01-24 13:05:01 +00:00
VitoAlbano f48017b45d Fixed wrong rule 2025-01-24 13:05:01 +00:00
VitoAlbano af7a6db8bc Readded rule for peer deps 2025-01-24 13:05:01 +00:00
VitoAlbano d4ac26d73e [MIGRATION] - Changing the building executor for eslint-rules 2025-01-24 13:05:01 +00:00
VitoAlbano 1af7843d69 [MIGRATION] - Checking if now eslint is releasable 2025-01-24 13:05:01 +00:00
VitoAlbano dc86a14016 [MIGRATION] - fixed storybook builds 2025-01-24 13:05:01 +00:00
AleksanderSklorzandVitoAlbano 77cca45b7e [ACS-9052] manage versions close button is too low (#10466)
* [ci:force] - Fixed lint

* [ACS-9052] Fixed close button in version manager position

* [ACS-9052] Reverted unwanted changes

---------

Co-authored-by: VitoAlbano <vito.albano.123@gmail.com>
2025-01-24 13:05:01 +00:00
VitoAlbano 4e00a74ec5 [MIGRATION] - updated lock 2025-01-24 13:05:01 +00:00
VitoAlbano 56fca182d7 [MIGRATION] - Checking deps 2025-01-24 13:05:01 +00:00
VitoAlbano 68f6c2446c [MIGRATION] - Readded removed action 2025-01-24 13:05:01 +00:00
VitoAlbano fde24116a2 [MIGRATION] - Rebased 2025-01-24 13:05:01 +00:00
VitoAlbano 0f9956cbf3 [MIGRATION] - Fixed type 2025-01-24 13:05:01 +00:00
VitoAlbano 3e07ed22a7 [MIGRATION] - Fixed lint 2025-01-24 13:05:01 +00:00
VitoAlbano 1765f62cf8 Removing temporarily eslint rule from publishing 2025-01-24 13:05:01 +00:00
VitoAlbano 6a3be59662 Fixed sonarqube errors 2025-01-24 13:05:01 +00:00
VitoAlbano a789ed82eb Reduced tserrors on building storybook 2025-01-24 13:05:01 +00:00
VitoAlbano c5f3b5639d Removed unused project parts 2025-01-24 13:05:01 +00:00
VitoAlbano 041838838a Removed unused project parts 2025-01-24 13:05:01 +00:00
Ehsan Rezaei 1a9e53d813 Fixed two excluded unit tests 2025-01-24 13:05:01 +00:00
Ehsan Rezaei 445b7803c3 Removing testing lib to sync with develop 2025-01-24 13:05:01 +00:00
Ehsan Rezaei 2aa4b5951e Trying to fix js-api unit tests 2025-01-24 13:05:01 +00:00
VitoAlbano 3039d1612f [MIGRATION] - Migrating to Jest - working but some tests fails 2025-01-24 13:05:01 +00:00
VitoAlbano 7c6e9ab831 [MIGRATION] - Fixing failing migrated tests 2025-01-24 13:05:01 +00:00
VitoAlbano 76fecf705a [MIGRATION] - Moving mocha to jest 2025-01-24 13:05:01 +00:00
VitoAlbano 3cb250eeea [MIGRATION] - Added injectionContext to avoid error NG0203 for unit tests 2025-01-24 13:05:01 +00:00
VitoAlbano f14f38a059 [MIGRATION] - fixed build and lint 2025-01-24 13:05:01 +00:00
VitoAlbano 4d1108e77e Cherry picked commit from oidc and run fix lint 2025-01-24 13:05:01 +00:00
Amedeo Lepore e162ebbfef AAE-26163 Fix infinite loop when authentication error event occured (#10272)
* AAE-26163 Logout user after 3 login attempts failed, avoiding infinite loop when an authentication error occured, like when a user machine clock is significantly out of sync

* AAE-26163 Wait to discovery document to be loaded and user not authenticated to perform a ssoLogin, logout user if login fails after 3 attempts

* AAE-26163 Fix missed id_token_hint invoking logout when a login error occured due to a clock significantly out of sync

* AAE-26163 Add fake observable to unit test

* AAE-26163 Show oauth event logs if showDebugInformation is enabled, remove auth items if access token is not valid

* AAE-26163 Improve tryLogin error message

* AAE-26163 Check if token has expired to fix case when user access the application after the token is expired and with a clock significantly out of sync

* AAE-26163 Test logout when clock is out of sync

* AAE-26163 Create a service to check if local machine time is out of sync

* AAE-26163 Update oauthErrorEvent$ and combinedOAuthErrorsStream$ to return errors

* AAE-26163 Output error within combined oauth error event subscription

* AAE-26163 Fix lint problems

* AAE-26163 Logout user when token refresh error happens for the second time, if the token is not refreshed properly after first refresh error

* AAE-26163 Logout user once an oauth error event occur due to clock out of sync

* AAE-26163 Fix retry login error message if the OAuthErrorEvent doesn t return reason

* AAE-26163 Fix the issue where the logout API call is canceled by the authorize call when login fails due to clock synchronization problems, causing an infinite loop.

* remove console.log

* AAE-26163 Fix retry login error message if the OAuthErrorEvent reason is an empty object
2025-01-24 13:05:01 +00:00
VitoAlbano 7bdec42329 [ci:force] - Fixed lint 2025-01-24 13:05:01 +00:00
VitoAlbano c1a42596dd [ci:force] - fixing lint 2025-01-24 13:05:01 +00:00
VitoAlbano 62baa655ed Fixed build for all the packages 2025-01-24 13:05:01 +00:00
VitoAlbano 1def5dcc0a [ci:force] - fixed build for testing 1 2025-01-24 13:05:01 +00:00
VitoAlbano 579f3fa801 [ci:force] - fixed deps 2025-01-24 13:05:01 +00:00
VitoAlbano d11afcd0d6 Migrate to NG17 2025-01-24 13:05:01 +00:00
741 changed files with 16753 additions and 16536 deletions
+1
View File
@@ -10,3 +10,4 @@ scripts
docs/**/*.md
lib/js-api/docs/**/*.md
.storybook
webpack.config.js
+1 -1
View File
@@ -234,7 +234,7 @@ jobs:
- uses: ./.github/actions/setup
- uses: ./.github/actions/download-node-modules-and-artifacts
- run: NX_REJECT_UNKNOWN_LOCAL_CACHE=0 npx nx affected:build $NX_CALCULATION_FLAGS --prod
- run: NX_REJECT_UNKNOWN_LOCAL_CACHE=0 npx nx affected --target=build-storybook $NX_CALCULATION_FLAGS --configuration=ci --parallel=1
- run: NX_REJECT_UNKNOWN_LOCAL_CACHE=0 npx nx affected --target=build-storybook $NX_CALCULATION_FLAGS --configuration=ci
- uses: ./.github/actions/upload-node-modules-and-artifacts
PR-forbidden-labels:
+1 -1
View File
@@ -2,4 +2,4 @@ export const parameters = {
docs: { inlineStories: true },
controls: { expanded: true }
};
export const tags = ['autodocs', 'autodocs', 'autodocs'];
export const tags = ['autodocs', 'autodocs', 'autodocs', 'autodocs', 'autodocs'];
+4
View File
@@ -0,0 +1,4 @@
// eslint-disable
const nxPreset = require('@nx/jest/preset').default;
module.exports = {...nxPreset };
+1 -1
View File
@@ -50,7 +50,7 @@
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": ["lib/cli/**/*.ts", "lib/cli/**/*.html"]
}
+9 -3
View File
@@ -10,7 +10,13 @@
"createDefaultProgram": true
},
"rules": {
"jsdoc/tag-lines": ["error", "any", {"startLines": 1}],
"jsdoc/tag-lines": [
"error",
"any",
{
"startLines": 1
}
],
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/consistent-type-assertions": "warn",
"@typescript-eslint/prefer-for-of": "warn",
@@ -44,7 +50,6 @@
"style": "kebab-case"
}
],
"@angular-eslint/no-host-metadata-property": "off",
"@angular-eslint/no-input-prefix": "error",
"@typescript-eslint/consistent-type-definitions": "error",
"@typescript-eslint/dot-notation": "off",
@@ -75,7 +80,8 @@
"rxjs/no-subject-unsubscribe": "error",
"rxjs/no-subject-value": "error",
"rxjs/no-unsafe-takeuntil": "error",
"unicorn/filename-case": "error"
"unicorn/filename-case": "error",
"@angular-eslint/prefer-standalone": "off"
}
},
{
+1 -1
View File
@@ -2,4 +2,4 @@ export const parameters = {
docs: { inlineStories: true },
controls: { expanded: true }
};
export const tags = ['autodocs', 'autodocs'];
export const tags = ['autodocs', 'autodocs', 'autodocs'];
+3 -9
View File
@@ -33,7 +33,7 @@
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": ["lib/content-services/**/*.ts", "lib/content-services/**/*.html"]
}
@@ -45,10 +45,7 @@
"browserTarget": "content-services:storybook",
"configDir": "lib/content-services/.storybook",
"compodoc": false,
"styles": [
"node_modules/cropperjs/dist/cropper.min.css",
"node_modules/pdfjs-dist/web/pdf_viewer.css"
],
"styles": ["node_modules/cropperjs/dist/cropper.min.css", "node_modules/pdfjs-dist/web/pdf_viewer.css"],
"stylePreprocessorOptions": {
"includePaths": ["lib", "lib/core/src/lib"]
}
@@ -66,10 +63,7 @@
"configDir": "lib/content-services/.storybook",
"outputDir": "dist/storybook/content-services",
"compodoc": false,
"styles": [
"node_modules/cropperjs/dist/cropper.min.css",
"node_modules/pdfjs-dist/web/pdf_viewer.css"
],
"styles": ["node_modules/cropperjs/dist/cropper.min.css", "node_modules/pdfjs-dist/web/pdf_viewer.css"],
"stylePreprocessorOptions": {
"includePaths": ["lib", "lib/core/src/lib"]
}
@@ -23,18 +23,17 @@ import { AlfrescoApiService } from '../services/alfresco-api.service';
@Injectable()
export class AlfrescoApiNoAuthService extends AlfrescoApiService {
constructor(
storage: StorageService,
appConfig: AppConfigService,
private readonly adfHttpClient: AdfHttpClient
) {
constructor(storage: StorageService, appConfig: AppConfigService, private readonly adfHttpClient: AdfHttpClient) {
super(appConfig, storage);
}
override createInstance(config: AlfrescoApiConfig) {
return new AlfrescoApi({
...config,
oauthInit: false
}, this.adfHttpClient);
return new AlfrescoApi(
{
...config,
oauthInit: false
},
this.adfHttpClient
);
}
}
@@ -18,7 +18,7 @@
import { AlfrescoApiConfig } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { AppConfigService, AppConfigValues, StorageService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AlfrescoApiService } from '../services/alfresco-api.service';
/**
* Create a factory to resolve an api service instance
@@ -34,10 +34,11 @@ export function createAlfrescoApiInstance(angularAlfrescoApiService: AlfrescoApi
providedIn: 'root'
})
export class AlfrescoApiLoaderService {
constructor(private readonly appConfig: AppConfigService,
private readonly apiService: AlfrescoApiService,
private storageService: StorageService) {
}
constructor(
private readonly appConfig: AppConfigService,
private readonly apiService: AlfrescoApiService,
private storageService: StorageService
) {}
async init(): Promise<any> {
await this.appConfig.load();
@@ -26,7 +26,6 @@ import { CommonModule } from '@angular/common';
@Component({
selector: 'adf-aspect-list-dialog',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, MatButtonModule, AspectListComponent, AutoFocusDirective],
templateUrl: './aspect-list-dialog.component.html',
styleUrls: ['./aspect-list-dialog.component.scss'],
@@ -31,7 +31,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-aspect-list',
standalone: true,
imports: [CommonModule, MatExpansionModule, MatCheckboxModule, MatTableModule, TranslateModule, MatProgressSpinnerModule],
templateUrl: './aspect-list.component.html',
styleUrls: ['./aspect-list.component.scss'],
@@ -16,7 +16,7 @@
*/
import { Injectable } from '@angular/core';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AppConfigService } from '@alfresco/adf-core';
import { from, Observable, of, zip } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
@@ -25,12 +25,12 @@ import { TagService } from '../../tag/services/tag.service';
providedIn: 'root'
})
export class NodeAspectService {
constructor(private nodesApiService: NodesApiService,
private dialogAspectListService: DialogAspectListService,
private cardViewContentUpdateService: CardViewContentUpdateService,
private tagService: TagService) {
}
constructor(
private nodesApiService: NodesApiService,
private dialogAspectListService: DialogAspectListService,
private cardViewContentUpdateService: CardViewContentUpdateService,
private tagService: TagService
) {}
updateNodeAspects(nodeId: string, selectorAutoFocusedOnClose?: string) {
this.dialogAspectListService.openAspectListDialog(nodeId, selectorAutoFocusedOnClose).subscribe((aspectList) => {
@@ -54,7 +54,6 @@ describe('ContentAuthLoaderService', () => {
basicAlfrescoAuthService = TestBed.inject(BasicAlfrescoAuthService);
});
it('should require Alf ticket on login if OAuth and provider is ALL or ECM', fakeAsync(() => {
spyOn(authService, 'isOauth').and.returnValue(true);
spyOn(authService, 'isALLProvider').and.returnValue(true);
@@ -21,22 +21,15 @@ import { take } from 'rxjs/operators';
@Injectable()
export class ContentAuthLoaderService {
constructor(
private readonly basicAlfrescoAuthService: BasicAlfrescoAuthService,
private readonly authService: AuthenticationService
) {
}
constructor(private readonly basicAlfrescoAuthService: BasicAlfrescoAuthService, private readonly authService: AuthenticationService) {}
init(): void {
this.authService.onLogin
.pipe(take(1))
.subscribe({
next: async () => {
if (this.authService.isOauth() && (this.authService.isALLProvider() || this.authService.isECMProvider())) {
await this.basicAlfrescoAuthService.requireAlfTicket();
}
this.authService.onLogin.pipe(take(1)).subscribe({
next: async () => {
if (this.authService.isOauth() && (this.authService.isALLProvider() || this.authService.isECMProvider())) {
await this.basicAlfrescoAuthService.requireAlfTicket();
}
});
}
});
}
}
@@ -33,8 +33,7 @@ describe('Breadcrumb', () => {
});
let documentListComponent: DocumentListComponent;
const getBreadcrumbActionText = (): string =>
fixture.debugElement.nativeElement.querySelector('.adf-breadcrumb-item-current').textContent.trim();
const getBreadcrumbActionText = (): string => fixture.debugElement.nativeElement.querySelector('.adf-breadcrumb-item-current').textContent.trim();
beforeEach(() => {
TestBed.configureTestingModule({
@@ -26,7 +26,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-breadcrumb',
standalone: true,
imports: [CommonModule, MatIconModule, TranslateModule, MatSelectModule],
templateUrl: './breadcrumb.component.html',
styleUrls: ['./breadcrumb.component.scss'],
@@ -25,7 +25,6 @@ import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-dropdown-breadcrumb',
standalone: true,
imports: [CommonModule, MatIconModule, MatSelectModule, TranslateModule],
templateUrl: './dropdown-breadcrumb.component.html',
styleUrls: ['./dropdown-breadcrumb.component.scss'],
@@ -53,7 +53,6 @@ interface CategoryNameControlErrors {
@Component({
selector: 'adf-categories-management',
standalone: true,
imports: [
CommonModule,
TranslateModule,
@@ -18,7 +18,10 @@
import { Injectable } from '@angular/core';
import {
CategoryEntry,
CategoryPaging, Pagination, PathInfo, ResultNode,
CategoryPaging,
Pagination,
PathInfo,
ResultNode,
ResultSetPaging,
ResultSetPagingList,
ResultSetRowEntry
@@ -27,7 +30,6 @@ import { Observable, of } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class CategoryServiceMock {
public getSubcategories(parentNodeId: string, skipCount?: number, maxItems?: number): Observable<CategoryPaging> {
return parentNodeId ? of(this.getChildrenLevelResponse(skipCount, maxItems)) : of(this.getRootLevelResponse(skipCount, maxItems));
}
@@ -66,12 +68,12 @@ export class CategoryServiceMock {
}
private getRootLevelResponse(skipCount?: number, maxItems?: number): CategoryPaging {
const rootCategoryEntry: CategoryEntry = {entry: {id: 'testId', name: 'testNode', parentId: '-root-', hasChildren: true}};
return {list: {pagination: {skipCount, maxItems, hasMoreItems: false}, entries: [rootCategoryEntry]}};
const rootCategoryEntry: CategoryEntry = { entry: { id: 'testId', name: 'testNode', parentId: '-root-', hasChildren: true } };
return { list: { pagination: { skipCount, maxItems, hasMoreItems: false }, entries: [rootCategoryEntry] } };
}
private getChildrenLevelResponse(skipCount?: number, maxItems?: number): CategoryPaging {
const childCategoryEntry: CategoryEntry = {entry: {id: 'childId', name: 'childNode', parentId: 'testId', hasChildren: false}};
return {list: {pagination: {skipCount, maxItems, hasMoreItems: true}, entries: [childCategoryEntry]}};
const childCategoryEntry: CategoryEntry = { entry: { id: 'childId', name: 'childNode', parentId: 'testId', hasChildren: false } };
return { list: { pagination: { skipCount, maxItems, hasMoreItems: true }, entries: [childCategoryEntry] } };
}
}
@@ -24,59 +24,65 @@ import { from, Observable } from 'rxjs';
import { map, mergeMap, toArray } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CategoryTreeDatasourceService extends TreeService<CategoryNode> {
export class CategoryTreeDatasourceService extends TreeService<CategoryNode> {
constructor(private categoryService: CategoryService) {
super();
}
public getSubNodes(parentNodeId: string, skipCount?: number, maxItems?: number, name?: string): Observable<TreeResponse<CategoryNode>> {
return !name ? this.categoryService.getSubcategories(parentNodeId, skipCount, maxItems).pipe(map((response: CategoryPaging) => {
const parentNode: CategoryNode = this.getParentNode(parentNodeId);
const nodesList: CategoryNode[] = response.list.entries.map((entry: CategoryEntry) => ({
id: entry.entry.id,
nodeName: entry.entry.name,
parentId: entry.entry.parentId,
hasChildren: entry.entry.hasChildren,
level: parentNode ? parentNode.level + 1 : 0,
isLoading: false,
nodeType: TreeNodeType.RegularNode
}));
if (response.list.pagination.hasMoreItems && parentNode) {
const loadMoreNode: CategoryNode = {
id: 'loadMore',
nodeName: '',
parentId: parentNode.id,
hasChildren: false,
level: parentNode.level + 1,
isLoading: false,
nodeType: TreeNodeType.LoadMoreNode
};
nodesList.push(loadMoreNode);
}
const treeResponse: TreeResponse<CategoryNode> = {entries: nodesList, pagination: response.list.pagination};
return treeResponse;
})) : this.categoryService.searchCategories(name, skipCount, maxItems).pipe(mergeMap((pagingResult) => {
const nextAfterGeneralPathPartIndex = 3;
const pathSeparator = '/';
return from(pagingResult.list.entries).pipe(mergeMap((category) => {
const path = category.entry.path.name.split(pathSeparator).slice(nextAfterGeneralPathPartIndex)
.join(pathSeparator);
return !name
? this.categoryService.getSubcategories(parentNodeId, skipCount, maxItems).pipe(
map((response: CategoryPaging) => {
const parentNode: CategoryNode = this.getParentNode(parentNodeId);
const nodesList: CategoryNode[] = response.list.entries.map((entry: CategoryEntry) => ({
id: entry.entry.id,
nodeName: entry.entry.name,
parentId: entry.entry.parentId,
hasChildren: entry.entry.hasChildren,
level: parentNode ? parentNode.level + 1 : 0,
isLoading: false,
nodeType: TreeNodeType.RegularNode
}));
if (response.list.pagination.hasMoreItems && parentNode) {
const loadMoreNode: CategoryNode = {
id: 'loadMore',
nodeName: '',
parentId: parentNode.id,
hasChildren: false,
level: parentNode.level + 1,
isLoading: false,
nodeType: TreeNodeType.LoadMoreNode
};
nodesList.push(loadMoreNode);
}
const treeResponse: TreeResponse<CategoryNode> = { entries: nodesList, pagination: response.list.pagination };
return treeResponse;
})
)
: this.categoryService.searchCategories(name, skipCount, maxItems).pipe(
mergeMap((pagingResult) => {
const nextAfterGeneralPathPartIndex = 3;
const pathSeparator = '/';
return from(pagingResult.list.entries).pipe(
mergeMap((category) => {
const path = category.entry.path.name.split(pathSeparator).slice(nextAfterGeneralPathPartIndex).join(pathSeparator);
return this.categoryService.getCategory(category.entry.id).pipe(
map((res) => ({
id: category.entry.id,
nodeName: path ? `${path}/${category.entry.name}` : category.entry.name,
parentId: category.entry.parentId,
level: 0,
nodeType: TreeNodeType.RegularNode,
hasChildren: res.entry.hasChildren,
isLoading: false
}))
);
}),
toArray(),
map(res => ({entries: res, pagination: pagingResult.list.pagination})));
}));
return this.categoryService.getCategory(category.entry.id).pipe(
map((res) => ({
id: category.entry.id,
nodeName: path ? `${path}/${category.entry.name}` : category.entry.name,
parentId: category.entry.parentId,
level: 0,
nodeType: TreeNodeType.RegularNode,
hasChildren: res.entry.hasChildren,
isLoading: false
}))
);
}),
toArray(),
map((res) => ({ entries: res, pagination: pagingResult.list.pagination }))
);
})
);
}
}
@@ -18,35 +18,27 @@
import { FileModel, FileUploadStatus } from '../models/file.model';
export class FileUploadEvent {
constructor(
public readonly file: FileModel,
public readonly status: FileUploadStatus = FileUploadStatus.Pending,
public readonly error: any = null) {
}
public readonly error: any = null
) {}
}
export class FileUploadCompleteEvent extends FileUploadEvent {
constructor(file: FileModel, public totalComplete: number = 0, public data?: any, public totalAborted: number = 0) {
super(file, FileUploadStatus.Complete);
}
}
export class FileUploadDeleteEvent extends FileUploadEvent {
constructor(file: FileModel, public totalComplete: number = 0) {
super(file, FileUploadStatus.Deleted);
}
}
export class FileUploadErrorEvent extends FileUploadEvent {
constructor(file: FileModel, public error: any, public totalError: number = 0) {
super(file, FileUploadStatus.Error);
}
}
@@ -18,9 +18,7 @@
import { FileModel } from './file.model';
describe('FileModel', () => {
describe('extension', () => {
it('should return the extension if file has it', () => {
const file = new FileModel({ name: 'tyrion-lannister.doc' } as File);
@@ -33,7 +31,7 @@ describe('FileModel', () => {
expect(file.extension).toBe('');
});
it('should return the empty string if file is starting with . and doesn\'t have extension', () => {
it("should return the empty string if file is starting with . and doesn't have extension", () => {
const file = new FileModel({ name: '.white-walkers' } as File);
expect(file.extension).toBe('');
@@ -21,7 +21,7 @@ import { Subject } from 'rxjs';
import { AuthenticationService, ThumbnailService } from '@alfresco/adf-core';
import { PermissionsEnum } from '../models/permissions.enum';
import { AllowableOperationsEnum } from '../models/allowable-operations.enum';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
export interface FolderCreatedEvent {
name: string;
@@ -26,7 +26,6 @@ import { catchError } from 'rxjs/operators';
providedIn: 'root'
})
export class FavoritesApiService {
private _favoritesApi: FavoritesApi;
get favoritesApi(): FavoritesApi {
this._favoritesApi = this._favoritesApi ?? new FavoritesApi(this.apiService.getInstance());
@@ -42,16 +41,11 @@ export class FavoritesApiService {
return { entry };
}
constructor(
private apiService: AlfrescoApiService,
private preferences: UserPreferencesService
) {
}
constructor(private apiService: AlfrescoApiService, private preferences: UserPreferencesService) {}
remapFavoritesData(data: FavoritePaging = {}): NodePaging {
const pagination = (data?.list?.pagination || {});
const entries: any[] = this
.remapFavoriteEntries(data?.list?.entries || []);
const pagination = data?.list?.pagination || {};
const entries: any[] = this.remapFavoriteEntries(data?.list?.entries || []);
return {
list: { entries, pagination }
@@ -63,7 +57,7 @@ export class FavoritesApiService {
.map(({ entry: { target } }: any) => ({
entry: target.file || target.folder
}))
.filter(({ entry }) => (!!entry))
.filter(({ entry }) => !!entry)
.map(FavoritesApiService.remapEntry);
}
@@ -82,12 +76,8 @@ export class FavoritesApiService {
include: ['properties', 'allowableOperations']
};
const queryOptions = Object.assign(defaultOptions, options);
const promise = this.favoritesApi
.listFavorites(personId, queryOptions)
.then(this.remapFavoritesData);
const promise = this.favoritesApi.listFavorites(personId, queryOptions).then(this.remapFavoritesData);
return from(promise).pipe(
catchError((err) => of(err))
);
return from(promise).pipe(catchError((err) => of(err)));
}
}
@@ -31,7 +31,6 @@ import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-content-metadata-card',
standalone: true,
imports: [CommonModule, MatCardModule, ContentMetadataComponent, MatButtonModule, MatIconModule, TranslateModule],
templateUrl: './content-metadata-card.component.html',
styleUrls: ['./content-metadata-card.component.scss'],
@@ -22,33 +22,32 @@ import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
@Component({
standalone: true,
imports: [CommonModule, MatIconModule, MatExpansionModule, TranslateModule],
selector: 'adf-content-metadata-header',
encapsulation: ViewEncapsulation.None,
styles: [
`
adf-content-metadata-header {
display: flex;
align-items: center;
width: 100%;
}
adf-content-metadata-header {
display: flex;
align-items: center;
width: 100%;
}
.adf-metadata-properties-title {
display: block;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 700;
font-size: 15px;
padding-left: 12px;
}
`
.adf-metadata-properties-title {
display: block;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 700;
font-size: 15px;
padding-left: 12px;
}
`
],
template: `
<ng-container>
<mat-icon>{{ expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>
<mat-panel-title *ngIf="title" class="adf-metadata-properties-title" [title]="title | translate">{{ title | translate }}</mat-panel-title>
<ng-content></ng-content>
<ng-content />
</ng-container>
`
})
@@ -63,7 +63,6 @@ enum DefaultPanels {
@Component({
selector: 'adf-content-metadata',
standalone: true,
imports: [
CommonModule,
MatExpansionModule,
@@ -19,13 +19,11 @@ import { AspectOrientedConfigService } from './aspect-oriented-config.service';
import { AspectOrientedConfig, Property, OrganisedPropertyGroup, PropertyGroupContainer } from '../../interfaces/content-metadata.interfaces';
describe('AspectOrientedConfigService', () => {
let configService: AspectOrientedConfigService;
const createConfigService = (configObj: AspectOrientedConfig) => new AspectOrientedConfigService(configObj);
describe('reorganiseByConfig', () => {
interface TestCase {
name: string;
config: AspectOrientedConfig;
@@ -51,54 +49,58 @@ describe('AspectOrientedConfigService', () => {
{
name: 'One property from One group',
config: {
berseria: [ 'property1' ]
},
expectations: [{
title: 'Berseria',
properties: [ property1 ]
}]
},
{
name: 'More properties from One group',
config: {
berseria: [ 'property1', 'property2' ]
},
expectations: [{
title: 'Berseria',
properties: [ property1, property2 ]
}]
},
{
name: 'One-one properties from More group',
config: {
berseria: [ 'property1' ],
zestiria: [ 'property3' ]
berseria: ['property1']
},
expectations: [
{
title: 'Berseria',
properties: [ property1 ]
properties: [property1]
}
]
},
{
name: 'More properties from One group',
config: {
berseria: ['property1', 'property2']
},
expectations: [
{
title: 'Berseria',
properties: [property1, property2]
}
]
},
{
name: 'One-one properties from More group',
config: {
berseria: ['property1'],
zestiria: ['property3']
},
expectations: [
{
title: 'Berseria',
properties: [property1]
},
{
title: 'Zestiria',
properties: [ property3 ]
properties: [property3]
}
]
},
{
name: 'More properties from More groups',
config: {
zestiria: [ 'property4', 'property3' ],
berseria: [ 'property2', 'property1' ]
zestiria: ['property4', 'property3'],
berseria: ['property2', 'property1']
},
expectations: [
{
title: 'Zestiria',
properties: [ property4, property3 ]
properties: [property4, property3]
},
{
title: 'Berseria',
properties: [ property2, property1 ]
properties: [property2, property1]
}
]
},
@@ -106,16 +108,16 @@ describe('AspectOrientedConfigService', () => {
name: 'Wildcard',
config: {
berseria: '*',
zestiria: [ 'property4' ]
zestiria: ['property4']
},
expectations: [
{
title: 'Berseria',
properties: [ property1, property2 ]
properties: [property1, property2]
},
{
title: 'Zestiria',
properties: [ property4 ]
properties: [property4]
}
]
},
@@ -124,29 +126,29 @@ describe('AspectOrientedConfigService', () => {
config: {
berseria: '*',
'not-existing-group': '*',
zestiria: [ 'property4' ]
zestiria: ['property4']
},
expectations: [
{
title: 'Berseria',
properties: [ property1, property2 ]
properties: [property1, property2]
},
{
title: 'Zestiria',
properties: [ property4 ]
properties: [property4]
}
]
},
{
name: 'Not existing property',
config: {
berseria: [ 'not-existing-property' ],
zestiria: [ 'property4' ]
berseria: ['not-existing-property'],
zestiria: ['property4']
},
expectations: [
{
title: 'Zestiria',
properties: [ property4 ]
properties: [property4]
}
]
}
@@ -160,7 +162,7 @@ describe('AspectOrientedConfigService', () => {
expect(organisedPropertyGroups.length).toBe(testCase.expectations.length, 'Group count should match');
testCase.expectations.forEach((expectation, i) => {
expect(organisedPropertyGroups[i].title).toBe(expectation.title, 'Group\'s title should match' );
expect(organisedPropertyGroups[i].title).toBe(expectation.title, "Group's title should match");
expect(organisedPropertyGroups[i].properties.length).toBe(
expectation.properties.length,
`Property count for '${organisedPropertyGroups[i].title}' group should match.`
@@ -194,11 +196,11 @@ describe('AspectOrientedConfigService', () => {
expectations: [
{
title: 'Berseria',
properties: [ property1, property2 ]
properties: [property1, property2]
},
{
title: 'Zestiria',
properties: [ property3, property4 ]
properties: [property3, property4]
}
]
};
@@ -208,7 +210,7 @@ describe('AspectOrientedConfigService', () => {
expect(organisedPropertyGroups.length).toBe(testCase.expectations.length, 'Group count should match');
testCase.expectations.forEach((expectation, i) => {
expect(organisedPropertyGroups[i].title).toBe(expectation.title, 'Group\'s title should match' );
expect(organisedPropertyGroups[i].title).toBe(expectation.title, "Group's title should match");
expect(organisedPropertyGroups[i].properties.length).toBe(
expectation.properties.length,
`Property count for '${organisedPropertyGroups[i].title}' group should match.`
@@ -231,11 +233,11 @@ describe('AspectOrientedConfigService', () => {
expectations: [
{
title: 'Berseria',
properties: [ property1, property2 ]
properties: [property1, property2]
},
{
title: 'Zestiria',
properties: [ property3, property4 ]
properties: [property3, property4]
}
]
};
@@ -19,8 +19,7 @@ import { ContentMetadataConfig, OrganisedPropertyGroup, PropertyGroupContainer,
import { getGroup, getProperty } from './property-group-reader';
export class AspectOrientedConfigService implements ContentMetadataConfig {
constructor(private config: any) { }
constructor(private config: any) {}
public isGroupAllowed(groupName: string): boolean {
if (this.isIncludeAllEnabled()) {
@@ -43,24 +42,23 @@ export class AspectOrientedConfigService implements ContentMetadataConfig {
}
public appendAllPreset(propertyGroups: PropertyGroupContainer): OrganisedPropertyGroup[] {
const groups = Object.keys(propertyGroups)
.map((groupName) => {
const propertyGroup = propertyGroups[groupName];
const properties = propertyGroup.properties;
const groups = Object.keys(propertyGroups).map((groupName) => {
const propertyGroup = propertyGroups[groupName];
const properties = propertyGroup.properties;
if (this.isAspectReadOnly(groupName)) {
Object.keys(properties).map((propertyName) => this.setReadOnlyProperty(properties[propertyName]));
}
if (this.isAspectReadOnly(groupName)) {
Object.keys(properties).map((propertyName) => this.setReadOnlyProperty(properties[propertyName]));
}
return Object.assign({}, propertyGroup, {
properties: Object.keys(properties).map((propertyName) => {
if (this.isPropertyReadOnly(propertyName)) {
this.setReadOnlyProperty(properties[propertyName]);
}
return properties[propertyName];
})
});
return Object.assign({}, propertyGroup, {
properties: Object.keys(properties).map((propertyName) => {
if (this.isPropertyReadOnly(propertyName)) {
this.setReadOnlyProperty(properties[propertyName]);
}
return properties[propertyName];
})
});
});
return groups;
}
@@ -87,7 +85,6 @@ export class AspectOrientedConfigService implements ContentMetadataConfig {
} else {
return readOnlyAspects === propertyGroupName;
}
}
public filterExcludedPreset(propertyGroups: OrganisedPropertyGroup[]): OrganisedPropertyGroup[] {
@@ -25,19 +25,17 @@ import { ContentMetadataConfig } from '../../interfaces/content-metadata.interfa
import { HttpClientModule } from '@angular/common/http';
describe('ContentMetadataConfigFactory', () => {
let factory: ContentMetadataConfigFactory;
let appConfig: AppConfigService;
let config: ContentMetadataConfig;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule
],
imports: [HttpClientModule],
providers: [
{
provide: LogService, useValue: {
provide: LogService,
useValue: {
error: () => {}
}
}
@@ -48,7 +46,6 @@ describe('ContentMetadataConfigFactory', () => {
});
describe('get', () => {
let logService: LogService;
beforeEach(() => {
@@ -57,7 +54,6 @@ describe('ContentMetadataConfigFactory', () => {
});
describe('get', () => {
it('should get back to default preset if no preset is provided as parameter', () => {
config = factory.get();
@@ -85,7 +81,6 @@ describe('ContentMetadataConfigFactory', () => {
});
describe('set', () => {
const setConfig = (presetName: string, presetConfig: any) => {
appConfig.config['content-metadata'] = {
presets: {
@@ -118,5 +113,5 @@ describe('ContentMetadataConfigFactory', () => {
expect(config).toEqual(jasmine.any(LayoutOrientedConfigService));
});
});
});
});
});
@@ -15,26 +15,22 @@
* limitations under the License.
*/
import { ContentMetadataConfig, OrganisedPropertyGroup,
PropertyGroupContainer
} from '../../interfaces/content-metadata.interfaces';
import { ContentMetadataConfig, OrganisedPropertyGroup, PropertyGroupContainer } from '../../interfaces/content-metadata.interfaces';
export class IndifferentConfigService implements ContentMetadataConfig {
isGroupAllowed(): boolean {
return true;
}
reorganiseByConfig(propertyGroups: PropertyGroupContainer): OrganisedPropertyGroup[] {
return Object.keys(propertyGroups)
.map((groupName) => {
const propertyGroup = propertyGroups[groupName];
const properties = propertyGroup.properties;
return Object.keys(propertyGroups).map((groupName) => {
const propertyGroup = propertyGroups[groupName];
const properties = propertyGroup.properties;
return Object.assign({}, propertyGroup, {
properties: Object.keys(properties).map((propertyName) => properties[propertyName])
});
return Object.assign({}, propertyGroup, {
properties: Object.keys(properties).map((propertyName) => properties[propertyName])
});
});
}
filterExcludedPreset(propertyGroups: OrganisedPropertyGroup[]): OrganisedPropertyGroup[] {
@@ -42,7 +38,7 @@ export class IndifferentConfigService implements ContentMetadataConfig {
}
appendAllPreset(): OrganisedPropertyGroup[] {
return[];
return [];
}
isIncludeAllEnabled(): boolean {
@@ -25,8 +25,7 @@ import {
import { getProperty } from './property-group-reader';
export class LayoutOrientedConfigService implements ContentMetadataConfig {
constructor(private config: any) { }
constructor(private config: any) {}
public isGroupAllowed(groupName: string): boolean {
if (this.isIncludeAllEnabled()) {
@@ -41,9 +40,9 @@ export class LayoutOrientedConfigService implements ContentMetadataConfig {
const organisedPropertyGroup = layoutBlocks.map((layoutBlock) => {
const flattenedItems = this.flattenItems(layoutBlock.items);
const properties = flattenedItems.reduce((props, explodedItem) => {
const isProperty = typeof explodedItem.property === 'object';
const isProperty = typeof explodedItem.property === 'object';
const propertyName = isProperty ? explodedItem.property.name : explodedItem.property;
let property = getProperty(propertyGroups, explodedItem.groupName, propertyName) || [];
let property = getProperty(propertyGroups, explodedItem.groupName, propertyName) || [];
if (isProperty) {
property = this.setPropertyTitle(property, explodedItem.property);
}
@@ -61,15 +60,14 @@ export class LayoutOrientedConfigService implements ContentMetadataConfig {
}
public appendAllPreset(propertyGroups: PropertyGroupContainer): OrganisedPropertyGroup[] {
return Object.keys(propertyGroups)
.map((groupName) => {
const propertyGroup = propertyGroups[groupName];
const properties = propertyGroup.properties;
return Object.keys(propertyGroups).map((groupName) => {
const propertyGroup = propertyGroups[groupName];
const properties = propertyGroup.properties;
return Object.assign({}, propertyGroup, {
properties: Object.keys(properties).map((propertyName) => properties[propertyName])
});
return Object.assign({}, propertyGroup, {
properties: Object.keys(properties).map((propertyName) => properties[propertyName])
});
});
}
public filterExcludedPreset(propertyGroups: OrganisedPropertyGroup[]): OrganisedPropertyGroup[] {
@@ -88,16 +86,14 @@ export class LayoutOrientedConfigService implements ContentMetadataConfig {
}
public isIncludeAllEnabled() {
const includeAllProperty = this.config
.map((config) => config.includeAll)
.find((includeAll) => includeAll !== undefined);
const includeAllProperty = this.config.map((config) => config.includeAll).find((includeAll) => includeAll !== undefined);
return includeAllProperty !== undefined ? includeAllProperty : false;
}
private setEditableProperty(propertyGroup: Property | Property[], itemConfig): Property | Property[] {
if (Array.isArray(propertyGroup)) {
propertyGroup.map((property) => property.editable = itemConfig.editable !== undefined ? itemConfig.editable : true);
propertyGroup.forEach((property) => (property.editable = itemConfig.editable !== undefined ? itemConfig.editable : true));
} else {
propertyGroup.editable = itemConfig.editable !== undefined ? itemConfig.editable : true;
}
@@ -107,7 +103,7 @@ export class LayoutOrientedConfigService implements ContentMetadataConfig {
private setPropertyTitle(item: Property | Property[], property: Property): Property | Property[] {
if (!Array.isArray(item)) {
return { ...item, ...(item.name === property.name && !!property.title) && { title: property.title } };
return { ...item, ...(item.name === property.name && !!property.title && { title: property.title }) };
}
return item;
}
@@ -31,24 +31,24 @@ import { VersionCompatibilityService } from '../../version-compatibility/version
providedIn: 'root'
})
export class ContentTypePropertiesService {
constructor(private contentTypeService: ContentTypeService,
private dialog: MatDialog,
private versionCompatibilityService: VersionCompatibilityService,
private propertyGroupTranslatorService: PropertyGroupTranslatorService) {
}
constructor(
private contentTypeService: ContentTypeService,
private dialog: MatDialog,
private versionCompatibilityService: VersionCompatibilityService,
private propertyGroupTranslatorService: PropertyGroupTranslatorService
) {}
getContentTypeCardItem(node: Node): Observable<CardViewItem[]> {
if (this.versionCompatibilityService.isVersionSupported('7')) {
return this.contentTypeService.getContentTypeByPrefix(node.nodeType).
pipe(
map((contentType) => {
const contentTypesOptions$ = this.getContentTypesAsSelectOption(contentType);
const contentTypeCard = this.buildContentTypeSelectCardModel(contentType.entry.id, contentTypesOptions$);
const filteredProperties = this.getContentTypeSpecificProperties(contentType);
const propertiesCard = this.buildCardItemsFromPropertyList(filteredProperties, node.properties);
return [contentTypeCard, ...propertiesCard];
}));
return this.contentTypeService.getContentTypeByPrefix(node.nodeType).pipe(
map((contentType) => {
const contentTypesOptions$ = this.getContentTypesAsSelectOption(contentType);
const contentTypeCard = this.buildContentTypeSelectCardModel(contentType.entry.id, contentTypesOptions$);
const filteredProperties = this.getContentTypeSpecificProperties(contentType);
const propertiesCard = this.buildCardItemsFromPropertyList(filteredProperties, node.properties);
return [contentTypeCard, ...propertiesCard];
})
);
} else {
return of([this.buildContentTypeTextCardModel(node.nodeType)]);
}
@@ -80,7 +80,10 @@ export class ContentTypePropertiesService {
return contentTypeCard;
}
private buildContentTypeSelectCardModel(currentValue: string, options$: Observable<CardViewSelectItemOption<string>[]>): CardViewSelectItemModel<string> {
private buildContentTypeSelectCardModel(
currentValue: string,
options$: Observable<CardViewSelectItemOption<string>[]>
): CardViewSelectItemModel<string> {
const contentTypeCard = new CardViewSelectItemModel({
label: 'CORE.METADATA.BASIC.CONTENT_TYPE',
value: currentValue,
@@ -100,7 +103,8 @@ export class ContentTypePropertiesService {
map(([contentTypesEntries, currentContentType]) => {
const updatedTypes = this.appendCurrentType(currentContentType, contentTypesEntries);
return updatedTypes.map((contentType) => ({ key: contentType.entry.id, label: contentType.entry.title ?? contentType.entry.id }));
}));
})
);
}
private appendCurrentType(currentType: TypeEntry, contentTypesEntries: TypeEntry[]): TypeEntry[] {
@@ -36,14 +36,13 @@ describe('PropertyDescriptorLoaderService', () => {
it('should load the groups passed by paramter', (done) => {
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve({}));
service.load(['exif:exif', 'cm:content', 'custom:custom'])
.subscribe(() => {
expect(classesApi.getClass).toHaveBeenCalledTimes(3);
expect(classesApi.getClass).toHaveBeenCalledWith('exif_exif');
expect(classesApi.getClass).toHaveBeenCalledWith('cm_content');
expect(classesApi.getClass).toHaveBeenCalledWith('custom_custom');
done();
});
service.load(['exif:exif', 'cm:content', 'custom:custom']).subscribe(() => {
expect(classesApi.getClass).toHaveBeenCalledTimes(3);
expect(classesApi.getClass).toHaveBeenCalledWith('exif_exif');
expect(classesApi.getClass).toHaveBeenCalledWith('cm_content');
expect(classesApi.getClass).toHaveBeenCalledWith('custom_custom');
done();
});
});
it('should merge the forked values', (done) => {
@@ -26,29 +26,29 @@ import { ClassesApi } from '@alfresco/js-api';
providedIn: 'root'
})
export class PropertyDescriptorsService {
private _classesApi: ClassesApi;
get classesApi(): ClassesApi {
this._classesApi = this._classesApi ?? new ClassesApi(this.alfrescoApiService.getInstance());
return this._classesApi;
}
constructor(private alfrescoApiService: AlfrescoApiService) {
}
constructor(private alfrescoApiService: AlfrescoApiService) {}
load(groupNames: string[]): Observable<PropertyGroupContainer> {
const groupFetchStreams = groupNames
.map((groupName) => groupName.replace(':', '_'))
.map((groupName) => defer(() => this.classesApi.getClass(groupName)));
return forkJoin(groupFetchStreams).pipe(
map(this.convertToObject)
);
return forkJoin(groupFetchStreams).pipe(map(this.convertToObject));
}
private convertToObject(propertyGroupsArray: PropertyGroup[]): PropertyGroupContainer {
return propertyGroupsArray.reduce((propertyGroups, propertyGroup) => Object.assign({}, propertyGroups, {
[propertyGroup.name]: propertyGroup
}), {});
return propertyGroupsArray.reduce(
(propertyGroups, propertyGroup) =>
Object.assign({}, propertyGroups, {
[propertyGroup.name]: propertyGroup
}),
{}
);
}
}
@@ -62,7 +62,6 @@ export const defaultValidation = () => true;
@Component({
selector: 'adf-content-node-selector-panel',
standalone: true,
imports: [
CommonModule,
MatFormFieldModule,
@@ -17,13 +17,7 @@
import { Component, DestroyRef, inject, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import {
EmptyListComponent,
NotificationService,
ToolbarComponent,
ToolbarTitleComponent,
TranslationService
} from '@alfresco/adf-core';
import { EmptyListComponent, NotificationService, ToolbarComponent, ToolbarTitleComponent, TranslationService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { AllowableOperationsEnum } from '../common/models/allowable-operations.enum';
import { ContentService } from '../common/services/content.service';
@@ -47,7 +41,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-content-node-selector',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
@@ -70,7 +63,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
encapsulation: ViewEncapsulation.None
})
export class ContentNodeSelectorComponent implements OnInit {
title: string;
action: NodeAction;
buttonActionName: string;
@@ -35,7 +35,6 @@ export enum Relations {
@Component({
selector: 'adf-sites-dropdown',
standalone: true,
imports: [CommonModule, TranslateModule, MatFormFieldModule, MatSelectModule, InfiniteSelectScrollDirective],
templateUrl: './sites-dropdown.component.html',
encapsulation: ViewEncapsulation.None,
@@ -41,7 +41,6 @@ interface SharedDialogFormProps {
@Component({
selector: 'adf-share-dialog',
standalone: true,
imports: [
CommonModule,
TranslateModule,
@@ -25,7 +25,6 @@ import { NodeSharedDirective } from '@alfresco/adf-content-services';
@Component({
selector: 'adf-node-share-test-component',
standalone: true,
imports: [NodeSharedDirective],
template: `
<button
@@ -26,7 +26,6 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class SharedLinksApiService {
error = new Subject<{ statusCode: number; message: string }>();
private _sharedLinksApi: SharedlinksApi;
@@ -35,9 +34,7 @@ export class SharedLinksApiService {
return this._sharedLinksApi;
}
constructor(private apiService: AlfrescoApiService,
private preferences: UserPreferencesService) {
}
constructor(private apiService: AlfrescoApiService, private preferences: UserPreferencesService) {}
/**
* Gets shared links available to the current user.
@@ -54,9 +51,7 @@ export class SharedLinksApiService {
const queryOptions = Object.assign({}, defaultOptions, options);
const promise = this.sharedLinksApi.listSharedLinks(queryOptions);
return from(promise).pipe(
catchError((err) => of(err))
);
return from(promise).pipe(catchError((err) => of(err)));
}
/**
@@ -68,11 +63,9 @@ export class SharedLinksApiService {
* @returns The shared link just created
*/
createSharedLinks(nodeId: string, sharedLinkWithExpirySettings?: SharedLinkBodyCreate, options: any = {}): Observable<SharedLinkEntry> {
const promise = this.sharedLinksApi.createSharedLink(sharedLinkWithExpirySettings? sharedLinkWithExpirySettings : { nodeId }, options);
const promise = this.sharedLinksApi.createSharedLink(sharedLinkWithExpirySettings ? sharedLinkWithExpirySettings : { nodeId }, options);
return from(promise).pipe(
catchError((err) => of(err))
);
return from(promise).pipe(catchError((err) => of(err)));
}
/**
@@ -84,8 +77,6 @@ export class SharedLinksApiService {
deleteSharedLink(sharedId: string): Observable<any | Error> {
const promise = this.sharedLinksApi.deleteSharedLink(sharedId);
return from(promise).pipe(
catchError((err: Error) => of(err))
);
return from(promise).pipe(catchError((err: Error) => of(err)));
}
}
@@ -28,7 +28,6 @@ import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-content-type-dialog',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, MatExpansionModule, MatTableModule, MatButtonModule],
templateUrl: './content-type-dialog.component.html',
styleUrls: ['./content-type-dialog.component.scss'],
@@ -25,15 +25,13 @@ import { map } from 'rxjs/operators';
providedIn: 'root'
})
export class ContentTypeService {
private _typesApi: TypesApi;
get typesApi(): TypesApi {
this._typesApi = this._typesApi ?? new TypesApi(this.alfrescoApiService.getInstance());
return this._typesApi;
}
constructor(private alfrescoApiService: AlfrescoApiService) {
}
constructor(private alfrescoApiService: AlfrescoApiService) {}
getContentTypeByPrefix(prefixedType: string): Observable<TypeEntry> {
return from(this.typesApi.getType(prefixedType));
@@ -45,8 +43,6 @@ export class ContentTypeService {
where,
include: ['properties']
};
return from(this.typesApi.listTypes(opts)).pipe(
map((result: TypePaging) => result.list.entries)
);
return from(this.typesApi.listTypes(opts)).pipe(map((result: TypePaging) => result.list.entries));
}
}
+13 -19
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { NgModule, ModuleWithProviders, APP_INITIALIZER } from '@angular/core';
import { NgModule, ModuleWithProviders, inject, provideAppInitializer } from '@angular/core';
import { provideTranslations } from '@alfresco/adf-core';
import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
import { CONTENT_TAG_DIRECTIVES } from './tag/tag.module';
@@ -115,24 +115,18 @@ export class ContentModule {
provideTranslations('adf-content-services', 'assets/adf-content-services'),
ContentAuthLoaderService,
{ provide: AlfrescoApiService, useClass: AlfrescoApiNoAuthService },
{
provide: APP_INITIALIZER,
useFactory: versionCompatibilityFactory,
deps: [VersionCompatibilityService],
multi: true
},
{
provide: APP_INITIALIZER,
useFactory: contentAuthLoaderFactory,
deps: [ContentAuthLoaderService],
multi: true
},
{
provide: APP_INITIALIZER,
useFactory: createAlfrescoApiInstance,
deps: [AlfrescoApiLoaderService],
multi: true
}
provideAppInitializer(() => {
const initializerFn = versionCompatibilityFactory(inject(VersionCompatibilityService));
return initializerFn();
}),
provideAppInitializer(() => {
const initializerFn = contentAuthLoaderFactory(inject(ContentAuthLoaderService));
return initializerFn();
}),
provideAppInitializer(() => {
const initializerFn = createAlfrescoApiInstance(inject(AlfrescoApiLoaderService));
return initializerFn();
})
]
};
}
@@ -31,7 +31,6 @@ export interface CategorySelectorDialogOptions {
@Component({
selector: 'adf-category-selector-dialog',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, CategoriesManagementComponent, MatButtonModule],
templateUrl: './category-selector.dialog.html',
styleUrls: ['./category-selector.dialog.scss'],
@@ -23,7 +23,8 @@ import { FileDownloadStatus } from '@alfresco/js-api';
@Component({
selector: 'adf-download-zip-dialog-storybook',
template: `<button mat-raised-button (click)="openDialog()">Open dialog</button>`
template: `<button mat-raised-button (click)="openDialog()">Open dialog</button>`,
standalone: false
})
export class DownloadZipDialogStorybookComponent implements OnInit, OnChanges {
@Input()
@@ -27,7 +27,8 @@ import { FileDownloadStatus } from '@alfresco/js-api';
templateUrl: './download-zip.dialog.html',
styleUrls: ['./download-zip.dialog.scss'],
host: { class: 'adf-download-zip-dialog' },
encapsulation: ViewEncapsulation.None
encapsulation: ViewEncapsulation.None,
standalone: false
})
export class DownloadZipDialogComponent implements OnInit {
// flag for async threads
@@ -24,15 +24,13 @@ import { AlfrescoApiService } from '../../../services/alfresco-api.service';
providedIn: 'root'
})
export class DownloadZipService {
private _downloadsApi: DownloadsApi;
get downloadsApi(): DownloadsApi {
this._downloadsApi = this._downloadsApi ?? new DownloadsApi(this.apiService.getInstance());
return this._downloadsApi;
}
constructor(private apiService: AlfrescoApiService) {
}
constructor(private apiService: AlfrescoApiService) {}
/**
* Creates a new download.
@@ -11,7 +11,7 @@
#{$mat-form-field-hide-placeholder} {
#{$mat-floating-label} {
padding-top: 11px;
padding-top: 20px;
}
}
@@ -32,7 +32,6 @@ import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-folder-dialog',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
@@ -34,7 +34,7 @@
&#{$mat-form-field-hide-placeholder} {
#{$mat-floating-label} {
padding-top: 11px;
padding-top: 20px;
}
}
@@ -43,7 +43,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-library-dialog',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
@@ -31,7 +31,6 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
@Component({
selector: 'adf-node-lock',
standalone: true,
imports: [
CommonModule,
TranslateModule,
@@ -22,7 +22,6 @@ import { By } from '@angular/platform-browser';
import { NoopTranslateModule } from '@alfresco/adf-core';
@Component({
standalone: true,
imports: [AutoFocusDirective],
template: ` <div tabindex="0" adf-auto-focus>Test</div>`
})
@@ -26,7 +26,8 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
@Component({
selector: 'adf-text-subject',
template: ''
template: '',
standalone: false
})
class TestComponent implements NodeAllowableOperationSubject {
disabled: boolean = false;
@@ -22,7 +22,6 @@ import { LibraryEntity } from '../interfaces/library-entity.interface';
import { HttpClientTestingModule } from '@angular/common/http/testing';
@Component({
standalone: true,
imports: [LibraryFavoriteDirective],
selector: 'app-test-component',
template: `<button #favoriteLibrary="favoriteLibrary" [adf-favorite-library]="selection">Favorite</button>`
@@ -22,7 +22,6 @@ import { By } from '@angular/platform-browser';
import { NoopTranslateModule } from '@alfresco/adf-core';
@Component({
standalone: true,
imports: [NodeCounterDirective],
template: `<div [adf-node-counter]="count"></div>`
})
@@ -44,7 +44,6 @@ export class NodeCounterDirective implements OnInit, OnChanges {
}
@Component({
standalone: true,
imports: [TranslateModule],
selector: 'adf-node-counter',
template: ` <div>{{ 'NODE_COUNTER.SELECTED_COUNT' | translate : { count: counter } }}</div> `
@@ -24,7 +24,6 @@ import { EMPTY, of } from 'rxjs';
import { CheckAllowableOperationDirective } from './check-allowable-operation.directive';
@Component({
standalone: true,
imports: [NodeDeleteDirective],
template: `<div id="delete-component" [adf-delete]="selection" (delete)="onDelete()"></div>`
})
@@ -38,7 +37,6 @@ class TestComponent {
}
@Component({
standalone: true,
imports: [NodeDeleteDirective, CheckAllowableOperationDirective],
template: `<div id="delete-component" [adf-check-allowable-operation]="'delete'" [adf-delete]="selection" (delete)="onDelete($event)"></div>`
})
@@ -52,7 +50,6 @@ class TestWithPermissionsComponent {
}
@Component({
standalone: true,
imports: [NodeDeleteDirective],
template: ` delete permanent
<div id="delete-permanent" [adf-delete]="selection" [permanent]="permanent" (delete)="onDelete($event)"></div>`
@@ -26,7 +26,6 @@ import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AlfrescoApiServiceMock } from '../mock/alfresco-api.service.mock';
@Component({
standalone: true,
imports: [NodeDownloadDirective],
template: '<div [adfNodeDownload]="selection" [version]="version"></div>'
})
@@ -30,7 +30,8 @@ const fakeNode = {
} as Node;
@Component({
template: '<div [adf-node-lock]="node"></div>'
template: '<div [adf-node-lock]="node"></div>',
standalone: false
})
class TestComponent {
node = null;
@@ -23,7 +23,6 @@ import { NoopTranslateModule, TranslationService } from '@alfresco/adf-core';
import { TrashcanApi } from '@alfresco/js-api';
@Component({
standalone: true,
imports: [NodeRestoreDirective],
template: ` <div [adf-restore]="selection" (restore)="doneSpy()"></div>`
})
@@ -48,7 +48,7 @@
<img [alt]="'ADF-DATATABLE.EMPTY.DRAG-AND-DROP.TITLE' | translate" class="adf-empty-folder-image" [src]="emptyFolderImageUrl">
</div>
</adf-empty-list>
<ng-content select="adf-custom-empty-content-template, empty-folder-content"></ng-content>
<ng-content select="adf-custom-empty-content-template, empty-folder-content" />
</ng-template>
</adf-no-content-template>
@@ -58,7 +58,7 @@
<mat-icon>error</mat-icon>
<p class="adf-no-permission__template--text">{{ 'ADF-DOCUMENT-LIST.NO_PERMISSION' | translate }}</p>
</div>
<ng-content select="adf-custom-no-permission-template, no-permission-content"></ng-content>
<ng-content select="adf-custom-no-permission-template, no-permission-content" />
</ng-template>
</adf-no-permission-template>
@@ -72,7 +72,7 @@
[color]="'primary'"
[mode]="'indeterminate'" />
</div>
<ng-content select="adf-custom-loading-content-template"></ng-content>
<ng-content select="adf-custom-loading-content-template" />
</ng-template>
</adf-loading-content-template>
@@ -30,16 +30,7 @@ import {
import { FavoritePaging, FavoritePagingList, Node, NodeEntry, NodePaging } from '@alfresco/js-api';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
Injector,
QueryList,
runInInjectionContext,
SimpleChange,
SimpleChanges,
ViewChild
} from '@angular/core';
import { Component, CUSTOM_ELEMENTS_SCHEMA, Injector, QueryList, runInInjectionContext, SimpleChange, SimpleChanges, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
import { By } from '@angular/platform-browser';
@@ -1139,7 +1130,7 @@ describe('DocumentList', () => {
fixture.detectChanges();
runInInjectionContext(injector, () => {
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock);
})
});
expect(documentList.dataTable).toBeDefined();
expect(fixture.debugElement.query(By.css('adf-empty-list'))).not.toBeNull();
});
@@ -1160,7 +1151,7 @@ describe('DocumentList', () => {
it('should empty folder NOT show the pagination', () => {
runInInjectionContext(injector, () => {
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock);
})
});
expect(documentList.isEmpty()).toBeTruthy();
expect(element.querySelector('alfresco-pagination')).toBe(null);
@@ -1888,7 +1879,6 @@ describe('DocumentList', () => {
});
@Component({
standalone: true,
imports: [CommonModule, DocumentListComponent, CustomLoadingContentTemplateDirective],
template: `
<adf-document-list #customDocumentList>
@@ -92,7 +92,6 @@ const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
@Component({
selector: 'adf-document-list',
standalone: true,
imports: [
CommonModule,
DataTableComponent,
@@ -735,7 +734,7 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
}
private isLinkFolder(node: Node) {
return node.nodeType === 'app:folderlink' && node.properties && node.properties['cm:destination'];
return node.nodeType === 'app:folderlink' && node.properties?.['cm:destination'];
}
private updateCustomSourceData(nodeId: string): void {
@@ -25,7 +25,6 @@ import { NodeDownloadDirective } from '../../../directives/node-download.directi
@Component({
selector: 'adf-file-auto-download',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, MatButtonModule, NodeDownloadDirective],
templateUrl: './file-auto-download.component.html'
})
@@ -26,7 +26,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-filter-header',
standalone: true,
imports: [CommonModule, HeaderFilterTemplateDirective, SearchFilterContainerComponent],
templateUrl: './filter-header.component.html'
})
@@ -27,7 +27,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-library-name-column',
standalone: true,
imports: [CommonModule, TranslateModule],
template: `
<span
@@ -26,7 +26,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-library-role-column',
standalone: true,
imports: [CommonModule, TranslateModule],
template: `
<span class="adf-datatable-cell-value" title="{{ displayText$ | async | translate }}">
@@ -26,7 +26,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-library-status-column',
standalone: true,
imports: [CommonModule, TranslateModule],
template: `
<span class="adf-datatable-cell-value" title="{{ displayText$ | async | translate }}">
@@ -27,7 +27,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-name-column',
standalone: true,
imports: [CommonModule, TranslateModule, NodeNameTooltipPipe],
template: `
<span
@@ -23,7 +23,6 @@ import { NodeNameTooltipPipe } from '../../../pipes/node-name-tooltip.pipe';
@Component({
selector: 'adf-trashcan-name-column',
standalone: true,
imports: [CommonModule, NodeNameTooltipPipe],
template: `
<ng-container *ngIf="!isLibrary">
@@ -15,13 +15,7 @@
* limitations under the License.
*/
import {
DataColumn,
DataRow,
DataSorting,
DataTableAdapter,
ThumbnailService
} from '@alfresco/adf-core';
import { DataColumn, DataRow, DataSorting, DataTableAdapter, ThumbnailService } from '@alfresco/adf-core';
import { NodePaging, NodeEntry } from '@alfresco/js-api';
import { PermissionStyleModel } from './../models/permissions-style.model';
import { ShareDataRow } from './share-data-row.model';
@@ -57,12 +51,14 @@ export class ShareDataTableAdapter implements DataTableAdapter {
return this._sortingMode;
}
constructor(private thumbnailService: ThumbnailService,
private contentService: ContentService,
schema: DataColumn[] = [],
sorting?: DataSorting,
sortingMode: string = 'client',
allowDropFiles: boolean = false) {
constructor(
private thumbnailService: ThumbnailService,
private contentService: ContentService,
schema: DataColumn[] = [],
sorting?: DataSorting,
sortingMode: string = 'client',
allowDropFiles: boolean = false
) {
this.rows = [];
this.columns = schema || [];
this.sorting = sorting;
@@ -106,7 +102,6 @@ export class ShareDataTableAdapter implements DataTableAdapter {
}
if (col.key === '$thumbnail') {
if (this.imageResolver) {
const resolved = this.imageResolver(row, col);
if (resolved) {
@@ -137,7 +132,6 @@ export class ShareDataTableAdapter implements DataTableAdapter {
}
if (col.type === 'image') {
if (this.imageResolver) {
const resolved = this.imageResolver(row, col);
if (resolved) {
@@ -149,7 +143,6 @@ export class ShareDataTableAdapter implements DataTableAdapter {
return dataRow.cacheValue(col.key, value);
}
/**
* Gets a thumbnail URL for the given document node.
*
@@ -217,14 +210,12 @@ export class ShareDataTableAdapter implements DataTableAdapter {
isSmartFolder(node: any) {
const nodeAspects = this.getNodeAspectNames(node);
return nodeAspects.indexOf('smf:customConfigSmartFolder') > -1 ||
(nodeAspects.indexOf('smf:systemConfigSmartFolder') > -1);
return nodeAspects.indexOf('smf:customConfigSmartFolder') > -1 || nodeAspects.indexOf('smf:systemConfigSmartFolder') > -1;
}
isRuleFolder(node: any) {
const nodeAspects = this.getNodeAspectNames(node);
return nodeAspects.indexOf('rule:rules') > -1 ||
(nodeAspects.indexOf('rule:rules') > -1);
return nodeAspects.indexOf('rule:rules') > -1;
}
isALinkFolder(node: any) {
@@ -233,7 +224,7 @@ export class ShareDataTableAdapter implements DataTableAdapter {
}
private getNodeAspectNames(node: any): any[] {
return node.entry?.aspectNames ? node.entry.aspectNames : (node.aspectNames ? node.aspectNames : []);
return node.entry?.aspectNames ? node.entry.aspectNames : node.aspectNames ? node.aspectNames : [];
}
private sortRows(rows: DataRow[], sorting: DataSorting) {
@@ -244,7 +235,6 @@ export class ShareDataTableAdapter implements DataTableAdapter {
const options: Intl.CollatorOptions = {};
if (sorting?.key && rows?.length) {
if (sorting.key.includes('sizeInBytes') || sorting.key === 'name') {
options.numeric = true;
}
@@ -256,21 +246,19 @@ export class ShareDataTableAdapter implements DataTableAdapter {
let left = a.getValue(sorting.key);
if (left) {
left = (left instanceof Date) ? left.valueOf().toString() : left.toString();
left = left instanceof Date ? left.valueOf().toString() : left.toString();
} else {
left = '';
}
let right = b.getValue(sorting.key);
if (right) {
right = (right instanceof Date) ? right.valueOf().toString() : right.toString();
right = right instanceof Date ? right.valueOf().toString() : right.toString();
} else {
right = '';
}
return sorting.direction === 'asc'
? left.localeCompare(right, undefined, options)
: right.localeCompare(left, undefined, options);
return sorting.direction === 'asc' ? left.localeCompare(right, undefined, options) : right.localeCompare(left, undefined, options);
});
}
}
@@ -283,7 +271,9 @@ export class ShareDataTableAdapter implements DataTableAdapter {
if (nodePaging?.list) {
const nodeEntries: NodeEntry[] = nodePaging.list.entries;
if (nodeEntries?.length) {
shareDataRows = nodeEntries.map((item) => new ShareDataRow(item, this.contentService, this.permissionsStyle, this.thumbnailService, this.allowDropFiles));
shareDataRows = nodeEntries.map(
(item) => new ShareDataRow(item, this.contentService, this.permissionsStyle, this.thumbnailService, this.allowDropFiles)
);
if (this.filter) {
shareDataRows = shareDataRows.filter(this.filter);
@@ -326,6 +316,6 @@ export class ShareDataTableAdapter implements DataTableAdapter {
}
getRowByNodeId(nodeId: string): DataRow {
return this.rows.find((row: DataRow) => row.node.entry.id === nodeId);
return this.rows.find((row: DataRow) => row.node.entry.id === nodeId);
}
}
@@ -59,14 +59,14 @@ export enum ContentActionTarget {
export type ContentActionHandler = (obj: any, target?: any, permission?: string) => any;
export class DocumentActionModel extends ContentActionModel {
constructor(json?: any) {
constructor(json?: any) {
super(json);
this.target = 'document';
}
}
export class FolderActionModel extends ContentActionModel {
constructor(json?: any) {
export class FolderActionModel extends ContentActionModel {
constructor(json?: any) {
super(json);
this.target = 'folder';
}
@@ -29,17 +29,18 @@ import { NodeActionsService } from './node-actions.service';
providedIn: 'root'
})
export class FolderActionsService {
permissionEvent = new Subject<PermissionModel>();
error = new Subject<Error>();
success = new Subject<string>();
private handlers: { [id: string]: ContentActionHandler } = {};
constructor(private nodeActionsService: NodeActionsService,
private documentListService: DocumentListService,
private contentService: ContentService,
private translation: TranslationService) {
constructor(
private nodeActionsService: NodeActionsService,
private documentListService: DocumentListService,
private contentService: ContentService,
private translation: TranslationService
) {
this.setupActionHandlers();
}
@@ -107,36 +108,36 @@ export class FolderActionsService {
}
private prepareHandlers(actionObservable: Observable<any>, target?: any): void {
actionObservable.subscribe(
(fileOperationMessage) => {
if (target && typeof target.reload === 'function') {
target.reload();
}
this.success.next(fileOperationMessage);
},
this.error.next.bind(this.error)
);
actionObservable.subscribe((fileOperationMessage) => {
if (target && typeof target.reload === 'function') {
target.reload();
}
this.success.next(fileOperationMessage);
}, this.error.next.bind(this.error));
}
private deleteNode(node: NodeEntry, target?: any, permission?: string): Observable<any> {
if (this.canExecuteAction(node)) {
if (this.contentService.hasAllowableOperations(node.entry, permission)) {
const handlerObservable = this.documentListService.deleteNode(node.entry.id);
handlerObservable.subscribe(() => {
if (target && typeof target.reload === 'function') {
target.reload();
}
handlerObservable.subscribe(
() => {
if (target && typeof target.reload === 'function') {
target.reload();
}
const message = this.translation.instant('CORE.DELETE_NODE.SINGULAR', { name: node.entry.name });
this.success.next(message);
}, () => {
const message = this.translation.instant('CORE.DELETE_NODE.ERROR_SINGULAR', { name: node.entry.name });
this.error.next(message);
});
const message = this.translation.instant('CORE.DELETE_NODE.SINGULAR', { name: node.entry.name });
this.success.next(message);
},
() => {
const message = this.translation.instant('CORE.DELETE_NODE.ERROR_SINGULAR', { name: node.entry.name });
this.error.next(message);
}
);
return handlerObservable;
} else {
this.permissionEvent.next(new PermissionModel({type: 'folder', action: 'delete', permission}));
this.permissionEvent.next(new PermissionModel({ type: 'folder', action: 'delete', permission }));
return throwError(new Error('No permission to delete'));
}
}
@@ -24,9 +24,7 @@ import { isAfter } from 'date-fns';
providedIn: 'root'
})
export class LockService {
constructor(private authService: AuthenticationService) {
}
constructor(private authService: AuthenticationService) {}
isLocked(node: Node): boolean {
let isLocked = false;
@@ -26,7 +26,8 @@ import { ContentTestingModule } from '../testing/content.testing.module';
import { ContentService } from '../common/services/content.service';
@Component({
template: '<div [adf-edit-folder]="folder" (success)="success($event)" title="edit-title"></div>'
template: '<div [adf-edit-folder]="folder" (success)="success($event)" title="edit-title"></div>',
standalone: false
})
class TestComponent {
folder = {};
@@ -25,27 +25,27 @@ import { map } from 'rxjs/operators';
providedIn: 'root'
})
export class GroupService {
private _groupsApi: GroupsApi;
get groupsApi(): GroupsApi {
this._groupsApi = this._groupsApi ?? new GroupsApi(this.alfrescoApiService.getInstance());
return this._groupsApi;
}
constructor(
private alfrescoApiService: AlfrescoApiService
) {
}
constructor(private alfrescoApiService: AlfrescoApiService) {}
async listAllGroupMembershipsForPerson(personId: string, opts?: any, accumulator = []): Promise<GroupEntry[]> {
const groupsPaginated = await this.groupsApi.listGroupMembershipsForPerson(personId, opts);
accumulator = [...accumulator, ...groupsPaginated.list.entries];
if (groupsPaginated.list.pagination.hasMoreItems) {
const skip = groupsPaginated.list.pagination.skipCount + groupsPaginated.list.pagination.count;
return this.listAllGroupMembershipsForPerson(personId, {
maxItems: opts.maxItems,
skipCount: skip
}, accumulator);
return this.listAllGroupMembershipsForPerson(
personId,
{
maxItems: opts.maxItems,
skipCount: skip
},
accumulator
);
} else {
return accumulator;
}
@@ -59,10 +59,12 @@ export class GroupService {
* @returns Observable<GroupEntry> group for specified id.
*/
getGroup(id: string, opts?: ContentIncludeQuery): Observable<GroupEntry> {
return from(this.groupsApi.getGroup(id, opts)).pipe(map((group) => {
group.entry.description ||= '';
return group;
}));
return from(this.groupsApi.getGroup(id, opts)).pipe(
map((group) => {
group.entry.description ||= '';
return group;
})
);
}
/**
@@ -73,12 +75,20 @@ export class GroupService {
* @returns Observable<GroupEntry> updated group.
*/
updateGroup(group: Group, opts?: ContentIncludeQuery): Observable<GroupEntry> {
return from(this.groupsApi.updateGroup(group.id, {
displayName: group.displayName,
description: group.description
}, opts)).pipe(map((updatedGroup) => {
updatedGroup.entry.description ||= '';
return updatedGroup;
}));
return from(
this.groupsApi.updateGroup(
group.id,
{
displayName: group.displayName,
description: group.description
},
opts
)
).pipe(
map((updatedGroup) => {
updatedGroup.entry.description ||= '';
return updatedGroup;
})
);
}
}
@@ -81,7 +81,8 @@ class TestDataSource extends InfiniteScrollDatasource<TestData> {
<div *cdkVirtualFor="let item of testDatasource" class="test-item" style="display: block; height: 100%; width: 100%;">
{{ item.testDescription }}
</div>
</cdk-virtual-scroll-viewport>`
</cdk-virtual-scroll-viewport>`,
standalone: false
})
class TestComponent implements OnInit {
testDatasource = new TestDataSource();
@@ -17,128 +17,126 @@
/* spellchecker: disable */
export const fakeAuthorityResults: any[] = [{
entry: {
aspectNames: [
'cm:personDisabled',
'cm:ownable',
'cm:preferences'
],
isFolder: false,
search: {
score: 4.014668
},
isFile: false,
name: 'dc103838-645f-43c1-8a2a-bc187e13c343',
location: 'nodes',
id: 'dc103838-645f-43c1-8a2a-bc187e13c343',
nodeType: 'cm:person',
properties: {
'cm:location': 'Tilbury, UK',
'cm:persondescription': {
contentUrl: 'store://2018/4/18/9/30/514bb261-bc61-4502-ad2f-dfafec9ae4eb.bin',
mimetype: 'application/octet-stream',
size: 55,
encoding: 'UTF-8',
locale: 'en_US',
id: 148,
infoUrl: 'contentUrl=store://2018/4/18/9/30/514bb261-bc61-4502-ad2f-dfafec9ae4eb.bin|mimetype=application/octet-stream|size=55|encoding=UTF-8|locale=en_US_'
export const fakeAuthorityResults: any[] = [
{
entry: {
aspectNames: ['cm:personDisabled', 'cm:ownable', 'cm:preferences'],
isFolder: false,
search: {
score: 4.014668
},
'cm:owner': {
id: 'abeecher',
displayName: 'Alice Beecher'
isFile: false,
name: 'dc103838-645f-43c1-8a2a-bc187e13c343',
location: 'nodes',
id: 'dc103838-645f-43c1-8a2a-bc187e13c343',
nodeType: 'cm:person',
properties: {
'cm:location': 'Tilbury, UK',
'cm:persondescription': {
contentUrl: 'store://2018/4/18/9/30/514bb261-bc61-4502-ad2f-dfafec9ae4eb.bin',
mimetype: 'application/octet-stream',
size: 55,
encoding: 'UTF-8',
locale: 'en_US',
id: 148,
infoUrl:
'contentUrl=store://2018/4/18/9/30/514bb261-bc61-4502-ad2f-dfafec9ae4eb.bin|mimetype=application/octet-stream|size=55|encoding=UTF-8|locale=en_US_'
},
'cm:owner': {
id: 'abeecher',
displayName: 'Alice Beecher'
},
'cm:companyaddress2': 'Tilbury',
'cm:userStatus': 'Helping to design the look and feel of the new web site',
'cm:companyaddress1': '200 Butterwick Street',
'cm:telephone': '0112211001100',
'cm:preferenceValues': {
contentUrl: 'store://2018/4/18/9/30/afc39bc9-6bac-4f24-8730-9d9f617a322e.bin',
mimetype: 'text/plain',
size: 709,
encoding: 'UTF-8',
locale: 'en_US',
id: 147,
infoUrl:
'contentUrl=store://2018/4/18/9/30/afc39bc9-6bac-4f24-8730-9d9f617a322e.bin|mimetype=text/plain|size=709|encoding=UTF-8|locale=en_US_'
},
'cm:userName': 'abeecher',
'cm:companyaddress3': 'UK',
'cm:userStatusTime': '2011-02-15T20:20:13.432+0000',
'cm:email': 'abeecher@example.com',
'cm:skype': 'abeecher',
'cm:jobtitle': 'Graphic Designer',
'cm:homeFolderProvider': 'userHomesHomeFolderProvider',
'cm:homeFolder': '242533d8-68e6-4811-bc3d-61ec63c614aa',
'cm:lastName': 'Beecher',
'cm:sizeCurrent': 8382006,
'cm:sizeQuota': -1,
'cm:firstName': 'Alice',
'cm:emailFeedId': 440,
'cm:authorizationStatus': 'NEVER_AUTHORIZED',
'cm:mobile': '0112211001100',
'cm:organization': 'Moresby, Garland and Wedge',
'cm:companypostcode': 'ALF1 SAM1'
},
'cm:companyaddress2': 'Tilbury',
'cm:userStatus': 'Helping to design the look and feel of the new web site',
'cm:companyaddress1': '200 Butterwick Street',
'cm:telephone': '0112211001100',
'cm:preferenceValues': {
contentUrl: 'store://2018/4/18/9/30/afc39bc9-6bac-4f24-8730-9d9f617a322e.bin',
mimetype: 'text/plain',
size: 709,
encoding: 'UTF-8',
locale: 'en_US',
id: 147,
infoUrl: 'contentUrl=store://2018/4/18/9/30/afc39bc9-6bac-4f24-8730-9d9f617a322e.bin|mimetype=text/plain|size=709|encoding=UTF-8|locale=en_US_'
parentId: '063f5d48-a0b3-4cbf-826c-88a4fbfa3336'
}
},
{
entry: {
aspectNames: ['cm:ownable', 'cm:preferences'],
isFolder: false,
search: {
score: 4.014668
},
'cm:userName': 'abeecher',
'cm:companyaddress3': 'UK',
'cm:userStatusTime': '2011-02-15T20:20:13.432+0000',
'cm:email': 'abeecher@example.com',
'cm:skype': 'abeecher',
'cm:jobtitle': 'Graphic Designer',
'cm:homeFolderProvider': 'userHomesHomeFolderProvider',
'cm:homeFolder': '242533d8-68e6-4811-bc3d-61ec63c614aa',
'cm:lastName': 'Beecher',
'cm:sizeCurrent': 8382006,
'cm:sizeQuota': -1,
'cm:firstName': 'Alice',
'cm:emailFeedId': 440,
'cm:authorizationStatus': 'NEVER_AUTHORIZED',
'cm:mobile': '0112211001100',
'cm:organization': 'Moresby, Garland and Wedge',
'cm:companypostcode': 'ALF1 SAM1'
},
parentId: '063f5d48-a0b3-4cbf-826c-88a4fbfa3336'
isFile: false,
name: 'e320c16b-a763-4a4e-9f22-286ff5d8dca2',
location: 'nodes',
id: 'e320c16b-a763-4a4e-9f22-286ff5d8dca2',
nodeType: 'cm:person',
properties: {
'cm:homeFolderProvider': 'bootstrapHomeFolderProvider',
'cm:preferenceValues': {
contentUrl: 'store://2018/4/23/14/42/92bb4aa9-db27-41a4-9804-ddab3cc83d3e.bin',
mimetype: 'text/plain',
size: 102,
encoding: 'UTF-8',
locale: 'en',
id: 313,
infoUrl:
'contentUrl=store://2018/4/23/14/42/92bb4aa9-db27-41a4-9804-ddab3cc83d3e.bin|mimetype=text/plain|size=102|encoding=UTF-8|locale=en_'
},
'cm:authorizationStatus': 'AUTHORIZED',
'cm:homeFolder': 'a20cd541-4ada-4525-9807-9fa0a047d9f4',
'cm:userName': 'admin',
'cm:sizeCurrent': 0,
'cm:email': 'admin@alfresco.com',
'cm:firstName': 'Administrator',
'cm:owner': {
id: 'admin',
displayName: 'Administrator'
}
},
parentId: '063f5d48-a0b3-4cbf-826c-88a4fbfa3336'
}
},
{
entry: {
isFolder: false,
search: {
score: 0.3541112
},
isFile: false,
name: 'GROUP_ALFRESCO_ADMINISTRATORS',
location: 'nodes',
id: 'GROUP_ALFRESCO_ADMINISTRATORS',
nodeType: 'cm:authorityContainer',
properties: {
'cm:authorityName': 'GROUP_ALFRESCO_ADMINISTRATORS'
},
parentId: '030d833e-da8e-4f5c-8ef9-d809638bd04b'
}
}
},
{
entry: {
aspectNames: [
'cm:ownable',
'cm:preferences'
],
isFolder: false,
search: {
score: 4.014668
},
isFile: false,
name: 'e320c16b-a763-4a4e-9f22-286ff5d8dca2',
location: 'nodes',
id: 'e320c16b-a763-4a4e-9f22-286ff5d8dca2',
nodeType: 'cm:person',
properties: {
'cm:homeFolderProvider': 'bootstrapHomeFolderProvider',
'cm:preferenceValues': {
contentUrl: 'store://2018/4/23/14/42/92bb4aa9-db27-41a4-9804-ddab3cc83d3e.bin',
mimetype: 'text/plain',
size: 102,
encoding: 'UTF-8',
locale: 'en',
id: 313,
infoUrl: 'contentUrl=store://2018/4/23/14/42/92bb4aa9-db27-41a4-9804-ddab3cc83d3e.bin|mimetype=text/plain|size=102|encoding=UTF-8|locale=en_'
},
'cm:authorizationStatus': 'AUTHORIZED',
'cm:homeFolder': 'a20cd541-4ada-4525-9807-9fa0a047d9f4',
'cm:userName': 'admin',
'cm:sizeCurrent': 0,
'cm:email': 'admin@alfresco.com',
'cm:firstName': 'Administrator',
'cm:owner': {
id: 'admin',
displayName: 'Administrator'
}
},
parentId: '063f5d48-a0b3-4cbf-826c-88a4fbfa3336'
}
},
{
entry: {
isFolder: false,
search: {
score: 0.3541112
},
isFile: false,
name: 'GROUP_ALFRESCO_ADMINISTRATORS',
location: 'nodes',
id: 'GROUP_ALFRESCO_ADMINISTRATORS',
nodeType: 'cm:authorityContainer',
properties: {
'cm:authorityName': 'GROUP_ALFRESCO_ADMINISTRATORS'
},
parentId: '030d833e-da8e-4f5c-8ef9-d809638bd04b'
}
}];
];
export const fakeAuthorityListResult: any = {
list: {
@@ -168,64 +166,67 @@ export const fakeNameListResult: any = {
lastTxId: 5496
}
},
entries: [{
entry: {
aspectNames: ['cm:ownable'],
isFolder: false,
search: {
score: 1.0
},
isFile: false,
name: '730cd9b0-5617-4865-aee8-90de1d596997',
location: 'nodes',
id: '730cd9b0-5617-4865-aee8-90de1d596997',
nodeType: 'cm:person',
properties: {
'cm:homeFolderProvider': 'userHomesHomeFolderProvider',
'cm:authorizationStatus': 'NEVER_AUTHORIZED',
'cm:homeFolder': '277f505d-6526-45b1-a7b3-c9bdd66f17f6',
'cm:userName': 'test1',
'cm:lastName': 'lastName1',
'cm:sizeCurrent': 0,
'cm:email': 'test1@gmail.com',
'cm:sizeQuota': 1073741824,
'cm:firstName': 'firstName',
'cm:owner': {
id: 'test1',
displayName: 'firstName lastName1'
}
},
parentId: '3e9ce910-a4a0-4531-8f80-7734bece6342'
entries: [
{
entry: {
aspectNames: ['cm:ownable'],
isFolder: false,
search: {
score: 1.0
},
isFile: false,
name: '730cd9b0-5617-4865-aee8-90de1d596997',
location: 'nodes',
id: '730cd9b0-5617-4865-aee8-90de1d596997',
nodeType: 'cm:person',
properties: {
'cm:homeFolderProvider': 'userHomesHomeFolderProvider',
'cm:authorizationStatus': 'NEVER_AUTHORIZED',
'cm:homeFolder': '277f505d-6526-45b1-a7b3-c9bdd66f17f6',
'cm:userName': 'test1',
'cm:lastName': 'lastName1',
'cm:sizeCurrent': 0,
'cm:email': 'test1@gmail.com',
'cm:sizeQuota': 1073741824,
'cm:firstName': 'firstName',
'cm:owner': {
id: 'test1',
displayName: 'firstName lastName1'
}
},
parentId: '3e9ce910-a4a0-4531-8f80-7734bece6342'
}
},
{
entry: {
aspectNames: ['cm:ownable'],
isFolder: false,
search: {
score: 1.0
},
isFile: false,
name: '3d1e9e57-505f-431e-bb2b-38ad8d5d2d15',
location: 'nodes',
id: '3d1e9e57-505f-431e-bb2b-38ad8d5d2d15',
nodeType: 'cm:person',
properties: {
'cm:homeFolderProvider': 'userHomesHomeFolderProvider',
'cm:authorizationStatus': 'NEVER_AUTHORIZED',
'cm:homeFolder': '81a07ff0-82fb-4bbb-b869-d5fd92e71e17',
'cm:userName': 'test11',
'cm:lastName': 'lastName2',
'cm:sizeCurrent': 0,
'cm:email': 'test2@gmail.com',
'cm:sizeQuota': -1,
'cm:firstName': 'firstName',
'cm:owner': {
id: 'test11',
displayName: 'firstName lastName2'
}
},
parentId: '3e9ce910-a4a0-4531-8f80-7734bece6342'
}
}
}, {
entry: {
aspectNames: ['cm:ownable'],
isFolder: false,
search: {
score: 1.0
},
isFile: false,
name: '3d1e9e57-505f-431e-bb2b-38ad8d5d2d15',
location: 'nodes',
id: '3d1e9e57-505f-431e-bb2b-38ad8d5d2d15',
nodeType: 'cm:person',
properties: {
'cm:homeFolderProvider': 'userHomesHomeFolderProvider',
'cm:authorizationStatus': 'NEVER_AUTHORIZED',
'cm:homeFolder': '81a07ff0-82fb-4bbb-b869-d5fd92e71e17',
'cm:userName': 'test11',
'cm:lastName': 'lastName2',
'cm:sizeCurrent': 0,
'cm:email': 'test2@gmail.com',
'cm:sizeQuota': -1,
'cm:firstName': 'firstName',
'cm:owner': {
id: 'test11',
displayName: 'firstName lastName2'
}
},
parentId: '3e9ce910-a4a0-4531-8f80-7734bece6342'
}
}]
]
}
};
@@ -21,9 +21,7 @@ import { AppConfigService, StorageService } from '@alfresco/adf-core';
@Injectable()
export class AlfrescoApiServiceMock extends AlfrescoApiService {
constructor(protected appConfig: AppConfigService,
protected storageService: StorageService) {
constructor(protected appConfig: AppConfigService, protected storageService: StorageService) {
super(appConfig, storageService);
if (!this.alfrescoApi) {
this.initAlfrescoApi();
@@ -18,7 +18,7 @@
import { SearchCategory } from '../search/models/search-category.interface';
export const mockSearchFilterWithoutDisplayedLabelsByField: SearchCategory = {
id : 'test',
id: 'test',
name: 'test',
expanded: false,
enabled: true,
@@ -33,7 +33,7 @@ export const mockSearchFilterWithoutDisplayedLabelsByField: SearchCategory = {
};
export const mockSearchFilterWithWrongDisplayedLabelsByField: SearchCategory = {
id : 'test',
id: 'test',
name: 'test',
expanded: false,
enabled: true,
@@ -51,7 +51,7 @@ export const mockSearchFilterWithWrongDisplayedLabelsByField: SearchCategory = {
};
export const mockSearchFilterWithDisplayedLabelsByField: SearchCategory = {
id : 'test',
id: 'test',
name: 'test',
expanded: false,
enabled: true,
@@ -27,10 +27,13 @@ export const fakeNodeWithCreatePermission = new Node({
path: {
name: '/Company Home/User Homes',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: '55052317-7e59-4058-8e07-769f41e615e1', name: 'User Homes' }]
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: '55052317-7e59-4058-8e07-769f41e615e1', name: 'User Homes' }
]
},
isFolder: true,
modifiedByUser: { id: 'Test', displayName: 'Test' },
@@ -51,10 +54,13 @@ export const fakeNodeWithNoPermission = new Node({
path: {
name: '/Company Home/User Homes',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: '55052317-7e59-4058-8e07-769f41e615e1', name: 'User Homes' }]
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: '55052317-7e59-4058-8e07-769f41e615e1', name: 'User Homes' }
]
},
isFolder: true,
modifiedByUser: { id: 'Test', displayName: 'Test' },
@@ -72,36 +78,41 @@ export const fakeNodeAnswerWithEntries = {
skipCount: 10,
maxItems: 10
},
entries: [{
entry: {
isFile: true,
createdByUser: { id: 'admin', displayName: 'Administrator' },
modifiedAt: '2017-05-24T15:08:55.640Z',
nodeType: 'cm:content',
content: {
mimeType: 'application/rtf',
mimeTypeName: 'Rich Text Format',
sizeInBytes: 14530,
encoding: 'UTF-8'
},
parentId: 'd124de26-6ba0-4f40-8d98-4907da2d337a',
createdAt: '2017-05-24T15:08:55.640Z',
path: {
name: '/Company Home/Guest Home',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }]
},
isFolder: false,
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
name: 'b_txt_file.rtf',
id: '67b80f77-dbca-4f58-be6c-71b9dd61ea53',
properties: { 'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR' },
allowableOperations: ['delete', 'update']
entries: [
{
entry: {
isFile: true,
createdByUser: { id: 'admin', displayName: 'Administrator' },
modifiedAt: '2017-05-24T15:08:55.640Z',
nodeType: 'cm:content',
content: {
mimeType: 'application/rtf',
mimeTypeName: 'Rich Text Format',
sizeInBytes: 14530,
encoding: 'UTF-8'
},
parentId: 'd124de26-6ba0-4f40-8d98-4907da2d337a',
createdAt: '2017-05-24T15:08:55.640Z',
path: {
name: '/Company Home/Guest Home',
isComplete: true,
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }
]
},
isFolder: false,
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
name: 'b_txt_file.rtf',
id: '67b80f77-dbca-4f58-be6c-71b9dd61ea53',
properties: { 'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR' },
allowableOperations: ['delete', 'update']
}
}
}]
]
}
};
@@ -127,34 +138,38 @@ export const fakeGetSitesAnswer = {
skipCount: 0,
maxItems: 20
},
entries: [{
entry: {
role: 'SiteManager',
visibility: 'PRIVATE',
guid: 'ac65fdbe-0c79-4f67-bd6a-b89a2768561b',
id: 'admin-site',
preset: 'site-dashboard',
title: 'Admin Site'
entries: [
{
entry: {
role: 'SiteManager',
visibility: 'PRIVATE',
guid: 'ac65fdbe-0c79-4f67-bd6a-b89a2768561b',
id: 'admin-site',
preset: 'site-dashboard',
title: 'Admin Site'
}
},
{
entry: {
role: 'SiteManager',
visibility: 'PUBLIC',
guid: 'b4cff62a-664d-4d45-9302-98723eac1319',
description: 'This is a Sample Alfresco Team site.',
id: 'swsdp',
preset: 'site-dashboard',
title: 'Sample: Web Site Design Project'
}
},
{
entry: {
visibility: 'PUBLIC',
guid: 'af36cf8f-d43c-4a4b-84e6-d1b03e3a2ce5',
id: 'test-site',
preset: 'site-dashboard',
title: 'Test Site'
}
}
}, {
entry: {
role: 'SiteManager',
visibility: 'PUBLIC',
guid: 'b4cff62a-664d-4d45-9302-98723eac1319',
description: 'This is a Sample Alfresco Team site.',
id: 'swsdp',
preset: 'site-dashboard',
title: 'Sample: Web Site Design Project'
}
}, {
entry: {
visibility: 'PUBLIC',
guid: 'af36cf8f-d43c-4a4b-84e6-d1b03e3a2ce5',
id: 'test-site',
preset: 'site-dashboard',
title: 'Test Site'
}
}]
]
}
};
@@ -167,30 +182,39 @@ export const fakeGetSiteMembership = {
skipCount: 0,
maxItems: 20
},
entries: [{
entry: {
site: {
entries: [
{
entry: {
site: {
role: 'SiteManager',
visibility: 'PRIVATE',
guid: 'ac65fdbe-0c79-4f67-bd6a-b89a2768561b',
id: 'admin-site',
preset: 'site-dashboard',
title: 'Admin Site'
},
role: 'SiteManager',
visibility: 'PRIVATE',
guid: 'ac65fdbe-0c79-4f67-bd6a-b89a2768561b',
id: 'admin-site',
preset: 'site-dashboard',
title: 'Admin Site'
}, role: 'SiteManager', guid: 'ac65fdbe-0c79-4f67-bd6a-b89a2768561b', id: 'admin-site'
}
}, {
entry: {
site: {
id: 'admin-site'
}
},
{
entry: {
site: {
role: 'SiteManager',
visibility: 'PUBLIC',
guid: 'b4cff62a-664d-4d45-9302-98723eac1319',
description: 'This is a Sample Alfresco Team site.',
id: 'swsdp',
preset: 'site-dashboard',
title: 'Sample: Web Site Design Project'
},
role: 'SiteManager',
visibility: 'PUBLIC',
guid: 'b4cff62a-664d-4d45-9302-98723eac1319',
description: 'This is a Sample Alfresco Team site.',
id: 'swsdp',
preset: 'site-dashboard',
title: 'Sample: Web Site Design Project'
}, role: 'SiteManager', guid: 'b4cff62a-664d-4d45-9302-98723eac1319', id: 'swsdp'
id: 'swsdp'
}
}
}]
]
}
};
@@ -202,17 +226,24 @@ export const fakeNodePaging: NodePaging = {
totalItems: 5,
skipCount: 0,
maxItems: 100
}, entries: [{
entry: fakeNodeWithNoPermission
}, {
entry: fakeNodeWithNoPermission
}, {
entry: fakeNodeWithNoPermission
}, {
entry: fakeNodeWithNoPermission
}, {
entry: fakeNodeWithNoPermission
}]
},
entries: [
{
entry: fakeNodeWithNoPermission
},
{
entry: fakeNodeWithNoPermission
},
{
entry: fakeNodeWithNoPermission
},
{
entry: fakeNodeWithNoPermission
},
{
entry: fakeNodeWithNoPermission
}
]
}
};
@@ -232,10 +263,13 @@ export const mockNode1 = new Node({
path: {
name: '/Company Home/Guest Home',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }]
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }
]
},
isFolder: false,
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
@@ -261,10 +295,13 @@ export const mockNode2 = new Node({
path: {
name: '/Company Home/Guest Home',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }]
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }
]
},
isFolder: false,
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
@@ -290,10 +327,13 @@ export const mockNode3 = new Node({
path: {
name: '/Company Home/Guest Home',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }]
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }
]
},
isFolder: false,
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
@@ -320,12 +360,17 @@ export const mockNodePagingWithPreselectedNodes: NodePaging = {
totalItems: 5,
skipCount: 0,
maxItems: 100
}, entries: [{
entry: mockNode1
}, {
entry: mockNode2
}, {
entry: mockNode3
}]
},
entries: [
{
entry: mockNode1
},
{
entry: mockNode2
},
{
entry: mockNode3
}
]
}
};
@@ -19,20 +19,17 @@ import { Component } from '@angular/core';
@Component({
template: `
<button id="sample-button-permission" adf-inherit-permission [nodeId]="nodeId"
(updated)="onUpdate($event)"> PERMISSION </button>
<button id="sample-button-permission" adf-inherit-permission [nodeId]="nodeId" (updated)="onUpdate($event)">PERMISSION</button>
<span id="update-notification" *ngIf="updatedNode"> NODE UPDATED </span>
`
`,
standalone: false
})
export class SimpleInheritedPermissionTestComponent {
message: string = '';
nodeId: string = 'fake-node-id';
updatedNode: boolean = false;
constructor() {
}
constructor() {}
onUpdate(node: any) {
this.updatedNode = node.permissions?.isInheritanceEnabled ?? false;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
export const mockNode: any = ({
export const mockNode: any = {
isFile: true,
createdByUser: { id: 'admin', displayName: 'Administrator' },
modifiedAt: '2017-05-24T15:08:55.640Z',
@@ -31,10 +31,13 @@ export const mockNode: any = ({
path: {
name: '/Company Home/Guest Home',
isComplete: true,
elements: [{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
}, { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }]
elements: [
{
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
name: 'Company Home'
},
{ id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }
]
},
isFolder: false,
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
@@ -42,7 +45,7 @@ export const mockNode: any = ({
id: '70e1cc6a-6918-468a-b84a-1048093b06fd',
properties: { 'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR' },
allowableOperations: ['delete', 'update']
});
};
export const mockFile = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
@@ -59,21 +62,13 @@ export const mockNewVersionUploaderData: any = {
modifiedAt: '2022-05-24T10:19:43.544Z',
nodeType: 'cm:content',
content: {
mimeType:
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
mimeTypeName: 'Microsoft Word 2007',
sizeInBytes: 11887,
encoding: 'UTF-8'
},
parentId: '422538ca-ea4b-4086-83f9-b36e4521ec7f',
aspectNames: [
'rn:renditioned',
'cm:versionable',
'cm:titled',
'cm:auditable',
'cm:author',
'cm:thumbnailModification'
],
aspectNames: ['rn:renditioned', 'cm:versionable', 'cm:titled', 'cm:auditable', 'cm:author', 'cm:thumbnailModification'],
createdAt: '2022-05-24T07:26:44.429Z',
isFolder: false,
modifiedByUser: {
@@ -101,21 +96,13 @@ export const mockNewVersionUploaderData: any = {
modifiedAt: '2022-05-24T07:26:45.337Z',
nodeType: 'cm:content',
content: {
mimeType:
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
mimeTypeName: 'Microsoft Word 2007',
sizeInBytes: 11949,
encoding: 'UTF-8'
},
parentId: '422538ca-ea4b-4086-83f9-b36e4521ec7f',
aspectNames: [
'rn:renditioned',
'cm:versionable',
'cm:titled',
'cm:auditable',
'cm:author',
'cm:thumbnailModification'
],
aspectNames: ['rn:renditioned', 'cm:versionable', 'cm:titled', 'cm:auditable', 'cm:author', 'cm:thumbnailModification'],
createdAt: '2022-05-24T07:26:44.429Z',
path: {
name: '/Company Home/User Homes/hruser',
@@ -155,13 +142,7 @@ export const mockNewVersionUploaderData: any = {
accessStatus: 'ALLOWED'
}
],
settable: [
'Contributor',
'Collaborator',
'Coordinator',
'Editor',
'Consumer'
],
settable: ['Contributor', 'Collaborator', 'Coordinator', 'Editor', 'Consumer'],
isInheritanceEnabled: true
},
modifiedByUser: {
@@ -100,16 +100,11 @@ export const simpleCategories: SearchCategory[] = [
}
}
}
];
export const searchFilter = {
'app:fields': [
'cm:name'
],
include: [
'allowableOperations'
],
'app:fields': ['cm:name'],
include: ['allowableOperations'],
sorting: {
options: [
{
@@ -412,8 +407,10 @@ export const mockSearchResult = {
label: 'SEARCH.FACET_QUERIES.MIMETYPE',
filterQuery: 'content.mimetype:text/html',
metrics: [{ type: 'count', value: { count: 13 } }]
}]
}, {
}
]
},
{
type: 'query',
label: 'Size facet queries',
buckets: [
@@ -421,60 +418,75 @@ export const mockSearchResult = {
label: 'my1',
filterQuery: 'content.size:[111111 TO MAX]',
metrics: [{ type: 'count', value: { count: 806 } }]
}, {
},
{
label: 'my3',
filterQuery: 'content.size:[333333 TO MAX]',
metrics: [{ type: 'count', value: { count: 669 } }]
}, {
},
{
label: 'my2',
filterQuery: 'content.size:[222222 TO MAX]',
metrics: [{ type: 'count', value: { count: 691 } }]
}, {
},
{
label: 'my5',
filterQuery: 'content.size:[5555 TO MAX]',
metrics: [{ type: 'count', value: { count: 1866 } }]
}, {
},
{
label: 'my4',
filterQuery: 'content.size:[444444 TO MAX]',
metrics: [{ type: 'count', value: { count: 665 } }]
}, {
},
{
label: 'my7',
filterQuery: 'content.size:[777777 TO MAX]',
metrics: [{ type: 'count', value: { count: 641 } }]
}, {
},
{
label: 'SEARCH.FACET_QUERIES.SMALL',
filterQuery: 'content.size:[10240 TO 102400]',
metrics: [{ type: 'count', value: { count: 526 } }]
}, {
},
{
label: 'my6',
filterQuery: 'content.size:[666666 TO MAX]',
metrics: [{ type: 'count', value: { count: 652 } }]
}, {
},
{
label: 'SEARCH.FACET_QUERIES.XTRALARGE',
filterQuery: 'content.size:[16777216 TO 134217728]',
metrics: [{ type: 'count', value: { count: 617 } }]
}, {
},
{
label: 'my8',
filterQuery: 'content.size:[888888 TO MAX]',
metrics: [{ type: 'count', value: { count: 641 } }]
}, {
},
{
label: 'SEARCH.FACET_QUERIES.XXTRALARGE',
filterQuery: 'content.size:[134217728 TO MAX]',
metrics: [{ type: 'count', value: { count: 0 } }]
}, {
},
{
label: 'SEARCH.FACET_QUERIES.MEDIUM',
filterQuery: 'content.size:[102400 TO 1048576]',
metrics: [{ type: 'count', value: { count: 630 } }]
}, {
},
{
label: 'SEARCH.FACET_QUERIES.LARGE',
filterQuery: 'content.size:[1048576 TO 16777216]',
metrics: [{ type: 'count', value: { count: 23 } }]
}, {
},
{
label: 'Extra Small',
filterQuery: 'content.size:[0 TO 10240]',
metrics: [{ type: 'count', value: { count: 10239 } }]
}]
}, {
}
]
},
{
type: 'query',
label: 'SEARCH.FACET_QUERIES.MY_FACET_QUERIES',
buckets: [
@@ -482,37 +494,45 @@ export const mockSearchResult = {
label: 'SEARCH.FACET_QUERIES.CREATED_THIS_YEAR',
filterQuery: 'created:2019',
metrics: [{ type: 'count', value: { count: 0 } }]
}]
}
]
},
{
type: 'field',
label: 'SEARCH.FACET_FIELDS.SIZE',
buckets: []
}, {
},
{
type: 'field',
label: 'SEARCH.FACET_FIELDS.CREATED',
buckets: []
}, {
},
{
type: 'field',
label: 'SEARCH.FACET_FIELDS.TYPE',
buckets: []
}, {
},
{
type: 'field',
label: 'SEARCH.FACET_FIELDS.MODIFIER',
buckets: []
}, {
},
{
type: 'field',
label: 'SEARCH.FACET_FIELDS.CREATOR',
buckets: []
}, {
},
{
type: 'interval',
label: 'TheModified',
buckets: []
}, {
},
{
type: 'interval',
label: 'The Created',
buckets: []
}]
}
]
}
}
};
@@ -609,29 +629,23 @@ export const sizeOptions = [
}
];
export const filteredResult = [
'my1 (806)',
'my2 (691)',
'my3 (669)',
'my4 (665)',
'my5 (1866)'
];
export const filteredResult = ['my1 (806)', 'my2 (691)', 'my3 (669)', 'my4 (665)', 'my5 (1866)'];
export const mockContentSizeResponseBucket = {
label: '5875',
filterQuery: 'content.size:5875',
metrics: [
{
type: 'count',
value: {
count: 364
}
label: '5875',
filterQuery: 'content.size:5875',
metrics: [
{
type: 'count',
value: {
count: 364
}
]
};
}
]
};
export const getMockSearchResultWithResponseBucket = () => {
const cloneResult = JSON.parse(JSON.stringify( mockSearchResult));
const cloneResult = JSON.parse(JSON.stringify(mockSearchResult));
cloneResult.list.context.facets[3].buckets.push(mockContentSizeResponseBucket);
return cloneResult;
};
@@ -106,7 +106,6 @@ export const noResult = {
</adf-search>
<span id="component-result-message">{{ message }}</span>
`,
standalone: true,
imports: [SearchModule, CommonModule]
})
export class SimpleSearchTestComponent {
@@ -16,6 +16,8 @@
*/
.adf-new-version-uploader-dialog {
display: block;
&-list {
height: 400px;
}
@@ -50,6 +52,7 @@
display: flex;
justify-content: flex-end;
color: var(--adf-theme-foreground-text-color-054);
-webkit-font-smoothing: antialiased;
button {
text-transform: uppercase;
@@ -28,7 +28,6 @@ import { VersionListComponent } from '../version-manager/version-list.component'
@Component({
selector: 'adf-new-version-uploader-dialog',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
@@ -40,7 +39,10 @@ import { VersionListComponent } from '../version-manager/version-list.component'
],
templateUrl: './new-version-uploader.dialog.html',
styleUrls: ['./new-version-uploader.dialog.scss'],
encapsulation: ViewEncapsulation.None
encapsulation: ViewEncapsulation.None,
host: {
class: 'adf-new-version-uploader-dialog'
}
})
export class NewVersionUploaderDialogComponent implements OnInit {
/**
@@ -34,7 +34,8 @@ import { NewVersionUploaderService } from './new-version-uploader.service';
import { Version, VersionPaging } from '@alfresco/js-api';
@Component({
template: ''
template: '',
standalone: false
})
class TestDialogComponent {
@Output()
@@ -46,31 +46,33 @@ export const fakeContentComments = {
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'
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'
}
}
}, {
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'
}
}
]
}
};
@@ -146,62 +148,62 @@ export const getDateXMinutesAgo = (minutes: number) => new Date(new Date().getTi
export const commentsNodeData: CommentModel[] = [
new CommentModel({
id: 1,
message: `I've done this component, is it cool?`,
created: getDateXMinutesAgo(30),
createdBy: new User(johnDoe),
isSelected: false
id: 1,
message: `I've done this component, is it cool?`,
created: getDateXMinutesAgo(30),
createdBy: new User(johnDoe),
isSelected: false
}),
new CommentModel({
id: 2,
message: 'Yeah',
created: getDateXMinutesAgo(15),
createdBy: new User(janeEod),
isSelected: false
id: 2,
message: 'Yeah',
created: getDateXMinutesAgo(15),
createdBy: new User(janeEod),
isSelected: false
}),
new CommentModel({
id: 3,
message: '+1',
created: getDateXMinutesAgo(12),
createdBy: new User(robertSmith),
isSelected: false
id: 3,
message: '+1',
created: getDateXMinutesAgo(12),
createdBy: new User(robertSmith),
isSelected: false
}),
new CommentModel({
id: 4,
message: 'ty',
created: new Date(),
createdBy: new User(johnDoe),
isSelected: false
id: 4,
message: 'ty',
created: new Date(),
createdBy: new User(johnDoe),
isSelected: false
})
];
export const commentsTaskData: CommentModel[] = [
new CommentModel({
id: 1,
message: `I've done this task, what's next?`,
created: getDateXMinutesAgo(30),
createdBy: new User(johnDoe),
isSelected: false
id: 1,
message: `I've done this task, what's next?`,
created: getDateXMinutesAgo(30),
createdBy: new User(johnDoe),
isSelected: false
}),
new CommentModel({
id: 2,
message: `I've assigned you another one 🤠`,
created: getDateXMinutesAgo(15),
createdBy: new User(janeEod),
isSelected: false
id: 2,
message: `I've assigned you another one 🤠`,
created: getDateXMinutesAgo(15),
createdBy: new User(janeEod),
isSelected: false
}),
new CommentModel({
id: 3,
message: '+1',
created: getDateXMinutesAgo(12),
createdBy: new User(robertSmith),
isSelected: false
id: 3,
message: '+1',
created: getDateXMinutesAgo(12),
createdBy: new User(robertSmith),
isSelected: false
}),
new CommentModel({
id: 4,
message: 'Cheers',
created: new Date(),
createdBy: new User(johnDoe),
isSelected: false
id: 4,
message: 'Cheers',
created: new Date(),
createdBy: new User(johnDoe),
isSelected: false
})
];
@@ -21,7 +21,6 @@ import { NodeCommentsService } from './services/node-comments.service';
@Component({
selector: 'adf-node-comments',
standalone: true,
imports: [CommentsComponent],
templateUrl: './node-comments.component.html',
encapsulation: ViewEncapsulation.None,
@@ -32,7 +32,6 @@ import { UserRoleColumnComponent } from '../user-role-column/user-role-column.co
@Component({
selector: 'adf-add-permission-dialog',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
@@ -33,7 +33,6 @@ import { UserIconColumnComponent } from '../user-icon-column/user-icon-column.co
@Component({
selector: 'adf-add-permission-panel',
standalone: true,
imports: [
CommonModule,
MatFormFieldModule,
@@ -28,7 +28,6 @@ import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-add-permission',
standalone: true,
imports: [CommonModule, AddPermissionPanelComponent, MatButtonModule, TranslateModule],
templateUrl: './add-permission.component.html',
styleUrls: ['./add-permission.component.scss'],
@@ -22,7 +22,6 @@ import { CommonModule } from '@angular/common';
@Component({
selector: 'adf-node-path-column',
standalone: true,
imports: [CommonModule],
template: `
<span class="adf-user-name-column adf-datatable-cell-value" title="{{ displayText$ | async }}">
@@ -38,7 +38,6 @@ import { UserRoleColumnComponent } from '../user-role-column/user-role-column.co
@Component({
selector: 'adf-permission-container',
standalone: true,
imports: [
CommonModule,
DataTableComponent,
@@ -34,7 +34,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-permission-list',
standalone: true,
imports: [
CommonModule,
MatCardModule,

Some files were not shown because too many files have changed in this diff Show More