[ACS-11306] upgrade frontend to angular 20 (#5122)

* [ACS-11306] Upgrade Angular to 20 version

* [ACS-11306] Reverted unwanted changes

* [ACS-11306] Reverted unwanted changes

* [ACS-11306] Reverted unwanted changes

* [ACS-11306] Upgrade ngrx to 20 version

* [ACS-11306] Updated eslintrc

* [ACS-11306] Added replacement for quotes related eslint rule

* [ACS-11306] Fixed eslint issues related with unused error and optional chaining

* [ACS-11306] Corrected versions in projects

* [ACS-11306] Fixed unit tests

* [ACS-11306] Updated stylelint version

* [link-adf:chore/ng20][ACS-11306] Test

* [link-adf:chore/ng20][ACS-11306] Changed tsconfig

* [link-adf:chore/ng20][ACS-11306] Test

* [link-adf:chore/ng20][ACS-11306] Test

* [link-adf:chore/ng20][ACS-11306] Removed redundant line from tsconfig

* [link-adf:chore/ng20][ACS-11306] Updated package-lock.json

* [link-adf:chore/ng20][ACS-11306] Fixed stylelint issue

* [link-adf:chore/ng20] [ACS-11306] Fix colors of text button, dialog text, form field placeholder and button styling

* [link-adf:chore/ng20] [ACS-11306] Fix create from template dialog confirm button color

* [link-adf:chore/ng20] [ACS-11306] Fix add permission dialog button colors

* [link-adf:chore/ng20] [ACS-11306] Fix login error icon color and alignment

* [link-adf:chore/ng20][ACS-11306] Updated package-lock.json

* [ACS-11306] Update package.json to use ADF with Angular 20

---------

Co-authored-by: g-jaskowski <grzegorz.jaskowski@hyland.com>
This commit is contained in:
AleksanderSklorz
2026-06-26 10:57:31 +02:00
committed by GitHub
co-authored by g-jaskowski
parent e4d5f9c9ad
commit 745cd14024
38 changed files with 2958 additions and 7239 deletions
@@ -281,7 +281,7 @@ export class ManageRulesSmartComponent implements OnInit {
try {
await this.folderRuleSetsService.deleteRuleSetLink(this.nodeId, linkedRuleSet.id);
this.folderRuleSetsService.refreshMainRuleSet();
} catch (error) {
} catch {
this.notificationService.showError('ACA_FOLDER_RULES.ERRORS.DELETE_RULE_SET_LINK_FAILED');
}
}
@@ -22,8 +22,8 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { SecurityControlsMarkResponse } from '@alfresco/adf-content-services/lib/security/services/models/security-controls-mark-response.interface';
import { UpdateNotification } from '@alfresco/adf-core';
import { SecurityControlsMarkResponse } from '@alfresco/adf-content-services';
export const securityMarksResponseMock: SecurityControlsMarkResponse = {
pagination: {
+9 -9
View File
@@ -3,21 +3,21 @@
"version": "0.0.1",
"license": "LGPL-3.0",
"peerDependencies": {
"@angular/animations": "^19.2.0",
"@angular/cdk": "^19.2.0",
"@angular/common": "^19.2.0",
"@angular/core": "^19.2.0",
"@angular/forms": "^19.2.0",
"@angular/material": "^19.2.0",
"@angular/platform-browser": "^19.2.0",
"@angular/router": "^19.2.0",
"@angular/animations": "^20.3.0",
"@angular/cdk": "^20.2.0",
"@angular/common": "^20.3.0",
"@angular/core": "^20.3.0",
"@angular/forms": "^20.3.0",
"@angular/material": "^20.2.0",
"@angular/platform-browser": "^20.3.0",
"@angular/router": "^20.3.0",
"@ngx-translate/core": "^17.0.0",
"rxjs": "^7.4.0",
"zone.js": "^0.14.0 || ^0.15.0"
},
"dependencies": {
"tslib": ">=2.3.0",
"ngx-markdown": ">=17.2.1"
"ngx-markdown": ">=20.0.0"
},
"publishConfig": {
"access": "public"
@@ -1,3 +1,5 @@
@use '@angular/material' as mat;
.aca-location-link {
&-unknown {
display: flex;
@@ -10,8 +12,12 @@
}
.aca-location-link-info-btn {
--mdc-icon-button-state-layer-size: 24px;
--mdc-icon-button-icon-size: 24px;
@include mat.icon-button-overrides(
(
state-layer-size: 24px,
icon-size: 24px
)
);
color: var(--theme-foreground-text-color);
padding: 0;
@@ -100,7 +100,7 @@ export class LocationLinkComponent implements OnInit {
}
openAdditionalLocationReferencesDialog() {
if (this.context.row.node) {
if (this.context?.row.node) {
this.dialogRef.open(DialogComponent, {
data: {
title: 'APP.ADDITIONAL_REFERENCES_DIALOG.TITLE',
@@ -276,7 +276,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
}
// check the child nodes to show dropped folder
if (event && event.file.options.parentId === this.getParentNodeId()) {
if (event?.file.options.parentId === this.getParentNodeId()) {
this.displayFolderParent(0, event.file.options.path);
return;
}
@@ -661,7 +661,7 @@ describe('SearchAiResultsComponent', () => {
}));
it('should call search api when reload references button is clicked', fakeAsync(() => {
setupReferencesTest([nodeId, secondNodeId], [toSearchResult([node1])]);
setupReferencesTest([nodeId, secondNodeId], [toSearchResult([node1]), toSearchResult([node1, node2])]);
getReloadButton().nativeElement.click();
expect(contentApiService.search).toHaveBeenCalledWith(
@@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
import { SearchSortingDefinition } from '@alfresco/adf-content-services/lib/search/models/search-sorting-definition.interface';
import { SearchSortingDefinition, SearchQueryBuilderService } from '@alfresco/adf-content-services';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppTestingModule } from '../../../testing/app-testing.module';
import { SearchActionMenuComponent } from './search-action-menu.component';
@@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
import { SearchSortingDefinition } from '@alfresco/adf-content-services/lib/search/models/search-sorting-definition.interface';
import { SearchQueryBuilderService, SearchSortingDefinition } from '@alfresco/adf-content-services';
import { Component, EventEmitter, OnInit, Output, ViewEncapsulation, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslatePipe } from '@ngx-translate/core';
@@ -68,7 +68,7 @@ aca-search-in-menu {
padding: 8px 16px;
}
@media screen and (max-width: 599px) {
@media screen and (width <= 599px) {
position: fixed;
left: 50%;
top: 65px;
@@ -78,7 +78,7 @@ aca-search-in-menu {
overflow-y: auto;
}
@media screen and (max-width: 320px) {
@media screen and (width <= 320px) {
top: 0;
max-height: 100vh;
}
@@ -58,7 +58,7 @@ $search-border-radius: 4px;
gap: 4px;
}
@media screen and (max-width: 959px) {
@media screen and (width <= 959px) {
$search-width-small: 400px;
.aca-search-input {
@@ -70,13 +70,13 @@ $search-border-radius: 4px;
}
}
@media screen and (max-width: 599px) {
@media screen and (width <= 599px) {
.aca-search-input {
max-width: 220px;
}
}
@media screen and (max-width: 380px) {
@media screen and (width <= 380px) {
.aca-search-input {
max-width: 148px;
}
@@ -122,7 +122,7 @@ export class SearchLibrariesResultsComponent extends PageComponent implements On
if (statusCode === 400) {
this.appHookService.library400Error.next();
}
} catch (e) {}
} catch {}
})
);
@@ -277,7 +277,7 @@ aca-search-results {
}
}
@media (max-width: 320px) {
@media (width <= 320px) {
.adf-search-results__content-header {
flex-direction: column;
}
@@ -33,6 +33,7 @@ import {
SearchConfiguration,
SearchFilterChipsComponent,
SearchFormComponent,
SearchSortingDefinition,
SearchQueryBuilderService,
TagService
} from '@alfresco/adf-content-services';
@@ -62,7 +63,6 @@ import {
PaginationDirective,
ToolbarComponent
} from '@alfresco/aca-shared';
import { SearchSortingDefinition } from '@alfresco/adf-content-services/lib/search/models/search-sorting-definition.interface';
import { filter, first, map, startWith, switchMap, take, tap, toArray } from 'rxjs/operators';
import { AsyncPipe, CommonModule } from '@angular/common';
import { TranslatePipe } from '@ngx-translate/core';
@@ -82,7 +82,7 @@ describe('SaveSearchDirective', () => {
});
it('should open the dialog with the correct configuration', () => {
spyOn(dialog, 'open');
spyOn(dialog, 'open').and.callThrough();
element.nativeElement.click();
const expectedConfig: MatDialogConfig<SaveSearchDirectiveDialogData> = {
@@ -105,7 +105,7 @@ describe('SaveSearchDirective', () => {
});
it('should open the dialog with the correct configuration', () => {
spyOn(dialog, 'open');
spyOn(dialog, 'open').and.callThrough();
element.nativeElement.click();
const expectedConfig: MatDialogConfig<SaveSearchDirectiveDialogData> = {
@@ -16,7 +16,7 @@ app-create-from-template-dialog {
}
&-create-button:enabled {
color: var(--theme-accent-color);
color: var(--theme-primary-color);
}
.app-create-from-template-footer-button {
@@ -516,7 +516,7 @@ export class ContentManagementService {
} else if (statusCode === 403) {
i18nMessageString = 'APP.MESSAGES.ERRORS.PERMISSION';
}
} catch (err) {
} catch {
/* Do nothing, keep the original message */
}
@@ -75,7 +75,7 @@ describe('NodeActionsService', () => {
new Promise((resolve, reject) => {
if (isForbidden) {
reject(permissionError);
} else if (nameExistingOnDestination && options && options.name === nameExistingOnDestination) {
} else if (nameExistingOnDestination && options?.name === nameExistingOnDestination) {
reject(conflictError);
} else {
resolve('');
@@ -387,7 +387,7 @@ export class NodeActionsService {
error: { statusCode }
} = JSON.parse(err.message);
errStatusCode = statusCode;
} catch (e) {
} catch {
//
}
@@ -513,7 +513,7 @@ export class NodeActionsService {
error: { statusCode }
} = JSON.parse(err.message);
errStatusCode = statusCode;
} catch (e) {
} catch {
//
}
@@ -157,7 +157,7 @@ export class TemplateEffects {
try {
statusCode = JSON.parse(error.message).error.statusCode;
} catch (e) {
} catch {
statusCode = null;
}
@@ -39,7 +39,7 @@ ng-component {
@include mixins.flex-column;
}
@media screen and (max-width: 600px) {
@media screen and (width <= 600px) {
app-root,
app-about,
adf-layout-container,
@@ -61,15 +61,6 @@
}
}
.adf-choose-action {
@include mat.button-overrides(
(
text-label-text-color: var(--theme-primary-color),
text-disabled-label-text-color: var(--adf-theme-foreground-text-color-054)
)
);
}
.adf-metadata-properties {
@include mat.expansion-overrides(
(
@@ -178,6 +169,20 @@
.adf-add-permission-dialog-actions {
--mat-sys-surface: var(--theme-white-background);
> button + button {
@include mat.button-overrides(
(
text-label-text-color: var(--theme-primary-color),
text-disabled-label-text-color: var(--adf-theme-foreground-text-color-054)
)
);
}
> button + button.adf-choose-action {
--mat-sys-primary: var(--theme-primary-color);
--mat-sys-on-surface-variant: var(--adf-theme-foreground-text-color-054);
}
}
// TODO get general designs from Shane and check styling for this part
@@ -264,8 +269,6 @@
}
.adf-permission-card {
--mdc-elevated-card-container-color: var(--adf-theme-background-card-color);
.adf-local-permission-container .adf-permission-content-header button:disabled {
@include mat.icon-overrides(
(
@@ -478,6 +481,14 @@
font-size: var(--mat-sys-body-small-size);
}
adf-login .adf-login-content .adf-error-message {
align-items: center;
.adf-error-icon {
color: var(--adf-theme-foreground-error-color);
}
}
adf-login .adf-login__field {
@include mat.form-field-overrides(
(
@@ -953,7 +964,11 @@
}
app-comments-tab {
--mdc-elevated-card-container-elevation: none;
@include mat.card-overrides(
(
elevated-container-elevation: none
)
);
}
adf-library-dialog {
+7 -3
View File
@@ -17,8 +17,6 @@ html {
:root {
--mat-sys-on-surface: var(--adf-theme-foreground-text-color-087);
--mdc-filled-text-field-container-color: transparent;
--mdc-text-button-label-text-color: inherit;
--mat-form-field-container-height: 47.5px;
--mat-sys-display-large-font: #{$default-font-family};
--mat-sys-display-large-size: 112px;
@@ -161,6 +159,7 @@ html {
outlined-disabled-outline-color: var(--adf-theme-foreground-text-color-040),
filled-label-text-size: 18px,
filled-label-text-tracking: normal,
filled-container-color: transparent,
subscript-text-tracking: normal,
filled-input-text-color: var(--adf-theme-foreground-text-color-087),
subscript-text-size: 12px
@@ -177,6 +176,7 @@ html {
(
text-state-layer-color: var(--adf-theme-foreground-base-color),
text-hover-state-layer-opacity: 0.04,
text-label-text-color: inherit,
filled-disabled-container-color: var(--adf-disabled-button-background),
text-label-text-tracking: normal,
text-horizontal-padding: 8px,
@@ -479,7 +479,11 @@ mat-slide-toggle {
padding: 16px 0;
color: var(--adf-theme-foreground-text-color-087);
--mdc-dialog-supporting-text-color: var(--theme-primary-text);
@include mat.dialog-overrides(
(
supporting-text-color: var(--theme-primary-text)
)
);
}
#{ms.$mat-dialog-surface} {
@@ -155,7 +155,7 @@ export class PreviewComponent extends PageComponent implements OnInit {
}
await this.router.navigate([this.previewLocation, id]);
} catch (err) {
if (!err || err.status !== 401) {
if (err?.status !== 401) {
await this.router.navigate([this.previewLocation, id]);
}
}
@@ -90,7 +90,7 @@ export class FavoritesPageApi {
}
};
return await Utils.retryCall(favorite);
} catch (error) {}
} catch {}
return isFavorite;
}
@@ -181,7 +181,7 @@ export class FileActionsApi {
logger.info(`waitForNodes: "${searchTerm}" — found ${totalItems}, expecting ${data.expect}`);
}
return totalItems;
} catch (error) {
} catch {
return 0;
}
};
@@ -45,7 +45,7 @@ export class SharedLinksApi {
expiresAt: expireDate
};
return await this.apiService.share.createSharedLink(data);
} catch (error) {
} catch {
return null;
}
}
@@ -31,7 +31,7 @@ type LaunchOptions = Parameters<typeof chromium.launch>[0];
try {
loadEnvFile();
} catch (error) {
} catch {
// .env file is optional, continue without it
}
+11 -11
View File
@@ -4,17 +4,17 @@
"license": "LGPL-3.0",
"scripts": {},
"peerDependencies": {
"@angular/animations": "^19.2.0",
"@angular/common": "^19.2.0",
"@angular/compiler": "^19.2.0",
"@angular/core": "^19.2.0",
"@angular/forms": "^19.2.0",
"@angular/material": "^19.2.0",
"@angular/platform-browser": "^19.2.0",
"@angular/router": "^19.2.0",
"@ngrx/effects": "^19.2.0",
"@ngrx/router-store": "^19.2.0",
"@ngrx/store": "^19.2.0",
"@angular/animations": "^20.3.0",
"@angular/common": "^20.3.0",
"@angular/compiler": "^20.3.0",
"@angular/core": "^20.3.0",
"@angular/forms": "^20.3.0",
"@angular/material": "^20.2.0",
"@angular/platform-browser": "^20.3.0",
"@angular/router": "^20.3.0",
"@ngrx/effects": "^20.1.0",
"@ngrx/router-store": "^20.1.0",
"@ngrx/store": "^20.1.0",
"@ngx-translate/core": "^17.0.0",
"rxjs": "^7.4.0",
"tslib": ">=2.0.0",
@@ -1,4 +1,5 @@
@use '../../styles/mat-selectors' as ms;
@use '@angular/material' as mat;
aca-open-in-app {
.aca-open-in-app {
@@ -57,9 +58,16 @@ aca-open-in-app {
}
}
#{ms.$mat-button} {
--mat-mdc-button-persistent-ripple-color: unset;
--mat-mdc-button-ripple-color: unset;
&-button-container {
@include mat.button-overrides(
(
text-ripple-color: transparent,
text-state-layer-color: transparent,
text-hover-state-layer-opacity: 0,
text-focus-state-layer-opacity: 0,
text-pressed-state-layer-opacity: 0
)
);
}
}
}
@@ -6,7 +6,11 @@ aca-toolbar-action {
line-height: 32px;
#{ms.$mat-mdc-button}#{ms.$mat-button-base}#{ms.$mat-outlined-button}#{ms.$mat-unthemed} {
--mdc-outlined-button-label-text-color: var(--theme-secondary-text);
@include mat.button-overrides(
(
outlined-label-text-color: var(--theme-secondary-text)
)
);
}
@include mat.button-overrides(
@@ -81,7 +81,7 @@ export class RouterExtensionService {
data: route.data
}
]
};
} as ExtensionRoute;
});
}