From 1e6d5c424b702d89c19cafe2443d601f636328fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:00:13 +0200 Subject: [PATCH 1/8] ci: test angular19 against the matching frontend branch PR CI checks out the frontend (and sibling plugins) at the branch the PR targets instead of always stable. Corepack is enabled before every yarn install, since the frontend's angular19 branch pins yarn@4; the Docker build uses yarn for the frontend build as well. Dead WDIO config copies are dropped (the frontend no longer has WDIO). Co-Authored-By: Claude Opus 5.5 --- .github/workflows/dotnet-core-master.yml | 2 ++ .github/workflows/dotnet-core-pr.yml | 6 ++++-- Dockerfile | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet-core-master.yml b/.github/workflows/dotnet-core-master.yml index 180dc798..94f4d680 100644 --- a/.github/workflows/dotnet-core-master.yml +++ b/.github/workflows/dotnet-core-master.yml @@ -119,6 +119,8 @@ jobs: cp -av main/eform-client/cypress/e2e/plugins/items-planning-pn eform-angular-frontend/eform-client/cypress/e2e/plugins/items-planning-pn cp -av main/eform-client/e2e/Assets eform-angular-frontend/eform-client/e2e/ cd eform-angular-frontend/eform-client && ../../main/testinginstallpn.sh + - name: Enable Corepack + run: corepack enable - name: yarn install run: cd eform-angular-frontend/eform-client && yarn install - name: Install Playwright browsers diff --git a/.github/workflows/dotnet-core-pr.yml b/.github/workflows/dotnet-core-pr.yml index 0d1d23a1..28d3bd37 100644 --- a/.github/workflows/dotnet-core-pr.yml +++ b/.github/workflows/dotnet-core-pr.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v3 with: repository: microting/eform-angular-frontend - ref: stable + ref: ${{ github.base_ref }} path: eform-angular-frontend - name: Copy dependencies run: | @@ -101,7 +101,7 @@ jobs: uses: actions/checkout@v3 with: repository: microting/eform-angular-frontend - ref: stable + ref: ${{ github.base_ref }} path: eform-angular-frontend - name: Copy dependencies run: | @@ -113,6 +113,8 @@ jobs: cp -av main/eform-client/cypress/e2e/plugins/items-planning-pn eform-angular-frontend/eform-client/cypress/e2e/plugins/items-planning-pn cp -av main/eform-client/e2e/Assets eform-angular-frontend/eform-client/e2e/ cd eform-angular-frontend/eform-client && ../../main/testinginstallpn.sh + - name: Enable Corepack + run: corepack enable - name: yarn install run: cd eform-angular-frontend/eform-client && yarn install - name: Install Playwright browsers diff --git a/Dockerfile b/Dockerfile index 5717de02..3f4b88af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,8 +2,9 @@ FROM node:22-bookworm-slim as node-env WORKDIR /app ENV PATH /app/node_modules/.bin:$PATH COPY eform-angular-frontend/eform-client ./ +RUN corepack enable RUN yarn install -RUN npm run build +RUN yarn build FROM mcr.microsoft.com/dotnet/sdk:10.0-noble AS build-env WORKDIR /app From 636ee4f1f2c50005959e9487075fba9d48679b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:05:07 +0200 Subject: [PATCH 2/8] refactor: convert items-planning-pn to standalone components for Angular 21 Co-Authored-By: Claude Opus 5.5 --- .../ItemsPlanning/ItemsPlanningPairingPage.ts | 2 +- .../ItemsPlanningPairingPage.ts | 4 +- .../items-planning-pn.module.ts | 23 +------- .../items-planning-pn-layout.component.ts | 3 +- .../pairing-grid-page.component.ts | 6 ++- .../pairing-grid-table.component.html | 2 +- .../pairing-grid-table.component.ts | 10 +++- .../pairing-grid-update.component.ts | 4 +- .../modules/pairing/pairing.module.ts | 35 +----------- .../planning-assign-sites-modal.component.ts | 9 +++- .../planning-create.component.ts | 14 ++++- .../planning-delete.component.ts | 4 +- .../planning-edit/planning-edit.component.ts | 14 ++++- .../planning-multiple-delete.component.ts | 4 +- .../planning-folders-modal.component.ts | 6 ++- .../planning-tags/planning-tags.component.ts | 5 +- .../plannings-bulk-import-modal.component.ts | 10 +++- .../plannings-container.component.ts | 10 +++- .../plannings-header.component.ts | 8 ++- .../plannings-table.component.html | 4 +- .../plannings-table.component.ts | 9 +++- .../modules/plannings/plannings.module.ts | 53 +------------------ 22 files changed, 110 insertions(+), 129 deletions(-) diff --git a/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts b/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts index b2d09442..1abf598b 100644 --- a/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts +++ b/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts @@ -23,7 +23,7 @@ export class ItemsPlanningPairingPage extends PageWithNavbarPage { public async countPlanningRow(): Promise { await browser.pause(500); - return (await $$('#planningName')).length; + return (await $$('[id^="planningName"]')).length; } public async savePairingGridBtn(): Promise { diff --git a/eform-client/playwright/e2e/plugins/items-planning-pn/ItemsPlanningPairingPage.ts b/eform-client/playwright/e2e/plugins/items-planning-pn/ItemsPlanningPairingPage.ts index 112f069c..fc4a52ba 100644 --- a/eform-client/playwright/e2e/plugins/items-planning-pn/ItemsPlanningPairingPage.ts +++ b/eform-client/playwright/e2e/plugins/items-planning-pn/ItemsPlanningPairingPage.ts @@ -22,7 +22,7 @@ export class ItemsPlanningPairingPage extends PageWithNavbarPage { public async countPlanningRow(): Promise { await this.page.waitForTimeout(500); - return await this.page.locator('#planningName').count(); + return await this.page.locator('[id^="planningName"]').count(); } public get savePairingGridBtn(): Locator { @@ -117,7 +117,7 @@ export class PairingRowObject { async getRow(rowNum: number): Promise { this.row = this.page.locator('tbody tr').nth(rowNum - 1); if ((await this.page.locator('tbody tr').count()) >= rowNum) { - this.planningName = (await this.row.locator('#planningName').textContent()) || ''; + this.planningName = (await this.row.locator('[id^="planningName"]').textContent()) || ''; this.pairRow = this.page.locator(`#planningRowCheckbox${rowNum - 1}`); this.pairRowForClick = this.pairRow; this.pairCheckboxes = []; diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts b/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts index ba5bba80..15f05f76 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts @@ -1,11 +1,5 @@ import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; -import {TranslateModule} from '@ngx-translate/core'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgSelectModule} from '@ng-select/ng-select'; -import {EformCasesModule} from 'src/app/common/modules/eform-cases/eform-cases.module'; import {ItemsPlanningPnLayoutComponent} from './layouts'; -import {RouterModule} from '@angular/router'; import {ItemsPlanningPnRouting} from './items-planning-pn.routing'; import { ItemsPlanningPnPairingService, @@ -14,9 +8,6 @@ import { ItemsPlanningPnTagsService, ItemsPlanningPnUploadedDataService, } from './services'; -import {FileUploadModule} from 'ng2-file-upload'; -import {EformSharedModule} from 'src/app/common/modules/eform-shared/eform-shared.module'; -import {EformSharedTagsModule} from 'src/app/common/modules/eform-shared-tags/eform-shared-tags.module'; import {StoreModule} from '@ngrx/store'; import { pairingReducer, @@ -26,25 +17,13 @@ import { @NgModule({ imports: [ - CommonModule, - TranslateModule, - FormsModule, - NgSelectModule, - EformSharedModule, - RouterModule, + ItemsPlanningPnLayoutComponent, ItemsPlanningPnRouting, - ReactiveFormsModule, - FileUploadModule, - EformCasesModule, - EformSharedTagsModule, StoreModule.forFeature('itemsPlanningPn', { pairingsState: pairingReducer, planningsState: planningsReducer, }) ], - declarations: [ - ItemsPlanningPnLayoutComponent, - ], providers: [ ItemsPlanningPnSettingsService, ItemsPlanningPnPlanningsService, diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/layouts/items-planning-pn-layout.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/layouts/items-planning-pn-layout.component.ts index 4e7cf6f5..6ca7e0f3 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/layouts/items-planning-pn-layout.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/layouts/items-planning-pn-layout.component.ts @@ -1,4 +1,5 @@ import {AfterContentInit, Component, OnInit, inject} from '@angular/core'; +import {RouterOutlet} from '@angular/router'; import {TranslateService} from '@ngx-translate/core'; import {translates} from './../i18n/translates'; import {Store} from '@ngrx/store'; @@ -9,7 +10,7 @@ import {take} from 'rxjs'; selector: 'app-items-planning-pn-layout', template: ` `, - standalone: false + imports: [RouterOutlet] }) export class ItemsPlanningPnLayoutComponent implements AfterContentInit, OnInit { private translateService = inject(TranslateService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.ts index fec59a34..3dd430f0 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.ts @@ -1,4 +1,8 @@ import {Component, OnDestroy, OnInit, inject} from '@angular/core'; +import {EformNewSubheaderComponent} from 'src/app/common/modules/eform-shared/components'; +import {PairingGridTableComponent} from '../pairing-grid-table/pairing-grid-table.component'; +import {MatTooltip} from '@angular/material/tooltip'; +import {TranslatePipe} from '@ngx-translate/core'; import { ItemsPlanningPnPairingService, } from '../../../../services'; @@ -18,7 +22,7 @@ import {dialogConfigHelper} from 'src/app/common/helpers'; selector: 'app-pairing-grid-page', templateUrl: './pairing-grid-page.component.html', styleUrls: ['./pairing-grid-page.component.scss'], - standalone: false + imports: [EformNewSubheaderComponent, PairingGridTableComponent, MatTooltip, TranslatePipe] }) export class PairingGridPageComponent implements OnInit, OnDestroy { private pairingService = inject(ItemsPlanningPnPairingService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.html b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.html index 08139cb1..78a85d3b 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.html +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.html @@ -59,7 +59,7 @@ -
+
); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts index d6c3f6d0..37b605b4 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts @@ -1,49 +1,18 @@ -import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; -import {RouterModule} from '@angular/router'; -import {TranslateModule} from '@ngx-translate/core'; import { PairingGridPageComponent, PairingGridTableComponent, PairingGridUpdateComponent, } from './components'; import {PairingRouting} from './pairing.routing'; -import {EformSharedModule} from 'src/app/common/modules/eform-shared/eform-shared.module'; -import {MtxGridModule} from '@ng-matero/extensions/grid'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {EformCasesModule} from 'src/app/common/modules/eform-cases/eform-cases.module'; -import {EformSharedTagsModule} from 'src/app/common/modules/eform-shared-tags/eform-shared-tags.module'; -import {MatButtonModule} from '@angular/material/button'; -import {MatTooltipModule} from '@angular/material/tooltip'; -import {MatFormFieldModule} from '@angular/material/form-field'; -import {MtxSelectModule} from '@ng-matero/extensions/select'; -import {MatCheckboxModule} from '@angular/material/checkbox'; -import {MatDialogModule} from '@angular/material/dialog'; @NgModule({ - declarations: [ + imports: [ + PairingRouting, PairingGridPageComponent, PairingGridTableComponent, PairingGridUpdateComponent, ], - imports: [ - CommonModule, - TranslateModule, - RouterModule, - PairingRouting, - EformSharedModule, - MtxGridModule, - FormsModule, - ReactiveFormsModule, - EformCasesModule, - EformSharedTagsModule, - MatButtonModule, - MatTooltipModule, - MatFormFieldModule, - MtxSelectModule, - MatCheckboxModule, - MatDialogModule, - ], }) export class PairingModule { } diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-assign-sites-modal/planning-assign-sites-modal.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-assign-sites-modal/planning-assign-sites-modal.component.ts index aa5caa2b..ae03a796 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-assign-sites-modal/planning-assign-sites-modal.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-assign-sites-modal/planning-assign-sites-modal.component.ts @@ -6,6 +6,13 @@ import { OnInit, inject } from '@angular/core'; +import {MatDialogTitle, MatDialogContent, MatDialogActions} from '@angular/material/dialog'; +import {MtxGrid} from '@ng-matero/extensions/grid'; +import {MatCheckbox} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {NgIf} from '@angular/common'; +import {StatusBarCompactComponent} from 'src/app/common/modules/eform-shared/components'; +import {TranslatePipe} from '@ngx-translate/core'; import { SiteNameDto } from 'src/app/common/models'; import { AutoUnsubscribe } from 'ngx-auto-unsubscribe'; import { @@ -29,7 +36,7 @@ import { MatCheckboxChange } from '@angular/material/checkbox'; selector: 'app-planning-assign-sites-modal', templateUrl: './planning-assign-sites-modal.component.html', styleUrls: ['./planning-assign-sites-modal.component.scss'], - standalone: false + imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MtxGrid, MatCheckbox, FormsModule, NgIf, StatusBarCompactComponent, TranslatePipe] }) export class PlanningAssignSitesModalComponent implements OnInit, OnDestroy { private itemsPlanningPnPlanningsService = inject(ItemsPlanningPnPlanningsService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-create/planning-create.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-create/planning-create.component.ts index 20439e8c..7df9cd6c 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-create/planning-create.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-create/planning-create.component.ts @@ -6,6 +6,18 @@ import { OnInit, inject } from '@angular/core'; +import {EformNewSubheaderComponent} from 'src/app/common/modules/eform-shared/components'; +import {MatButton, MatIconButton} from '@angular/material/button'; +import {MatCard, MatCardHeader, MatCardContent} from '@angular/material/card'; +import {NgFor, NgIf} from '@angular/common'; +import {ReactiveFormsModule, FormsModule} from '@angular/forms'; +import {MatFormField, MatLabel} from '@angular/material/form-field'; +import {MatInput} from '@angular/material/input'; +import {MatTooltip} from '@angular/material/tooltip'; +import {MatIcon} from '@angular/material/icon'; +import {MtxSelect} from '@ng-matero/extensions/select'; +import {MatDatepicker, MatDatepickerInput} from '@angular/material/datepicker'; +import {TranslatePipe} from '@ngx-translate/core'; import {debounceTime, switchMap} from 'rxjs/operators'; import { ItemsPlanningPnPlanningsService, @@ -41,7 +53,7 @@ import {MatDatepickerInputEvent} from '@angular/material/datepicker'; selector: 'app-planning-create', templateUrl: './planning-create.component.html', styleUrls: ['./planning-create.component.scss'], - standalone: false + imports: [EformNewSubheaderComponent, MatButton, MatIconButton, MatCard, MatCardHeader, MatCardContent, NgFor, NgIf, ReactiveFormsModule, FormsModule, MatFormField, MatLabel, MatInput, MatTooltip, MatIcon, MtxSelect, MatDatepicker, MatDatepickerInput, TranslatePipe] }) export class PlanningCreateComponent implements OnInit, OnDestroy { private foldersService = inject(FoldersService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-delete/planning-delete.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-delete/planning-delete.component.ts index f7a01cac..8cacea79 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-delete/planning-delete.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-delete/planning-delete.component.ts @@ -1,4 +1,6 @@ import {Component, EventEmitter, Inject, OnInit, inject} from '@angular/core'; +import {MatDialogTitle, MatDialogContent, MatDialogActions} from '@angular/material/dialog'; +import {TranslatePipe} from '@ngx-translate/core'; import {ItemsPlanningPnPlanningsService} from '../../../../../services'; import {PlanningModel} from '../../../../../models'; import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; @@ -7,7 +9,7 @@ import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; selector: 'app-planning-delete', templateUrl: './planning-delete.component.html', styleUrls: ['./planning-delete.component.scss'], - standalone: false + imports: [MatDialogTitle, MatDialogContent, MatDialogActions, TranslatePipe] }) export class PlanningDeleteComponent implements OnInit { private itemsPlanningPnPlanningsService = inject(ItemsPlanningPnPlanningsService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-edit/planning-edit.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-edit/planning-edit.component.ts index a4e80b0d..fc42adac 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-edit/planning-edit.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-edit/planning-edit.component.ts @@ -19,6 +19,18 @@ import { OnInit, inject } from '@angular/core'; +import {EformNewSubheaderComponent} from 'src/app/common/modules/eform-shared/components'; +import {MatButton, MatIconButton} from '@angular/material/button'; +import {MatCard, MatCardHeader, MatCardContent} from '@angular/material/card'; +import {NgFor, NgIf} from '@angular/common'; +import {ReactiveFormsModule, FormsModule} from '@angular/forms'; +import {MatFormField, MatLabel} from '@angular/material/form-field'; +import {MatInput} from '@angular/material/input'; +import {MatTooltip} from '@angular/material/tooltip'; +import {MatIcon} from '@angular/material/icon'; +import {MtxSelect, MtxSelectLabelTemplate} from '@ng-matero/extensions/select'; +import {MatDatepicker, MatDatepickerInput} from '@angular/material/datepicker'; +import {TranslatePipe} from '@ngx-translate/core'; import { Location } from '@angular/common'; import { debounceTime, switchMap, take } from 'rxjs/operators'; import { PlanningModel, PlanningUpdateModel } from '../../../../../models'; @@ -38,7 +50,7 @@ import {MatDatepickerInputEvent} from '@angular/material/datepicker'; selector: 'app-planning-edit', templateUrl: './planning-edit.component.html', styleUrls: ['./planning-edit.component.scss'], - standalone: false + imports: [EformNewSubheaderComponent, MatButton, MatIconButton, MatCard, MatCardHeader, MatCardContent, NgFor, NgIf, ReactiveFormsModule, FormsModule, MatFormField, MatLabel, MatInput, MatTooltip, MatIcon, MtxSelect, MtxSelectLabelTemplate, MatDatepicker, MatDatepickerInput, TranslatePipe] }) export class PlanningEditComponent implements OnInit, OnDestroy { private foldersService = inject(FoldersService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-multiple-delete/planning-multiple-delete.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-multiple-delete/planning-multiple-delete.component.ts index 48862960..70fb44d6 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-multiple-delete/planning-multiple-delete.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-actions/planning-multiple-delete/planning-multiple-delete.component.ts @@ -1,11 +1,13 @@ import {Component, EventEmitter, Inject, OnInit, inject} from '@angular/core'; +import {MatDialogTitle, MatDialogActions} from '@angular/material/dialog'; +import {TranslatePipe} from '@ngx-translate/core'; import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; @Component({ selector: 'app-planning-multiple-delete', templateUrl: './planning-multiple-delete.component.html', styleUrls: ['./planning-multiple-delete.component.scss'], - standalone: false + imports: [MatDialogTitle, MatDialogActions, TranslatePipe] }) export class PlanningMultipleDeleteComponent implements OnInit { public dialogRef = inject(MatDialogRef); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.ts index 1cc5068f..325489c8 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.ts @@ -6,6 +6,10 @@ import { OnInit, inject } from '@angular/core'; +import {MatDialogTitle, MatDialogContent} from '@angular/material/dialog'; +import {MatCard, MatCardContent} from '@angular/material/card'; +import {EformTreeViewPickerComponent} from 'src/app/common/modules/eform-shared/components'; +import {TranslatePipe} from '@ngx-translate/core'; import { FolderDto, SiteNameDto } from 'src/app/common/models'; import { AutoUnsubscribe } from 'ngx-auto-unsubscribe'; import { PlanningModel } from '../../../../../models'; @@ -16,7 +20,7 @@ import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; selector: 'app-planning-folders-modal', templateUrl: './planning-folders-modal.component.html', styleUrls: ['./planning-folders-modal.component.scss'], - standalone: false + imports: [MatDialogTitle, MatDialogContent, MatCard, MatCardContent, EformTreeViewPickerComponent, TranslatePipe] }) export class PlanningFoldersModalComponent implements OnInit, OnDestroy { public dialogRef = inject(MatDialogRef); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts index 4e71a3a6..aa79b861 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts @@ -27,8 +27,7 @@ import {dialogConfigHelper} from 'src/app/common/helpers'; @Component({ selector: 'app-planning-tags', templateUrl: './planning-tags.component.html', - styleUrls: ['./planning-tags.component.scss'], - standalone: false + styleUrls: ['./planning-tags.component.scss'] }) export class PlanningTagsComponent implements OnInit, OnDestroy, OnChanges { private tagsService = inject(ItemsPlanningPnTagsService); @@ -120,7 +119,7 @@ export class PlanningTagsComponent implements OnInit, OnDestroy, OnChanges { ngOnChanges(changes: SimpleChanges): void { if (!changes.availableTags.firstChange && changes.availableTags && this.dialogRef) { - this.dialogRef.componentInstance.availableTags = changes.availableTags.currentValue; + this.dialogRef.componentInstance.setAvailableTags(changes.availableTags.currentValue); } } diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.ts index d787f927..bb107fe5 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.ts @@ -1,4 +1,12 @@ import {Component, ElementRef, EventEmitter, OnInit, ViewChild, inject} from '@angular/core'; +import {MatDialogTitle, MatDialogContent, MatDialogActions} from '@angular/material/dialog'; +import {MatButton} from '@angular/material/button'; +import {MatButtonLoading} from '@ng-matero/extensions/button'; +import {MtxProgress} from '@ng-matero/extensions/progress'; +import {MtxGrid} from '@ng-matero/extensions/grid'; +import {FileUploadModule} from 'ng2-file-upload'; +import {AsyncPipe} from '@angular/common'; +import {TranslatePipe} from '@ngx-translate/core'; import {FileUploader} from 'ng2-file-upload'; import {ToastrService} from 'ngx-toastr'; import {TranslateService} from '@ngx-translate/core'; @@ -14,7 +22,7 @@ import {selectBearerToken} from 'src/app/state/auth/auth.selector'; selector: 'app-plannings-bulk-import-modal', templateUrl: './plannings-bulk-import-modal.component.html', styleUrls: ['./plannings-bulk-import-modal.component.scss'], - standalone: false + imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatButton, MatButtonLoading, MtxProgress, MtxGrid, FileUploadModule, AsyncPipe, TranslatePipe] }) export class PlanningsBulkImportModalComponent implements OnInit { private store = inject(Store); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-container/plannings-container.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-container/plannings-container.component.ts index 54ff41f6..273587b0 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-container/plannings-container.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-container/plannings-container.component.ts @@ -1,4 +1,12 @@ import {AfterViewInit, Component, OnDestroy, OnInit, ViewChild, inject} from '@angular/core'; +import {EformNewSubheaderComponent} from 'src/app/common/modules/eform-shared/components'; +import {MatTooltip} from '@angular/material/tooltip'; +import {MatIcon} from '@angular/material/icon'; +import {NgIf, AsyncPipe} from '@angular/common'; +import {RouterLink} from '@angular/router'; +import {TranslatePipe} from '@ngx-translate/core'; +import {PlanningsHeaderComponent} from '../plannings-header/plannings-header.component'; +import {PlanningsTableComponent} from '../plannings-table/plannings-table.component'; import { PlanningModel } from '../../../../../models'; import { ItemsPlanningPnPlanningsService, @@ -35,7 +43,7 @@ import {Store} from '@ngrx/store'; selector: 'app-plannings-container', templateUrl: './plannings-container.component.html', styleUrls: ['./plannings-container.component.scss'], - standalone: false + imports: [EformNewSubheaderComponent, MatTooltip, MatIcon, NgIf, AsyncPipe, RouterLink, TranslatePipe, PlanningsHeaderComponent, PlanningsTableComponent, PlanningTagsComponent] }) export class PlanningsContainerComponent implements OnInit, OnDestroy, AfterViewInit { private store = inject(Store); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.ts index f297cc78..5b53525a 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.ts @@ -7,6 +7,12 @@ import { Output, inject } from '@angular/core'; +import {MatFormField, MatLabel} from '@angular/material/form-field'; +import {MtxSelect} from '@ng-matero/extensions/select'; +import {FormsModule} from '@angular/forms'; +import {MatInput} from '@angular/material/input'; +import {AsyncPipe} from '@angular/common'; +import {TranslatePipe} from '@ngx-translate/core'; import { CommonDictionaryModel, SiteNameDto } from 'src/app/common/models'; import { PlanningsStateService } from '../../store'; import {Store} from "@ngrx/store"; @@ -22,7 +28,7 @@ import { templateUrl: './plannings-header.component.html', styleUrls: ['./plannings-header.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false + imports: [MatFormField, MatLabel, MtxSelect, FormsModule, MatInput, AsyncPipe, TranslatePipe] }) export class PlanningsHeaderComponent implements OnInit { private planningsStore = inject(Store); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html index 099af228..a0f47c31 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html @@ -30,8 +30,8 @@ done close - -
+ +
discount diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts index 508c5457..24490a9c 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts @@ -6,6 +6,13 @@ import { Output, inject } from '@angular/core'; +import {MtxGrid} from '@ng-matero/extensions/grid'; +import {MatIcon} from '@angular/material/icon'; +import {MatTooltip} from '@angular/material/tooltip'; +import {NgIf, NgFor, AsyncPipe} from '@angular/common'; +import {TranslatePipe} from '@ngx-translate/core'; +import {MatChip} from '@angular/material/chips'; +import {EformPaginationComponent} from 'src/app/common/modules/eform-shared/components'; import { PlanningModel } from '../../../../../models'; import {Paged, PaginationModel} from 'src/app/common/models'; import { ItemsPlanningPnClaims } from '../../../../../enums'; @@ -26,7 +33,7 @@ import { selector: 'app-plannings-table', templateUrl: './plannings-table.component.html', styleUrls: ['./plannings-table.component.scss'], - standalone: false + imports: [MtxGrid, MatIcon, MatTooltip, NgIf, NgFor, AsyncPipe, TranslatePipe, MatChip, EformPaginationComponent] }) export class PlanningsTableComponent implements OnInit { public planningsStateService = inject(PlanningsStateService); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts index bc0252bb..6a5dead4 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts @@ -1,7 +1,4 @@ -import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; -import {RouterModule} from '@angular/router'; -import {TranslateModule} from '@ngx-translate/core'; import { PlanningCreateComponent, PlanningEditComponent, @@ -16,29 +13,10 @@ import { PlanningTagsComponent, } from './components'; import {PlanningsRouting} from './plannings.routing'; -import {EformSharedModule} from 'src/app/common/modules/eform-shared/eform-shared.module'; -import {MtxGridModule} from '@ng-matero/extensions/grid'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgSelectModule} from '@ng-select/ng-select'; -import {FileUploadModule} from 'ng2-file-upload'; -import {EformCasesModule} from 'src/app/common/modules/eform-cases/eform-cases.module'; -import {EformSharedTagsModule} from 'src/app/common/modules/eform-shared-tags/eform-shared-tags.module'; -import {MatButtonModule} from '@angular/material/button'; -import {MatIconModule} from '@angular/material/icon'; -import {MatTooltipModule} from '@angular/material/tooltip'; -import {MatFormFieldModule} from '@angular/material/form-field'; -import {MtxSelectModule} from '@ng-matero/extensions/select'; -import {MatInputModule} from '@angular/material/input'; -import {MatChipsModule} from '@angular/material/chips'; -import {MatDialogModule} from '@angular/material/dialog'; -import {MtxButtonModule} from '@ng-matero/extensions/button'; -import {MtxProgressModule} from '@ng-matero/extensions/progress'; -import {MatCardModule} from '@angular/material/card'; -import {MatCheckboxModule} from '@angular/material/checkbox'; -import {MatDatepickerModule} from '@angular/material/datepicker'; @NgModule({ - declarations: [ + imports: [ + PlanningsRouting, PlanningCreateComponent, PlanningEditComponent, PlanningsContainerComponent, @@ -51,33 +29,6 @@ import {MatDatepickerModule} from '@angular/material/datepicker'; PlanningsTableComponent, PlanningTagsComponent, ], - imports: [ - CommonModule, - TranslateModule, - RouterModule, - PlanningsRouting, - EformSharedModule, - MtxGridModule, - FormsModule, - NgSelectModule, - ReactiveFormsModule, - FileUploadModule, - EformCasesModule, - EformSharedTagsModule, - MatButtonModule, - MatIconModule, - MatTooltipModule, - MatFormFieldModule, - MtxSelectModule, - MatInputModule, - MatChipsModule, - MatDialogModule, - MtxButtonModule, - MtxProgressModule, - MatCardModule, - MatCheckboxModule, - MatDatepickerModule, - ], exports: [ PlanningTagsComponent ] From 4e745107a515aaca6bb7fb7dc3f2ae91b4580ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:07:19 +0200 Subject: [PATCH 3/8] test: migrate items-planning-pn specs from Jest to Vitest Co-Authored-By: Claude Opus 5.5 --- .../pairing-grid-page.component.spec.ts | 48 ++++++++++++++----- .../pairing-grid-table.component.spec.ts | 34 +++++++++---- .../pairing-grid-update.component.spec.ts | 27 +++++++---- .../planning-folders-modal.component.spec.ts | 34 +++++++------ ...nnings-bulk-import-modal.component.spec.ts | 32 +++++++++---- .../plannings-header.component.spec.ts | 20 +++++--- 6 files changed, 132 insertions(+), 63 deletions(-) diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.spec.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.spec.ts index 7aa04f11..0f4ba9b6 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.spec.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-page/pairing-grid-page.component.spec.ts @@ -1,22 +1,48 @@ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; - +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {describe, it, expect, beforeEach, vi} from 'vitest'; +import {of} from 'rxjs'; +import {provideNoopAnimations} from '@angular/platform-browser/animations'; +import {provideHttpClient} from '@angular/common/http'; +import {provideHttpClientTesting} from '@angular/common/http/testing'; +import {provideRouter} from '@angular/router'; +import {MatDialog} from '@angular/material/dialog'; +import {Overlay} from '@angular/cdk/overlay'; +import {Store} from '@ngrx/store'; +import {TranslateModule} from '@ngx-translate/core'; import {PairingGridPageComponent} from './pairing-grid-page.component'; +import {PairingStateService} from '../store'; +import {AppMenuStateService, AuthStateService} from 'src/app/common/store'; +import {SitesService, TitleService} from 'src/app/common/services'; +import {ItemsPlanningPnTagsService} from '../../../../services'; +import {ItemsPlanningPnPairingService} from '../../../../services'; describe('PairingGridPageComponent', () => { let component: PairingGridPageComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ PairingGridPageComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PairingGridPageComponent, TranslateModule.forRoot()], + providers: [ + provideNoopAnimations(), + provideHttpClient(), + provideHttpClientTesting(), + provideRouter([]), + // the page embeds the subheader and the grid table; stub what they inject + {provide: AppMenuStateService, useValue: {}}, + {provide: AuthStateService, useValue: {}}, + {provide: SitesService, useValue: {}}, + {provide: ItemsPlanningPnTagsService, useValue: {getPlanningsTags: vi.fn(() => of(null))}}, + {provide: TitleService, useValue: {setTitle: vi.fn()}}, + {provide: Store, useValue: {select: vi.fn(() => of(null)), dispatch: vi.fn()}}, + {provide: ItemsPlanningPnPairingService, useValue: {updatePairings: vi.fn()}}, + {provide: PairingStateService, useValue: {getAllPairings: vi.fn(() => of(null))}}, + {provide: MatDialog, useValue: {open: vi.fn()}}, + {provide: Overlay, useValue: {}}, + ], + }).compileComponents(); fixture = TestBed.createComponent(PairingGridPageComponent); component = fixture.componentInstance; - fixture.detectChanges(); }); it('should create', () => { diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.spec.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.spec.ts index 24b74d7f..598ce579 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.spec.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-table/pairing-grid-table.component.spec.ts @@ -1,21 +1,35 @@ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; - +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {describe, it, expect, beforeEach, vi} from 'vitest'; +import {of} from 'rxjs'; +import {provideNoopAnimations} from '@angular/platform-browser/animations'; +import {Store} from '@ngrx/store'; +import {TranslateModule} from '@ngx-translate/core'; import {PairingGridTableComponent} from './pairing-grid-table.component'; +import {PairingStateService} from '../store'; +import {ItemsPlanningPnTagsService} from '../../../../services'; +import {AuthStateService} from 'src/app/common/store'; +import {SitesService} from 'src/app/common/services'; +import {PairingsModel} from '../../../../models'; describe('PairingGridTableComponent', () => { let component: PairingGridTableComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ PairingGridTableComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PairingGridTableComponent, TranslateModule.forRoot()], + providers: [ + provideNoopAnimations(), + {provide: Store, useValue: {select: vi.fn(() => of(null)), dispatch: vi.fn()}}, + {provide: AuthStateService, useValue: {}}, + {provide: PairingStateService, useValue: {}}, + {provide: SitesService, useValue: {getAllSitesForPairing: vi.fn(() => of(null))}}, + {provide: ItemsPlanningPnTagsService, useValue: {getPlanningsTags: vi.fn(() => of(null))}}, + ], + }).compileComponents(); fixture = TestBed.createComponent(PairingGridTableComponent); component = fixture.componentInstance; + component.pairingsModel = new PairingsModel(); fixture.detectChanges(); }); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-update/pairing-grid-update.component.spec.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-update/pairing-grid-update.component.spec.ts index b770a9a7..49c4c001 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-update/pairing-grid-update.component.spec.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/components/pairing-grid-update/pairing-grid-update.component.spec.ts @@ -1,19 +1,21 @@ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; - +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {describe, it, expect, beforeEach, vi} from 'vitest'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; +import {TranslateModule} from '@ngx-translate/core'; import {PairingGridUpdateComponent} from './pairing-grid-update.component'; describe('PairingGridUpdateComponent', () => { let component: PairingGridUpdateComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ PairingGridUpdateComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PairingGridUpdateComponent, TranslateModule.forRoot()], + providers: [ + {provide: MatDialogRef, useValue: {close: vi.fn()}}, + {provide: MAT_DIALOG_DATA, useValue: [{paired: true}, {paired: false}, {paired: false}]}, + ], + }).compileComponents(); fixture = TestBed.createComponent(PairingGridUpdateComponent); component = fixture.componentInstance; fixture.detectChanges(); @@ -22,4 +24,9 @@ describe('PairingGridUpdateComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should split the pairings into deploy and retract', () => { + expect(component.pairingsForDeploy.length).toBe(1); + expect(component.pairingsForRetract.length).toBe(2); + }); }); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.spec.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.spec.ts index 9322b442..a0d87b57 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.spec.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-folders-modal/planning-folders-modal.component.spec.ts @@ -1,20 +1,24 @@ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {describe, it, expect, beforeEach, vi} from 'vitest'; +import {provideNoopAnimations} from '@angular/platform-browser/animations'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; +import {TranslateModule} from '@ngx-translate/core'; +import {PlanningFoldersModalComponent} from './planning-folders-modal.component'; -import {PlanningAssignSitesModalComponent} from './planning-folders-modal.component'; +describe('PlanningFoldersModalComponent', () => { + let component: PlanningFoldersModalComponent; + let fixture: ComponentFixture; -describe('PlanningAssignSitesModalComponent', () => { - let component: PlanningAssignSitesModalComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ PlanningAssignSitesModalComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(PlanningAssignSitesModalComponent); + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PlanningFoldersModalComponent, TranslateModule.forRoot()], + providers: [ + provideNoopAnimations(), + {provide: MatDialogRef, useValue: {close: vi.fn()}}, + {provide: MAT_DIALOG_DATA, useValue: {folders: [], planningModel: undefined}}, + ], + }).compileComponents(); + fixture = TestBed.createComponent(PlanningFoldersModalComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.spec.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.spec.ts index 40301760..52ca8457 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.spec.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/plannings-bulk-import-modal/plannings-bulk-import-modal.component.spec.ts @@ -1,19 +1,31 @@ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; - +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {describe, it, expect, beforeEach, vi} from 'vitest'; +import {of} from 'rxjs'; +import {provideNoopAnimations} from '@angular/platform-browser/animations'; +import {MatDialogRef} from '@angular/material/dialog'; +import {Store} from '@ngrx/store'; +import {ToastrService} from 'ngx-toastr'; +import {TranslateModule} from '@ngx-translate/core'; import {PlanningsBulkImportModalComponent} from './plannings-bulk-import-modal.component'; +import {LoaderService} from 'src/app/common/services/loader.service'; +import {AuthStateService} from 'src/app/common/store'; describe('PlanningsBulkImportModalComponent', () => { let component: PlanningsBulkImportModalComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ PlanningsBulkImportModalComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PlanningsBulkImportModalComponent, TranslateModule.forRoot()], + providers: [ + provideNoopAnimations(), + {provide: Store, useValue: {select: vi.fn(() => of('token')), dispatch: vi.fn()}}, + {provide: ToastrService, useValue: {success: vi.fn(), warning: vi.fn(), error: vi.fn()}}, + {provide: LoaderService, useValue: {isLoading: of(false), setLoading: vi.fn()}}, + {provide: AuthStateService, useValue: {}}, + {provide: MatDialogRef, useValue: {close: vi.fn()}}, + ], + }).compileComponents(); fixture = TestBed.createComponent(PlanningsBulkImportModalComponent); component = fixture.componentInstance; fixture.detectChanges(); diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.spec.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.spec.ts index f45198db..f5312ba4 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.spec.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-header/plannings-header.component.spec.ts @@ -1,6 +1,11 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; - +import {describe, it, expect, beforeEach, vi} from 'vitest'; +import {of} from 'rxjs'; +import {provideNoopAnimations} from '@angular/platform-browser/animations'; +import {Store} from '@ngrx/store'; +import {TranslateModule} from '@ngx-translate/core'; import {PlanningsHeaderComponent} from './plannings-header.component'; +import {PlanningsStateService} from '../../store'; describe('PlanningsHeaderComponent', () => { let component: PlanningsHeaderComponent; @@ -8,12 +13,13 @@ describe('PlanningsHeaderComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ PlanningsHeaderComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { + imports: [PlanningsHeaderComponent, TranslateModule.forRoot()], + providers: [ + provideNoopAnimations(), + {provide: Store, useValue: {select: vi.fn(() => of(null)), dispatch: vi.fn()}}, + {provide: PlanningsStateService, useValue: {}}, + ], + }).compileComponents(); fixture = TestBed.createComponent(PlanningsHeaderComponent); component = fixture.componentInstance; fixture.detectChanges(); From 0eebd684bf032b0aa94e95e2e1d8040cf0530ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:10:58 +0200 Subject: [PATCH 4/8] fix: render planning tags in a mat-chip-set (mat-chip-list no longer exists) Co-Authored-By: Claude Opus 5.5 --- .../plannings-table/plannings-table.component.html | 4 ++-- .../plannings-table/plannings-table.component.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html index a0f47c31..97e50752 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.html @@ -32,12 +32,12 @@
- + discount {{ tag.name }} - +
diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts index 24490a9c..d44050dd 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/plannings-page/plannings-table/plannings-table.component.ts @@ -11,7 +11,7 @@ import {MatIcon} from '@angular/material/icon'; import {MatTooltip} from '@angular/material/tooltip'; import {NgIf, NgFor, AsyncPipe} from '@angular/common'; import {TranslatePipe} from '@ngx-translate/core'; -import {MatChip} from '@angular/material/chips'; +import {MatChip, MatChipSet} from '@angular/material/chips'; import {EformPaginationComponent} from 'src/app/common/modules/eform-shared/components'; import { PlanningModel } from '../../../../../models'; import {Paged, PaginationModel} from 'src/app/common/models'; @@ -33,7 +33,7 @@ import { selector: 'app-plannings-table', templateUrl: './plannings-table.component.html', styleUrls: ['./plannings-table.component.scss'], - imports: [MtxGrid, MatIcon, MatTooltip, NgIf, NgFor, AsyncPipe, TranslatePipe, MatChip, EformPaginationComponent] + imports: [MtxGrid, MatIcon, MatTooltip, NgIf, NgFor, AsyncPipe, TranslatePipe, MatChip, MatChipSet, EformPaginationComponent] }) export class PlanningsTableComponent implements OnInit { public planningsStateService = inject(PlanningsStateService); From 75a5a8df686b5fe1c11e9e4a25fd3bc74b09f60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:11:03 +0200 Subject: [PATCH 5/8] fix: index-aware pairing selector and ngOnChanges guard Co-Authored-By: Claude Opus 5.5 --- .../e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts | 2 +- .../planning-additions/planning-tags/planning-tags.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts b/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts index 1abf598b..b63e3a72 100644 --- a/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts +++ b/eform-client/e2e/Page objects/ItemsPlanning/ItemsPlanningPairingPage.ts @@ -122,7 +122,7 @@ export class PairingRowObject { async getRow(rowNum: number): Promise { this.row = (await $$('tbody tr'))[rowNum - 1]; if (this.row) { - this.planningName = await (await this.row.$('#planningName')).getText(); + this.planningName = await (await this.row.$('[id^="planningName"]')).getText(); this.pairRow = await this.row.$(`#planningRowCheckbox${rowNum - 1}`); this.pairRowForClick = await this.pairRow.$('label'); this.pairCheckboxes = []; diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts index aa79b861..64658438 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/components/planning-additions/planning-tags/planning-tags.component.ts @@ -118,7 +118,7 @@ export class PlanningTagsComponent implements OnInit, OnDestroy, OnChanges { } ngOnChanges(changes: SimpleChanges): void { - if (!changes.availableTags.firstChange && changes.availableTags && this.dialogRef) { + if (changes.availableTags && !changes.availableTags.firstChange && this.dialogRef) { this.dialogRef.componentInstance.setAvailableTags(changes.availableTags.currentValue); } } From f4c38d5c9327d47daffa65b365a7f996b270214b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:11:10 +0200 Subject: [PATCH 6/8] ci: run items-planning-pn unit tests with ng test Co-Authored-By: Claude Opus 5.5 --- .github/workflows/dotnet-core-master.yml | 26 ++++++++++++++++++++++++ .github/workflows/dotnet-core-pr.yml | 26 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/.github/workflows/dotnet-core-master.yml b/.github/workflows/dotnet-core-master.yml index 94f4d680..17684b3d 100644 --- a/.github/workflows/dotnet-core-master.yml +++ b/.github/workflows/dotnet-core-master.yml @@ -46,6 +46,32 @@ jobs: with: name: items-planning-container path: items-planning-container.tar + angular-unit-test: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + with: + path: eform-angular-items-planning-plugin + - name: 'Preparing Frontend checkout' + uses: actions/checkout@v3 + with: + repository: microting/eform-angular-frontend + ref: ${{ github.ref_name }} + path: eform-angular-frontend + - name: Copy dependencies + run: | + cp -av eform-angular-items-planning-plugin/eform-client/src/app/plugins/modules/items-planning-pn eform-angular-frontend/eform-client/src/app/plugins/modules/items-planning-pn + cd eform-angular-frontend/eform-client && ../../eform-angular-items-planning-plugin/testinginstallpn.sh + - uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Enable Corepack + run: corepack enable + - name: yarn install + run: cd eform-angular-frontend/eform-client && yarn install + - name: Unit tests + run: cd eform-angular-frontend/eform-client && npx ng test --watch=false --include='src/app/plugins/modules/items-planning-pn/**/*.spec.ts' test-dotnet: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/dotnet-core-pr.yml b/.github/workflows/dotnet-core-pr.yml index 28d3bd37..9c94b8b3 100644 --- a/.github/workflows/dotnet-core-pr.yml +++ b/.github/workflows/dotnet-core-pr.yml @@ -43,6 +43,32 @@ jobs: with: name: items-planning-container path: items-planning-container.tar + angular-unit-test: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + with: + path: eform-angular-items-planning-plugin + - name: 'Preparing Frontend checkout' + uses: actions/checkout@v3 + with: + repository: microting/eform-angular-frontend + ref: ${{ github.base_ref }} + path: eform-angular-frontend + - name: Copy dependencies + run: | + cp -av eform-angular-items-planning-plugin/eform-client/src/app/plugins/modules/items-planning-pn eform-angular-frontend/eform-client/src/app/plugins/modules/items-planning-pn + cd eform-angular-frontend/eform-client && ../../eform-angular-items-planning-plugin/testinginstallpn.sh + - uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Enable Corepack + run: corepack enable + - name: yarn install + run: cd eform-angular-frontend/eform-client && yarn install + - name: Unit tests + run: cd eform-angular-frontend/eform-client && npx ng test --watch=false --include='src/app/plugins/modules/items-planning-pn/**/*.spec.ts' test-dotnet: runs-on: ubuntu-latest steps: From 50348a9ff7925048ec81322987b95cd31f6fa8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 08:27:09 +0200 Subject: [PATCH 7/8] fix: keep MatDialogModule so plugin dialogs resolve module-provided services Co-Authored-By: Claude Opus 5.5 --- .../modules/items-planning-pn/modules/pairing/pairing.module.ts | 2 ++ .../items-planning-pn/modules/plannings/plannings.module.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts index 37b605b4..219976c7 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/pairing/pairing.module.ts @@ -1,4 +1,5 @@ import {NgModule} from '@angular/core'; +import {MatDialogModule} from '@angular/material/dialog'; import { PairingGridPageComponent, PairingGridTableComponent, @@ -8,6 +9,7 @@ import {PairingRouting} from './pairing.routing'; @NgModule({ imports: [ + MatDialogModule, PairingRouting, PairingGridPageComponent, PairingGridTableComponent, diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts index 6a5dead4..7c2497ee 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/modules/plannings/plannings.module.ts @@ -1,4 +1,5 @@ import {NgModule} from '@angular/core'; +import {MatDialogModule} from '@angular/material/dialog'; import { PlanningCreateComponent, PlanningEditComponent, @@ -16,6 +17,7 @@ import {PlanningsRouting} from './plannings.routing'; @NgModule({ imports: [ + MatDialogModule, PlanningsRouting, PlanningCreateComponent, PlanningEditComponent, From 714d23678cd02cf6243eb183ce9a89acc169a172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Sun, 18 Oct 2026 09:24:28 +0200 Subject: [PATCH 8/8] fix: keep a feature-scoped MatDialog where shared modules used to provide it Co-Authored-By: Claude Opus 5.5 --- .../modules/items-planning-pn/items-planning-pn.module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts b/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts index 15f05f76..66e70f7a 100644 --- a/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts +++ b/eform-client/src/app/plugins/modules/items-planning-pn/items-planning-pn.module.ts @@ -1,4 +1,5 @@ import {NgModule} from '@angular/core'; +import {MatDialogModule} from '@angular/material/dialog'; import {ItemsPlanningPnLayoutComponent} from './layouts'; import {ItemsPlanningPnRouting} from './items-planning-pn.routing'; import { @@ -17,6 +18,7 @@ import { @NgModule({ imports: [ + MatDialogModule, ItemsPlanningPnLayoutComponent, ItemsPlanningPnRouting, StoreModule.forFeature('itemsPlanningPn', {