8000 NAS-136168 / 25.10 / Update to Angular 20 by denysbutenko · Pull Request #12121 · truenas/webui · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

NAS-136168 / 25.10 / Update to Angular 20 #12121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e4a2c82
NAS-136168: Update to Angular 20
denysbutenko Jun 10, 2025
6b19e9c
NAS-136168: Update styles
denysbutenko Jun 10, 2025
6d9732b
NAS-136168: Update styles
denysbutenko Jun 10, 2025
92fe784
Merge branch 'master' into NAS-136168
denysbutenko Jun 10, 2025
60311cf
NAS-136168: Update to Angular 20
denysbutenko Jun 10, 2025
f7f6c62
Merge branch 'master' into NAS-136168
denysbutenko Jun 16, 2025
06d6ef9
NAS-136168: Update to Angular 20
denysbutenko Jun 16, 2025
9b855c3
Merge branch 'master' into NAS-136168
denysbutenko Jun 16, 2025
8031ed4
NAS-136168: Update to Angular 20
denysbutenko Jun 16, 2025
08c5326
NAS-136168: Update to Angular 20
denysbutenko Jun 17, 2025
02f4509
Merge branch 'master' into NAS-136168
denysbutenko Jun 17, 2025
57e81d9
NAS-136168: Update to Angular 20
denysbutenko Jun 17, 2025
a8cd432
NAS-136168: Update to Angular 20
denysbutenko Jun 17, 2025
de88de9
Merge branch 'master' into NAS-136168
denysbutenko Jun 18, 2025
a916bbd
NAS-136168: Update to Angular 20
denysbutenko Jun 18, 2025
3673b24
Merge branch 'master' into NAS-136168
denysbutenko Jun 18, 2025
4f11ad7
NAS-136168: Update to Angular 20
denysbutenko Jun 18, 2025
04dad80
NAS-136168: Update to Angular 20
denysbutenko Jun 18, 2025
5e7975b
NAS-136168: Update to Angular 20
denysbutenko Jun 18, 2025
58d2bf7
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
973e483
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
36b2f65
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
08cf007
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
49d94fa
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
22e7915
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
242536c
Merge branch 'master' into NAS-136168
denysbutenko Jun 19, 2025
344b771
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
be560c0
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
75a9170
NAS-136168: Update to Angular 20
denysbutenko Jun 19, 2025
48f9ee2
NAS-136168: Update node
denysbutenko Jun 19, 2025
da1d0e2
NAS-136168: Update node
denysbutenko Jun 19, 2025
853a116
NAS-136168: Update node
denysbutenko Jun 20, 2025
1c5cdc2
Merge branch 'master' into NAS-136168
denysbutenko Jun 20, 2025
d72f2ca
NAS-136168: Update node
denysbutenko Jun 20, 2025
6a65f5f
NAS-136168: Update node
denysbutenko Jun 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
##NODE temporary builder image
from node:20-bookworm as uibuilder
FROM node:20-bookworm as uibuilder
COPY ./ /src-ui
WORKDIR /src-ui
RUN yarn install --frozen-lockfile
RUN yarn build:prod:aot

#Download base image debian buster
FROM debian:buster-slim
FROM debian:bookworm-slim

# Install packages
#COPY docker/krb5.conf /etc/krb5.conf
Expand Down
24 changes: 22 additions & 2 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,30 @@
"@schematics/angular:component": {
"prefix": "ix",
"style": "scss",
"changeDetection": "OnPush"
"changeDetection": "OnPush",
"type": "component"
},
"@schematics/angular:directive": {
"prefix": "ix"
"prefix": "ix",
"type": "directive"
},
"@schematics/angular:service": {
"type": "service"
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:interceptor": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
},
"cli": {
Expand Down
2 changes: 1 addition & 1 deletion docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Requirements

- yarn >= 1.22
- Node.js >= 18.19.1
- Node.js >= 20.19
- Running instance with TrueNAS nightly (VM is fine).

> [!TIP]
Expand Down
15 changes: 11 additions & 4 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,39 @@ process.env.TZ = 'Europe/Kiev';
const esmPatterns = [
'.*\\.mjs$',
'is-cidr',
'ip-regex',
'ip-regex',
'cidr-regex',
'lodash-es',
'internmap',
'd3',
'delaunator',
'cheerio',
'robust-predicates',
'@angular',< 10000 /span>
'@ngneat',
'@ngrx',
'@ngx-translate',
'ng-mocks',
'ngx-translate-messageformat-compiler'
];

module.exports = {
preset: 'jest-preset-angular',
globalSetup: 'jest-preset-angular/global-setup',
setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
collectCoverage: false,
collectCoverageFrom: ["./src/**/*.ts"],
coverageReporters: ['html', 'json'],
coverageDirectory: 'coverage/webui',
moduleDirectories: ['node_modules', 'src'],
cacheDirectory: "<rootDir>/.jest/cache",
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths || {}),
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths || {}),
},
testPathIgnorePatterns: [
'<rootDir>/dist/',
],
transformIgnorePatterns: [
`node_modules/(?!(${esmPatterns.join('|')}))`
`node_modules/(?!${esmPatterns.join('|')})`
],
reporters: [
"default",
Expand Down
46 changes: 23 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,24 @@
"url": "https://jira.ixsystems.com"
},
"engines": {
"node": ">=18.19.1"
"node": ">=20.19.0"
},
"private": true,
"dependencies": {
"@angular-devkit/core": "^19.0.3",
"@angular/animations": "^19.0.3",
"@angular/build": "^19.0.3",
"@angular/cdk": "^19.0.2",
"@angular/cli": "^19.0.3",
"@angular/common": "^19.0.3",
"@angular/compiler": "^19.0.3",
"@angular/compiler-cli": "^19.0.3",
"@angular/core": "^19.0.3",
"@angular/forms": "^19.0.3",
"@angular/material": "^19.0.2",
"@angular/platform-browser": "^19.0.3",
"@angular/platform-browser-dynamic": "^19.0.3",
"@angular/router": "^19.0.3",
"@angular-devkit/core": "^20.0.1",
"@angular/animations": "^20.0.2",
"@angular/build": "^20.0.1",
"@angular/cdk": "^20.0.2",
"@angular/cli": "^20.0.1",
"@angular/common": "^20.0.2",
"@angular/compiler": "^20.0.2",
"@angular/compiler-cli": "^20.0.2",
"@angular/core": "^20.0.2",
"@angular/forms": "^20.0.2",
"@angular/material": "^20.0.2",
"@angular/platform-browser": "^20.0.2",
"@angular/platform-browser-dynamic": "^20.0.2",
"@angular/router": "^20.0.2",
"@biesbjerg/ngx-translate-extract-marker": "~1.0.0",
"@bugsplat/angular-tree-component": "~18.0.0",
"@codemirror/autocomplete": "~6.18.6",
Expand Down Expand Up @@ -109,12 +109,12 @@
"@types/figlet": "~1.5.5",
"@types/fontfaceobserver": "^2.1.3",
"@types/glob": "~7.2.0",
"@types/jest": "~29.5.13",
"@types/jest": "~29.5.14",
"@types/jest-when": "^3.5.5",
"@types/js-yaml": "~4.0.8",
"@types/lodash-es": "~4.17.12",
"@types/mime-types": "~2.1.1",
"@types/node": "^18.19.1",
"@types/node": "^22.14.0",
"@types/randomcolor": "~0.5.9",
"@types/svg-sprite": "~0.0.39",
"@types/vinyl": "~2.0.12",
Expand All @@ -139,8 +139,8 @@
"cronstrue": "~2.50.0",
"crypto": "~1.0.1",
"d3": "~7.9.0",
"date-fns": "~2.28.0",
"date-fns-tz": "~1.3.8",
"date-fns": "~4.1.0",
"date-fns-tz": "~3.2.0",
"dompurify": "~3.2.5",
"dygraphs": "~2.2.1",
"email-validator": "~2.0.4",
Expand Down Expand Up @@ -169,7 +169,7 @@
"jest-canvas-mock": "^2.5.0",
"jest-fail-on-console": "~3.3.0",
"jest-junit": "~16.0.0",
"jest-preset-angular": "~14.2.4",
"jest-preset-angular": "~14.6.0",
"jest-when": "~3.6.0",
"jira-prepare-commit-msg": "^1.6.1",
"js-yaml": "~4.1.0",
Expand All @@ -182,7 +182,7 @@
"mime-types": "~2.1.35",
"ng-gallery": "~11.0.0",
"ng-lazyload-image": "~9.1.3",
"ng-mocks": "~14.13.1",
"ng-mocks": "~14.13.5",
"ng-qrcode": "~18.0.0",
"ng2-charts": "~6.0.1",
"ng2-fittext": "~2.0.0",
Expand All @@ -206,7 +206,7 @@
"ts-jest": "~29.2.5",
"tsconfig-paths": "~4.2.0",
"tsx": "~4.19.1",
"typescript": "~5.5.4",
"typescript": "~5.8.3",
"typescript-eslint": "~8.11.0",
"utility-types": "~3.11.0",
"vinyl": "~3.0.0",
Expand All @@ -219,6 +219,6 @@
"*.scss": "stylelint --fix"
},
"devDependencies": {
"@angular/build": "^19.0.3"
"@angular/build": "^20.0.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function makeArrayDeviceSlots(
is_top: options.is_top ?? false,
is_rear: options.is_rear ?? false,
is_internal: options.is_internal ?? false,
};
} as DashboardEnclosureSlot;
});

return keyBy(slots, 'drive_bay_number');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DashboardEnclosure, DashboardEnclosureSlot,
Enclosure,
EnclosureElement,
EnclosureSlotPoolInfo,
} from 'app/interfaces/enclosure.interface';
import { addPoolsToDisks, randomizeDiskStatuses } from './pool.utils';

Expand Down Expand Up @@ -108,7 +109,7 @@ describe('pool.utils', () => {
...enclosure.elements,
[EnclosureElementType.ArrayDeviceSlot]: Object.values(
enclosure.elements[EnclosureElementType.ArrayDeviceSlot],
).map((slot) => ({ ...slot, pool_info: undefined })),
).map((slot) => ({ ...slot, pool_info: undefined as EnclosureSlotPoolInfo | null })),
},
};
});
Expand Down
3 changes: 1 addition & 2 deletions src/app/helpers/operators/select-not-null.helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { select } from '@ngrx/store';
import { Selector } from '@ngrx/store/src/models';
import { select, Selector } from '@ngrx/store';
import { Observable, pipe, UnaryFunction } from 'rxjs';
import { filter } from 'rxjs/operators';

Expand Down
2 changes: 1 addition & 1 deletion src/app/helpers/time.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { intervalToDuration } from 'date-fns';
import { intervalToDuration, Duration } from 'date-fns';

export function secondsToDuration(seconds: number): Duration {
return intervalToDuration({
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/alerts/store/alert.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const alertReducer = createReducer(
on(alertIndicatorPressed, (state) => ({ ...state, isPanelOpen: !state.isPanelOpen })),
on(alertPanelClosed, (state) => ({ ...state, isPanelOpen: false })),

on(adminUiInitialized, (state) => ({ ...state, isLoading: true, error: null })),
on(adminUiInitialized, (state) => ({ ...state, isLoading: true, error: null as string | null })),
on(alertsLoaded, (state, { alerts }) => {
return {
...adapter.setAll(alerts, state),
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export class AuthService {
refreshUser(): Observable<undefined> {
this.loggedInUser$.next(null);
return this.getLoggedInUserInformation().pipe(
map(() => undefined),
map((): undefined => undefined),
);
}

Expand Down
6 changes: 3 additions & 3 deletions src/app/modules/dates/pipes/ix-date/ix-date.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
} from '@angular/core';
import { MatTooltip } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';
import { toZonedTime, fromZonedTime } from 'date-fns-tz';
import { FormatDateTimePipe } from 'app/modules/dates/pipes/format-date-time/format-datetime.pipe';
import { LocaleService } from 'app/modules/language/locale.service';

Expand All @@ -26,8 +26,8 @@ export class IxDateComponent {
defaultTz: string = Intl.DateTimeFormat().resolvedOptions().timeZone;

get machineTime(): Date {
const utc = zonedTimeToUtc(this.date(), this.defaultTz);
return utcToZonedTime(utc, this.machineTimezone);
const utc = fromZonedTime(this.date(), this.defaultTz);
return toZonedTime(utc, this.machineTimezone);
}

get isTimezoneDifference(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@ngneat/spectator/jest';
import { of } from 'rxjs';
import { fakeFile } from 'app/core/testing/utils/fake-file.uitls';
import { mockApi, mockCall } from 'app/core/testing/utils/mock-api.utils';
import { FileReviewComponent } from 'app/modules/feedback/components/file-review/file-review.component';
import { FeedbackService } from 'app/modules/feedback/services/feedback.service';
import { IxStarRatingComponent } from 'app/modules/forms/ix-forms/components/ix-star-rating/ix-star-rating.component';
Expand All @@ -28,6 +29,9 @@ describe('FileReviewComponent', () => {
IxStarRatingComponent,
],
providers: [
mockApi([
mockCall('system.product_type'),
]),
mockProvider(FeedbackService, {
createReview: jest.fn(() => of()),
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MatDatepickerInputEvent, MatDatepickerModule } from '@angular/material/
import { MatHint, MatSuffix } from '@angular/material/form-field';
import { MatInput } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
import { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';
import { toZonedTime, fromZonedTime } from 'date-fns-tz';
import { FormatDateTimePipe } from 'app/modules/dates/pipes/format-date-time/format-datetime.pipe';
import { IxDateAdapter } from 'app/modules/dates/services/ix-date-adapter';
import { IxErrorsComponent } from 'app/modules/forms/ix-forms/components/ix-errors/ix-errors.component';
Expand Down Expand Up @@ -86,7 +86,7 @@ export class IxDatepickerComponent implements ControlValueAccessor {
}

writeValue(value: Date): void {
const dateInMachineTimezone = utcToZonedTime(value, this.locale.timezone);
const dateInMachineTimezone = toZonedTime(value, this.locale.timezone);
this.value.set(dateInMachineTimezone);
}

Expand All @@ -96,7 +96,7 @@ export class IxDatepickerComponent implements ControlValueAccessor {

onDateChanged(event: MatDatepickerInputEvent<Date>): void {
this.value.set(event.value);
const dateInUtc = zonedTimeToUtc(event.value, this.locale.timezone);
const dateInUtc = fromZonedTime(event.value, this.locale.timezone);
this.onChange(dateInUtc);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { EventEmitter } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import {
ITreeState,
TreeComponent,
TreeModel,
TreeModule,
} from '@bugsplat/angular-tree-component';
import { IDTypeDictionary } from '@bugsplat/angular-tree-component/lib/defs/api';
import { FormControl } from '@ngneat/reactive-forms';
import { SpectatorHost } from '@ngneat/spectator';
import { createHostFactory } from '@ngneat/spectator/jest';
Expand All @@ -17,17 +17,13 @@ import { mntPath } from 'app/enums/mnt-path.enum';
import { IxExplorerComponent } from 'app/modules/forms/ix-forms/components/ix-explorer/ix-explorer.component';
import { IxLabelComponent } from 'app/modules/forms/ix-forms/components/ix-label/ix-label.component';

// TODO: Update when fix is ready
// See https://github.com/help-me-mom/ng-mocks/issues/10503

// eslint-disable-next-line jest/no-disabled-tests
describe.skip('IxExplorerComponent', () => {
describe('IxExplorerComponent', () => {
const mockTreeMock = {
selectedLeafNodeIds: {},
get selectedLeafNodes(): unknown[] {
return [];
},
setState(newState: { selectedLeafNodeIds: IDTypeDictionary }) {
setState(newState: ITreeState) {
this.selectedLeafNodeIds = newState.selectedLeafNodeIds;
},
getState() {
Expand Down Expand Up @@ -66,7 +62,7 @@ describe.skip('IxExplorerComponent', () => {
[hint]="hint"
[required]="required"
[tooltip]="tooltip"
[roots]="[root]"
[rootNodes]="[root]"
[multiple]="multiple"
></ix-explorer>`,
{
Expand All @@ -77,7 +73,12 @@ describe.skip('IxExplorerComponent', () => {
hint: undefined,
required: false,
tooltip: undefined,
root: mntPath,
root: {
hasChildren: true,
name: mntPath,
path: mntPath,
type: ExplorerNodeType.Directory,
},
multiple: false,
},
},
Expand All @@ -95,7 +96,6 @@ describe.skip('IxExplorerComponent', () => {
name: mntPath,
path: mntPath,
type: ExplorerNodeType.Directory,
isMountpoint: true,
},
]);
});
Expand Down
Loading
Loading
0