diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 69a6feef8b..436e1fa0aa 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -35,7 +35,7 @@ runs: - name: get latest tag sha if: ${{ inputs.full-setup == 'true' }} id: tag-sha - uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@5177eca5d3d71342d7f7e0a2a4d74cc16b1eeb1b # v18.21.3 + uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@98bcfbe06aafffdc0e9a790f352602316f82303b # v18.23.0 - name: load "NPM TAG" if: ${{ inputs.full-setup == 'true' }} id: set-npm-tag diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 88c32e79f5..9a2c2a18d4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -30,7 +30,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v3.29.5 + uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v3.29.5 # Override language selection by uncommenting this and choosing your languages with: languages: javascript @@ -39,7 +39,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@5595ccaf912efad79be6eef63a5619ff05969be3 # v3.29.5 + uses: github/codeql-action/autobuild@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v3.29.5 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -53,4 +53,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v3.29.5 + uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v3.29.5 diff --git a/.github/workflows/notify-on-an-bdu-label.yml b/.github/workflows/notify-on-an-bdu-label.yml index 2248248c4e..cafc0dff62 100644 --- a/.github/workflows/notify-on-an-bdu-label.yml +++ b/.github/workflows/notify-on-an-bdu-label.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Check if label was added after PR creation (with time threshold) id: check_label_timing - uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const prCreatedAt = new Date('${{ github.event.pull_request.created_at }}'); @@ -53,7 +53,7 @@ jobs: - name: Send Teams notification if: steps.check_label_timing.outputs.should_notify == 'true' - uses: Alfresco/alfresco-build-tools/.github/actions/send-teams-notification@5177eca5d3d71342d7f7e0a2a4d74cc16b1eeb1b # v18.21.3 + uses: Alfresco/alfresco-build-tools/.github/actions/send-teams-notification@98bcfbe06aafffdc0e9a790f352602316f82303b # v18.23.0 with: webhook-url: ${{ secrets.TEAMS_NOTIFICATION_ADF_BDU_WEBHOOK }} skip_checkout: true diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 424b51941b..371fe5e0fa 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -254,6 +254,8 @@ jobs: name: "Unit Tests" needs: [setup] uses: ./.github/workflows/unit-test-workflow.yml + secrets: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: base_ref: ${{ github.base_ref || 'develop' }} diff --git a/.github/workflows/sonar-develop.yml b/.github/workflows/sonar-develop.yml new file mode 100644 index 0000000000..83bd79b0e7 --- /dev/null +++ b/.github/workflows/sonar-develop.yml @@ -0,0 +1,22 @@ +name: "SonarCloud Full Scan (develop)" + +on: + schedule: + - cron: '0 5 * * *' + workflow_dispatch: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: read + +jobs: + full-unit-tests-and-sonar-scan: + name: "Full Unit Tests + SonarCloud Scan" + uses: ./.github/workflows/unit-test-workflow.yml + secrets: inherit + with: + full: true diff --git a/.github/workflows/stale-pr-cleanup.yml b/.github/workflows/stale-pr-cleanup.yml index c50211b485..e14f9155c7 100644 --- a/.github/workflows/stale-pr-cleanup.yml +++ b/.github/workflows/stale-pr-cleanup.yml @@ -11,4 +11,4 @@ permissions: jobs: stale-pr-cleanup: - uses: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml@5177eca5d3d71342d7f7e0a2a4d74cc16b1eeb1b # v18.21.3 + uses: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml@98bcfbe06aafffdc0e9a790f352602316f82303b # v18.23.0 diff --git a/.github/workflows/supply-chain-pr-instructions.yml b/.github/workflows/supply-chain-pr-instructions.yml index 9ebc9bee49..5c5166f57f 100644 --- a/.github/workflows/supply-chain-pr-instructions.yml +++ b/.github/workflows/supply-chain-pr-instructions.yml @@ -16,7 +16,7 @@ jobs: permissions: pull-requests: write steps: - - uses: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment@5177eca5d3d71342d7f7e0a2a4d74cc16b1eeb1b # v18.21.3 + - uses: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment@98bcfbe06aafffdc0e9a790f352602316f82303b # v18.23.0 with: comment-identifier: supply-chain-review-instructions comment-body: | diff --git a/.github/workflows/supply-chain-review.lock.yml b/.github/workflows/supply-chain-review.lock.yml index 8b1a7db227..8a114a76b5 100644 --- a/.github/workflows/supply-chain-review.lock.yml +++ b/.github/workflows/supply-chain-review.lock.yml @@ -41,7 +41,7 @@ # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 +# - github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 # # Container images used: # - ghcr.io/github/gh-aw-firewall/agent:0.27.44@sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4 @@ -125,7 +125,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 + uses: github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -494,7 +494,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 + uses: github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1128,7 +1128,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 + uses: github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1404,7 +1404,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 + uses: github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1653,7 +1653,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 + uses: github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1732,7 +1732,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8914f47b6c1bb8a802c7549f5ac1a81434b66403 # v0.86.1 + uses: github/gh-aw-actions/setup@6aab9e5b5c91c615506061f09bedd81a23babe3c # v0.86.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} diff --git a/.github/workflows/unit-test-workflow.yml b/.github/workflows/unit-test-workflow.yml index 8759f8b863..2b52941aec 100644 --- a/.github/workflows/unit-test-workflow.yml +++ b/.github/workflows/unit-test-workflow.yml @@ -2,12 +2,21 @@ name: "Unit Tests Workflow" on: workflow_call: + secrets: + SONAR_TOKEN: + description: 'Token for SonarCloud analysis' + required: false inputs: base_ref: description: 'Base branch for affected calculation' required: false type: string default: 'develop' + full: + description: 'Run the full (non-affected) test suite for every project instead of only affected ones' + required: false + type: boolean + default: false jobs: generate-affected-matrix: @@ -30,9 +39,15 @@ jobs: id: set-matrix env: BASE_REF: ${{ inputs.base_ref }} + FULL_RUN: ${{ inputs.full }} run: | - echo "Base ref is $BASE_REF" - AFFECTED_UNIT=$(pnpm nx show projects --affected --target=test --base=origin/$BASE_REF --head=HEAD --select=projects --plain --exclude=cli,stories,eslint-angular) + if [ "$FULL_RUN" == "true" ]; then + echo "Running full (non-affected) test suite" + AFFECTED_UNIT=$(pnpm nx show projects --target=test --select=projects --plain --exclude=cli,stories,eslint-angular) + else + echo "Base ref is $BASE_REF" + AFFECTED_UNIT=$(pnpm nx show projects --affected --target=test --base=origin/$BASE_REF --head=HEAD --select=projects --plain --exclude=cli,stories,eslint-angular) + fi echo "Affected projects for UNIT: $AFFECTED_UNIT" if [ -z "$AFFECTED_UNIT" ]; then @@ -74,8 +89,56 @@ jobs: NODE_OPTIONS: "--max-old-space-size=5120" run: | xvfb-run --auto-servernum pnpm nx run ${{ matrix.project }}:test + - name: Upload coverage report + if: ${{ always() }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: coverage-${{ matrix.project }} + path: coverage/${{ matrix.project }}/lcov.info + if-no-files-found: ignore + retention-days: 1 - name: Save nx cache if: ${{ success() }} uses: ./.github/actions/save-nx-cache with: cache-suffix: test-${{ matrix.project }} + + sonarcloud: + name: "SonarCloud Scan" + runs-on: ubuntu-latest + needs: [generate-affected-matrix, unit-tests] + if: ${{ needs.generate-affected-matrix.outputs.hasProjects == 'true' && always() && needs.unit-tests.result != 'cancelled' }} + permissions: + contents: read + pull-requests: read + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + - name: Download all coverage artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + pattern: coverage-* + path: coverage-reports + - name: Merge coverage reports + run: | + mkdir -p coverage + echo "Artifact structure:" + find coverage-reports -type f -name 'lcov.info' 2>/dev/null || true + for dir in coverage-reports/coverage-*/; do + project_name=$(basename "$dir" | sed 's/^coverage-//') + lcov_file=$(find "$dir" -name 'lcov.info' -type f | head -1) + if [ -n "$lcov_file" ]; then + mkdir -p "coverage/${project_name}" + cp "$lcov_file" "coverage/${project_name}/lcov.info" + echo "Copied coverage for ${project_name}" + fi + done + echo "Coverage files found:" + find coverage -name 'lcov.info' -type f + - name: SonarCloud Scan + uses: SonarSource/sonarqube-scan-action@aa494459d7c39c106cc77b166de8b4250a32bb97 # v5.1.0 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: https://sonarcloud.io diff --git a/docs/core/models/form-field.model.md b/docs/core/models/form-field.model.md index ed98e18f8d..ab88e0ab5a 100644 --- a/docs/core/models/form-field.model.md +++ b/docs/core/models/form-field.model.md @@ -52,7 +52,8 @@ Contains the value and metadata for a field of a [`Form`](../../../lib/process-s | columns | [`ContainerColumnModel`](../../../lib/core/src/lib/form/components/widgets/core/container-column.model.ts)\[] | \[] | Column definitions for a container field | | rows | [`ContainerRowModel`](../../../lib/core/src/lib/form/components/widgets/core/container-row.model.ts)\[] | \[] | Row definitions for a repeatable section field | | emptyOption | [`FormFieldOption`](../../../lib/core/src/lib/form/components/widgets/core/form-field-option.ts) | | Dropdown menu item to use when no option is chosen | -| validationSummary | string | | Error/information message added during field validation (see [`FormFieldValidator`](../../../lib/core/src/lib/form/components/widgets/core/form-field-validator.ts) interface) | +| validationSummary | [`ErrorMessageModel`](../../../lib/core/src/lib/form/components/widgets/core/error-message.model.ts) | | Error/information message added during field validation (see [`FormFieldValidator`](../../../lib/core/src/lib/form/components/widgets/core/form-field-validator.ts) interface) | +| validationSummaryChanges$ | Observable<[`ErrorMessageModel`](../../../lib/core/src/lib/form/components/widgets/core/error-message.model.ts)> | | Replays the current validation summary to subscribers and emits the completed summary after each validation | ## Details diff --git a/lib/content-services/karma.conf.js b/lib/content-services/karma.conf.js index a37f38f5e1..6880782c7c 100644 --- a/lib/content-services/karma.conf.js +++ b/lib/content-services/karma.conf.js @@ -56,7 +56,7 @@ module.exports = function (config) { coverageReporter: { dir: join(__dirname, '../../coverage/content-services'), subdir: '.', - reporters: [{ type: 'html' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], + reporters: [{ type: 'html' }, { type: 'lcov' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], check: { global: { statements: 75, diff --git a/lib/content-services/package.json b/lib/content-services/package.json index abce4fea81..7e17e7c9ea 100644 --- a/lib/content-services/package.json +++ b/lib/content-services/package.json @@ -12,14 +12,14 @@ }, "peerDependencies": { "@angular/cdk": ">=20.2.14", - "@angular/common": ">=20.3.25", - "@angular/compiler": ">=20.3.25", - "@angular/core": ">=20.3.25", - "@angular/forms": ">=20.3.25", + "@angular/common": ">=20.3.27", + "@angular/compiler": ">=20.3.27", + "@angular/core": ">=20.3.27", + "@angular/forms": ">=20.3.27", "@angular/material": ">=20.2.14", - "@angular/platform-browser": ">=20.3.25", - "@angular/platform-browser-dynamic": ">=20.3.25", - "@angular/router": ">=20.3.25", + "@angular/platform-browser": ">=20.3.27", + "@angular/platform-browser-dynamic": ">=20.3.27", + "@angular/router": ">=20.3.27", "@alfresco/js-api": ">=10.0.0", "@ngx-translate/core": ">=17.0.0", "@alfresco/adf-core": ">=9.0.0" diff --git a/lib/content-services/src/lib/search/components/search-filter-chips/search-filter-menu-card/search-filter-menu-card.component.html b/lib/content-services/src/lib/search/components/search-filter-chips/search-filter-menu-card/search-filter-menu-card.component.html index 8167e8b14e..dd4ca6f210 100644 --- a/lib/content-services/src/lib/search/components/search-filter-chips/search-filter-menu-card/search-filter-menu-card.component.html +++ b/lib/content-services/src/lib/search/components/search-filter-chips/search-filter-menu-card/search-filter-menu-card.component.html @@ -1,6 +1,8 @@
- +

+ +

diff --git a/lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts b/lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts index 5c9eda7791..d1a340e48c 100644 --- a/lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts +++ b/lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts @@ -17,7 +17,7 @@ /* eslint-disable @angular-eslint/component-selector */ -import { NgClass, NgIf } from '@angular/common'; +import { NgClass } from '@angular/common'; import { Component, ViewEncapsulation } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -47,7 +47,7 @@ import { WidgetComponent } from '../widget.component'; '(invalid)': 'event($event)', '(select)': 'event($event)' }, - imports: [NgClass, MatCheckboxModule, FormsModule, TranslatePipe, ErrorWidgetComponent, NgIf], + imports: [NgClass, MatCheckboxModule, FormsModule, TranslatePipe, ErrorWidgetComponent], encapsulation: ViewEncapsulation.None }) export class CheckboxWidgetComponent extends WidgetComponent {} diff --git a/lib/core/src/lib/form/components/widgets/core/error-message.model.ts b/lib/core/src/lib/form/components/widgets/core/error-message.model.ts index 19a7b4f183..c55236257c 100644 --- a/lib/core/src/lib/form/components/widgets/core/error-message.model.ts +++ b/lib/core/src/lib/form/components/widgets/core/error-message.model.ts @@ -17,24 +17,36 @@ export class ErrorMessageModel { message: string = ''; - attributes: Map = null; + attributes: Map = new Map(); constructor(obj?: any) { this.message = obj?.message || ''; - this.attributes = obj?.attributes || new Map(); + + if (obj?.attributes) { + this.attributes = obj.attributes; + } } isActive(): boolean { return !!this.message; } - getAttributesAsJsonObj() { - const result = {}; + getAttributesAsJsonObj(): Record { + const result: Record = {}; if (this.attributes.size > 0) { this.attributes.forEach((value, key) => { result[key] = typeof value === 'string' ? value : JSON.stringify(value); }); } + return result; } } + +export const getValidationSummaryTranslationParameters = (validationSummary?: ErrorMessageModel): Record => { + if (validationSummary?.isActive()) { + return validationSummary.getAttributesAsJsonObj(); + } + + return {}; +}; diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts index 0e4c65e9b4..03bac3ae4b 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts @@ -17,9 +17,10 @@ import { DateFnsUtils } from '../../../../common'; import { FormRulesEvent } from '../../../events/form-rules.event'; -import { firstValueFrom, map, Subject, take, timeout } from 'rxjs'; +import { firstValueFrom, map, skip, Subject, take, timeout } from 'rxjs'; +import { ErrorMessageModel, getValidationSummaryTranslationParameters } from './error-message.model'; import { FormFieldTypes } from './form-field-types'; -import { RequiredFieldValidator } from './form-field-validator'; +import { MinValueFieldValidator, RequiredFieldValidator } from './form-field-validator'; import { FormFieldModel } from './form-field.model'; import { FormModel } from './form.model'; @@ -36,6 +37,58 @@ describe('FormFieldModel', () => { expect(model.json).toBe(json); }); + it('should return an isolated authored value snapshot', () => { + const authoredValue = { blocks: [{ data: { text: '${field.name}' } }] }; + const model = new FormFieldModel(new FormModel(), { id: 'richText', type: FormFieldTypes.DISPLAY_RICH_TEXT, value: authoredValue }); + + const snapshot = model.authoredValue as typeof authoredValue; + snapshot.blocks[0].data.text = 'changed'; + + expect((model.authoredValue as typeof authoredValue).blocks[0].data.text).toBe('${field.name}'); + expect(authoredValue.blocks[0].data.text).toBe('${field.name}'); + }); + + it('should not capture authored values for other field types', () => { + const model = new FormFieldModel(new FormModel(), { id: 'json', type: FormFieldTypes.JSON, value: { content: 'value' } }); + + expect(model.authoredValue).toBeUndefined(); + }); + + it('should return undefined for authored values that cannot be cloned', () => { + const circularValue: { self?: unknown } = {}; + circularValue.self = circularValue; + + const circularValueModel = new FormFieldModel(new FormModel(), { + id: 'circular', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: circularValue + }); + const bigintValueModel = new FormFieldModel(new FormModel(), { + id: 'bigint', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: BigInt(1) + }); + + expect(circularValueModel.authoredValue).toBeUndefined(); + expect(bigintValueModel.authoredValue).toBeUndefined(); + }); + + it('should preserve authored value when form data overrides the field value', () => { + const authoredValue = { blocks: [{ data: { text: '${field.name}' } }] }; + const savedValue = { blocks: [{ data: { text: 'John' } }] }; + const form = new FormModel( + { + fields: [{ id: 'richText', name: 'richText', type: FormFieldTypes.DISPLAY_RICH_TEXT, value: authoredValue }] + }, + { richText: savedValue } + ); + const model = form.getFieldById('richText'); + + expect(model.value).toEqual(savedValue); + expect(model.authoredValue).toEqual(authoredValue); + expect(model.authoredValue).not.toBe(authoredValue); + }); + it('should setup with json config', () => { const json = { fieldType: '', @@ -1222,6 +1275,57 @@ describe('FormFieldModel', () => { }); }); + describe('validation summary changes', () => { + const createField = (): FormFieldModel => { + const form = new FormModel(); + form.fieldValidators = [new MinValueFieldValidator()]; + + return new FormFieldModel(form, { + id: 'number-field', + type: FormFieldTypes.NUMBER, + value: 1, + minValue: '10' + }); + }; + + it('should replay an inactive validation summary before the first validation', async () => { + const field = new FormFieldModel(new FormModel()); + + const validationSummary = await firstValueFrom(field.validationSummaryChanges$); + + expect(validationSummary).toEqual(jasmine.any(ErrorMessageModel)); + expect(validationSummary.isActive()).toBe(false); + }); + + it('should replay the completed validation summary when subscribing after validation', async () => { + const field = createField(); + field.validate(); + + const validationSummary = await firstValueFrom(field.validationSummaryChanges$); + + expect(validationSummary.message).toBe('FORM.FIELD.VALIDATOR.NOT_LESS_THAN'); + expect(validationSummary.attributes.get('minValue')).toBe('10'); + }); + + it('should emit completed summaries when validation state changes', async () => { + const field = createField(); + const invalidSummaryPromise = firstValueFrom(field.validationSummaryChanges$.pipe(skip(1))); + + field.validate(); + const invalidSummary = await invalidSummaryPromise; + + field.value = 10; + const validSummaryPromise = firstValueFrom(field.validationSummaryChanges$.pipe(skip(1))); + field.validate(); + const validSummary = await validSummaryPromise; + + expect(invalidSummary.message).toBe('FORM.FIELD.VALIDATOR.NOT_LESS_THAN'); + expect(invalidSummary.attributes.get('minValue')).toBe('10'); + expect(validSummary.isActive()).toBe(false); + expect(validSummary.attributes.size).toBe(0); + }); + }); + it('should fail validation for readOnly required display-external-property field with null value', () => { const form = new FormModel(); const field = new FormFieldModel(form, { @@ -2056,3 +2160,35 @@ describe('FormFieldTypes', () => { }); }); }); + +describe('ErrorMessageModel', () => { + it('should initialize empty attributes when attributes are omitted', () => { + const errorMessage = new ErrorMessageModel(); + + expect(errorMessage.attributes).toEqual(new Map()); + }); + + it('should retain provided attributes', () => { + const attributes = new Map([['minValue', '10']]); + + const errorMessage = new ErrorMessageModel({ attributes }); + + expect(errorMessage.attributes).toBe(attributes); + }); +}); + +describe('getValidationSummaryTranslationParameters', () => { + it('should return validation attributes when the summary is active', () => { + const validationSummary = new ErrorMessageModel({ + message: 'FORM.FIELD.VALIDATOR.NOT_LESS_THAN', + attributes: new Map([['minValue', '10']]) + }); + + expect(getValidationSummaryTranslationParameters(validationSummary)).toEqual({ minValue: '10' }); + }); + + it('should return empty parameters when the summary is inactive or omitted', () => { + expect(getValidationSummaryTranslationParameters(new ErrorMessageModel())).toEqual({}); + expect(getValidationSummaryTranslationParameters()).toEqual({}); + }); +}); diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts index 6241cf8f84..884e23eb41 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts @@ -29,6 +29,7 @@ import { VariableConfig } from './form-field-variable-options'; import { DataColumn } from '../../../../datatable/data/data-column.model'; import { DateFnsUtils } from '../../../../common'; import { isValid as isValidDate } from 'date-fns'; +import { Observable, ReplaySubject } from 'rxjs'; import { ContainerRowModel } from './container-row.model'; import { RepeatableSectionModel, ROW_ID_PREFIX, TEMPLATE_ROW_ID } from './repeatable-section.model'; import { formFieldRuleHandler } from './handlers/form-field-rule.handler'; @@ -38,12 +39,35 @@ export type FieldOptionType = 'rest' | 'manual' | 'variable'; export type FieldSelectionType = 'single' | 'multiple'; export type FieldAlignmentType = 'vertical' | 'horizontal'; +interface ValidationSummaryChangesState { + subject: ReplaySubject; + observable: Observable; +} + +const validationSummaryChangesByField = new WeakMap(); + +const isJsonPrimitive = (value: unknown): value is null | string | number | boolean => + value === null || ['string', 'number', 'boolean'].includes(typeof value); + +const cloneJsonCompatibleValue = (value: unknown): unknown => { + if (value === undefined || isJsonPrimitive(value)) { + return value; + } + + try { + return JSON.parse(JSON.stringify(value)); + } catch { + return undefined; + } +}; + // Maps to FormFieldRepresentation export class FormFieldModel extends FormWidgetModel { private _value: string; private _readOnly: boolean = false; private _isValid: boolean = true; private _required: boolean = false; + private readonly _authoredValue: unknown; readonly defaultDateFormat: string = 'D-M-YYYY'; readonly defaultDateTimeFormat: string = 'D-M-YYYY hh:mm A'; @@ -110,7 +134,21 @@ export class FormFieldModel extends FormWidgetModel { // util members emptyOption: FormFieldOption; - validationSummary: ErrorMessageModel; + validationSummary: ErrorMessageModel = new ErrorMessageModel(); + + get validationSummaryChanges$(): Observable { + const existingState = validationSummaryChangesByField.get(this); + if (existingState) { + return existingState.observable; + } + + const subject = new ReplaySubject(1); + const observable = subject.asObservable(); + validationSummaryChangesByField.set(this, { subject, observable }); + subject.next(this.validationSummary); + + return observable; + } get value(): any { return this._value; @@ -123,6 +161,10 @@ export class FormFieldModel extends FormWidgetModel { } } + get authoredValue(): unknown { + return cloneJsonCompatibleValue(this._authoredValue); + } + get readOnly(): boolean { if (this.form?.readOnly) { return true; @@ -173,16 +215,19 @@ export class FormFieldModel extends FormWidgetModel { for (const validator of validators) { if (!validator.validate(this)) { this._isValid = false; + validationSummaryChangesByField.get(this)?.subject.next(this.validationSummary); return this._isValid; } } this._isValid = true; + validationSummaryChangesByField.get(this)?.subject.next(this.validationSummary); return this._isValid; } constructor(form: any, json?: any, parent?: RepeatableSectionModel) { super(form, json); + this._authoredValue = json?.type === FormFieldTypes.DISPLAY_RICH_TEXT ? cloneJsonCompatibleValue(json.value) : undefined; if (json) { this.fieldType = json.fieldType; this.id = this.getId(json.id, parent); @@ -221,7 +266,6 @@ export class FormFieldModel extends FormWidgetModel { this.enableFractions = json.enableFractions; this.currency = json.currency; this.dateDisplayFormat = json.dateDisplayFormat || this.getDefaultDateFormat(json); - this.validationSummary = new ErrorMessageModel(); this.tooltip = json.tooltip || ''; this.selectionType = json.selectionType; this.alignmentType = json.alignmentType; diff --git a/lib/core/src/lib/form/components/widgets/decimal/decimal.component.spec.ts b/lib/core/src/lib/form/components/widgets/decimal/decimal.component.spec.ts index d4ab7fab85..a1fbbab018 100644 --- a/lib/core/src/lib/form/components/widgets/decimal/decimal.component.spec.ts +++ b/lib/core/src/lib/form/components/widgets/decimal/decimal.component.spec.ts @@ -22,8 +22,20 @@ import { UnitTestingUtils } from '../../../../testing'; import { FormService } from '../../../services/form.service'; import { FormFieldModel, FormFieldTypes, FormModel } from '../core'; import { DecimalWidgetComponent } from './decimal.component'; +import { TranslateService } from '@ngx-translate/core'; describe('DecimalComponent', () => { + const validatorTranslations = { + FORM: { + FIELD: { + VALIDATOR: { + NOT_LESS_THAN: "Can't be less than {{ minValue }}", + NOT_GREATER_THAN: "Can't be greater than {{ maxValue }}", + INVALID_DECIMAL_PRECISION: 'Precision {{ precision }}' + } + } + } + }; let loader: HarnessLoader; let widget: DecimalWidgetComponent; let fixture: ComponentFixture; @@ -107,6 +119,62 @@ describe('DecimalComponent', () => { }); }); + describe('when validation runs without widget interaction', () => { + let field: FormFieldModel; + + beforeEach(() => { + const translateService = TestBed.inject(TranslateService); + translateService.use('en').subscribe(); + translateService.setTranslation('en', validatorTranslations); + field = new FormFieldModel(new FormModel({ taskId: '' }), { + id: 'decimal-id', + type: FormFieldTypes.DECIMAL, + value: 1, + minValue: 10 + }); + field.validate(); + field.form.showAllValidationErrors = true; + fixture.componentRef.setInput('field', field); + fixture.detectChanges(); + }); + + it('should render the minimum value in the message when initial validation fails', async () => { + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain("Can't be less than 10"); + }); + + it('should render the updated maximum value when programmatic revalidation fails', async () => { + field.value = 10; + field.minValue = '1'; + field.maxValue = '5'; + field.validate(); + fixture.detectChanges(); + + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain("Can't be greater than 5"); + }); + + it('should render decimal precision when programmatic revalidation fails', async () => { + field.value = 1.234; + field.minValue = '1'; + field.precision = 2; + field.validate(); + fixture.detectChanges(); + + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('Precision 2'); + }); + }); + describe('when form model has left labels', () => { it('should have left labels classes on leftLabels true', async () => { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), { diff --git a/lib/core/src/lib/form/components/widgets/decimal/decimal.component.ts b/lib/core/src/lib/form/components/widgets/decimal/decimal.component.ts index a88390caf7..a25bbb1b36 100644 --- a/lib/core/src/lib/form/components/widgets/decimal/decimal.component.ts +++ b/lib/core/src/lib/form/components/widgets/decimal/decimal.component.ts @@ -16,13 +16,15 @@ */ import { NgIf } from '@angular/common'; -import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule, FormGroupDirective, NgForm, UntypedFormControl } from '@angular/forms'; import { ErrorStateMatcher } from '@angular/material/core'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { TranslatePipe } from '@ngx-translate/core'; +import { getValidationSummaryTranslationParameters } from '../core/error-message.model'; import { WidgetComponent } from '../widget.component'; @Component({ @@ -46,19 +48,21 @@ import { WidgetComponent } from '../widget.component'; export class DecimalWidgetComponent extends WidgetComponent implements OnInit { errorStateMatcher: ErrorStateMatcher; translateParameters: Record = {}; + private readonly destroyRef = inject(DestroyRef); ngOnInit(): void { this.initErrorStateMatcher(); + this.field.validationSummaryChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((validationSummary) => { + this.translateParameters = getValidationSummaryTranslationParameters(validationSummary); + }); } onBlur(): void { this.markAsTouched(); - this.updateTranslateParameters(); } onDecimalFieldChanged(): void { this.onFieldChanged(this.field); - this.updateTranslateParameters(); } private initErrorStateMatcher(): void { @@ -67,12 +71,4 @@ export class DecimalWidgetComponent extends WidgetComponent implements OnInit { !this.field.isValid && this.isTouched() }; } - - private updateTranslateParameters(): void { - if (this.field.validationSummary?.isActive()) { - this.translateParameters = this.field.validationSummary.getAttributesAsJsonObj(); - } else { - this.translateParameters = {}; - } - } } diff --git a/lib/core/src/lib/form/components/widgets/error/error.component.scss b/lib/core/src/lib/form/components/widgets/error/error.component.scss index 026768b39d..2b57daf87a 100644 --- a/lib/core/src/lib/form/components/widgets/error/error.component.scss +++ b/lib/core/src/lib/form/components/widgets/error/error.component.scss @@ -10,12 +10,16 @@ } } +error-widget { + display: block; +} + .adf-error { display: flex; align-items: center; &-widget-container { - height: auto; + height: 40px; } &-animate { diff --git a/lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.scss b/lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.scss index a5f2b96287..91025303f0 100644 --- a/lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.scss +++ b/lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.scss @@ -1,6 +1,7 @@ .adf-hyperlink-widget { padding: 0.4375em 0; border-top: 0.8438em solid transparent; + margin-bottom: 20px; a { color: var(--mat-sys-primary); diff --git a/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.scss b/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.scss index 435d152e6e..242d172457 100644 --- a/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.scss +++ b/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.scss @@ -43,6 +43,6 @@ @include mixins.adf-error-icon; } -.adf-container-widget .adf-multiline-text-widget .adf-form-field-input.adf-has-counter { - margin-bottom: 44px; +.adf-container-widget .adf-multiline-text-widget mat-form-field.adf-form-field-input.adf-has-counter { + margin-bottom: 20px; } diff --git a/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.spec.ts b/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.spec.ts index b2398bf024..96ed448e98 100644 --- a/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.spec.ts +++ b/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.spec.ts @@ -25,8 +25,19 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { UnitTestingUtils } from '../../../../testing/unit-testing-utils'; import { ADF_CUSTOM_MESSAGE } from '../core/custom-validation-message.token'; import { of, Subject } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; describe('MultilineTextWidgetComponentComponent', () => { + const validatorTranslations = { + FORM: { + FIELD: { + VALIDATOR: { + AT_LEAST_LONG: 'Minimum {{ minLength }}', + NO_LONGER_THAN: 'Maximum {{ maxLength }}' + } + } + } + }; let loader: HarnessLoader; let widget: MultilineTextWidgetComponentComponent; let fixture: ComponentFixture; @@ -109,6 +120,48 @@ describe('MultilineTextWidgetComponentComponent', () => { }); }); + describe('when validation runs without widget interaction', () => { + let field: FormFieldModel; + + beforeEach(() => { + const translateService = TestBed.inject(TranslateService); + translateService.use('en').subscribe(); + translateService.setTranslation('en', validatorTranslations); + field = new FormFieldModel(new FormModel({ taskId: '' }), { + id: 'multiline-text-id', + type: FormFieldTypes.MULTILINE_TEXT, + value: 'text', + minLength: 10 + }); + field.validate(); + field.form.showAllValidationErrors = true; + fixture.componentRef.setInput('field', field); + fixture.detectChanges(); + }); + + it('should render the minimum length in the message when initial validation fails', async () => { + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('Minimum 10'); + }); + + it('should render the updated maximum length when programmatic revalidation fails', async () => { + field.value = 'too long'; + field.minLength = 1; + field.maxLength = 5; + field.validate(); + fixture.detectChanges(); + + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('Maximum 5'); + }); + }); + describe('when is required', () => { beforeEach(() => { widget.field = new FormFieldModel(new FormModel({ taskId: '' }), { diff --git a/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.ts b/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.ts index ecfad39ae3..53fd4c37aa 100644 --- a/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.ts +++ b/lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.ts @@ -27,6 +27,7 @@ import { MatInputModule } from '@angular/material/input'; import { TranslatePipe } from '@ngx-translate/core'; import { isObservable } from 'rxjs'; import { ADF_CUSTOM_MESSAGE } from '../core/custom-validation-message.token'; +import { getValidationSummaryTranslationParameters } from '../core/error-message.model'; import { WidgetComponent } from '../widget.component'; @Component({ @@ -56,6 +57,9 @@ export class MultilineTextWidgetComponentComponent extends WidgetComponent imple ngOnInit(): void { this.initErrorStateMatcher(); + this.field.validationSummaryChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((validationSummary) => { + this.translateParameters = getValidationSummaryTranslationParameters(validationSummary); + }); if (this.enableCustomMessage != null) { if (isObservable(this.enableCustomMessage)) { this.enableCustomMessage.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((enabled: boolean) => { @@ -73,12 +77,10 @@ export class MultilineTextWidgetComponentComponent extends WidgetComponent imple onBlur(): void { this.markAsTouched(); - this.updateTranslateParameters(); } onMultilineTextFieldChanged(): void { this.onFieldChanged(this.field); - this.updateTranslateParameters(); } private initErrorStateMatcher(): void { @@ -87,12 +89,4 @@ export class MultilineTextWidgetComponentComponent extends WidgetComponent imple !this.field.isValid && this.isTouched() }; } - - private updateTranslateParameters(): void { - if (this.field.validationSummary?.isActive()) { - this.translateParameters = this.field.validationSummary.getAttributesAsJsonObj(); - } else { - this.translateParameters = {}; - } - } } diff --git a/lib/core/src/lib/form/components/widgets/number/number.widget.spec.ts b/lib/core/src/lib/form/components/widgets/number/number.widget.spec.ts index 3ef03a164e..e853c0c43b 100644 --- a/lib/core/src/lib/form/components/widgets/number/number.widget.spec.ts +++ b/lib/core/src/lib/form/components/widgets/number/number.widget.spec.ts @@ -22,8 +22,20 @@ import { UnitTestingUtils } from '../../../../testing'; import { FormFieldModel, FormFieldTypes, FormModel } from '../core'; import { NumberWidgetComponent } from './number.widget'; import { DecimalNumberPipe } from '../../../../pipes'; +import { TranslateService } from '@ngx-translate/core'; describe('NumberWidgetComponent', () => { + const validatorTranslations = { + FORM: { + FIELD: { + VALIDATOR: { + NOT_LESS_THAN: "Can't be less than {{ minValue }}", + NOT_GREATER_THAN: "Can't be greater than {{ maxValue }}", + NO_LONGER_THAN: 'Maximum length {{ maxLength }}' + } + } + } + }; let loader: HarnessLoader; let widget: NumberWidgetComponent; let fixture: ComponentFixture; @@ -175,6 +187,60 @@ describe('NumberWidgetComponent', () => { }); }); + describe('when validation runs without widget interaction', () => { + let field: FormFieldModel; + + beforeEach(() => { + const translateService = TestBed.inject(TranslateService); + translateService.use('en').subscribe(); + translateService.setTranslation('en', validatorTranslations); + field = new FormFieldModel(new FormModel({ taskId: '' }), { + id: 'number-id', + type: FormFieldTypes.NUMBER, + value: 1, + minValue: 10 + }); + field.validate(); + fixture.componentRef.setInput('field', field); + fixture.detectChanges(); + }); + + it('should render the minimum value in the message when initial validation fails', async () => { + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain("Can't be less than 10"); + }); + + it('should render the updated maximum value when programmatic revalidation fails', async () => { + field.value = 10; + field.minValue = '1'; + field.maxValue = '5'; + field.validate(); + fixture.detectChanges(); + + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain("Can't be greater than 5"); + }); + + it('should render the maximum length when programmatic revalidation fails', async () => { + field.value = 12345678901; + field.minValue = '1'; + field.validate(); + fixture.detectChanges(); + + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('Maximum length 10'); + }); + }); + describe('when form model has left labels', () => { it('should have left labels classes on leftLabels true', async () => { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), { diff --git a/lib/core/src/lib/form/components/widgets/number/number.widget.ts b/lib/core/src/lib/form/components/widgets/number/number.widget.ts index 113219a0ef..e7f378ca1d 100644 --- a/lib/core/src/lib/form/components/widgets/number/number.widget.ts +++ b/lib/core/src/lib/form/components/widgets/number/number.widget.ts @@ -18,7 +18,8 @@ /* eslint-disable @angular-eslint/component-selector */ import { NgIf } from '@angular/common'; -import { Component, inject, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule, FormGroupDirective, NgForm, UntypedFormControl } from '@angular/forms'; import { ErrorStateMatcher } from '@angular/material/core'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -26,6 +27,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { TranslatePipe } from '@ngx-translate/core'; import { DecimalNumberPipe } from '../../../../pipes'; +import { getValidationSummaryTranslationParameters } from '../core/error-message.model'; import { WidgetComponent } from '../widget.component'; @Component({ @@ -53,6 +55,7 @@ export class NumberWidgetComponent extends WidgetComponent implements OnInit { translateParameters: Record = {}; private readonly decimalNumberPipe = inject(DecimalNumberPipe); + private readonly destroyRef = inject(DestroyRef); ngOnInit() { if (this.field.readOnly) { @@ -61,11 +64,13 @@ export class NumberWidgetComponent extends WidgetComponent implements OnInit { this.displayValue = this.field.value; } this.initErrorStateMatcher(); + this.field.validationSummaryChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((validationSummary) => { + this.translateParameters = getValidationSummaryTranslationParameters(validationSummary); + }); } onBlur(): void { this.markAsTouched(); - this.updateTranslateParameters(); } protected onNumberChange(value: string) { @@ -74,7 +79,6 @@ export class NumberWidgetComponent extends WidgetComponent implements OnInit { } this.onFieldChanged(this.field); - this.updateTranslateParameters(); } private initErrorStateMatcher(): void { @@ -83,12 +87,4 @@ export class NumberWidgetComponent extends WidgetComponent implements OnInit { !!this.field.validationSummary?.message || (this.isInvalidFieldRequired() && this.isTouched()) }; } - - private updateTranslateParameters(): void { - if (this.field.validationSummary?.isActive()) { - this.translateParameters = this.field.validationSummary.getAttributesAsJsonObj(); - } else { - this.translateParameters = {}; - } - } } diff --git a/lib/core/src/lib/form/components/widgets/repeat/repeat.widget.scss b/lib/core/src/lib/form/components/widgets/repeat/repeat.widget.scss index 33e09becd6..843afbe1cd 100644 --- a/lib/core/src/lib/form/components/widgets/repeat/repeat.widget.scss +++ b/lib/core/src/lib/form/components/widgets/repeat/repeat.widget.scss @@ -9,7 +9,8 @@ } &-row-action { - margin-left: 10px; + margin-inline-start: 10px; + margin-block-end: 35px; } &-row-limit { diff --git a/lib/core/src/lib/form/components/widgets/text/text.widget.spec.ts b/lib/core/src/lib/form/components/widgets/text/text.widget.spec.ts index 48e576800a..816ad455a7 100644 --- a/lib/core/src/lib/form/components/widgets/text/text.widget.spec.ts +++ b/lib/core/src/lib/form/components/widgets/text/text.widget.spec.ts @@ -27,9 +27,20 @@ import { UnitTestingUtils } from '../../../../testing/unit-testing-utils'; import { ADF_CUSTOM_MESSAGE } from '../core/custom-validation-message.token'; import { ADF_TYPED_VALUE_FORMATTING_ENABLED } from '../../../services/form-field-value-formatter.token'; import { of, Subject } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; describe('TextWidgetComponent', () => { const form = new FormModel({ taskId: 'fake-task-id' }); + const validatorTranslations = { + FORM: { + FIELD: { + VALIDATOR: { + AT_LEAST_LONG: 'Minimum {{ minLength }}', + NO_LONGER_THAN: 'Maximum {{ maxLength }}' + } + } + } + }; let loader: HarnessLoader; let widget: TextWidgetComponent; @@ -64,6 +75,47 @@ describe('TextWidgetComponent', () => { }); }); + describe('when validation runs without widget interaction', () => { + let field: FormFieldModel; + + beforeEach(() => { + const translateService = TestBed.inject(TranslateService); + translateService.use('en').subscribe(); + translateService.setTranslation('en', validatorTranslations); + field = new FormFieldModel(form, { + id: 'text-id', + type: FormFieldTypes.TEXT, + value: 'text', + minLength: 10 + }); + field.validate(); + fixture.componentRef.setInput('field', field); + fixture.detectChanges(); + }); + + it('should render the minimum length in the message when initial validation fails', async () => { + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('Minimum 10'); + }); + + it('should render the updated maximum length when programmatic revalidation fails', async () => { + field.value = 'too long'; + field.minLength = 1; + field.maxLength = 5; + field.validate(); + fixture.detectChanges(); + + const formField = await testingUtils.formField.get(); + const errors = await formField.getTextErrors(); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('Maximum 5'); + }); + }); + describe('when template is ready', () => { describe('and no mask is configured on text element', () => { it('should raise ngModelChange event', async () => { diff --git a/lib/core/src/lib/form/components/widgets/text/text.widget.ts b/lib/core/src/lib/form/components/widgets/text/text.widget.ts index 665b315fd7..161afcaaef 100644 --- a/lib/core/src/lib/form/components/widgets/text/text.widget.ts +++ b/lib/core/src/lib/form/components/widgets/text/text.widget.ts @@ -19,6 +19,7 @@ import { NgIf, NgTemplateOutlet } from '@angular/common'; import { Component, Directive, inject, InjectionToken, Input, TemplateRef, ViewEncapsulation } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule, FormGroupDirective, NgForm, UntypedFormControl } from '@angular/forms'; import { ErrorStateMatcher } from '@angular/material/core'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -26,7 +27,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { TranslatePipe } from '@ngx-translate/core'; import { WidgetComponent } from '../widget.component'; -import { ErrorMessageModel } from '../core/error-message.model'; +import { ErrorMessageModel, getValidationSummaryTranslationParameters } from '../core/error-message.model'; import { FormattableTextWidgetComponent } from '../core/formattable-text.widget'; import { DEFAULT_TEXT_MAX_LENGTH } from '../core/form-field-validator'; import { InputMaskDirective } from './text-mask.component'; @@ -97,6 +98,9 @@ export class TextWidgetComponent extends FormattableTextWidgetComponent { this.isMaskReversed = this.field.params['inputMaskReversed'] ? this.field.params['inputMaskReversed'] : false; } this.initErrorStateMatcher(); + this.field.validationSummaryChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((validationSummary) => { + this.translateParameters = getValidationSummaryTranslationParameters(validationSummary); + }); } onPaste(event: ClipboardEvent): void { @@ -125,12 +129,10 @@ export class TextWidgetComponent extends FormattableTextWidgetComponent { onBlur(): void { this.markAsTouched(); - this.updateTranslateParameters(); } onTextFieldChanged(): void { this.onFieldChanged(this.field); - this.updateTranslateParameters(); } private initErrorStateMatcher(): void { @@ -143,14 +145,6 @@ export class TextWidgetComponent extends FormattableTextWidgetComponent { }; } - private updateTranslateParameters(): void { - if (this.field.validationSummary?.isActive()) { - this.translateParameters = this.field.validationSummary.getAttributesAsJsonObj(); - } else { - this.translateParameters = {}; - } - } - private getLengthAfterPaste(input: HTMLInputElement, pastedValue: string): number { const value = input.value ?? ''; const selectionStart = input.selectionStart ?? value.length; diff --git a/lib/core/src/lib/form/services/form-validation-service.interface.ts b/lib/core/src/lib/form/services/form-validation-service.interface.ts index 08b78bd6b5..7a5c5d6e7d 100644 --- a/lib/core/src/lib/form/services/form-validation-service.interface.ts +++ b/lib/core/src/lib/form/services/form-validation-service.interface.ts @@ -16,6 +16,7 @@ */ import { Subject } from 'rxjs'; +import { FormEvent } from '../events/form.event'; import { FormFieldEvent } from '../events/form-field.event'; import { FormRulesEvent } from '../events/form-rules.event'; import { ValidateFormFieldEvent } from '../events/validate-form-field.event'; @@ -26,4 +27,5 @@ export interface FormValidationService { validateForm: Subject; validateFormField: Subject; formRulesEvent?: Subject; + formVisibilityRefreshed?: Subject; } diff --git a/lib/core/src/lib/form/services/form.service.ts b/lib/core/src/lib/form/services/form.service.ts index be9091917a..131430c972 100644 --- a/lib/core/src/lib/form/services/form.service.ts +++ b/lib/core/src/lib/form/services/form.service.ts @@ -62,6 +62,12 @@ export class FormService implements FormValidationService { formRulesEvent = new Subject(); + /** + * Emitted after form field/outcome visibility has been re-evaluated via WidgetVisibilityService.refreshVisibility. + * Internal ADF form-rendering event — not part of the FormValidationService contract. + */ + formVisibilityRefreshed = new Subject(); + constructor() { const injectedFieldValidators = inject(FORM_SERVICE_FIELD_VALIDATORS_TOKEN, { optional: true }); diff --git a/lib/core/src/lib/form/services/widget-visibility.service.spec.ts b/lib/core/src/lib/form/services/widget-visibility.service.spec.ts index 796a01afb9..a75f9fa768 100644 --- a/lib/core/src/lib/form/services/widget-visibility.service.spec.ts +++ b/lib/core/src/lib/form/services/widget-visibility.service.spec.ts @@ -19,6 +19,7 @@ import { TestBed } from '@angular/core/testing'; import { ContainerModel, FormFieldModel, FormFieldTypes, FormModel, TabModel } from '../components/widgets/core'; import { WidgetVisibilityModel } from '../models/widget-visibility.model'; import { WidgetVisibilityService } from './widget-visibility.service'; +import { FormService } from './form.service'; import { fakeFormJson, formTest, @@ -50,6 +51,30 @@ describe('WidgetVisibilityService', () => { service = TestBed.inject(WidgetVisibilityService); }); + it('should emit formVisibilityRefreshed when visibility is refreshed', () => { + const formService = TestBed.inject(FormService); + let emittedForm: FormModel | undefined; + + formService.formVisibilityRefreshed.subscribe((event) => { + emittedForm = event.form; + }); + + service.refreshVisibility(stubFormWithFields); + + expect(emittedForm).toBe(stubFormWithFields); + }); + + it('should not emit formVisibilityRefreshed when form is null', () => { + const formService = TestBed.inject(FormService); + let emitCount = 0; + + formService.formVisibilityRefreshed.subscribe(() => emitCount++); + + service.refreshVisibility(null); + + expect(emitCount).toBe(0); + }); + describe('should be able to evaluate next condition operations', () => { it('using == and return true', () => { const resultsArray = evaluateConditions( diff --git a/lib/core/src/lib/form/services/widget-visibility.service.ts b/lib/core/src/lib/form/services/widget-visibility.service.ts index 3e717afa2f..a7d1ea039d 100644 --- a/lib/core/src/lib/form/services/widget-visibility.service.ts +++ b/lib/core/src/lib/form/services/widget-visibility.service.ts @@ -15,16 +15,20 @@ * limitations under the License. */ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { FormFieldModel, FormModel, TabModel, ContainerModel, FormOutcomeModel } from '../components/widgets/core'; +import { FormEvent } from '../events/form.event'; import { TaskProcessVariableModel } from '../models/task-process-variable.model'; import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model'; import { format, isValid, parse } from 'date-fns'; +import { FormService } from './form.service'; @Injectable({ providedIn: 'root' }) export class WidgetVisibilityService { + private readonly formService = inject(FormService); + private processVarList: TaskProcessVariableModel[]; private form: FormModel; @@ -45,6 +49,8 @@ export class WidgetVisibilityService { } form.getFormFields().map((field) => this.refreshEntityVisibility(field)); + + this.formService.formVisibilityRefreshed.next(new FormEvent(form)); } } diff --git a/lib/core/src/lib/styles/_mat-selectors.scss b/lib/core/src/lib/styles/_mat-selectors.scss index 31fa2b1208..dba941cafa 100644 --- a/lib/core/src/lib/styles/_mat-selectors.scss +++ b/lib/core/src/lib/styles/_mat-selectors.scss @@ -17,6 +17,7 @@ $mat-button: '.mat-mdc-button'; $mat-button-label: '.mdc-button__label'; $mat-form-field: '.mat-mdc-form-field'; $mat-form-field-wrapper: '.mat-mdc-text-field-wrapper'; +$mat-form-field-subscript-wrapper: '.mat-mdc-form-field-subscript-wrapper'; $mat-line-ripple: '.mdc-line-ripple'; $mat-form-field-prefix: '.mat-mdc-form-field-text-prefix'; $mat-form-field-suffix: '.mat-mdc-form-field-text-suffix'; diff --git a/lib/extensions/karma.conf.js b/lib/extensions/karma.conf.js index 4bdd4cd6e4..99b34c1729 100644 --- a/lib/extensions/karma.conf.js +++ b/lib/extensions/karma.conf.js @@ -23,7 +23,7 @@ module.exports = function (config) { coverageReporter: { dir: join(__dirname, '../../coverage/extensions'), subdir: '.', - reporters: [{ type: 'html' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], + reporters: [{ type: 'html' }, { type: 'lcov' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], check: { global: { statements: 75, diff --git a/lib/extensions/package.json b/lib/extensions/package.json index 9f30b6074f..804d7593dc 100644 --- a/lib/extensions/package.json +++ b/lib/extensions/package.json @@ -12,8 +12,8 @@ "url": "https://github.com/Alfresco/alfresco-ng2-components/issues" }, "peerDependencies": { - "@angular/common": ">=20.3.25", - "@angular/core": ">=20.3.25", + "@angular/common": ">=20.3.27", + "@angular/core": ">=20.3.27", "@alfresco/js-api": ">=10.0.0" }, "keywords": [ diff --git a/lib/insights/karma.conf.js b/lib/insights/karma.conf.js index 059cf7eb8a..8cf50ccf31 100644 --- a/lib/insights/karma.conf.js +++ b/lib/insights/karma.conf.js @@ -44,7 +44,7 @@ module.exports = function (config) { coverageReporter: { dir: join(__dirname, '../../coverage/insights'), subdir: '.', - reporters: [{ type: 'html' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], + reporters: [{ type: 'html' }, { type: 'lcov' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], check: { global: { statements: 75, diff --git a/lib/insights/package.json b/lib/insights/package.json index 6f4f422df3..bf0225cff7 100644 --- a/lib/insights/package.json +++ b/lib/insights/package.json @@ -16,10 +16,10 @@ "raphael": ">=2.3.0" }, "peerDependencies": { - "@angular/common": ">=20.3.25", - "@angular/compiler": ">=20.3.25", - "@angular/core": ">=20.3.25", - "@angular/forms": ">=20.3.25", + "@angular/common": ">=20.3.27", + "@angular/compiler": ">=20.3.27", + "@angular/core": ">=20.3.27", + "@angular/forms": ">=20.3.27", "@angular/material": ">=20.2.14", "@alfresco/adf-core": ">=9.0.0", "@alfresco/adf-content-services": ">=9.0.0", diff --git a/lib/insights/src/lib/diagram/models/chart/chart.model.spec.ts b/lib/insights/src/lib/diagram/models/chart/chart.model.spec.ts new file mode 100644 index 0000000000..e56e4854bc --- /dev/null +++ b/lib/insights/src/lib/diagram/models/chart/chart.model.spec.ts @@ -0,0 +1,148 @@ +/*! + * @license + * Copyright © 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Chart } from './chart.model'; + +describe('Chart Model', () => { + describe('constructor', () => { + it('should create with default values when no argument is provided', () => { + const chart = new Chart(); + expect(chart.labels).toEqual([]); + expect(chart.data).toEqual([]); + expect(chart.datasets).toEqual([]); + expect(chart.showDetails).toBe(false); + }); + + it('should populate properties from input object', () => { + const chart = new Chart({ + id: '1', + title: 'Test Chart', + titleKey: 'KEY', + labels: ['a', 'b'], + data: [1, 2], + datasets: [{ data: [1] }], + showDetails: true, + detailsTable: { key: 'value' }, + options: { responsive: true } + }); + + expect(chart.id).toBe('1'); + expect(chart.title).toBe('Test Chart'); + expect(chart.titleKey).toBe('KEY'); + expect(chart.labels).toEqual(['a', 'b']); + expect(chart.data).toEqual([1, 2]); + expect(chart.datasets).toEqual([{ data: [1] }]); + expect(chart.showDetails).toBe(true); + expect(chart.detailsTable).toEqual({ key: 'value' }); + expect(chart.options).toEqual({ responsive: true }); + }); + + it('should convert type and set icon for pieChart', () => { + const chart = new Chart({ type: 'pieChart' }); + expect(chart.type).toBe('pie'); + expect(chart.icon).toBe('pie_chart'); + }); + + it('should convert type and set icon for barChart', () => { + const chart = new Chart({ type: 'barChart' }); + expect(chart.type).toBe('bar'); + expect(chart.icon).toBe('equalizer'); + }); + + it('should convert type and set icon for line', () => { + const chart = new Chart({ type: 'line' }); + expect(chart.type).toBe('line'); + expect(chart.icon).toBe('show_chart'); + }); + + it('should convert type and set icon for table', () => { + const chart = new Chart({ type: 'table' }); + expect(chart.type).toBe('table'); + expect(chart.icon).toBe('web'); + }); + + it('should convert type and set icon for multiBarChart', () => { + const chart = new Chart({ type: 'multiBarChart' }); + expect(chart.type).toBe('multiBar'); + expect(chart.icon).toBe('poll'); + }); + + it('should convert type and set icon for processDefinitionHeatMap', () => { + const chart = new Chart({ type: 'processDefinitionHeatMap' }); + expect(chart.type).toBe('HeatMap'); + expect(chart.icon).toBe('share'); + }); + + it('should convert type and set icon for masterDetailTable', () => { + const chart = new Chart({ type: 'masterDetailTable' }); + expect(chart.type).toBe('masterDetailTable'); + expect(chart.icon).toBe('subtitles'); + }); + + it('should default to table type for unknown types', () => { + const chart = new Chart({ type: 'unknown' }); + expect(chart.type).toBe('table'); + expect(chart.icon).toBe('web'); + }); + }); + + describe('hasData', () => { + it('should return true when data is not empty', () => { + const chart = new Chart({ data: [1, 2, 3] }); + expect(chart.hasData()).toBe(true); + }); + + it('should return false when data is empty', () => { + const chart = new Chart({ data: [] }); + expect(chart.hasData()).toBe(false); + }); + + it('should return false when no data is provided', () => { + const chart = new Chart(); + expect(chart.hasData()).toBe(false); + }); + }); + + describe('hasDatasets', () => { + it('should return true when datasets is not empty', () => { + const chart = new Chart({ datasets: [{ data: [1] }] }); + expect(chart.hasDatasets()).toBe(true); + }); + + it('should return false when datasets is empty', () => { + const chart = new Chart({ datasets: [] }); + expect(chart.hasDatasets()).toBe(false); + }); + }); + + describe('hasZeroValues', () => { + it('should return true when all data values are zero', () => { + const chart = new Chart({ data: [0, 0, 0] }); + expect(chart.hasZeroValues()).toBe(true); + }); + + it('should return false when at least one value is non-zero', () => { + const chart = new Chart({ data: [0, 1, 0] }); + expect(chart.hasZeroValues()).toBe(false); + }); + + it('should return false when data is empty', () => { + const chart = new Chart({ data: [] }); + expect(chart.hasZeroValues()).toBe(false); + }); + }); +}); diff --git a/lib/process-services-cloud/karma.conf.js b/lib/process-services-cloud/karma.conf.js index a7d6664844..154eff3679 100644 --- a/lib/process-services-cloud/karma.conf.js +++ b/lib/process-services-cloud/karma.conf.js @@ -48,7 +48,7 @@ module.exports = function (config) { coverageReporter: { dir: join(__dirname, '../../coverage/process-services-cloud'), subdir: '.', - reporters: [{ type: 'html' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], + reporters: [{ type: 'html' }, { type: 'lcov' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], check: { global: { statements: 75, diff --git a/lib/process-services-cloud/package.json b/lib/process-services-cloud/package.json index 86f933119c..24193bc443 100644 --- a/lib/process-services-cloud/package.json +++ b/lib/process-services-cloud/package.json @@ -12,14 +12,14 @@ }, "peerDependencies": { "@angular/cdk": ">=20.2.14", - "@angular/common": ">=20.3.25", - "@angular/compiler": ">=20.3.25", - "@angular/core": ">=20.3.25", - "@angular/forms": ">=20.3.25", + "@angular/common": ">=20.3.27", + "@angular/compiler": ">=20.3.27", + "@angular/core": ">=20.3.27", + "@angular/forms": ">=20.3.27", "@angular/material": ">=20.2.14", - "@angular/platform-browser": ">=20.3.25", - "@angular/platform-browser-dynamic": ">=20.3.25", - "@angular/router": ">=20.3.25", + "@angular/platform-browser": ">=20.3.27", + "@angular/platform-browser-dynamic": ">=20.3.27", + "@angular/router": ">=20.3.27", "@alfresco/js-api": ">=10.0.0", "@alfresco/adf-core": ">=9.0.0", "@alfresco/adf-content-services": ">=9.0.0", diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts index ba87073a06..221f4dedb5 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts @@ -17,6 +17,7 @@ import { VersionCompatibilityService, AlfrescoApiService } from '@alfresco/adf-content-services'; import { + ADF_DISPLAY_TEXT_SETTINGS, ContentLinkModel, CoreModule, FormFieldModel, @@ -31,6 +32,8 @@ import { provideTranslations, AuthModule, FormFieldEvent, + FormEvent, + FormRulesEvent, NoopTranslateModule, NoopAuthModule, FORM_FIELD_VALIDATORS @@ -117,7 +120,8 @@ describe('FormCloudComponent', () => { useValue: {} }, { provide: FormRenderingService, useClass: CloudFormRenderingService }, - { provide: FORM_CLOUD_FIELD_VALIDATORS_TOKEN, useValue: [fakeValidator] } + { provide: FORM_CLOUD_FIELD_VALIDATORS_TOKEN, useValue: [fakeValidator] }, + { provide: ADF_DISPLAY_TEXT_SETTINGS, useValue: { enableExpressionEvaluation: true } } ] }); const apiService = TestBed.inject(AlfrescoApiService); @@ -874,6 +878,39 @@ describe('FormCloudComponent', () => { expect(savedForm).toEqual(formModel); }); + it('should materialize unrendered rich text expressions when saving a task form', () => { + spyOn(formCloudService, 'saveTaskForm').and.returnValue(of(undefined)); + const formModel = new FormModel({ + id: '23', + taskId: '123-223', + fields: [ + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: 'Hello ${field.name}' } }] } + }, + { id: 'name', type: FormFieldTypes.TEXT, value: 'John' } + ] + }); + const originalValues = JSON.parse(JSON.stringify(formModel.values)); + formComponent.form = formModel; + formComponent.taskId = formModel.taskId; + formComponent.appName = 'test-app'; + + formComponent.saveTaskForm(); + + expect(formCloudService.saveTaskForm).toHaveBeenCalledWith( + 'test-app', + formModel.taskId, + undefined, + formModel.id, + jasmine.objectContaining({ + richText: { blocks: [{ type: 'paragraph', data: { text: 'Hello John' } }] } + }) + ); + expect(formModel.values).toEqual(originalValues); + }); + it('should handle error during form save', () => { const error = 'Error'; spyOn(formCloudService, 'saveTaskForm').and.callFake(() => throwError(error)); @@ -981,6 +1018,39 @@ describe('FormCloudComponent', () => { expect(completedForm).toBe(formComponent.form); }); + it('should materialize unrendered rich text expressions when completing a task form', () => { + spyOn(formCloudService, 'completeTaskForm').and.returnValue(of(undefined)); + const formModel = new FormModel({ + id: '23', + taskId: '123-223', + fields: [ + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: '${field.name}' } }] } + }, + { id: 'name', type: FormFieldTypes.TEXT, value: 'John' } + ] + }); + formComponent.form = formModel; + formComponent.taskId = formModel.taskId; + formComponent.appName = 'test-app'; + + formComponent.completeTaskForm('complete'); + + expect(formCloudService.completeTaskForm).toHaveBeenCalledWith( + 'test-app', + formModel.taskId, + undefined, + formModel.id, + jasmine.objectContaining({ + richText: { blocks: [{ type: 'paragraph', data: { text: 'John' } }] } + }), + 'complete', + undefined + ); + }); + it('should open confirmation dialog on complete task', async () => { formComponent.form = new FormModel({ confirmMessage: { @@ -1231,6 +1301,38 @@ describe('FormCloudComponent', () => { expect(formComponent.visibleOutcomes).toEqual([]); }); + it('should recompute visibleOutcomes when form visibility is refreshed', () => { + formComponent.showCompleteButton = true; + const formModel = new FormModel(cloudFormMock); + formComponent.form = formModel; + + expect(formComponent.visibleOutcomes.length).toBeGreaterThan(0); + + formModel.outcomes.forEach((outcome) => { + outcome.isVisible = false; + }); + + TestBed.inject(FormService).formVisibilityRefreshed.next(new FormEvent(formModel)); + + expect(formComponent.visibleOutcomes).toEqual([]); + }); + + it('should recompute visibleOutcomes when fieldValueChanged rule event fires', () => { + formComponent.showCompleteButton = true; + const formModel = new FormModel(cloudFormMock); + formComponent.form = formModel; + + expect(formComponent.visibleOutcomes.length).toBeGreaterThan(0); + + formModel.outcomes.forEach((outcome) => { + outcome.isVisible = false; + }); + + TestBed.inject(FormService).formRulesEvent.next(new FormRulesEvent('fieldValueChanged', new FormEvent(formModel))); + + expect(formComponent.visibleOutcomes).toEqual([]); + }); + it('should raise [executeOutcome] event for formService', async () => { spyOn(formComponent.executeOutcome, 'emit'); diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts index 33f50d4fb8..c2ab42da40 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts @@ -30,14 +30,17 @@ import { SimpleChanges, ViewChild } from '@angular/core'; -import { forkJoin, isObservable, Observable, of, Subscription } from 'rxjs'; +import { forkJoin, isObservable, merge, Observable, of, Subscription } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; import { ConfirmDialogComponent, ContentLinkModel, + ADF_DISPLAY_TEXT_SETTINGS, + DisplayTextWidgetSettings, FormatSpacePipe, FormBaseComponent, FormEvent, + FormExpressionService, FormFieldModel, FormRulesEvent, FormFieldValidator, @@ -67,6 +70,7 @@ import { TranslatePipe } from '@ngx-translate/core'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { A11yModule } from '@angular/cdk/a11y'; +import { getExpressionEvaluationEnabled$, materializeSubmissionValues } from '../services/form-cloud-submission-values'; interface FormFieldRuntimeState { value: any; @@ -228,6 +232,8 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, protected changeDetector = inject(ChangeDetectorRef); private readonly destroyRef = inject(DestroyRef); + private readonly expressions = inject(FormExpressionService); + private enableExpressionEvaluation = false; private get currentForm(): FormModel | undefined { return super.form; @@ -252,6 +258,9 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, constructor() { const injectedFieldValidators = inject(FORM_CLOUD_FIELD_VALIDATORS_TOKEN, { optional: true }); const tabNavEnabledToken = inject(ADF_FORM_TAB_NAV_ENABLED, { optional: true }); + const displayTextSettings = inject | DisplayTextWidgetSettings>(ADF_DISPLAY_TEXT_SETTINGS, { + optional: true + }); super(); this.loadInjectedFieldValidators(injectedFieldValidators); @@ -270,6 +279,12 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, } } + getExpressionEvaluationEnabled$(displayTextSettings) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((enabled) => { + this.enableExpressionEvaluation = enabled; + }); + this.formService.formContentClicked.pipe(takeUntilDestroyed()).subscribe((content) => { if (content instanceof UploadWidgetContentLinkModel) { this.form.setNodeIdValueForViewersLinkedToUploadWidget(content); @@ -291,11 +306,11 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, } }); - this.formService.formRulesEvent - .pipe( - filter((event) => event?.type === 'fieldValueChanged' && event.form?.id === this.form?.id), - takeUntilDestroyed() - ) + merge( + this.formService.formVisibilityRefreshed.pipe(filter((event) => event.form?.id === this.form?.id)), + this.formService.formRulesEvent.pipe(filter((event) => event?.type === 'fieldValueChanged' && event.form?.id === this.form?.id)) + ) + .pipe(takeUntilDestroyed()) .subscribe(() => this.recomputeVisibleOutcomes()); } @@ -482,7 +497,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, saveTaskForm() { if (this.form && this.appName && this.taskId) { this.formCloudService - .saveTaskForm(this.appName, this.taskId, this.processInstanceId, `${this.form.id}`, this.form.values) + .saveTaskForm(this.appName, this.taskId, this.processInstanceId, `${this.form.id}`, this.getSubmissionValues()) .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => { @@ -523,7 +538,15 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, private completeForm(outcome?: string, outcomeId?: string) { if (this.form && this.appName && this.taskId) { this.formCloudService - .completeTaskForm(this.appName, this.taskId, this.processInstanceId, `${this.form.id}`, this.form.values, outcome, this.appVersion) + .completeTaskForm( + this.appName, + this.taskId, + this.processInstanceId, + `${this.form.id}`, + this.getSubmissionValues(), + outcome, + this.appVersion + ) .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => { @@ -536,6 +559,10 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, } } + private getSubmissionValues(): FormValues { + return materializeSubmissionValues(this.form, { enableExpressionEvaluation: this.enableExpressionEvaluation }, this.expressions); + } + parseForm(formCloudRepresentationJSON?: any): FormModel | null { if (formCloudRepresentationJSON) { const formValues: FormValues = {}; @@ -568,7 +595,6 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, checkVisibility(field: FormFieldModel) { if (field?.form) { this.visibilityService.refreshVisibility(field.form); - this.recomputeVisibleOutcomes(); } } @@ -586,7 +612,6 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, this.setCheckParentVisibilityForValidationOnFields(); this.visibilityService.refreshVisibility(this.form); this.form.validateForm(); - this.recomputeVisibleOutcomes(); this.onFormLoaded(this.form); this.formService.formRulesEvent.next(new FormRulesEvent('dataRefreshed', new FormEvent(this.form))); this.onFormDataRefreshed(this.form); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html index 0fea08b342..cb90cebccc 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html @@ -1,21 +1,26 @@
-
-
@@ -34,12 +39,15 @@ (contentModelFileHandler)="contentModelFormFileHandler($event)" (removeAttachFile)="onRemoveAttachFile($event)" /> -
- {{ 'FORM.FIELD.NO_FILE_ATTACHED' | translate }} -
- + @if (!hasFile && field.readOnly) { +
+ {{ 'FORM.FIELD.NO_FILE_ATTACHED' | translate }} +
+ }
- - +
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.html index 4bc5484ca1..a973a54176 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.html @@ -1,31 +1,23 @@
- +
- + @if (!previewState) { - + - - - - + [required]="dataTableLoadFailed ? ('FORM.FIELD.DATA_TABLE_LOAD_FAILED' | translate) : ''" + /> + } @else {
-
+ }
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.scss b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.scss index 532599f8e3..ed9398c207 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.scss +++ b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.scss @@ -1,4 +1,5 @@ .adf-data-table-widget-failed-message { + display: block; margin: 10px; } diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.spec.ts index 2ec50a2d85..f770440650 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.spec.ts @@ -283,7 +283,8 @@ describe('DataTableWidgetComponent', () => { const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-data-table-widget-failed-message')); assertData(mockCountryColumns, []); - expect(failedErrorMsgElement).toBeNull(); + expect(failedErrorMsgElement).toBeTruthy(); + expect(failedErrorMsgElement.nativeElement.textContent.trim()).toBe(''); }); it('path points to single object with appropriate schema definition', () => { @@ -294,7 +295,8 @@ describe('DataTableWidgetComponent', () => { const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-data-table-widget-failed-message')); assertData(mockCountryColumns, [mockEuropeCountriesRows[1]]); - expect(failedErrorMsgElement).toBeNull(); + expect(failedErrorMsgElement).toBeTruthy(); + expect(failedErrorMsgElement.nativeElement.textContent.trim()).toBe(''); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.ts index 15034eed76..a49c9ade68 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/data-table/data-table.widget.ts @@ -27,7 +27,6 @@ import { NoContentTemplateDirective, EmptyContentComponent } from '@alfresco/adf-core'; -import { NgIf } from '@angular/common'; import { TranslatePipe } from '@ngx-translate/core'; import { FormCloudService } from '../../../services/form-cloud.service'; import { TaskVariableCloud } from '../../../models/task-variable-cloud.model'; @@ -36,7 +35,7 @@ import { DataTablePathParserHelper } from './helpers/data-table-path-parser.help @Component({ standalone: true, - imports: [NgIf, TranslatePipe, FormBaseModule, DataTableComponent, NoContentTemplateDirective, EmptyContentComponent], + imports: [TranslatePipe, FormBaseModule, DataTableComponent, NoContentTemplateDirective, EmptyContentComponent], selector: 'data-table', templateUrl: './data-table.widget.html', styleUrls: ['./data-table.widget.scss'], diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.spec.ts index 80062e72f7..cc646237b5 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.spec.ts @@ -200,6 +200,51 @@ describe('DisplayRichTextWidgetComponent', () => { expect(widget.field.value.blocks[0].data.text).toBe('Hello John'); }); + it('should resolve from authored value after saved data rehydrates the field', () => { + const form = new FormModel( + { + fields: [ + { + id: 'richText1', + name: 'richText1', + type: 'display-rich-text', + value: { + blocks: [{ type: 'paragraph', data: { text: 'Hello ${field.name}' } }] + } + }, + { id: 'name', name: 'name', type: 'text', value: 'John' } + ] + }, + { + richText1: { + blocks: [{ type: 'paragraph', data: { text: 'Hello John' } }] + }, + name: 'Jane' + } + ); + + widget.field = form.getFieldById('richText1'); + fixture.detectChanges(); + + expect(widget.field.value.blocks[0].data.text).toBe('Hello Jane'); + }); + + it('should preserve the current value when the authored value is unavailable', () => { + const form = new FormModel({ + fields: [{ id: 'richText1', type: 'display-rich-text' }] + }); + const currentValue = { + blocks: [{ type: 'paragraph', data: { text: 'Current value' } }] + }; + const field = form.getFieldById('richText1'); + field.value = currentValue; + widget.field = field; + + fixture.detectChanges(); + + expect(widget.field.value).toBe(currentValue); + }); + it('should resolve expressions in multiple blocks', () => { const form = new FormModel({ fields: [ diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts index 92708cf69c..785059ac9f 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts @@ -22,6 +22,7 @@ import { BaseDisplayTextWidgetComponent } from '@alfresco/adf-core'; import { DomSanitizer } from '@angular/platform-browser'; import { Subscription } from 'rxjs'; import { RichTextParserService } from '../../../services/rich-text-parser.service'; +import { resolveRichTextExpressions } from './rich-text-expression-resolver'; export const RICH_TEXT_PARSER_TOKEN = new InjectionToken('RichTextParserService', { factory: () => new RichTextParserService() @@ -66,7 +67,10 @@ export class DisplayRichTextWidgetComponent extends BaseDisplayTextWidgetCompone protected storeOriginalValue(): void { if (this.field) { - this.originalFieldValue = JSON.stringify(this.field.value); + const authoredValue = this.field.authoredValue; + if (authoredValue !== undefined) { + this.originalFieldValue = JSON.stringify(authoredValue); + } } } @@ -75,8 +79,10 @@ export class DisplayRichTextWidgetComponent extends BaseDisplayTextWidgetCompone return; } - const value = JSON.parse(JSON.stringify(this.field.value)); - this.applyExpressionsToBlocks(value); + const authoredValue = this.field.authoredValue; + if (authoredValue !== undefined) { + this.applyExpressionsToBlocks(authoredValue); + } } protected reevaluateExpressions(): void { @@ -89,16 +95,7 @@ export class DisplayRichTextWidgetComponent extends BaseDisplayTextWidgetCompone } private applyExpressionsToBlocks(value: any): void { - for (const block of value.blocks) { - if (block.type === 'list') { - for (const item of block.data.items) { - item.content = this.resolveExpressions(item.content, true); - } - } else { - block.data.text = this.resolveExpressions(block.data.text, true); - } - } - this.field.value = value; + this.field.value = resolveRichTextExpressions(value, (content) => this.resolveExpressions(content, true)); } private parseAndSanitize(): void { diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/rich-text-expression-resolver.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/rich-text-expression-resolver.spec.ts new file mode 100644 index 0000000000..07c3b3c5da --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/rich-text-expression-resolver.spec.ts @@ -0,0 +1,137 @@ +/*! + * @license + * Copyright Š 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { resolveRichTextExpressions } from './rich-text-expression-resolver'; + +describe('resolveRichTextExpressions', () => { + const resolve = (value: string) => value.replaceAll('${field.name}', 'John').replaceAll('${variable.status}', 'Active'); + + it('should resolve supported rich text content without mutating the input', () => { + const value = { + time: 1, + blocks: [ + { + type: 'paragraph', + data: { + text: 'Hello ${field.name}', + caption: 'Status: ${variable.status}', + content: [ + ['Cell ${field.name}'], + { + label: '${variable.status}' + } + ] + } + }, + { + type: 'list', + data: { + items: [ + { + content: '${field.name}', + items: [{ content: '${variable.status}' }] + } + ] + } + } + ], + version: '2.30.0' + }; + const originalValue = JSON.parse(JSON.stringify(value)); + + const result = resolveRichTextExpressions(value, resolve); + + expect(result).toEqual({ + time: 1, + blocks: [ + { + type: 'paragraph', + data: { + text: 'Hello John', + caption: 'Status: Active', + content: [['Cell John'], { label: 'Active' }] + } + }, + { + type: 'list', + data: { + items: [{ content: 'John', items: [{ content: 'Active' }] }] + } + } + ], + version: '2.30.0' + }); + expect(value).toEqual(originalValue); + expect(result).not.toBe(value); + }); + + it('should resolve a caller-owned clone without cloning it again', () => { + const value = { + blocks: [{ type: 'paragraph', data: { text: 'Hello ${field.name}' } }] + }; + + const result = resolveRichTextExpressions(value, resolve, { cloneValue: false }) as typeof value; + + expect(result).toBe(value); + expect(result.blocks[0].data.text).toBe('Hello John'); + }); + + it('should preserve unknown blocks and properties', () => { + const value = { + blocks: [ + { + type: 'custom', + data: { + label: '${field.name}' + }, + metadata: '${variable.status}' + } + ] + }; + + expect(resolveRichTextExpressions(value, resolve)).toEqual(value); + }); + + it('should not introduce missing content properties', () => { + const result = resolveRichTextExpressions({ blocks: [{ type: 'paragraph', data: {} }] }, resolve) as { + blocks: Array<{ data: Record }>; + }; + + expect(result.blocks[0].data).toEqual({}); + }); + + it('should return malformed values unchanged', () => { + const malformedValues = [null, undefined, 'text', [], {}, { blocks: null }]; + + malformedValues.forEach((value) => { + expect(resolveRichTextExpressions(value, resolve)).toBe(value); + }); + }); + + it('should return non-cloneable values without mutating them', () => { + const value: { + blocks: Array<{ data: { text: string } }>; + self?: unknown; + } = { + blocks: [{ data: { text: '${field.name}' } }] + }; + value.self = value; + + expect(resolveRichTextExpressions(value, resolve)).toBe(value); + expect(value.blocks[0].data.text).toBe('${field.name}'); + }); +}); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/rich-text-expression-resolver.ts b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/rich-text-expression-resolver.ts new file mode 100644 index 0000000000..9606b31f76 --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/components/widgets/display-rich-text/rich-text-expression-resolver.ts @@ -0,0 +1,111 @@ +/*! + * @license + * Copyright Š 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type JsonObject = Record; + +export type RichTextExpressionResolver = (value: string) => string; + +export interface RichTextExpressionResolverOptions { + cloneValue?: boolean; +} + +const isJsonObject = (value: unknown): value is JsonObject => typeof value === 'object' && value !== null && !Array.isArray(value); + +const cloneJsonValue = (value: unknown): unknown => { + try { + return JSON.parse(JSON.stringify(value)); + } catch { + return undefined; + } +}; + +const resolveNestedContent = (value: unknown, resolve: RichTextExpressionResolver): unknown => { + if (typeof value === 'string') { + return resolve(value); + } + + if (Array.isArray(value)) { + return value.map((entry) => resolveNestedContent(entry, resolve)); + } + + if (isJsonObject(value)) { + return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolveNestedContent(entry, resolve)])); + } + + return value; +}; + +const resolveListItems = (items: unknown, resolve: RichTextExpressionResolver): unknown => { + if (!Array.isArray(items)) { + return items; + } + + return items.map((item) => { + if (!isJsonObject(item)) { + return item; + } + + if (Object.hasOwn(item, 'content')) { + item.content = resolveNestedContent(item.content, resolve); + } + + if (Object.hasOwn(item, 'items')) { + item.items = resolveListItems(item.items, resolve); + } + + return item; + }); +}; + +export const resolveRichTextExpressions = ( + value: unknown, + resolve: RichTextExpressionResolver, + options: RichTextExpressionResolverOptions = {} +): unknown => { + if (!isJsonObject(value) || !Array.isArray(value.blocks)) { + return value; + } + + const resolvedValue = options.cloneValue === false ? value : cloneJsonValue(value); + if (!isJsonObject(resolvedValue) || !Array.isArray(resolvedValue.blocks)) { + return value; + } + + resolvedValue.blocks.forEach((block) => { + if (!isJsonObject(block) || !isJsonObject(block.data)) { + return; + } + + if (typeof block.data.text === 'string') { + block.data.text = resolve(block.data.text); + } + + if (typeof block.data.caption === 'string') { + block.data.caption = resolve(block.data.caption); + } + + if (Object.hasOwn(block.data, 'content')) { + block.data.content = resolveNestedContent(block.data.content, resolve); + } + + if (block.type === 'list' && Object.hasOwn(block.data, 'items')) { + block.data.items = resolveListItems(block.data.items, resolve); + } + }); + + return resolvedValue; +}; diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html index 83b2abe75f..e3ed0116de 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html @@ -4,11 +4,13 @@ [class.adf-readonly]="field.readOnly" [class.adf-left-label-input-container]="field.leftLabels" > -
- -
+ @if (field.leftLabels) { +
+ +
+ }
- -
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.spec.ts index 15ef00254b..6d6afa7d45 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.spec.ts @@ -141,8 +141,9 @@ describe('GroupCloudWidgetComponent', () => { fixture.detectChanges(); await fixture.whenStable(); - expect(element.querySelector('.adf-error-text')).toBeTruthy(); - expect(element.querySelector('.adf-error-text').textContent).toContain('ADF_CLOUD_GROUPS.ERROR.NOT_FOUND'); + const errorMessages = element.querySelectorAll('.adf-error-text'); + expect(errorMessages.length).toBe(1); + expect(errorMessages[0].textContent).toContain('ADF_CLOUD_GROUPS.ERROR.NOT_FOUND'); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts index f6555a01a7..c4c6a58a85 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts @@ -16,7 +16,7 @@ */ import { Component, DestroyRef, inject, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; -import { ErrorWidgetComponent, WidgetComponent } from '@alfresco/adf-core'; +import { WidgetComponent } from '@alfresco/adf-core'; import { UntypedFormControl } from '@angular/forms'; import { filter } from 'rxjs/operators'; import { ComponentSelectionMode } from '../../../../types'; @@ -31,7 +31,7 @@ import { GroupCloudComponent } from '../../../../group/components/group-cloud.co @Component({ selector: 'group-cloud-widget', - imports: [CommonModule, TranslatePipe, ErrorWidgetComponent, GroupCloudComponent], + imports: [CommonModule, TranslatePipe, GroupCloudComponent], templateUrl: './group-cloud.widget.html', host: { '(click)': 'event($event)', diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html index 399f01aca0..457aad503a 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html @@ -1,10 +1,16 @@ -
-
- -
+
+ @if (field.leftLabels) { +
+ +
+ }
- -
- diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.spec.ts index 981033fdea..eb0d49d3bf 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.spec.ts @@ -171,8 +171,9 @@ describe('PeopleCloudWidgetComponent', () => { fixture.detectChanges(); await fixture.whenStable(); - expect(element.querySelector('.adf-error-text')).toBeTruthy(); - expect(element.querySelector('.adf-error-text').textContent).toContain('ADF_CLOUD_USERS.ERROR.NOT_FOUND'); + const errorMessages = element.querySelectorAll('.adf-error-text'); + expect(errorMessages.length).toBe(1); + expect(errorMessages[0].textContent).toContain('ADF_CLOUD_USERS.ERROR.NOT_FOUND'); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts index 976e4f3c0b..e849ff395e 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts @@ -16,7 +16,7 @@ */ import { Component, DestroyRef, inject, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; -import { ErrorWidgetComponent, WidgetComponent } from '@alfresco/adf-core'; +import { WidgetComponent } from '@alfresco/adf-core'; import { UntypedFormControl } from '@angular/forms'; import { filter } from 'rxjs/operators'; import { ComponentSelectionMode } from '../../../../types'; @@ -27,13 +27,12 @@ import { ReactivePreselectionService } from '../reactive-preselection.service'; import { CommonModule } from '@angular/common'; import { TranslatePipe } from '@ngx-translate/core'; import { PeopleCloudComponent } from '../../../../people/components/people-cloud.component'; -import { MatFormFieldModule } from '@angular/material/form-field'; /* eslint-disable @angular-eslint/component-selector */ @Component({ selector: 'people-cloud-widget', - imports: [CommonModule, TranslatePipe, ErrorWidgetComponent, PeopleCloudComponent, MatFormFieldModule], + imports: [CommonModule, TranslatePipe, PeopleCloudComponent], templateUrl: './people-cloud.widget.html', host: { '(click)': 'event($event)', diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss index 3e2ae3f677..ae2d2c54f7 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss @@ -11,7 +11,6 @@ } &-radio-button-container-horizontal { - margin-bottom: 15px; display: flex; flex-flow: column wrap; align-items: flex-start; diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.html index 6b8cb1a67d..ed73ace101 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.html @@ -4,51 +4,50 @@ >
- - - - {{file.name}} - - - + @if (hasFile) { + + + + {{file.name}} + @if (!field.readOnly) { + + } + + + }
-
- -
- -
{{ 'FORM.FIELD.NO_FILE_ATTACHED' | translate }}
+ @if ((!hasFile || multipleOption) && !field.readOnly) { +
+ +
+ } @if (!hasFile && field.readOnly) { +
{{ 'FORM.FIELD.NO_FILE_ATTACHED' | translate }}
+ }
- - +
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.spec.ts index 61e4537d8d..39f922fcfd 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/upload/upload-cloud.widget.spec.ts @@ -55,4 +55,12 @@ describe('UploadCloudWidgetComponent', () => { expect(eventSpy).toHaveBeenCalledWith(clickEvent); }); }); + + it('should render one reserved form field status area', () => { + widget.field = new FormFieldModel(new FormModel(), {}); + fixture.detectChanges(); + + const statusAreas = fixture.nativeElement.querySelectorAll('error-widget'); + expect(statusAreas.length).toBe(1); + }); }); diff --git a/lib/process-services-cloud/src/lib/form/public-api.ts b/lib/process-services-cloud/src/lib/form/public-api.ts index 758c688f72..10256da84f 100644 --- a/lib/process-services-cloud/src/lib/form/public-api.ts +++ b/lib/process-services-cloud/src/lib/form/public-api.ts @@ -43,5 +43,6 @@ export * from './services/form-cloud.service'; export * from './services/content-cloud-node-selector.service'; export * from './services/process-cloud-content.service'; export * from './services/display-mode.service'; +export * from './services/form-cloud-submission-values'; export * from './form-cloud.module'; diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud-submission-values.spec.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud-submission-values.spec.ts new file mode 100644 index 0000000000..c5df7f6b1e --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/services/form-cloud-submission-values.spec.ts @@ -0,0 +1,185 @@ +/*! + * @license + * Copyright Š 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestBed } from '@angular/core/testing'; +import { FormExpressionService, FormFieldModel, FormFieldTypes, FormModel } from '@alfresco/adf-core'; +import { firstValueFrom, of } from 'rxjs'; +import { getExpressionEvaluationEnabled$, materializeSubmissionValues } from './form-cloud-submission-values'; + +describe('getExpressionEvaluationEnabled$', () => { + it('should return the configured static value', async () => { + const enabled = await firstValueFrom(getExpressionEvaluationEnabled$({ enableExpressionEvaluation: true })); + + expect(enabled).toBe(true); + }); + + it('should return values emitted by observable settings', async () => { + const enabled = await firstValueFrom(getExpressionEvaluationEnabled$(of({ enableExpressionEvaluation: true }))); + + expect(enabled).toBe(true); + }); + + it('should return false when settings are unavailable', async () => { + const enabled = await firstValueFrom(getExpressionEvaluationEnabled$(undefined)); + + expect(enabled).toBe(false); + }); +}); + +describe('materializeSubmissionValues', () => { + let expressions: FormExpressionService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [FormExpressionService] + }); + expressions = TestBed.inject(FormExpressionService); + }); + + it('should resolve root rich text values from the authored template without mutating the form', () => { + const authoredValue = { + blocks: [ + { + type: 'paragraph', + data: { + text: 'Hello ${field.name} - ${variable.status} - ${field.missing} - ${field.unsafe}' + } + } + ] + }; + const form = new FormModel({ + fields: [ + { id: 'richText', name: 'richText', type: FormFieldTypes.DISPLAY_RICH_TEXT, value: authoredValue }, + { id: 'name', name: 'name', type: FormFieldTypes.TEXT, value: 'John' }, + { id: 'unsafe', name: 'unsafe', type: FormFieldTypes.TEXT, value: 'John' } + ], + variables: [{ id: 'status', name: 'status', type: 'string', value: 'Active' }] + }); + const richTextField = form.getFieldById('richText'); + richTextField.value = { blocks: [{ type: 'paragraph', data: { text: 'stale rendered value' } }] }; + const originalValues = JSON.parse(JSON.stringify(form.values)); + const originalDefinition = JSON.parse(JSON.stringify(form.json)); + + const values = materializeSubmissionValues(form, { enableExpressionEvaluation: true }, expressions); + + expect(values.richText).toEqual({ + blocks: [ + { + type: 'paragraph', + data: { + text: 'Hello John - Active - - <b>John</b>' + } + } + ] + }); + expect(form.values).toEqual(originalValues); + expect(form.json).toEqual(originalDefinition); + expect(richTextField.value).toEqual({ blocks: [{ type: 'paragraph', data: { text: 'stale rendered value' } }] }); + }); + + it('should produce stable values across repeated materialization', () => { + const form = new FormModel({ + fields: [ + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: '${field.name}' } }] } + }, + { id: 'name', type: FormFieldTypes.TEXT, value: 'John' } + ] + }); + + const firstValues = materializeSubmissionValues(form, { enableExpressionEvaluation: true }, expressions); + const secondValues = materializeSubmissionValues(form, { enableExpressionEvaluation: true }, expressions); + + expect(secondValues).toEqual(firstValues); + }); + + it('should return a shallow clone without resolving expressions when evaluation is disabled', () => { + const form = new FormModel({ + fields: [ + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: '${field.name}' } }] } + }, + { id: 'name', type: FormFieldTypes.TEXT, value: 'John' } + ] + }); + + const values = materializeSubmissionValues(form, { enableExpressionEvaluation: false }, expressions); + + expect(values).toEqual(form.values); + expect(values).not.toBe(form.values); + expect(values.richText).toBe(form.values.richText); + }); + + it('should isolate materialized repeatable section rows', () => { + const form = new FormModel(); + form.values = { + section: [ + { richText: 'saved row one', untouched: 'one' }, + { richText: 'saved row two', untouched: 'two' } + ], + name: 'John' + }; + const nameField = new FormFieldModel(form, { id: 'name', type: FormFieldTypes.TEXT, value: 'John' }); + const firstField = new FormFieldModel( + form, + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: 'First ${field.name}' } }] } + }, + { id: 'section', uid: 'richText-Row1', fields: {}, rowIndex: 0 } + ); + const secondField = new FormFieldModel( + form, + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: 'Second ${field.name}' } }] } + }, + { id: 'section', uid: 'richText-Row2', fields: {}, rowIndex: 1 } + ); + form.fieldsCache = [nameField, firstField, secondField]; + form.values.section = [ + { richText: 'saved row one', untouched: 'one' }, + { richText: 'saved row two', untouched: 'two' } + ]; + const originalSection = form.values.section; + const originalFirstRow = form.values.section[0]; + const originalSecondRow = form.values.section[1]; + + const values = materializeSubmissionValues(form, { enableExpressionEvaluation: true }, expressions); + + expect(values.section).toEqual([ + { + richText: { blocks: [{ type: 'paragraph', data: { text: 'First John' } }] }, + untouched: 'one' + }, + { + richText: { blocks: [{ type: 'paragraph', data: { text: 'Second John' } }] }, + untouched: 'two' + } + ]); + expect(values.section).not.toBe(originalSection); + expect(values.section[0]).not.toBe(originalFirstRow); + expect(values.section[1]).not.toBe(originalSecondRow); + expect(form.values.section).toBe(originalSection); + }); +}); diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud-submission-values.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud-submission-values.ts new file mode 100644 index 0000000000..a43709e4e2 --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/services/form-cloud-submission-values.ts @@ -0,0 +1,80 @@ +/*! + * @license + * Copyright Š 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DisplayTextWidgetSettings, FormExpressionService, FormFieldTypes, FormModel, FormValues, ROW_ID_PREFIX } from '@alfresco/adf-core'; +import { isObservable, Observable, of } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { resolveRichTextExpressions } from '../components/widgets/display-rich-text/rich-text-expression-resolver'; + +type SubmissionRow = Record; + +const isSubmissionRow = (value: unknown): value is SubmissionRow => typeof value === 'object' && value !== null && !Array.isArray(value); + +export interface FormCloudSubmissionValuesOptions { + enableExpressionEvaluation: boolean; +} + +export const getExpressionEvaluationEnabled$ = ( + settings: Observable | DisplayTextWidgetSettings | null | undefined +): Observable => + isObservable(settings) + ? settings.pipe(map((value) => value?.enableExpressionEvaluation ?? false)) + : of(settings?.enableExpressionEvaluation ?? false); + +export const materializeSubmissionValues = ( + form: FormModel, + options: FormCloudSubmissionValuesOptions, + expressions: FormExpressionService +): FormValues => { + const values = { ...form.values }; + + if (!options.enableExpressionEvaluation) { + return values; + } + + for (const field of form.getFormFields([FormFieldTypes.DISPLAY_RICH_TEXT])) { + const { authoredValue, parent } = field; + if (authoredValue === undefined || parent?.isTemplate) { + continue; + } + + const materializedValue = resolveRichTextExpressions(authoredValue, (content) => expressions.resolveExpressions(form, content, true), { + cloneValue: false + }); + + if (!parent) { + values[field.id] = materializedValue; + continue; + } + + const sectionValues = values[parent.id]; + const sectionRow = Array.isArray(sectionValues) ? sectionValues[parent.rowIndex] : undefined; + if (!isSubmissionRow(sectionRow)) { + continue; + } + + const materializedRows = [...sectionValues]; + const fieldId = field.id.split(ROW_ID_PREFIX)[0]; + materializedRows[parent.rowIndex] = { + ...sectionRow, + [fieldId]: materializedValue + }; + values[parent.id] = materializedRows; + } + + return values; +}; diff --git a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.html b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.html index 759941de30..d903177dbb 100644 --- a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.html +++ b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.html @@ -1,27 +1,37 @@
- - @if (label || required) { {{label}} } + + @if (label || required) { + {{ label }} + } - {{group.name}} - + title="{{ (group.readonly ? 'ADF_CLOUD_GROUPS.MANDATORY' : '') | translate }}" + > + {{ group.name }} + @if (!(group.readonly || readOnly)) { + + } - + - - -
- - {{group.name}} + data-automation-id="adf-cloud-group-autocomplete" + > + @if ((searchGroups$ | async)?.length) { + +
+ + {{ group.name }}
- + } @else { + + } - - {{ 'ADF_CLOUD_GROUPS.ERROR.NOT_FOUND' | translate }} - + @if (searchGroupsControl.hasError('searchTypingError') && !searchLoading) { + + {{ 'ADF_CLOUD_GROUPS.ERROR.NOT_FOUND' | translate }} + + } - -
- - -
{{ 'ADF_CLOUD_GROUPS.ERROR.NOT_FOUND' | translate }}
-
- - -
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_PATTERN' | translate: { pattern: getValidationPattern() } }}
+ @if (validationLoading) { + + } + @if (hasPreselectError() && !isValidationLoading()) { + + +
{{ 'ADF_CLOUD_GROUPS.ERROR.NOT_FOUND' | translate }}
- - -
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MAX_LENGTH' | translate: { requiredLength: getValidationMaxLength() } }}
-
- - -
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MIN_LENGTH' | translate: { requiredLength: getValidationMinLength() } }}
-
- - -
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.REQUIRED' | translate }}
-
- - -
{{ 'ADF_CLOUD_GROUPS.ERROR.NOT_FOUND' | translate }}
-
+ } + @if (searchGroupsControl.hasError('pattern')) { + + +
+ {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_PATTERN' | translate: { pattern: getValidationPattern() } }} +
+
+ } + @if (searchGroupsControl.hasError('maxlength')) { + + +
+ {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MAX_LENGTH' | translate: { requiredLength: getValidationMaxLength() } }} +
+
+ } + @if (searchGroupsControl.hasError('minlength')) { + + +
+ {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MIN_LENGTH' | translate: { requiredLength: getValidationMinLength() } }} +
+
+ } + @if ((searchGroupsControl.hasError('required') || groupChipsCtrl.hasError('required')) && isDirty()) { + + +
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.REQUIRED' | translate }}
+
+ } + @if (searchGroupsControl.hasError('searchTypingError') && !this.isFocused) { + + +
{{ 'ADF_CLOUD_GROUPS.ERROR.NOT_FOUND' | translate }}
+
+ }
diff --git a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.scss b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.scss index a9cdd5daad..7cca3876c9 100644 --- a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.scss +++ b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.scss @@ -57,10 +57,12 @@ } } -.adf-error-messages-container .adf-error-icon { - @include mixins.adf-error-icon; -} +.adf-error-messages-container { + .adf-error-icon { + @include mixins.adf-error-icon; + } -.adf-error-messages-container .adf-error { - animation: slide-down-fade-in 300ms cubic-bezier(0.55, 0, 0.55, 0.2); + .adf-error { + animation: slide-down-fade-in 300ms cubic-bezier(0.55, 0, 0.55, 0.2); + } } diff --git a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.spec.ts index 09d88fe3f2..2c37fff1ca 100644 --- a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.spec.ts @@ -27,6 +27,8 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { MatChipHarness } from '@angular/material/chips/testing'; import { MatIconHarness } from '@angular/material/icon/testing'; import { MatInputHarness } from '@angular/material/input/testing'; +import { MatFormField } from '@angular/material/form-field'; +import { MatProgressBar } from '@angular/material/progress-bar'; describe('GroupCloudComponent', () => { let loader: HarnessLoader; @@ -98,6 +100,22 @@ describe('GroupCloudComponent', () => { expect(await inputElement.getPlaceholder()).toEqual(''); }); + it('should use dynamic form field subscript sizing', () => { + fixture.detectChanges(); + + const formField = fixture.debugElement.query(By.directive(MatFormField)).componentInstance as MatFormField; + expect(formField.subscriptSizing).toBe('dynamic'); + }); + + it('should render validation progress inside the reserved status area', () => { + component.validationLoading = true; + fixture.detectChanges(); + + const progressBar = fixture.debugElement.query(By.directive(MatProgressBar)); + + expect(progressBar.parent.classes['adf-error-messages-container']).toBeTrue(); + }); + describe('Search group', () => { beforeEach(() => { fixture.detectChanges(); diff --git a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.html b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.html index e71ef489b3..c2b2633fe4 100644 --- a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.html +++ b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.html @@ -4,10 +4,14 @@ class="adf-people-cloud adf-form-field-input" [class.adf-invalid]="hasError() && isDirty()" > - - {{label}} - - {{ title | translate }} + @if (!title) { + + {{ label }} + + } + @if (title) { + {{ title | translate }} + } {{ user | fullName }} - + @if (!(user.readonly || readOnly)) { + + } - + @if ((searchUsers$ | async)?.length) {
-
- {{ user | fullName : true }} +
+ {{ user | fullName: true }}
-
+ } @else { + + } - - {{ 'ADF_CLOUD_USERS.ERROR.NOT_FOUND' | translate : { userName: searchedValue } }} - + @if (searchUserCtrl.hasError('searchTypingError') && !searchLoading) { + + {{ 'ADF_CLOUD_USERS.ERROR.NOT_FOUND' | translate: { userName: searchedValue } }} + + } - - -
- - -
{{ 'ADF_CLOUD_USERS.ERROR.NOT_FOUND' | translate : { userName: validateUsersMessage } }}
-
- - -
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_PATTERN' | translate : { pattern: getValidationPattern() } }}
-
- - -
- {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MAX_LENGTH' | translate : { requiredLength: getValidationMaxLength() } }} -
-
- - -
- {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MIN_LENGTH' | translate : { requiredLength: getValidationMinLength() } }} -
-
- - -
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.REQUIRED' | translate }}
-
- - -
{{ 'ADF_CLOUD_USERS.ERROR.NOT_FOUND' | translate : { userName: searchedValue } }}
-
+
+ @if (validationLoading) { + + } + @if (showErrors) { + @if (hasPreselectError() && !isValidationLoading()) { + + +
{{ 'ADF_CLOUD_USERS.ERROR.NOT_FOUND' | translate: { userName: validateUsersMessage } }}
+
+ } + @if (searchUserCtrl.hasError('pattern')) { + + +
+ {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_PATTERN' | translate: { pattern: getValidationPattern() } }} +
+
+ } + @if (searchUserCtrl.hasError('maxlength')) { + + +
+ {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MAX_LENGTH' | translate: { requiredLength: getValidationMaxLength() } }} +
+
+ } + @if (searchUserCtrl.hasError('minlength')) { + + +
+ {{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.INVALID_MIN_LENGTH' | translate: { requiredLength: getValidationMinLength() } }} +
+
+ } + @if ((searchUserCtrl.hasError('required') || userChipsCtrl.hasError('required')) && isDirty()) { + + +
{{ 'ADF_CLOUD_PEOPLE_GROUPS.ERROR.REQUIRED' | translate }}
+
+ } + @if (searchUserCtrl.hasError('searchTypingError') && !this.isFocused) { + + +
{{ 'ADF_CLOUD_USERS.ERROR.NOT_FOUND' | translate: { userName: searchedValue } }}
+
+ } + }
diff --git a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts index 3b99609dd0..98381d0c34 100644 --- a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts @@ -27,6 +27,7 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { MatChipHarness } from '@angular/material/chips/testing'; import { MatInputHarness } from '@angular/material/input/testing'; import { MatFormFieldHarness } from '@angular/material/form-field/testing'; +import { MatProgressBar } from '@angular/material/progress-bar'; import { IdentityUserService } from '../services/identity-user.service'; describe('PeopleCloudComponent', () => { @@ -99,6 +100,19 @@ describe('PeopleCloudComponent', () => { expect(await inputField.getLabel()).toEqual('TITLE_KEY'); }); + it('should use dynamic form field subscript sizing by default', () => { + expect(component.formFieldSubscriptSizing).toBe('dynamic'); + }); + + it('should render validation progress inside the reserved status area', () => { + component.validationLoading = true; + fixture.detectChanges(); + + const progressBar = fixture.debugElement.query(By.directive(MatProgressBar)); + + expect(progressBar.parent.classes['adf-error-messages-container']).toBeTrue(); + }); + describe('Search user', () => { beforeEach(() => { fixture.detectChanges(); diff --git a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts index 5a11dd42e7..62a47a8af9 100644 --- a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts @@ -169,7 +169,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit { * Material form field subscript sizing (fixed / dynamic) */ @Input() - formFieldSubscriptSizing: SubscriptSizing = 'fixed'; + formFieldSubscriptSizing: SubscriptSizing = 'dynamic'; /** * Show errors under the form field diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts index 71136e5c5b..0f9559bc03 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts @@ -17,8 +17,8 @@ import { DebugElement, SimpleChange } from '@angular/core'; import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; -import { FormModel, FormOutcomeEvent, FormOutcomeModel } from '@alfresco/adf-core'; -import { of, throwError } from 'rxjs'; +import { ADF_DISPLAY_TEXT_SETTINGS, FormFieldTypes, FormModel, FormOutcomeEvent, FormOutcomeModel } from '@alfresco/adf-core'; +import { Subject, of, throwError } from 'rxjs'; import { StartProcessCloudService } from '../services/start-process-cloud.service'; import { FormCloudService } from '../../../form/services/form-cloud.service'; import { FormCloudComponent } from '../../../form/components/form-cloud.component'; @@ -47,7 +47,7 @@ import { HarnessLoader } from '@angular/cdk/testing'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing'; import { MatButtonHarness } from '@angular/material/button/testing'; -import { FormCloudDisplayMode } from '../../../services/form-fields.interfaces'; +import { FormCloudDisplayMode, FormContent } from '../../../services/form-fields.interfaces'; import { MatDialogHarness } from '@angular/material/dialog/testing'; import { MatDialog } from '@angular/material/dialog'; import { ReactiveFormsModule } from '@angular/forms'; @@ -92,7 +92,10 @@ describe('StartProcessCloudComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [StartProcessCloudComponent, ReactiveFormsModule, StartProcessScreenCloudComponent], - providers: [provideScreen(screenId, MockedTaskScreenCloudComponent)] + providers: [ + provideScreen(screenId, MockedTaskScreenCloudComponent), + { provide: ADF_DISPLAY_TEXT_SETTINGS, useValue: { enableExpressionEvaluation: true } } + ] }); processService = TestBed.inject(StartProcessCloudService); formCloudService = TestBed.inject(FormCloudService); @@ -417,6 +420,54 @@ describe('StartProcessCloudComponent', () => { expect(startBtn.disabled).toBe(false); }); + it('should keep the start action unavailable while the form definition is loading', async () => { + const formDefinition = new Subject(); + formDefinitionSpy.and.returnValue(formDefinition); + typeValueInto('[data-automation-id="adf-inplace-input"]', 'My new process with form'); + await selectOptionByName('processwithform'); + + const startButton = fixture.nativeElement.querySelector('#button-start'); + expect(startButton).toBeNull(); + expect(startProcessWithFormSpy).not.toHaveBeenCalled(); + }); + + it('should materialize unrendered rich text expressions when starting a process', async () => { + formDefinitionSpy.and.returnValue(of(fakeStartForm)); + component.processDefinitionCurrent = fakeProcessDefinitions[2]; + component.processPayloadCloud.processDefinitionKey = fakeProcessDefinitions[2].key; + component.processInstanceName.setValue('My process'); + fixture.detectChanges(); + await fixture.whenStable(); + + const form = new FormModel({ + fields: [ + { + id: 'richText', + type: FormFieldTypes.DISPLAY_RICH_TEXT, + value: { blocks: [{ type: 'paragraph', data: { text: 'Hello ${field.name}' } }] } + }, + { id: 'name', type: FormFieldTypes.TEXT, value: 'John' } + ] + }); + const formElement = fixture.debugElement.query(By.css('adf-cloud-form')); + const startButton = fixture.debugElement.query(By.css('#button-start')); + + formElement.triggerEventHandler('formLoaded', form); + fixture.detectChanges(); + startButton.triggerEventHandler('click', null); + + expect(startProcessWithFormSpy).toHaveBeenCalledWith( + component.appName, + fakeProcessDefinitions[2].formKey, + fakeProcessDefinitions[2].version, + jasmine.objectContaining({ + values: jasmine.objectContaining({ + richText: { blocks: [{ type: 'paragraph', data: { text: 'Hello John' } }] } + }) + }) + ); + }); + it('should be able to start a process with form full display mode', async () => { component.displayModeConfigurations = [ { diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts index c06299d703..40126c5722 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts @@ -30,10 +30,14 @@ import { ViewEncapsulation } from '@angular/core'; import { + ADF_DISPLAY_TEXT_SETTINGS, ConfirmDialogComponent, ContentLinkModel, + DisplayTextWidgetSettings, + FormExpressionService, FormModel, FormOutcomeEvent, + FormValues, IconModule, InplaceFormInputComponent, LocalizedDatePipe, @@ -65,6 +69,7 @@ import { FormCustomOutcomesComponent } from '../../../form/components/form-cloud import { MatDialog } from '@angular/material/dialog'; import { StartProcessScreenCloudComponent } from '../../../screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component'; import { TaskTypeResolverService } from '../../../services/task-type-resolver/task-type-resolver.service'; +import { getExpressionEvaluationEnabled$, materializeSubmissionValues } from '../../../form/services/form-cloud-submission-values'; const MAX_NAME_LENGTH: number = 255; const PROCESS_DEFINITION_DEBOUNCE: number = 300; @@ -211,6 +216,11 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { private readonly hasVisibleOutcomesSubject = new BehaviorSubject(false); private readonly dialog = inject(MatDialog); private readonly taskTypeResolverService = inject(TaskTypeResolverService); + private readonly expressions = inject(FormExpressionService); + private readonly displayTextSettings = inject | DisplayTextWidgetSettings>(ADF_DISPLAY_TEXT_SETTINGS, { + optional: true + }); + private enableExpressionEvaluation = false; private screenSubmitPayload: unknown; @@ -218,8 +228,12 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { showCompleteButton = false; get isProcessFormValid(): boolean { - if (this.hasForm && this.isFormCloudLoaded) { - return (this.formCloud ? !Object.keys(this.formCloud.values).length : false) || this.formCloud?.isValid || this.isProcessStarting; + if (this.hasForm) { + if (!this.isFormCloudLoaded || !this.formCloud) { + return false; + } + + return !Object.keys(this.formCloud.values).length || this.formCloud.isValid || this.isProcessStarting; } else if (this.hasScreen) { return true; } else { @@ -268,6 +282,12 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { constructor() { this.startProcessButtonLabel = this.defaultStartProcessButtonLabel; this.cancelButtonLabel = this.defaultCancelProcessButtonLabel; + + getExpressionEvaluationEnabled$(this.displayTextSettings) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((enabled) => { + this.enableExpressionEvaluation = enabled; + }); } ngOnInit() { @@ -482,6 +502,14 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { } startProcessWithoutConfirmation() { + let submissionValues = this.screenSubmitPayload; + if (this.hasForm) { + if (!this.formCloud) { + return; + } + submissionValues = this.getFormSubmissionValues(this.formCloud); + } + this.isProcessStarting = true; let action: Observable; @@ -495,7 +523,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { processName: this.processInstanceName.value, processDefinitionKey: this.processPayloadCloud.processDefinitionKey, variables: this.variables ?? {}, - values: this.hasForm ? this.formCloud.values : this.screenSubmitPayload, + values: submissionValues, outcome: this.customOutcomeName }) ); @@ -524,6 +552,10 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { }); } + private getFormSubmissionValues(form: FormModel): FormValues { + return materializeSubmissionValues(form, { enableExpressionEvaluation: this.enableExpressionEvaluation }, this.expressions); + } + startProcess() { if (!this.formCloud?.confirmMessage?.show) { this.startProcessWithoutConfirmation(); diff --git a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.spec.ts new file mode 100644 index 0000000000..f1135da80e --- /dev/null +++ b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.spec.ts @@ -0,0 +1,198 @@ +/*! + * @license + * Copyright Š 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, ComponentRef, OnDestroy } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { BaseScreenCloudComponent } from './base-screen-cloud.component'; +import { provideScreen } from '../../../services/provide-screen'; +import { ScreenRenderingService } from '../../../services/screen-rendering.service'; + +@Component({ + selector: 'adf-cloud-test-dynamic-screen', + template: `
dynamic screen
` +}) +class TestDynamicScreenComponent implements OnDestroy { + destroyed = false; + + ngOnDestroy(): void { + this.destroyed = true; + } +} + +@Component({ + selector: 'adf-cloud-test-host-screen', + template: `` +}) +class TestHostScreenComponent extends BaseScreenCloudComponent { + setInputsCalls: ComponentRef[] = []; + subscribeToOutputsCalls: ComponentRef[] = []; + + get dynamicComponentRef(): ComponentRef | undefined { + return this.componentRef; + } + + get dynamicComponentRefSignalValue(): ComponentRef | undefined { + return this.componentRefChanged(); + } + + protected override setInputsForDynamicComponent(componentRef: ComponentRef): void { + this.setInputsCalls.push(componentRef); + } + + protected subscribeToOutputs(componentRef: ComponentRef): void { + this.subscribeToOutputsCalls.push(componentRef); + } +} + +/** Same host component, but without the `#container` anchor in its template. */ +@Component({ + selector: 'adf-cloud-test-host-screen-without-container', + template: `
` +}) +class TestHostScreenWithoutContainerComponent extends TestHostScreenComponent {} + +describe('BaseScreenCloudComponent', () => { + const screenId = 'test-screen'; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestHostScreenComponent, TestHostScreenWithoutContainerComponent, TestDynamicScreenComponent], + providers: [provideScreen(screenId, TestDynamicScreenComponent)] + }); + }); + + describe('when a screenId is provided', () => { + let fixture: ComponentFixture; + let component: TestHostScreenComponent; + + beforeEach(() => { + fixture = TestBed.createComponent(TestHostScreenComponent); + component = fixture.componentInstance; + fixture.componentRef.setInput('screenId', screenId); + fixture.detectChanges(); + }); + + it('should create the dynamic component and expose it through the signal', () => { + expect(component.dynamicComponentRef).toBeDefined(); + expect(component.dynamicComponentRefSignalValue).toBe(component.dynamicComponentRef); + expect(fixture.debugElement.query(By.css('.adf-cloud-test-dynamic-screen'))).toBeTruthy(); + }); + + it('should wire inputs and outputs once, passing the created component reference', () => { + expect(component.setInputsCalls).toEqual([component.dynamicComponentRef!]); + expect(component.subscribeToOutputsCalls).toEqual([component.dynamicComponentRef!]); + }); + + it('should destroy the dynamic component reference on destroy', () => { + const destroySpy = spyOn(component.dynamicComponentRef!, 'destroy').and.callThrough(); + + fixture.destroy(); + + expect(destroySpy).toHaveBeenCalledTimes(1); + }); + + it('should run the ngOnDestroy hook of the dynamic component on destroy', () => { + const dynamicComponentInstance = component.dynamicComponentRef?.instance; + expect(dynamicComponentInstance?.destroyed).toBeFalse(); + + fixture.destroy(); + + expect(dynamicComponentInstance?.destroyed).toBeTrue(); + }); + + it('should clear the dynamic component reference and the signal on destroy', () => { + fixture.destroy(); + + expect(component.dynamicComponentRef).toBeUndefined(); + expect(component.dynamicComponentRefSignalValue).toBeUndefined(); + }); + + it('should destroy the dynamic component reference only once when ngOnDestroy runs again', () => { + const destroySpy = spyOn(component.dynamicComponentRef!, 'destroy'); + + component.ngOnDestroy(); + component.ngOnDestroy(); + + expect(destroySpy).toHaveBeenCalledTimes(1); + }); + }); + + describe('when no screenId is provided', () => { + let fixture: ComponentFixture; + let component: TestHostScreenComponent; + + beforeEach(() => { + fixture = TestBed.createComponent(TestHostScreenComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should not create any dynamic component nor wire inputs and outputs', () => { + expect(component.dynamicComponentRef).toBeUndefined(); + expect(component.dynamicComponentRefSignalValue).toBeUndefined(); + expect(component.setInputsCalls).toEqual([]); + expect(component.subscribeToOutputsCalls).toEqual([]); + expect(fixture.debugElement.query(By.css('.adf-cloud-test-dynamic-screen'))).toBeNull(); + }); + + it('should not throw on destroy', () => { + expect(() => fixture.destroy()).not.toThrow(); + expect(component.dynamicComponentRef).toBeUndefined(); + }); + }); + + describe('when the container anchor is missing', () => { + let fixture: ComponentFixture; + let component: TestHostScreenWithoutContainerComponent; + + beforeEach(() => { + fixture = TestBed.createComponent(TestHostScreenWithoutContainerComponent); + component = fixture.componentInstance; + fixture.componentRef.setInput('screenId', screenId); + }); + + it('should not throw and should not create any dynamic component', () => { + expect(() => fixture.detectChanges()).not.toThrow(); + + expect(component.container).toBeUndefined(); + expect(component.dynamicComponentRef).toBeUndefined(); + expect(component.dynamicComponentRefSignalValue).toBeUndefined(); + }); + + it('should not wire inputs and outputs when no dynamic component was created', () => { + fixture.detectChanges(); + + expect(component.setInputsCalls).toEqual([]); + expect(component.subscribeToOutputsCalls).toEqual([]); + }); + + it('should not resolve any component type', () => { + const resolveComponentTypeSpy = spyOn(TestBed.inject(ScreenRenderingService), 'resolveComponentType').and.callThrough(); + + fixture.detectChanges(); + + expect(resolveComponentTypeSpy).not.toHaveBeenCalled(); + }); + + it('should not throw on destroy', () => { + fixture.detectChanges(); + + expect(() => fixture.destroy()).not.toThrow(); + }); + }); +}); diff --git a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.ts b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.ts index b00f85c4da..7da72468dc 100644 --- a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/base-screen/base-screen-cloud.component.ts @@ -15,20 +15,20 @@ * limitations under the License. */ -import { Component, ComponentRef, inject, Input, OnInit, signal, ViewChild, ViewContainerRef } from '@angular/core'; +import { Component, ComponentRef, inject, Input, OnDestroy, OnInit, signal, ViewChild, ViewContainerRef } from '@angular/core'; import { ScreenRenderingService } from '../../../services/screen-rendering.service'; @Component({ template: '' }) -export abstract class BaseScreenCloudComponent implements OnInit { +export abstract class BaseScreenCloudComponent implements OnInit, OnDestroy { @Input() screenId: string = ''; @ViewChild('container', { read: ViewContainerRef, static: true }) - container: ViewContainerRef; + container: ViewContainerRef | undefined; - protected componentRef: ComponentRef; + protected componentRef: ComponentRef | undefined; private readonly _componentRefChanged = signal | undefined>(undefined); protected readonly componentRefChanged = this._componentRefChanged.asReadonly(); protected readonly screenRenderingService = inject(ScreenRenderingService); @@ -37,17 +37,27 @@ export abstract class BaseScreenCloudComponent imple this.createDynamicComponent(); } - private createDynamicComponent(): void { - if (this.screenId) { - const componentType = this.screenRenderingService.resolveComponentType({ type: this.screenId }); - this.componentRef = this.container.createComponent(componentType); - this._componentRefChanged.set(this.componentRef); - this.setInputsForDynamicComponent(); - this.subscribeToOutputs(); - } + ngOnDestroy(): void { + this.componentRef?.destroy(); + this.componentRef = undefined; + this._componentRefChanged.set(undefined); } - protected setInputsForDynamicComponent(): void {} + private createDynamicComponent(): void { + if (!this.screenId || !this.container) { + return; + } - protected abstract subscribeToOutputs(): void; + const componentType = this.screenRenderingService.resolveComponentType({ type: this.screenId }); + const componentRef: ComponentRef = this.container.createComponent(componentType); + + this.componentRef = componentRef; + this._componentRefChanged.set(componentRef); + this.setInputsForDynamicComponent(componentRef); + this.subscribeToOutputs(componentRef); + } + + protected setInputsForDynamicComponent(_componentRef: ComponentRef): void {} + + protected abstract subscribeToOutputs(componentRef: ComponentRef): void; } diff --git a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.spec.ts index 937d1ad536..da37f04b9e 100644 --- a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.spec.ts @@ -16,6 +16,7 @@ */ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Component, Input, OnDestroy, input, output } from '@angular/core'; import { StartProcessScreenCloudComponent } from './start-process-screen-cloud.component'; import { MockedTaskScreenCloudComponent } from '../../../../testing/start-process-screen-mock.component'; import { provideScreen } from '../../../services/provide-screen'; @@ -66,11 +67,11 @@ describe('StartProcessScreenCloudComponent', () => { it('should set appName', () => { const screenInstance: StartProcessScreenCloud = fixture.debugElement.query(By.directive(MockedTaskScreenCloudComponent)).componentInstance; - expect(screenInstance.appName()).toEqual(''); + expect(screenInstance.appName?.()).toEqual(''); const newValue = 'new-app-name'; fixture.componentRef.setInput('appName', newValue); fixture.detectChanges(); - expect(screenInstance.appName()).toEqual(newValue); + expect(screenInstance.appName?.()).toEqual(newValue); }); it('should set process definition id', () => { @@ -84,10 +85,125 @@ describe('StartProcessScreenCloudComponent', () => { it('should set resolvedValues', () => { const screenInstance: StartProcessScreenCloud = fixture.debugElement.query(By.directive(MockedTaskScreenCloudComponent)).componentInstance; - expect(screenInstance.resolvedValues()).toBeUndefined(); + expect(screenInstance.resolvedValues?.()).toBeUndefined(); const newValues = [new TaskVariableCloud({ id: 'new-id', name: 'new-name' })]; fixture.componentRef.setInput('resolvedValues', newValues); fixture.detectChanges(); - expect(screenInstance.resolvedValues()).toEqual(newValues); + expect(screenInstance.resolvedValues?.()).toEqual(newValues); + }); +}); + +@Component({ + selector: 'adf-cloud-destroy-tracking-screen', + template: `
screen
` +}) +class DestroyTrackingScreenComponent implements StartProcessScreenCloud, OnDestroy { + readonly appName = input(''); + processDefinitionId = input(''); + readonly resolvedValues = input(); + defaultStartProcessButtonsConfigurationChange = output(); + startProcessPayloadChanged = output(); + + destroyed = false; + + ngOnDestroy(): void { + this.destroyed = true; + } +} + +@Component({ + selector: 'adf-cloud-test-start-process-wrapper', + template: ` + @if (showScreen) { + + } + `, + imports: [StartProcessScreenCloudComponent] +}) +class TestStartProcessWrapperComponent { + @Input() screenId = ''; + showScreen = true; +} + +describe('StartProcessScreenCloudComponent - destroy', () => { + let fixture: ComponentFixture; + let component: TestStartProcessWrapperComponent; + const screenId = 'screen-1234-5678-121212-123456'; + + const getScreenInstance = (): DestroyTrackingScreenComponent => + fixture.debugElement.query(By.directive(DestroyTrackingScreenComponent)).componentInstance; + + const destroyScreen = () => { + component.showScreen = false; + fixture.detectChanges(); + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestStartProcessWrapperComponent], + providers: [provideScreen(screenId, DestroyTrackingScreenComponent)] + }); + + fixture = TestBed.createComponent(TestStartProcessWrapperComponent); + component = fixture.componentInstance; + fixture.componentRef.setInput('screenId', screenId); + fixture.detectChanges(); + }); + + it('should destroy the screen component when the host is destroyed', () => { + const screenInstance = getScreenInstance(); + expect(screenInstance.destroyed).toBeFalse(); + + destroyScreen(); + + expect(screenInstance.destroyed).toBeTrue(); + }); + + it('should remove the screen component from the DOM when the host is destroyed', () => { + expect(fixture.debugElement.query(By.css('.adf-cloud-destroy-tracking-screen'))).toBeTruthy(); + + destroyScreen(); + + expect(fixture.debugElement.query(By.css('.adf-cloud-destroy-tracking-screen'))).toBeNull(); + }); + + it('should create a new screen component instance when the host is re-created', () => { + const firstInstance = getScreenInstance(); + + destroyScreen(); + component.showScreen = true; + fixture.detectChanges(); + + const secondInstance = getScreenInstance(); + expect(secondInstance).not.toBe(firstInstance); + expect(secondInstance.destroyed).toBeFalse(); + expect(secondInstance.processDefinitionId()).toBe('definition-id'); + }); +}); + +describe('StartProcessScreenCloudComponent - without screenId', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [StartProcessScreenCloudComponent] + }); + fixture = TestBed.createComponent(StartProcessScreenCloudComponent); + }); + + it('should not create any screen component and should not throw', () => { + expect(() => fixture.detectChanges()).not.toThrow(); + expect(fixture.debugElement.query(By.directive(DestroyTrackingScreenComponent))).toBeNull(); + }); + + it('should not throw when inputs change or on destroy', () => { + fixture.detectChanges(); + + expect(() => { + fixture.componentRef.setInput('appName', 'new-app-name'); + fixture.componentRef.setInput('resolvedValues', [new TaskVariableCloud({ id: 'id', name: 'name' })]); + fixture.detectChanges(); + }).not.toThrow(); + expect(() => fixture.destroy()).not.toThrow(); }); }); diff --git a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.ts b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.ts index 0f9c94dc81..ce069b6cdb 100644 --- a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, effect, input, output, signal } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ComponentRef, effect, input, output, signal } from '@angular/core'; import { BaseScreenCloudComponent } from '../base-screen/base-screen-cloud.component'; import { MatCardModule } from '@angular/material/card'; import { CommonModule } from '@angular/common'; @@ -43,7 +43,7 @@ export class StartProcessScreenCloudComponent extends BaseScreenCloudComponent { const componentRef = this.componentRefChanged(); - if (componentRef.instance && 'appName' in componentRef.instance) { + if (componentRef?.instance && 'appName' in componentRef.instance) { componentRef.setInput('appName', this.appName()); } }); @@ -56,9 +56,9 @@ export class StartProcessScreenCloudComponent extends BaseScreenCloudComponent this.screenStartProcessPayloadChange.emit(payload)); - this.componentRef.instance.defaultStartProcessButtonsConfigurationChange.subscribe((config) => { + protected subscribeToOutputs(componentRef: ComponentRef): void { + componentRef.instance.startProcessPayloadChanged.subscribe((payload) => this.screenStartProcessPayloadChange.emit(payload)); + componentRef.instance.defaultStartProcessButtonsConfigurationChange.subscribe((config) => { this.showStartProcessButtons.set(config.show); this.disableStartProcessButton.emit(config.disable); }); diff --git a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.spec.ts index 3bf74e8816..e271a8a6e6 100644 --- a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.spec.ts @@ -16,7 +16,7 @@ */ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, Output, ViewChild } from '@angular/core'; import { By } from '@angular/platform-browser'; import { ScreenRenderingService } from '../../../services/screen-rendering.service'; import { TaskScreenCloudComponent } from './screen-cloud.component'; @@ -32,18 +32,22 @@ import { TaskScreenCloudComponent } from './screen-cloud.component';
` }) -class TestComponent { +class TestComponent implements OnDestroy { @Input() taskId = ''; @Input() screenId = ''; @Input() rootProcessInstanceId = ''; @Output() taskCompleted = new EventEmitter(); - displayMode: string; + displayMode: string | undefined; + destroyed = false; onComplete() { this.taskCompleted.emit(); } switchToDisplayMode(newDisplayMode?: string) { this.displayMode = newDisplayMode; } + ngOnDestroy(): void { + this.destroyed = true; + } } @Component({ @@ -61,7 +65,7 @@ class TestComponent { }) class TestWrapperComponent { @Input() screenId = ''; - @ViewChild('adfCloudTaskScreen') adfCloudTaskScreen: TaskScreenCloudComponent; + @ViewChild('adfCloudTaskScreen') adfCloudTaskScreen: TaskScreenCloudComponent | undefined; onTaskCompleted() {} switchToDisplayMode(newDisplayMode?: string): void { if (this.adfCloudTaskScreen) { @@ -118,6 +122,118 @@ describe('TaskScreenCloudComponent', () => { component.switchToDisplayMode(); fixture.detectChanges(); - expect(component.adfCloudTaskScreen.switchToDisplayMode).toHaveBeenCalled(); + expect(component.adfCloudTaskScreen?.switchToDisplayMode).toHaveBeenCalled(); + }); +}); + +@Component({ + selector: 'adf-cloud-test-conditional-component', + template: ` + @if (showTaskScreen) { + + } + `, + imports: [TaskScreenCloudComponent] +}) +class TestConditionalWrapperComponent { + showTaskScreen = true; + onTaskCompleted() {} +} + +describe('TaskScreenCloudComponent - destroy', () => { + let fixture: ComponentFixture; + let component: TestConditionalWrapperComponent; + + const getDynamicComponentInstance = (): TestComponent => fixture.debugElement.query(By.directive(TestComponent)).componentInstance; + + const getTaskScreen = (): TaskScreenCloudComponent => fixture.debugElement.query(By.directive(TaskScreenCloudComponent)).componentInstance; + + const destroyTaskScreen = () => { + component.showTaskScreen = false; + fixture.detectChanges(); + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TaskScreenCloudComponent, TestComponent, TestConditionalWrapperComponent] + }); + TestBed.inject(ScreenRenderingService).register({ ['test']: () => TestComponent }); + + fixture = TestBed.createComponent(TestConditionalWrapperComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should destroy the dynamic component when the task screen is destroyed', () => { + const dynamicComponentInstance = getDynamicComponentInstance(); + expect(dynamicComponentInstance.destroyed).toBeFalse(); + + destroyTaskScreen(); + + expect(dynamicComponentInstance.destroyed).toBeTrue(); + }); + + it('should remove the dynamic component from the DOM when the task screen is destroyed', () => { + expect(fixture.debugElement.query(By.css('.adf-cloud-test-container'))).toBeTruthy(); + + destroyTaskScreen(); + + expect(fixture.debugElement.query(By.css('.adf-cloud-test-container'))).toBeNull(); + }); + + it('should not emit outputs of the dynamic component after the task screen is destroyed', () => { + const onTaskCompletedSpy = spyOn(component, 'onTaskCompleted'); + const dynamicComponentInstance = getDynamicComponentInstance(); + + destroyTaskScreen(); + dynamicComponentInstance.taskCompleted.emit(); + + expect(onTaskCompletedSpy).not.toHaveBeenCalled(); + }); + + it('should not call the dynamic component when switching display mode after destroy', () => { + const taskScreen = getTaskScreen(); + const switchToDisplayModeSpy = spyOn(getDynamicComponentInstance(), 'switchToDisplayMode'); + + destroyTaskScreen(); + + expect(() => taskScreen.switchToDisplayMode('mode')).not.toThrow(); + expect(switchToDisplayModeSpy).not.toHaveBeenCalled(); + }); + + it('should create a new dynamic component instance when the task screen is re-created', () => { + const firstInstance = getDynamicComponentInstance(); + + destroyTaskScreen(); + component.showTaskScreen = true; + fixture.detectChanges(); + + const secondInstance = getDynamicComponentInstance(); + expect(secondInstance).not.toBe(firstInstance); + expect(secondInstance.destroyed).toBeFalse(); + expect(secondInstance.taskId).toBe('1'); + }); +}); + +describe('TaskScreenCloudComponent - without screenId', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TaskScreenCloudComponent] + }); + fixture = TestBed.createComponent(TaskScreenCloudComponent); + }); + + it('should not create any dynamic component and should not throw', () => { + expect(() => fixture.detectChanges()).not.toThrow(); + expect(fixture.debugElement.query(By.directive(TestComponent))).toBeNull(); + }); + + it('should not throw when switching display mode or destroying', () => { + fixture.detectChanges(); + + expect(() => fixture.componentInstance.switchToDisplayMode('mode')).not.toThrow(); + expect(() => fixture.destroy()).not.toThrow(); }); }); diff --git a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.ts b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.ts index 14ad0b5893..5069d34735 100644 --- a/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/screen/components/screen-cloud/user-task-screen/screen-cloud.component.ts @@ -16,7 +16,7 @@ */ import { CommonModule } from '@angular/common'; -import { Component, DestroyRef, EventEmitter, inject, Input, Output } from '@angular/core'; +import { Component, ComponentRef, DestroyRef, EventEmitter, inject, Input, Output } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { UserTaskCustomUi } from './screen-cloud.model'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -102,65 +102,65 @@ export class TaskScreenCloudComponent extends BaseScreenCloudComponent): void { + if (this.taskId && Object.prototype.hasOwnProperty.call(componentRef.instance, 'taskId')) { + componentRef.setInput('taskId', this.taskId); } - if (this.appName && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'appName')) { - this.componentRef.setInput('appName', this.appName); + if (this.appName && Object.prototype.hasOwnProperty.call(componentRef.instance, 'appName')) { + componentRef.setInput('appName', this.appName); } - if (this.screenId && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'screenId')) { - this.componentRef.setInput('screenId', this.screenId); + if (this.screenId && Object.prototype.hasOwnProperty.call(componentRef.instance, 'screenId')) { + componentRef.setInput('screenId', this.screenId); } - if (this.processInstanceId && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'processInstanceId')) { - this.componentRef.setInput('processInstanceId', this.processInstanceId); + if (this.processInstanceId && Object.prototype.hasOwnProperty.call(componentRef.instance, 'processInstanceId')) { + componentRef.setInput('processInstanceId', this.processInstanceId); } - if (this.taskName && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'taskName')) { - this.componentRef.setInput('taskName', this.taskName); + if (this.taskName && Object.prototype.hasOwnProperty.call(componentRef.instance, 'taskName')) { + componentRef.setInput('taskName', this.taskName); } - if (this.canClaimTask && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'canClaimTask')) { - this.componentRef.setInput('canClaimTask', this.canClaimTask); + if (this.canClaimTask && Object.prototype.hasOwnProperty.call(componentRef.instance, 'canClaimTask')) { + componentRef.setInput('canClaimTask', this.canClaimTask); } - if (this.canUnclaimTask && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'canUnclaimTask')) { - this.componentRef.setInput('canUnclaimTask', this.canUnclaimTask); + if (this.canUnclaimTask && Object.prototype.hasOwnProperty.call(componentRef.instance, 'canUnclaimTask')) { + componentRef.setInput('canUnclaimTask', this.canUnclaimTask); } - if (this.showCancelButton && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'showCancelButton')) { - this.componentRef.setInput('showCancelButton', this.showCancelButton); + if (this.showCancelButton && Object.prototype.hasOwnProperty.call(componentRef.instance, 'showCancelButton')) { + componentRef.setInput('showCancelButton', this.showCancelButton); } - if (this.rootProcessInstanceId && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'rootProcessInstanceId')) { - this.componentRef.setInput('rootProcessInstanceId', this.rootProcessInstanceId); + if (this.rootProcessInstanceId && Object.prototype.hasOwnProperty.call(componentRef.instance, 'rootProcessInstanceId')) { + componentRef.setInput('rootProcessInstanceId', this.rootProcessInstanceId); } - if (this.showNextTaskCheckbox && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'showNextTaskCheckbox')) { - this.componentRef.setInput('showNextTaskCheckbox', this.showNextTaskCheckbox); + if (this.showNextTaskCheckbox && Object.prototype.hasOwnProperty.call(componentRef.instance, 'showNextTaskCheckbox')) { + componentRef.setInput('showNextTaskCheckbox', this.showNextTaskCheckbox); } - if (this.isNextTaskCheckboxChecked && Object.prototype.hasOwnProperty.call(this.componentRef.instance, 'isNextTaskCheckboxChecked')) { - this.componentRef.setInput('isNextTaskCheckboxChecked', this.isNextTaskCheckboxChecked); + if (this.isNextTaskCheckboxChecked && Object.prototype.hasOwnProperty.call(componentRef.instance, 'isNextTaskCheckboxChecked')) { + componentRef.setInput('isNextTaskCheckboxChecked', this.isNextTaskCheckboxChecked); } } - protected override subscribeToOutputs(): void { - if (this.componentRef.instance?.taskSaved) { - this.componentRef.instance.taskSaved.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.taskSaved.emit()); + protected override subscribeToOutputs(componentRef: ComponentRef): void { + if (componentRef.instance?.taskSaved) { + componentRef.instance.taskSaved.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.taskSaved.emit()); } - if (this.componentRef.instance?.taskCompleted) { - this.componentRef.instance.taskCompleted + if (componentRef.instance?.taskCompleted) { + componentRef.instance.taskCompleted .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((openNextTask) => this.taskCompleted.emit(openNextTask)); } - if (this.componentRef.instance?.error) { - this.componentRef.instance.error.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.error.emit(data)); + if (componentRef.instance?.error) { + componentRef.instance.error.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.error.emit(data)); } - if (this.componentRef.instance?.claimTask) { - this.componentRef.instance.claimTask.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.claimTask.emit(data)); + if (componentRef.instance?.claimTask) { + componentRef.instance.claimTask.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.claimTask.emit(data)); } - if (this.componentRef.instance?.unclaimTask) { - this.componentRef.instance.unclaimTask.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.unclaimTask.emit(data)); + if (componentRef.instance?.unclaimTask) { + componentRef.instance.unclaimTask.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.unclaimTask.emit(data)); } - if (this.componentRef.instance?.cancelTask) { - this.componentRef.instance.cancelTask.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.cancelTask.emit(data)); + if (componentRef.instance?.cancelTask) { + componentRef.instance.cancelTask.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.cancelTask.emit(data)); } - if (this.componentRef.instance?.nextTaskCheckboxCheckedChanged) { - this.componentRef.instance.nextTaskCheckboxCheckedChanged + if (componentRef.instance?.nextTaskCheckboxCheckedChanged) { + componentRef.instance.nextTaskCheckboxCheckedChanged .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((data) => this.nextTaskCheckboxCheckedChanged.emit(data)); } diff --git a/lib/process-services/karma.conf.js b/lib/process-services/karma.conf.js index 03f0c6ac0f..27c5bf8de9 100644 --- a/lib/process-services/karma.conf.js +++ b/lib/process-services/karma.conf.js @@ -43,7 +43,7 @@ module.exports = function (config) { coverageReporter: { dir: join(__dirname, '../../coverage/process-services'), subdir: '.', - reporters: [{ type: 'html' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], + reporters: [{ type: 'html' }, { type: 'lcov' }, { type: 'text-summary' }, { type: 'text-summary', subdir: '.', file: 'summary.txt' }], check: { global: { statements: 75, diff --git a/lib/process-services/package.json b/lib/process-services/package.json index 17fc12b3fe..19125a69b4 100644 --- a/lib/process-services/package.json +++ b/lib/process-services/package.json @@ -12,14 +12,14 @@ }, "peerDependencies": { "@angular/cdk": ">=20.2.14", - "@angular/common": ">=20.3.25", - "@angular/compiler": ">=20.3.25", - "@angular/core": ">=20.3.25", - "@angular/forms": ">=20.3.25", + "@angular/common": ">=20.3.27", + "@angular/compiler": ">=20.3.27", + "@angular/core": ">=20.3.27", + "@angular/forms": ">=20.3.27", "@angular/material": ">=20.2.14", - "@angular/platform-browser": ">=20.3.25", - "@angular/platform-browser-dynamic": ">=20.3.25", - "@angular/router": ">=20.3.25", + "@angular/platform-browser": ">=20.3.27", + "@angular/platform-browser-dynamic": ">=20.3.27", + "@angular/router": ">=20.3.27", "@alfresco/js-api": ">=10.0.0", "@alfresco/adf-core": ">=9.0.0", "@alfresco/adf-content-services": ">=9.0.0", diff --git a/nx.json b/nx.json index 45492e45a3..30bdd681b6 100644 --- a/nx.json +++ b/nx.json @@ -10,7 +10,8 @@ "cache": true }, "test": { - "cache": true + "cache": true, + "outputs": ["{workspaceRoot}/coverage/{projectName}"] }, "stylelint": { "cache": true diff --git a/package.json b/package.json index f28c8eba5f..790f5677b8 100644 --- a/package.json +++ b/package.json @@ -40,17 +40,17 @@ ], "dependencies": { "@angular-eslint/utils": "20.7.0", - "@angular/animations": "20.3.26", + "@angular/animations": "20.3.27", "@angular/cdk": "20.2.14", "@angular/common": "20.3.27", "@angular/compiler": "20.3.27", "@angular/core": "20.3.27", - "@angular/forms": "20.3.26", + "@angular/forms": "20.3.27", "@angular/material": "20.2.14", "@angular/material-date-fns-adapter": "20.2.14", - "@angular/platform-browser": "20.3.26", - "@angular/platform-browser-dynamic": "20.3.26", - "@angular/router": "20.3.26", + "@angular/platform-browser": "20.3.27", + "@angular/platform-browser-dynamic": "20.3.27", + "@angular/router": "20.3.27", "@apollo/client": "3.13.1", "@cspell/eslint-plugin": "10.0.0", "@mat-datetimepicker/core": "16.0.1", @@ -83,7 +83,7 @@ "@angular-eslint/eslint-plugin-template": "20.7.0", "@angular-eslint/template-parser": "22.1.0", "@angular/build": "20.3.32", - "@angular/compiler-cli": "20.3.26", + "@angular/compiler-cli": "20.3.27", "@chromatic-com/storybook": "4.1.3", "@eslint/compat": "^2.1.0", "@nx/angular": "23.1.1", @@ -98,10 +98,10 @@ "@types/jasminewd2": "2.0.13", "@types/node": "26.1.1", "@types/sinon": "22.0.0", - "@typescript-eslint/eslint-plugin": "8.66.0", - "@typescript-eslint/parser": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/utils": "8.66.0", + "@typescript-eslint/eslint-plugin": "8.67.0", + "@typescript-eslint/parser": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0", + "@typescript-eslint/utils": "8.67.0", "ajv": "8.20.0", "dotenv": "16.4.7", "eslint": "10.8.0", @@ -115,7 +115,7 @@ "eslint-plugin-unicorn": "61.0.2", "graphql": "16.14.0", "husky": "9.1.7", - "jasmine-core": "5.13.0", + "jasmine-core": "6.3.0", "jasmine-reporters": "2.5.2", "jsonc-eslint-parser": "2.4.2", "karma": "6.4.4", @@ -140,7 +140,7 @@ "ts-node": "10.9.2", "typescript": "5.9.3", "undici": "8.9.0", - "webpack": "5.109.0" + "webpack": "5.109.2" }, "license": "Apache-2.0", "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 089c200cbf..e695136426 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,12 +6,13 @@ settings: overrides: fast-uri: 3.1.5 - js-yaml@4.2.0: 4.3.0 + js-yaml@4.2.0: 4.3.1 + brace-expansion@5.0.8: 5.0.9 brace-expansion@<1.1.18: 1.1.18 + socket.io-parser@4.2.6: 4.2.7 svgo: 4.0.2 shell-quote: 1.9.0 adm-zip: 0.6.0 - brace-expansion@5.0.8: 5.0.9 minimatch@10.2.5: 10.2.6 axios: 1.18.0 serialize-javascript: '>=7.0.5' @@ -30,10 +31,10 @@ importers: dependencies: '@angular-eslint/utils': specifier: 20.7.0 - version: 20.7.0(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) + version: 20.7.0(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) '@angular/animations': - specifier: 20.3.26 - version: 20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + specifier: 20.3.27 + version: 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) '@angular/cdk': specifier: 20.2.14 version: 20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) @@ -47,23 +48,23 @@ importers: specifier: 20.3.27 version: 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) '@angular/forms': - specifier: 20.3.26 - version: 20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) + specifier: 20.3.27 + version: 20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) '@angular/material': specifier: 20.2.14 - version: 20.2.14(455430e5d13335858a88189cadfe3159) + version: 20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7) '@angular/material-date-fns-adapter': specifier: 20.2.14 - version: 20.2.14(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(455430e5d13335858a88189cadfe3159))(date-fns@2.30.0) + version: 20.2.14(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7))(date-fns@2.30.0) '@angular/platform-browser': - specifier: 20.3.26 - version: 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + specifier: 20.3.27 + version: 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) '@angular/platform-browser-dynamic': - specifier: 20.3.26 - version: 20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))) + specifier: 20.3.27 + version: 20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))) '@angular/router': - specifier: 20.3.26 - version: 20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) + specifier: 20.3.27 + version: 20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) '@apollo/client': specifier: 3.13.1 version: 3.13.1(graphql-ws@6.0.8(graphql@16.14.0)(ws@8.21.0))(graphql@16.14.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -72,7 +73,7 @@ importers: version: 10.0.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)) '@mat-datetimepicker/core': specifier: 16.0.1 - version: 16.0.1(@angular/cdk@20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(455430e5d13335858a88189cadfe3159)) + version: 16.0.1(@angular/cdk@20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7)) '@ngx-translate/core': specifier: 17.0.0 version: 17.0.0(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) @@ -145,19 +146,19 @@ importers: version: 20.3.32(chokidar@4.0.3) '@angular-eslint/eslint-plugin': specifier: 20.7.0 - version: 20.7.0(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) + version: 20.7.0(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) '@angular-eslint/eslint-plugin-template': specifier: 20.7.0 - version: 20.7.0(@angular-eslint/template-parser@22.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3))(@typescript-eslint/types@8.65.0)(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) + version: 20.7.0(@angular-eslint/template-parser@22.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3))(@typescript-eslint/types@8.67.0)(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) '@angular-eslint/template-parser': specifier: 22.1.0 version: 22.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) '@angular/build': specifier: 20.3.32 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.6.6)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0) + version: 20.3.32(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.6.6)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0) '@angular/compiler-cli': - specifier: 20.3.26 - version: 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + specifier: 20.3.27 + version: 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) '@chromatic-com/storybook': specifier: 4.1.3 version: 4.1.3(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)) @@ -166,16 +167,16 @@ importers: version: 2.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)) '@nx/angular': specifier: 23.1.1 - version: 23.1.1(14b0b041890a4d9ad84851ba43aed6f3) + version: 23.1.1(1871ac9779a3c1c87e7a2019dffef8ff) '@nx/eslint-plugin': specifier: 23.1.1 - version: 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3) + version: 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@typescript-eslint/parser@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3) '@nx/js': specifier: 23.1.1 version: 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) '@nx/storybook': specifier: 23.1.1 - version: 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@nx/web@23.1.1(69165f71226cdd786def4faf955c6def))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@7.2.0)(typescript@5.9.3) + version: 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@nx/web@23.1.1(9aad18717af1cde75effe0fe4ceb25af))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@7.2.0)(typescript@5.9.3) '@nx/workspace': specifier: 23.1.1 version: 23.1.1 @@ -187,7 +188,7 @@ importers: version: 10.4.0(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)) '@storybook/angular': specifier: 10.4.0 - version: 10.4.0(641969a558ebac8287ee9e40d24c89b8) + version: 10.4.0(69b0d8b90b0fe3d6016d76a1b6c3fcbb) '@types/jasmine': specifier: 4.0.3 version: 4.0.3 @@ -201,17 +202,17 @@ importers: specifier: 22.0.0 version: 22.0.0 '@typescript-eslint/eslint-plugin': - specifier: 8.66.0 - version: 8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + specifier: 8.67.0 + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.66.0 - version: 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + specifier: 8.67.0 + version: 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/typescript-estree': - specifier: 8.66.0 - version: 8.66.0(supports-color@7.2.0)(typescript@5.9.3) + specifier: 8.67.0 + version: 8.67.0(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/utils': - specifier: 8.66.0 - version: 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + specifier: 8.67.0 + version: 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -252,8 +253,8 @@ importers: specifier: 9.1.7 version: 9.1.7 jasmine-core: - specifier: 5.13.0 - version: 5.13.0 + specifier: 6.3.0 + version: 6.3.0 jasmine-reporters: specifier: 2.5.2 version: 2.5.2 @@ -274,13 +275,13 @@ importers: version: 5.1.0(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)) karma-jasmine-html-reporter: specifier: 2.2.0 - version: 2.2.0(jasmine-core@5.13.0)(karma-jasmine@5.1.0(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)))(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)) + version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)))(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)) lint-staged: specifier: 17.2.0 version: 17.2.0 ng-packagr: specifier: 20.3.2 - version: 20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + version: 20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) nx: specifier: 23.1.1 version: 23.1.1 @@ -298,7 +299,7 @@ importers: version: 6.1.3 sass-loader: specifier: 16.0.8 - version: 16.0.8(@rspack/core@1.6.8)(sass-embedded@1.100.0)(sass@1.101.0)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + version: 16.0.8(@rspack/core@1.6.8)(sass-embedded@1.100.0)(sass@1.101.0)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) semver: specifier: 7.6.3 version: 7.6.3 @@ -327,8 +328,8 @@ importers: specifier: 8.9.0 version: 8.9.0 webpack: - specifier: 5.109.0 - version: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + specifier: 5.109.2 + version: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) lib/eslint-angular: {} @@ -463,12 +464,12 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '*' - '@angular/animations@20.3.26': - resolution: {integrity: sha512-hfNrX19v8xs/usNkELSqc6q5IwBfS2GGW8sQ4OMpxAmLZDJwaLUxkj48t8VYhUFezsIfzR+sDEi6ZQBOaMIYug==} + '@angular/animations@20.3.27': + resolution: {integrity: sha512-BgGTloDiD3qIFVSxZq8xO6CiyhKn00WbhQQiklZF8WI2hXd3Hmc1OUAAHqSMh2c9uL7X1ZYkg9lSzjiasK2vKg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 20.3.26 + '@angular/core': 20.3.27 '@angular/build@20.3.16': resolution: {integrity: sha512-p1W3wwMG1Bs4tkPW7ceXO4woO1KCP28sjfpBJg32dIMW3dYSC+iWNmUkYS/wb4YEkqCV0wd6Apnd98mZjL6rNg==} @@ -576,12 +577,12 @@ packages: '@angular/core': 20.3.27 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@20.3.26': - resolution: {integrity: sha512-3rHtC87ecldvaiFHwQEZ6Wx3QaZ/Q7b0Gb7XORDOjn/M+5CYZ4rQsvbxE5TUjwreg07oQ4Y2h8ADESXTJEUYOQ==} + '@angular/compiler-cli@20.3.27': + resolution: {integrity: sha512-R0j9mFfUdGmmw867V/TfMSOBkLZT6ASxyY5tc1NDNmxQioZDVIDP9pqBOayzhJ0xiuDc9JellQXUTZ+vm+b/Zg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 20.3.26 + '@angular/compiler': 20.3.27 typescript: '>=5.8 <6.0' peerDependenciesMeta: typescript: @@ -604,13 +605,13 @@ packages: zone.js: optional: true - '@angular/forms@20.3.26': - resolution: {integrity: sha512-ia0YaPVjlG2oBFKCfaAgqQ0jGRrhGTAcrbZG3tVeFDpi7LQ6WdP3Syw2H+0D3GPyzpl/5UqU10Fum5Wr1br4QQ==} + '@angular/forms@20.3.27': + resolution: {integrity: sha512-cNG26wi3tr3m8At6puxJpAMVk9mBhEqREA4Jk/klalMwWuYEf8ApTEAw0a5NUfMxDkL3dcJJwDRf8rK6ma6TYQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 20.3.26 - '@angular/core': 20.3.26 - '@angular/platform-browser': 20.3.26 + '@angular/common': 20.3.27 + '@angular/core': 20.3.27 + '@angular/platform-browser': 20.3.27 rxjs: ^6.5.3 || ^7.4.0 '@angular/material-date-fns-adapter@20.2.14': @@ -630,34 +631,34 @@ packages: '@angular/platform-browser': ^20.0.0 || ^21.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/platform-browser-dynamic@20.3.26': - resolution: {integrity: sha512-/9eq0GGmtMoBV5UvcjvhnV4ZDcgZr15h+dzoxkZodUncb2z7fxybSyha7wWD9aTeabZ/q/KYVUSnoYqVyBhbVQ==} + '@angular/platform-browser-dynamic@20.3.27': + resolution: {integrity: sha512-4UUs8vOswgBOWCRoeZrswguarBLrM3j6WGb927Y3GXdN37fVJQYjyKHivNeQwZvwsGgl5Nl6mvpBpZv47n/OrQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} deprecated: '@angular/platform-browser-dynamic is deprecated. Use `@angular/platform-browser` instead.' peerDependencies: - '@angular/common': 20.3.26 - '@angular/compiler': 20.3.26 - '@angular/core': 20.3.26 - '@angular/platform-browser': 20.3.26 + '@angular/common': 20.3.27 + '@angular/compiler': 20.3.27 + '@angular/core': 20.3.27 + '@angular/platform-browser': 20.3.27 - '@angular/platform-browser@20.3.26': - resolution: {integrity: sha512-In4wUiLUUT9LqyV9Rjz78k/dsnKAwec4AtDmwZoX8/ZmeJOSH7g5X1gTM+hxTxmifmZkrapQjXR299IcfIkzrw==} + '@angular/platform-browser@20.3.27': + resolution: {integrity: sha512-IV2zQ4zk6liyw5NE48bQqSk3nOAZ1rmDAQi7W4Kw0N8cs9MYVgK3zulo0zx5UqSv1kuNDAGb0HPR5tUGVOf9kw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/animations': 20.3.26 - '@angular/common': 20.3.26 - '@angular/core': 20.3.26 + '@angular/animations': 20.3.27 + '@angular/common': 20.3.27 + '@angular/core': 20.3.27 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/router@20.3.26': - resolution: {integrity: sha512-q0k0b5uuQx93Trk4qEMYe8LoPOozheRBIjze51q+LUTlLXWik4W0ughXLiTJL346KRudR/vB5ksfZP8b6WlQyA==} + '@angular/router@20.3.27': + resolution: {integrity: sha512-F3hfJQ0GAuD6LdeB7A6fMfaErc4HXCtCQGh3C/8VrbVEbGfIgSveNjQXzGYPNklnOLhj1BmWf5w0WniUAEjLBA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 20.3.26 - '@angular/core': 20.3.26 - '@angular/platform-browser': 20.3.26 + '@angular/common': 20.3.27 + '@angular/core': 20.3.27 + '@angular/platform-browser': 20.3.27 rxjs: ^6.5.3 || ^7.4.0 '@apollo/client@3.13.1': @@ -4281,9 +4282,6 @@ packages: '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node@25.9.1': - resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} - '@types/node@26.1.1': resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==} @@ -4338,11 +4336,11 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.66.0': - resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==} + '@typescript-eslint/eslint-plugin@8.67.0': + resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.66.0 + '@typescript-eslint/parser': ^8.67.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' @@ -4352,8 +4350,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@typescript-eslint/parser@8.66.0': - resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==} + '@typescript-eslint/parser@8.67.0': + resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4371,6 +4369,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.67.0': + resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/scope-manager@5.62.0': resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4383,6 +4387,10 @@ packages: resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.67.0': + resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.65.0': resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4395,6 +4403,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/tsconfig-utils@8.67.0': + resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.65.0': resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4402,8 +4416,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.66.0': - resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==} + '@typescript-eslint/type-utils@8.67.0': + resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4421,6 +4435,10 @@ packages: resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.67.0': + resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@5.62.0': resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4442,6 +4460,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/typescript-estree@8.67.0': + resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@5.62.0': resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4462,6 +4486,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.67.0': + resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@5.62.0': resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4474,6 +4505,10 @@ packages: resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.67.0': + resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.2': resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==} @@ -4562,6 +4597,7 @@ packages: '@xmldom/xmldom@0.8.13': resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -4604,6 +4640,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + address@2.0.3: resolution: {integrity: sha512-XNAb/a6TCqou+TufU8/u11HCu9x1gYvOoxLwtlXgIqmkrYQADVv6ljyW2zwiPhHz9R1gItAWpuDrdJMmrOBFEA==} engines: {node: '>= 16.0.0'} @@ -4863,6 +4904,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-browser-mapping@2.11.14: + resolution: {integrity: sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==} + engines: {node: '>=6.0.0'} + hasBin: true + basic-auth@2.0.1: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} @@ -4922,6 +4968,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.28.8: + resolution: {integrity: sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -4974,6 +5025,9 @@ packages: caniuse-lite@1.0.30001803: resolution: {integrity: sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==} + caniuse-lite@1.0.30001809: + resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} + case-sensitive-paths-webpack-plugin@2.4.0: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} @@ -5617,6 +5671,9 @@ packages: electron-to-chromium@1.5.389: resolution: {integrity: sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==} + electron-to-chromium@1.5.406: + resolution: {integrity: sha512-hWH5ORBi3d0IipnMh7BN5GDTaAmrSSSWmznwt2zltdiRNEWoEQyTwF0FFSBxzHO7hLSRT6loQu3IQGV0wg/Tvg==} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5649,12 +5706,8 @@ packages: resolution: {integrity: sha512-clKkw4C7nJ22mGgoVcCg6V/W/TxdNyIOTr89k2ONZu81qqkddPFDF0LXcbAwhzPD8DjkiRCjzuiO6Y+fkpD4vg==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.24.0: - resolution: {integrity: sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==} - engines: {node: '>=10.13.0'} - - enhanced-resolve@5.24.3: - resolution: {integrity: sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==} + enhanced-resolve@5.24.5: + resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} engines: {node: '>=10.13.0'} enquirer@2.3.6: @@ -5717,8 +5770,8 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + es-module-lexer@2.3.1: + resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} @@ -6627,8 +6680,8 @@ packages: jasmine-core@4.6.1: resolution: {integrity: sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==} - jasmine-core@5.13.0: - resolution: {integrity: sha512-vsYjfh7lyqvZX5QgqKc4YH8phs7g96Z8bsdIFNEU3VqXhlHaq+vov/Fgn/sr6MiUczdZkyXRC3TX369Ll4Nzbw==} + jasmine-core@6.3.0: + resolution: {integrity: sha512-eMm5qBovNjNoGOcgE/W207+wrcK5zrQv0Rg/rWGboUJUmZp0dFCpHTyjpuDAfCwRCqg7f9U2q2jtv/aUuzdCQg==} jasmine-reporters@2.5.2: resolution: {integrity: sha512-qdewRUuFOSiWhiyWZX8Yx3YNQ9JG51ntBEO4ekLQRpktxFTwUHy24a86zD/Oi2BRTKksEdfWQZcQFqzjqIkPig==} @@ -6664,8 +6717,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.3.0: - resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} hasBin: true jsdoc-type-pratt-parser@7.3.0: @@ -7239,6 +7292,10 @@ packages: resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} engines: {node: '>=18'} + node-releases@2.0.53: + resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} + engines: {node: '>=18'} + node-schedule@2.1.1: resolution: {integrity: sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==} engines: {node: '>=6'} @@ -8406,8 +8463,8 @@ packages: socket.io-adapter@2.5.8: resolution: {integrity: sha512-6Oy52pbg+kvdCVvjcN+FnY7BvxZ7cIHNScbvztT/It5d0vbwoJoVZmF2gjJmnV0/4WlXRfG15zc45ySk9Ah8bw==} - socket.io-parser@4.2.6: - resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==} + socket.io-parser@4.2.7: + resolution: {integrity: sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg==} engines: {node: '>=10.0.0'} socket.io@4.8.3: @@ -8704,8 +8761,8 @@ packages: engines: {node: '>=10'} hasBin: true - terser@5.49.0: - resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==} + terser@5.50.0: + resolution: {integrity: sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w==} engines: {node: '>=10'} hasBin: true @@ -8889,9 +8946,6 @@ packages: resolution: {integrity: sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==} hasBin: true - undici-types@7.24.6: - resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - undici-types@8.3.0: resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} @@ -8941,6 +8995,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.3.1: + resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -9187,8 +9247,8 @@ packages: webpack-cli: optional: true - webpack@5.109.0: - resolution: {integrity: sha512-vomrngskVVXEZF9sMZfYAd4pXZUnfaWdJGlF+BTNF+gJBCKYCQBnOeVPlrh39Ewl7nlCsirDplMy6o5g9xJHBg==} + webpack@5.109.2: + resolution: {integrity: sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -9369,14 +9429,14 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@20.3.16(18d336cd389c837facbd563dfff009d7)': + '@angular-devkit/build-angular@20.3.16(c48ca78b9b10b3f91f8dcbb193e451e5)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.16(chokidar@4.0.3) '@angular-devkit/build-webpack': 0.2003.16(chokidar@4.0.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) '@angular-devkit/core': 20.3.16(chokidar@4.0.3) - '@angular/build': 20.3.16(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0) - '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + '@angular/build': 20.3.16(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0) + '@angular/compiler-cli': 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) '@babel/core': 7.28.3(supports-color@7.2.0) '@babel/generator': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 @@ -9387,11 +9447,11 @@ snapshots: '@babel/preset-env': 7.28.3(@babel/core@7.28.3(supports-color@7.2.0))(supports-color@7.2.0) '@babel/runtime': 7.28.3 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 20.3.16(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@ngtools/webpack': 20.3.16(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) ansi-colors: 4.1.3 autoprefixer: 10.4.21(postcss@8.5.25) babel-loader: 10.0.0(@babel/core@7.28.3(supports-color@7.2.0))(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - browserslist: 4.28.5 + browserslist: 4.28.8 copy-webpack-plugin: 13.0.1(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) css-loader: 7.1.2(@rspack/core@1.6.8)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) esbuild-wasm: 0.25.9 @@ -9426,13 +9486,13 @@ snapshots: webpack-dev-middleware: 7.4.2(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) webpack-dev-server: 6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) optionalDependencies: '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) esbuild: 0.25.9 karma: 6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0) - ng-packagr: 20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + ng-packagr: 20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) transitivePeerDependencies: - '@angular/compiler' - '@minify-html/node' @@ -9507,23 +9567,23 @@ snapshots: '@angular-eslint/bundled-angular-compiler@22.1.0': {} - '@angular-eslint/eslint-plugin-template@20.7.0(@angular-eslint/template-parser@22.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3))(@typescript-eslint/types@8.65.0)(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3)': + '@angular-eslint/eslint-plugin-template@20.7.0(@angular-eslint/template-parser@22.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3))(@typescript-eslint/types@8.67.0)(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 '@angular-eslint/template-parser': 22.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) - '@angular-eslint/utils': 20.7.0(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) - '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@angular-eslint/utils': 20.7.0(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/utils': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) aria-query: 5.3.2 axobject-query: 4.1.0 eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) typescript: 5.9.3 - '@angular-eslint/eslint-plugin@20.7.0(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3)': + '@angular-eslint/eslint-plugin@20.7.0(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 - '@angular-eslint/utils': 20.7.0(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@angular-eslint/utils': 20.7.0(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 @@ -9535,31 +9595,31 @@ snapshots: eslint-scope: 9.1.2 typescript: 5.9.3 - '@angular-eslint/utils@20.7.0(@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3)': + '@angular-eslint/utils@20.7.0(@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(typescript@5.9.3)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) typescript: 5.9.3 - '@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))': + '@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))': dependencies: '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) tslib: 2.8.1 - '@angular/build@20.3.16(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0)': + '@angular/build@20.3.16(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.16(chokidar@4.0.3) '@angular/compiler': 20.3.27 - '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + '@angular/compiler-cli': 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) '@babel/core': 7.28.3(supports-color@7.2.0) '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 '@inquirer/confirm': 5.1.14(@types/node@26.1.1) '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@26.1.1)(jiti@2.7.0)(less@4.4.0)(sass-embedded@1.100.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.9.0)) beasties: 0.3.5 - browserslist: 4.28.5 + browserslist: 4.28.8 esbuild: 0.25.9 https-proxy-agent: 7.0.6(supports-color@7.2.0) istanbul-lib-instrument: 6.0.3(supports-color@7.2.0) @@ -9581,11 +9641,11 @@ snapshots: watchpack: 2.4.4 optionalDependencies: '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) karma: 6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0) less: 4.4.0 lmdb: 3.4.2 - ng-packagr: 20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + ng-packagr: 20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) postcss: 8.5.25 transitivePeerDependencies: - '@types/node' @@ -9600,12 +9660,12 @@ snapshots: - tsx - yaml - '@angular/build@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.6.6)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0)': + '@angular/build@20.3.32(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.6.6)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.32(chokidar@4.0.3) '@angular/compiler': 20.3.27 - '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + '@angular/compiler-cli': 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 @@ -9634,11 +9694,11 @@ snapshots: watchpack: 2.4.4 optionalDependencies: '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) karma: 6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0) less: 4.6.6 lmdb: 3.4.2 - ng-packagr: 20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + ng-packagr: 20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) postcss: 8.5.25 transitivePeerDependencies: - '@types/node' @@ -9667,7 +9727,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3)': + '@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@angular/compiler': 20.3.27 '@babel/core': 7.29.7(supports-color@7.2.0) @@ -9695,52 +9755,52 @@ snapshots: '@angular/compiler': 20.3.27 zone.js: 0.15.0 - '@angular/forms@20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)': + '@angular/forms@20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)': dependencies: '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/material-date-fns-adapter@20.2.14(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(455430e5d13335858a88189cadfe3159))(date-fns@2.30.0)': + '@angular/material-date-fns-adapter@20.2.14(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7))(date-fns@2.30.0)': dependencies: '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/material': 20.2.14(455430e5d13335858a88189cadfe3159) + '@angular/material': 20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7) date-fns: 2.30.0 tslib: 2.8.1 - '@angular/material@20.2.14(455430e5d13335858a88189cadfe3159)': + '@angular/material@20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7)': dependencies: '@angular/cdk': 20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/forms': 20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/forms': 20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/platform-browser-dynamic@20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))': + '@angular/platform-browser-dynamic@20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))': dependencies: '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/compiler': 20.3.27 '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) tslib: 2.8.1 - '@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))': + '@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))': dependencies: '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/animations': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) - '@angular/router@20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)': + '@angular/router@20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)': dependencies: '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) rxjs: 7.8.2 tslib: 2.8.1 @@ -9843,7 +9903,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.5 + browserslist: 4.28.8 lru-cache: 5.1.1 semver: 6.3.1 @@ -11434,7 +11494,7 @@ snapshots: '@es-joy/jsdoccomment@0.90.0': dependencies: '@types/estree': 1.0.9 - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/types': 8.67.0 comment-parser: 1.4.7 esquery: 1.7.0 jsdoc-type-pratt-parser: 7.3.0 @@ -12063,12 +12123,12 @@ snapshots: '@lmdb/lmdb-win32-x64@3.4.2': optional: true - '@mat-datetimepicker/core@16.0.1(@angular/cdk@20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(455430e5d13335858a88189cadfe3159))': + '@mat-datetimepicker/core@16.0.1(@angular/cdk@20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/material@20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7))': dependencies: '@angular/cdk': 20.2.14(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/material': 20.2.14(455430e5d13335858a88189cadfe3159) + '@angular/material': 20.2.14(7fc7dc26a5364b20a95267fc7b4f10c7) tslib: 2.8.1 '@module-federation/bridge-react-webpack-plugin@2.5.1(node-fetch@2.7.0(encoding@0.1.13))': @@ -12113,7 +12173,7 @@ snapshots: - utf-8-validate optional: true - '@module-federation/enhanced@2.5.1(@rspack/core@1.6.8)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': + '@module-federation/enhanced@2.5.1(@rspack/core@1.6.8)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': dependencies: '@module-federation/bridge-react-webpack-plugin': 2.5.1(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/cli': 2.5.1(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3) @@ -12131,7 +12191,7 @@ snapshots: upath: 2.0.1 optionalDependencies: typescript: 5.9.3 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -12172,16 +12232,16 @@ snapshots: - vue-tsc optional: true - '@module-federation/node@2.7.44(@rspack/core@1.6.8)(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': + '@module-federation/node@2.7.44(@rspack/core@1.6.8)(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': dependencies: - '@module-federation/enhanced': 2.5.1(@rspack/core@1.6.8)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@module-federation/enhanced': 2.5.1(@rspack/core@1.6.8)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) '@module-federation/runtime': 2.5.1(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/sdk': 2.5.1(node-fetch@2.7.0(encoding@0.1.13)) encoding: 0.1.13 node-fetch: 2.7.0(encoding@0.1.13) tapable: 2.3.0 optionalDependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -12455,9 +12515,9 @@ snapshots: '@neoconfetti/react@1.0.0': {} - '@ngtools/webpack@20.3.16(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': + '@ngtools/webpack@20.3.16(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': dependencies: - '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + '@angular/compiler-cli': 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) typescript: 5.9.3 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) @@ -12481,17 +12541,17 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@nx/angular@23.1.1(14b0b041890a4d9ad84851ba43aed6f3)': + '@nx/angular@23.1.1(1871ac9779a3c1c87e7a2019dffef8ff)': dependencies: '@angular-devkit/core': 20.3.32(chokidar@4.0.3) '@angular-devkit/schematics': 20.3.32(chokidar@4.0.3) '@nx/devkit': 23.1.1(nx@23.1.1) '@nx/eslint': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) '@nx/js': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) - '@nx/module-federation': 23.1.1(159f6bdc10a59ab922b88ca0434a74ba) - '@nx/rspack': 23.1.1(d1f2db652c3431e28213a9ed1561260a) - '@nx/web': 23.1.1(69165f71226cdd786def4faf955c6def) - '@nx/webpack': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@nx/module-federation': 23.1.1(fbabc342ac83f23db68b8d27ddbe599a) + '@nx/rspack': 23.1.1(f7d730e8feeef54478a80edef0d832f6) + '@nx/web': 23.1.1(9aad18717af1cde75effe0fe4ceb25af) + '@nx/webpack': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) '@phenomnomnominal/tsquery': 6.2.0(typescript@5.9.3) '@schematics/angular': 20.3.32(chokidar@4.0.3) '@typescript-eslint/type-utils': 8.65.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) @@ -12505,10 +12565,10 @@ snapshots: tslib: 2.8.1 webpack-merge: 5.10.0 optionalDependencies: - '@angular-devkit/build-angular': 20.3.16(18d336cd389c837facbd563dfff009d7) - '@angular/build': 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.6.6)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0) + '@angular-devkit/build-angular': 20.3.16(c48ca78b9b10b3f91f8dcbb193e451e5) + '@angular/build': 20.3.32(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@types/node@26.1.1)(chokidar@4.0.3)(jiti@2.7.0)(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0))(less@4.6.6)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3))(postcss@8.5.25)(sass-embedded@1.100.0)(supports-color@7.2.0)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.9.0) '@nx/cypress': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3) - ng-packagr: 20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + ng-packagr: 20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) transitivePeerDependencies: - '@babel/traverse' - '@minify-html/node' @@ -12584,13 +12644,13 @@ snapshots: tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/eslint-plugin@23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)': + '@nx/eslint-plugin@23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@typescript-eslint/parser@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@nx/devkit': 23.1.1(nx@23.1.1) '@nx/js': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) '@phenomnomnominal/tsquery': 6.2.0(typescript@5.9.3) '@typescript-eslint/type-utils': 8.65.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) confusing-browser-globals: 1.0.11 globals: 17.6.0 jsonc-eslint-parser: 2.4.2 @@ -12598,7 +12658,7 @@ snapshots: semver: 7.6.3 tslib: 2.8.1 optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) eslint-config-prettier: 10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)) transitivePeerDependencies: - '@babel/traverse' @@ -12668,11 +12728,11 @@ snapshots: - nx - supports-color - '@nx/module-federation@23.1.1(159f6bdc10a59ab922b88ca0434a74ba)': + '@nx/module-federation@23.1.1(fbabc342ac83f23db68b8d27ddbe599a)': dependencies: '@nx/devkit': 23.1.1(nx@23.1.1) '@nx/js': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) - '@nx/web': 23.1.1(69165f71226cdd786def4faf955c6def) + '@nx/web': 23.1.1(9aad18717af1cde75effe0fe4ceb25af) '@rspack/core': 2.1.8(@module-federation/runtime-tools@2.5.1(node-fetch@2.7.0(encoding@0.1.13))) express: 4.22.2(supports-color@7.2.0) http-proxy-middleware: 3.0.7(supports-color@7.2.0) @@ -12680,8 +12740,8 @@ snapshots: tslib: 2.8.1 webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: - '@module-federation/enhanced': 2.5.1(@rspack/core@1.6.8)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - '@module-federation/node': 2.7.44(@rspack/core@1.6.8)(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@module-federation/enhanced': 2.5.1(@rspack/core@1.6.8)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@module-federation/node': 2.7.44(@rspack/core@1.6.8)(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) transitivePeerDependencies: - '@babel/traverse' - '@minify-html/node' @@ -12742,15 +12802,15 @@ snapshots: '@nx/nx-win32-x64-msvc@23.1.1': optional: true - '@nx/rspack@23.1.1(d1f2db652c3431e28213a9ed1561260a)': + '@nx/rspack@23.1.1(f7d730e8feeef54478a80edef0d832f6)': dependencies: '@nx/devkit': 23.1.1(nx@23.1.1) '@nx/js': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) - '@nx/module-federation': 23.1.1(159f6bdc10a59ab922b88ca0434a74ba) - '@nx/web': 23.1.1(69165f71226cdd786def4faf955c6def) + '@nx/module-federation': 23.1.1(fbabc342ac83f23db68b8d27ddbe599a) + '@nx/web': 23.1.1(9aad18717af1cde75effe0fe4ceb25af) '@phenomnomnominal/tsquery': 6.2.0(typescript@5.9.3) autoprefixer: 10.5.0(postcss@8.5.25) - browserslist: 4.28.5 + browserslist: 4.28.8 css-loader: 6.11.0(@rspack/core@1.6.8)(webpack@5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) enquirer: 2.3.6 express: 4.22.2(supports-color@7.2.0) @@ -12775,7 +12835,7 @@ snapshots: webpack-node-externals: 3.0.0 optionalDependencies: '@rspack/core': 1.6.8 - '@rspack/dev-server': 1.2.1(@rspack/core@1.6.8)(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@rspack/dev-server': 1.2.1(@rspack/core@1.6.8)(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) '@rspack/plugin-react-refresh': 1.6.2(react-refresh@0.18.0)(webpack-hot-middleware@2.26.1) transitivePeerDependencies: - '@babel/traverse' @@ -12812,7 +12872,7 @@ snapshots: - verdaccio - webpack-cli - '@nx/storybook@23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@nx/web@23.1.1(69165f71226cdd786def4faf955c6def))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@7.2.0)(typescript@5.9.3)': + '@nx/storybook@23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@nx/web@23.1.1(9aad18717af1cde75effe0fe4ceb25af))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@nx/cypress': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3) '@nx/devkit': 23.1.1(nx@23.1.1) @@ -12823,7 +12883,7 @@ snapshots: storybook: 10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tslib: 2.8.1 optionalDependencies: - '@nx/web': 23.1.1(69165f71226cdd786def4faf955c6def) + '@nx/web': 23.1.1(9aad18717af1cde75effe0fe4ceb25af) transitivePeerDependencies: - '@babel/traverse' - '@nx/jest' @@ -12838,7 +12898,7 @@ snapshots: - typescript - verdaccio - '@nx/web@23.1.1(69165f71226cdd786def4faf955c6def)': + '@nx/web@23.1.1(9aad18717af1cde75effe0fe4ceb25af)': dependencies: '@nx/devkit': 23.1.1(nx@23.1.1) '@nx/js': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) @@ -12849,7 +12909,7 @@ snapshots: optionalDependencies: '@nx/cypress': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3) '@nx/eslint': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@zkochan/js-yaml@0.0.7)(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(nx@23.1.1)(supports-color@7.2.0) - '@nx/webpack': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + '@nx/webpack': 23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -12860,7 +12920,7 @@ snapshots: - supports-color - verdaccio - '@nx/webpack@23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': + '@nx/webpack@23.1.1(@babel/traverse@7.29.7(supports-color@7.2.0))(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(nx@23.1.1)(supports-color@7.2.0)(typescript@5.9.3)(webpack-dev-server@6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': dependencies: '@babel/core': 7.29.7(supports-color@7.2.0) '@nx/devkit': 23.1.1(nx@23.1.1) @@ -12868,36 +12928,36 @@ snapshots: '@phenomnomnominal/tsquery': 6.2.0(typescript@5.9.3) ajv: 8.20.0 autoprefixer: 10.5.0(postcss@8.5.25) - babel-loader: 9.2.1(@babel/core@7.29.7(supports-color@7.2.0))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - browserslist: 4.28.5 - copy-webpack-plugin: 14.0.0(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - css-loader: 6.11.0(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - css-minimizer-webpack-plugin: 8.0.0(clean-css@5.3.3)(csso@5.0.5)(esbuild@0.25.9)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + babel-loader: 9.2.1(@babel/core@7.29.7(supports-color@7.2.0))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + browserslist: 4.28.8 + copy-webpack-plugin: 14.0.0(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + css-loader: 6.11.0(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + css-minimizer-webpack-plugin: 8.0.0(clean-css@5.3.3)(csso@5.0.5)(esbuild@0.25.9)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) less: 4.5.1 - less-loader: 12.3.3(@rspack/core@1.6.8)(less@4.5.1)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - license-webpack-plugin: 4.0.2(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + less-loader: 12.3.3(@rspack/core@1.6.8)(less@4.5.1)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + license-webpack-plugin: 4.0.2(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) loader-utils: 2.0.4 - mini-css-extract-plugin: 2.4.7(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + mini-css-extract-plugin: 2.4.7(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) parse5: 4.0.0 picocolors: 1.1.1 postcss: 8.5.25 postcss-import: 14.1.0(postcss@8.5.25) - postcss-loader: 8.2.1(@rspack/core@1.6.8)(postcss@8.5.25)(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + postcss-loader: 8.2.1(@rspack/core@1.6.8)(postcss@8.5.25)(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) rxjs: 7.8.2 sass: 1.101.0 sass-embedded: 1.100.0 - sass-loader: 16.0.8(@rspack/core@1.6.8)(sass-embedded@1.100.0)(sass@1.101.0)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - source-map-loader: 5.0.0(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - style-loader: 3.3.4(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - terser-webpack-plugin: 5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - ts-loader: 9.6.1(loader-utils@2.0.4)(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + sass-loader: 16.0.8(@rspack/core@1.6.8)(sass-embedded@1.100.0)(sass@1.101.0)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + source-map-loader: 5.0.0(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + style-loader: 3.3.4(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + terser-webpack-plugin: 5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + ts-loader: 9.6.1(loader-utils@2.0.4)(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) tsconfig-paths-webpack-plugin: 4.2.0 tslib: 2.8.1 webpack-node-externals: 3.0.0 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) optionalDependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) webpack-dev-server: 6.0.0(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) transitivePeerDependencies: - '@babel/traverse' @@ -13578,7 +13638,7 @@ snapshots: optionalDependencies: '@module-federation/runtime-tools': 2.5.1(node-fetch@2.7.0(encoding@0.1.13)) - '@rspack/dev-server@1.2.1(@rspack/core@1.6.8)(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': + '@rspack/dev-server@1.2.1(@rspack/core@1.6.8)(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)(tslib@2.8.1)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25))': dependencies: '@rspack/core': 1.6.8 '@types/bonjour': 3.5.13 @@ -13607,7 +13667,7 @@ snapshots: serve-index: 1.9.2(supports-color@7.2.0) sockjs: 0.3.24 spdy: 4.0.2(supports-color@7.2.0) - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) ws: 8.21.0 transitivePeerDependencies: - bufferutil @@ -13663,17 +13723,17 @@ snapshots: storybook: 10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) ts-dedent: 2.3.0 - '@storybook/angular@10.4.0(641969a558ebac8287ee9e40d24c89b8)': + '@storybook/angular@10.4.0(69b0d8b90b0fe3d6016d76a1b6c3fcbb)': dependencies: '@angular-devkit/architect': 0.2003.16(chokidar@4.0.3) - '@angular-devkit/build-angular': 20.3.16(18d336cd389c837facbd563dfff009d7) + '@angular-devkit/build-angular': 20.3.16(c48ca78b9b10b3f91f8dcbb193e451e5) '@angular-devkit/core': 20.3.32(chokidar@4.0.3) '@angular/common': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/compiler': 20.3.27 - '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + '@angular/compiler-cli': 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) '@angular/core': 20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) - '@angular/platform-browser-dynamic': 20.3.26(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))) + '@angular/platform-browser': 20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/platform-browser-dynamic': 20.3.27(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@20.3.27)(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@20.3.27(@angular/animations@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0))) '@storybook/builder-webpack5': 10.4.0(@rspack/core@1.6.8)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@5.9.3) '@storybook/global': 5.0.0 rxjs: 7.8.2 @@ -13682,9 +13742,9 @@ snapshots: ts-dedent: 2.3.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.9.3 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: - '@angular/animations': 20.3.26(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/animations': 20.3.27(@angular/core@20.3.27(@angular/compiler@20.3.27)(rxjs@7.8.2)(zone.js@0.15.0)) zone.js: 0.15.0 transitivePeerDependencies: - '@minify-html/node' @@ -13707,17 +13767,17 @@ snapshots: '@storybook/core-webpack': 10.4.0(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)) case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.3 - css-loader: 7.1.4(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + css-loader: 7.1.4(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) es-module-lexer: 1.7.0 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - html-webpack-plugin: 5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + html-webpack-plugin: 5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) magic-string: 0.30.21 storybook: 10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - style-loader: 4.0.0(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - terser-webpack-plugin: 5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + style-loader: 4.0.0(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + terser-webpack-plugin: 5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) ts-dedent: 2.3.0 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - webpack-dev-middleware: 6.1.3(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack-dev-middleware: 6.1.3(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.6.2 optionalDependencies: @@ -13905,10 +13965,6 @@ snapshots: '@types/node': 26.1.1 optional: true - '@types/node@25.9.1': - dependencies: - undici-types: 7.24.6 - '@types/node@26.1.1': dependencies: undici-types: 8.3.0 @@ -13974,14 +14030,14 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/type-utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/parser': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/type-utils': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) ignore: 7.0.6 natural-compare: 1.4.0 @@ -13998,12 +14054,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + '@typescript-eslint/parser@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3(supports-color@7.2.0) eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) typescript: 5.9.3 @@ -14012,8 +14068,8 @@ snapshots: '@typescript-eslint/project-service@8.65.0(supports-color@7.2.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@5.9.3) - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 debug: 4.4.3(supports-color@7.2.0) typescript: 5.9.3 transitivePeerDependencies: @@ -14021,8 +14077,17 @@ snapshots: '@typescript-eslint/project-service@8.66.0(supports-color@7.2.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@5.9.3) - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + debug: 4.4.3(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.67.0(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 debug: 4.4.3(supports-color@7.2.0) typescript: 5.9.3 transitivePeerDependencies: @@ -14043,6 +14108,11 @@ snapshots: '@typescript-eslint/types': 8.66.0 '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/scope-manager@8.67.0': + dependencies: + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + '@typescript-eslint/tsconfig-utils@8.65.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -14051,6 +14121,10 @@ snapshots: dependencies: typescript: 5.9.3 + '@typescript-eslint/tsconfig-utils@8.67.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + '@typescript-eslint/type-utils@8.65.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.65.0 @@ -14063,11 +14137,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) debug: 4.4.3(supports-color@7.2.0) eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -14081,6 +14155,8 @@ snapshots: '@typescript-eslint/types@8.66.0': {} + '@typescript-eslint/types@8.67.0': {} + '@typescript-eslint/typescript-estree@5.62.0(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 5.62.0 @@ -14125,6 +14201,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.67.0(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3(supports-color@7.2.0) + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@5.62.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)) @@ -14162,6 +14253,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.67.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0)) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@7.2.0)(typescript@5.9.3) + eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -14177,6 +14279,11 @@ snapshots: '@typescript-eslint/types': 8.66.0 eslint-visitor-keys: 5.0.1 + '@typescript-eslint/visitor-keys@8.67.0': + dependencies: + '@typescript-eslint/types': 8.67.0 + eslint-visitor-keys: 5.0.1 + '@ungap/structured-clone@1.3.2': {} '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.11(@types/node@26.1.1)(jiti@2.7.0)(less@4.4.0)(sass-embedded@1.100.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.9.0))': @@ -14325,20 +14432,22 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 - acorn-import-phases@1.0.4(acorn@8.17.0): + acorn-import-phases@1.0.4(acorn@8.18.0): dependencies: - acorn: 8.17.0 + acorn: 8.18.0 - acorn-jsx@5.3.2(acorn@8.17.0): + acorn-jsx@5.3.2(acorn@8.18.0): dependencies: - acorn: 8.17.0 + acorn: 8.18.0 acorn-walk@8.3.5: dependencies: - acorn: 8.17.0 + acorn: 8.18.0 acorn@8.17.0: {} + acorn@8.18.0: {} + address@2.0.3: {} adjust-sourcemap-loader@4.0.0: @@ -14483,8 +14592,8 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.25): dependencies: - browserslist: 4.28.5 - caniuse-lite: 1.0.30001803 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -14493,7 +14602,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 caniuse-lite: 1.0.30001803 fraction.js: 5.3.4 picocolors: 1.1.1 @@ -14518,12 +14627,12 @@ snapshots: find-up: 5.0.0 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - babel-loader@9.2.1(@babel/core@7.29.7(supports-color@7.2.0))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + babel-loader@9.2.1(@babel/core@7.29.7(supports-color@7.2.0))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: '@babel/core': 7.29.7(supports-color@7.2.0) find-cache-dir: 4.0.0 schema-utils: 4.3.3 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) babel-plugin-const-enum@1.2.0(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0): dependencies: @@ -14617,6 +14726,8 @@ snapshots: baseline-browser-mapping@2.10.42: {} + baseline-browser-mapping@2.11.14: {} + basic-auth@2.0.1: dependencies: safe-buffer: 5.1.2 @@ -14717,6 +14828,14 @@ snapshots: node-releases: 2.0.51 update-browserslist-db: 1.2.3(browserslist@4.28.5) + browserslist@4.28.8: + dependencies: + baseline-browser-mapping: 2.11.14 + caniuse-lite: 1.0.30001809 + electron-to-chromium: 1.5.406 + node-releases: 2.0.53 + update-browserslist-db: 1.3.1(browserslist@4.28.8) + buffer-from@1.1.2: {} buffer@5.7.1: @@ -14763,8 +14882,8 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.28.5 - caniuse-lite: 1.0.30001803 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 @@ -14772,6 +14891,8 @@ snapshots: caniuse-lite@1.0.30001803: {} + caniuse-lite@1.0.30001809: {} + case-sensitive-paths-webpack-plugin@2.4.0: {} caseless@0.12.0: {} @@ -14988,18 +15109,18 @@ snapshots: tinyglobby: 0.2.17 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - copy-webpack-plugin@14.0.0(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + copy-webpack-plugin@14.0.0(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 7.0.6 tinyglobby: 0.2.17 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) core-js-compat@3.49.0: dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 core-util-is@1.0.3: optional: true @@ -15022,7 +15143,7 @@ snapshots: cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 - js-yaml: 4.3.0 + js-yaml: 4.3.1 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: @@ -15032,7 +15153,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.3.0 + js-yaml: 4.3.1 parse-json: 5.2.0 optionalDependencies: typescript: 5.9.3 @@ -15132,7 +15253,7 @@ snapshots: '@rspack/core': 1.6.8 webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - css-loader@6.11.0(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + css-loader@6.11.0(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: icss-utils: 5.1.0(postcss@8.5.25) postcss: 8.5.25 @@ -15144,7 +15265,7 @@ snapshots: semver: 7.6.3 optionalDependencies: '@rspack/core': 1.6.8 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) css-loader@7.1.2(@rspack/core@1.6.8)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: @@ -15160,7 +15281,7 @@ snapshots: '@rspack/core': 1.6.8 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - css-loader@7.1.4(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + css-loader@7.1.4(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: icss-utils: 5.1.0(postcss@8.5.25) postcss: 8.5.25 @@ -15172,9 +15293,9 @@ snapshots: semver: 7.6.3 optionalDependencies: '@rspack/core': 1.6.8 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - css-minimizer-webpack-plugin@8.0.0(clean-css@5.3.3)(csso@5.0.5)(esbuild@0.25.9)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + css-minimizer-webpack-plugin@8.0.0(clean-css@5.3.3)(csso@5.0.5)(esbuild@0.25.9)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: '@jridgewell/trace-mapping': 0.3.31 cssnano: 7.1.9(postcss@8.5.25) @@ -15182,7 +15303,7 @@ snapshots: postcss: 8.5.25 schema-utils: 4.3.3 serialize-javascript: 7.0.6 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: clean-css: 5.3.3 csso: 5.0.5 @@ -15232,7 +15353,7 @@ snapshots: cssnano-preset-default@7.0.17(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 css-declaration-sorter: 7.4.0(postcss@8.5.25) cssnano-utils: 5.0.3(postcss@8.5.25) postcss: 8.5.25 @@ -15440,6 +15561,8 @@ snapshots: electron-to-chromium@1.5.389: {} + electron-to-chromium@1.5.406: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -15478,12 +15601,7 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.24.0: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - - enhanced-resolve@5.24.3: + enhanced-resolve@5.24.5: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -15537,7 +15655,7 @@ snapshots: es-module-lexer@1.7.0: {} - es-module-lexer@2.1.0: {} + es-module-lexer@2.3.1: {} es-object-atoms@1.1.1: dependencies: @@ -15751,7 +15869,7 @@ snapshots: eslint-plugin-storybook@10.4.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(storybook@10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@7.2.0)(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) eslint: 10.8.0(jiti@2.7.0)(supports-color@7.2.0) storybook: 10.4.0(@testing-library/dom@10.4.1)(prettier@3.9.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) transitivePeerDependencies: @@ -15835,14 +15953,14 @@ snapshots: espree@11.2.0: dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) eslint-visitor-keys: 5.0.1 espree@9.6.1: dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -16088,7 +16206,7 @@ snapshots: optionalDependencies: debug: 4.4.3(supports-color@7.2.0) - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: '@babel/code-frame': 7.29.7 chalk: 4.1.2 @@ -16103,7 +16221,7 @@ snapshots: semver: 7.6.3 tapable: 2.3.3 typescript: 5.9.3 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) form-data@4.0.6: dependencies: @@ -16321,11 +16439,11 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.49.0 + terser: 5.50.0 html-tags@3.3.1: {} - html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -16334,7 +16452,7 @@ snapshots: tapable: 2.3.3 optionalDependencies: '@rspack/core': 1.6.8 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) htmlparser2@10.1.0: dependencies: @@ -16673,7 +16791,7 @@ snapshots: jasmine-core@4.6.1: {} - jasmine-core@5.13.0: {} + jasmine-core@6.3.0: {} jasmine-reporters@2.5.2: dependencies: @@ -16693,7 +16811,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 25.9.1 + '@types/node': 26.1.1 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -16714,7 +16832,7 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.3.0: + js-yaml@4.3.1: dependencies: argparse: 2.0.1 @@ -16770,9 +16888,9 @@ snapshots: transitivePeerDependencies: - supports-color - karma-jasmine-html-reporter@2.2.0(jasmine-core@5.13.0)(karma-jasmine@5.1.0(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)))(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)): + karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)))(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)): dependencies: - jasmine-core: 5.13.0 + jasmine-core: 6.3.0 karma: 6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0) karma-jasmine: 5.1.0(karma@6.4.4(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0)) @@ -16845,12 +16963,12 @@ snapshots: '@rspack/core': 1.6.8 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - less-loader@12.3.3(@rspack/core@1.6.8)(less@4.5.1)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + less-loader@12.3.3(@rspack/core@1.6.8)(less@4.5.1)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: less: 4.5.1 optionalDependencies: '@rspack/core': 1.6.8 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) less-loader@12.3.3(@rspack/core@1.6.8)(less@4.6.6)(webpack@5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: @@ -16917,11 +17035,11 @@ snapshots: optionalDependencies: webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - license-webpack-plugin@4.0.2(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + license-webpack-plugin@4.0.2(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: webpack-sources: 3.5.1 optionalDependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) lilconfig@3.1.3: {} @@ -17144,10 +17262,10 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.4.7(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + mini-css-extract-plugin@2.4.7(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: schema-utils: 4.3.3 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) mini-css-extract-plugin@2.9.4(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: @@ -17168,13 +17286,13 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + minimizer-webpack-plugin@5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.0 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + terser: 5.50.0 + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: clean-css: 5.3.3 cssnano: 7.1.9(postcss@8.5.25) @@ -17239,10 +17357,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@20.3.2(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): + ng-packagr@20.3.2(@angular/compiler-cli@20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) + '@angular/compiler-cli': 20.3.27(@angular/compiler@20.3.27)(supports-color@7.2.0)(typescript@5.9.3) '@rollup/plugin-json': 6.1.0(rollup@4.62.2) '@rollup/wasm-node': 4.62.2 ajv: 8.20.0 @@ -17310,6 +17428,8 @@ snapshots: node-releases@2.0.51: {} + node-releases@2.0.53: {} + node-schedule@2.1.1: dependencies: cron-parser: 4.9.0 @@ -17765,14 +17885,14 @@ snapshots: postcss-colormin@7.0.10(postcss@8.5.25): dependencies: '@colordx/core': 5.4.3 - browserslist: 4.28.5 + browserslist: 4.28.8 caniuse-api: 3.0.0 postcss: 8.5.25 postcss-value-parser: 4.2.0 postcss-convert-values@7.0.12(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 postcss: 8.5.25 postcss-value-parser: 4.2.0 @@ -17824,7 +17944,7 @@ snapshots: transitivePeerDependencies: - typescript - postcss-loader@8.2.1(@rspack/core@1.6.8)(postcss@8.5.25)(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + postcss-loader@8.2.1(@rspack/core@1.6.8)(postcss@8.5.25)(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: cosmiconfig: 9.0.2(typescript@5.9.3) jiti: 2.7.0 @@ -17832,7 +17952,7 @@ snapshots: semver: 7.6.3 optionalDependencies: '@rspack/core': 1.6.8 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) transitivePeerDependencies: - typescript @@ -17846,7 +17966,7 @@ snapshots: postcss-merge-rules@7.0.11(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 caniuse-api: 3.0.0 cssnano-utils: 5.0.3(postcss@8.5.25) postcss: 8.5.25 @@ -17866,14 +17986,14 @@ snapshots: postcss-minify-params@7.0.9(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 cssnano-utils: 5.0.3(postcss@8.5.25) postcss: 8.5.25 postcss-value-parser: 4.2.0 postcss-minify-selectors@7.1.2(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 caniuse-api: 3.0.0 cssesc: 3.0.0 postcss: 8.5.25 @@ -17931,7 +18051,7 @@ snapshots: postcss-normalize-unicode@7.0.9(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 postcss: 8.5.25 postcss-value-parser: 4.2.0 @@ -17953,7 +18073,7 @@ snapshots: postcss-reduce-initial@7.0.9(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 caniuse-api: 3.0.0 postcss: 8.5.25 @@ -18513,14 +18633,14 @@ snapshots: sass-embedded: 1.100.0 webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - sass-loader@16.0.8(@rspack/core@1.6.8)(sass-embedded@1.100.0)(sass@1.101.0)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + sass-loader@16.0.8(@rspack/core@1.6.8)(sass-embedded@1.100.0)(sass@1.101.0)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: neo-async: 2.6.2 optionalDependencies: '@rspack/core': 1.6.8 sass: 1.101.0 sass-embedded: 1.100.0 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) sass@1.100.0: dependencies: @@ -18751,7 +18871,7 @@ snapshots: - supports-color - utf-8-validate - socket.io-parser@4.2.6(supports-color@7.2.0): + socket.io-parser@4.2.7(supports-color@7.2.0): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@7.2.0) @@ -18766,7 +18886,7 @@ snapshots: debug: 4.4.3(supports-color@7.2.0) engine.io: 6.6.9(supports-color@7.2.0) socket.io-adapter: 2.5.8(supports-color@7.2.0) - socket.io-parser: 4.2.6(supports-color@7.2.0) + socket.io-parser: 4.2.7(supports-color@7.2.0) transitivePeerDependencies: - bufferutil - supports-color @@ -18796,11 +18916,11 @@ snapshots: source-map-js: 1.2.1 webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - source-map-loader@5.0.0(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + source-map-loader@5.0.0(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) source-map-support@0.5.19: dependencies: @@ -18936,17 +19056,17 @@ snapshots: dependencies: webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - style-loader@3.3.4(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + style-loader@3.3.4(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) - style-loader@4.0.0(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + style-loader@4.0.0(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) stylehacks@7.0.11(postcss@8.5.25): dependencies: - browserslist: 4.28.5 + browserslist: 4.28.8 postcss: 8.5.25 postcss-selector-parser: 7.1.4 @@ -19099,7 +19219,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.0 + terser: 5.50.0 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: clean-css: 5.3.3 @@ -19114,7 +19234,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.0 + terser: 5.50.0 webpack: 5.105.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: clean-css: 5.3.3 @@ -19124,13 +19244,13 @@ snapshots: html-minifier-terser: 6.1.0 postcss: 8.5.25 - terser-webpack-plugin@5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + terser-webpack-plugin@5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.0 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + terser: 5.50.0 + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: clean-css: 5.3.3 cssnano: 7.1.9(postcss@8.5.25) @@ -19142,14 +19262,14 @@ snapshots: terser@5.43.1: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.17.0 + acorn: 8.18.0 commander: 2.20.3 source-map-support: 0.5.21 - terser@5.49.0: + terser@5.50.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.17.0 + acorn: 8.18.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -19221,15 +19341,15 @@ snapshots: dependencies: tslib: 2.8.1 - ts-loader@9.6.1(loader-utils@2.0.4)(typescript@5.9.3)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + ts-loader@9.6.1(loader-utils@2.0.4)(typescript@5.9.3)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: chalk: 4.1.2 - enhanced-resolve: 5.24.3 + enhanced-resolve: 5.24.5 micromatch: 4.0.8 semver: 7.6.3 source-map: 0.7.6 typescript: 5.9.3 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: loader-utils: 2.0.4 @@ -19254,7 +19374,7 @@ snapshots: tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.24.0 + enhanced-resolve: 5.24.5 tapable: 2.3.3 tsconfig-paths: 4.2.0 @@ -19311,8 +19431,6 @@ snapshots: ua-parser-js@0.7.41: {} - undici-types@7.24.6: {} - undici-types@8.3.0: {} undici@8.9.0: {} @@ -19353,6 +19471,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.3.1(browserslist@4.28.8): + dependencies: + browserslist: 4.28.8 + escalade: 3.2.0 + picocolors: 1.1.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -19443,7 +19567,7 @@ snapshots: webidl-conversions@3.0.1: optional: true - webpack-dev-middleware@6.1.3(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + webpack-dev-middleware@6.1.3(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: colorette: 2.0.20 memfs: 3.5.3 @@ -19451,7 +19575,7 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) webpack-dev-middleware@7.4.2(tslib@2.8.1)(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: @@ -19466,7 +19590,7 @@ snapshots: transitivePeerDependencies: - tslib - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: colorette: 2.0.20 memfs: 4.57.8(tslib@2.8.1) @@ -19475,7 +19599,7 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) transitivePeerDependencies: - tslib optional: true @@ -19548,19 +19672,19 @@ snapshots: webpack-sources@3.5.1: {} - webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: typed-assert: 1.0.9 webpack: 5.105.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: - html-webpack-plugin: 5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + html-webpack-plugin: 5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) - webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)))(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)): dependencies: typed-assert: 1.0.9 - webpack: 5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) + webpack: 5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25) optionalDependencies: - html-webpack-plugin: 5.6.7(@rspack/core@1.6.8)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + html-webpack-plugin: 5.6.7(@rspack/core@1.6.8)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) webpack-virtual-modules@0.6.2: {} @@ -19572,12 +19696,12 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.17.0 - acorn-import-phases: 1.0.4(acorn@8.17.0) - browserslist: 4.28.5 + acorn: 8.18.0 + acorn-import-phases: 1.0.4(acorn@8.18.0) + browserslist: 4.28.8 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.24.3 - es-module-lexer: 2.1.0 + enhanced-resolve: 5.24.5 + es-module-lexer: 2.3.1 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -19613,12 +19737,12 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.17.0 - acorn-import-phases: 1.0.4(acorn@8.17.0) - browserslist: 4.28.5 + acorn: 8.18.0 + acorn-import-phases: 1.0.4(acorn@8.18.0) + browserslist: 4.28.8 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.24.3 - es-module-lexer: 2.1.0 + enhanced-resolve: 5.24.5 + es-module-lexer: 2.3.1 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -19646,23 +19770,23 @@ snapshots: - postcss - uglify-js - webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25): + webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.17.0 - browserslist: 4.28.5 + acorn: 8.18.0 + browserslist: 4.28.8 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.24.3 - es-module-lexer: 2.1.0 + enhanced-resolve: 5.24.5 + es-module-lexer: 2.3.1 eslint-scope: 5.1.1 events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.0(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) + minimizer-webpack-plugin: 5.6.1(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)(webpack@5.109.2(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.25))(csso@5.0.5)(esbuild@0.25.9)(html-minifier-terser@6.1.0)(postcss@8.5.25)) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 965dd4910c..3cf22bafd5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,9 +8,10 @@ minimumReleaseAgeStrict: true overrides: # Security fixes fast-uri: 3.1.5 - "js-yaml@4.2.0": "4.3.0" + "js-yaml@4.2.0": "4.3.1" "brace-expansion@5.0.8": "5.0.9" "brace-expansion@<1.1.18": "1.1.18" + "socket.io-parser@4.2.6": 4.2.7 svgo: 4.0.2 shell-quote: 1.9.0 adm-zip: 0.6.0 diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000000..03cc6905f7 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,11 @@ +sonar.organization=alfresco +sonar.projectKey=Alfresco_alfresco-ng2-components + +sonar.sources=lib +sonar.tests=lib +sonar.test.inclusions=**/*.spec.ts +sonar.exclusions=**/node_modules/**,**/dist/**,**/*.spec.ts,**/*.mock.ts,**/mock/**,**/mocks/**,**/testing/**,**/stories/** + +sonar.javascript.lcov.reportPaths=coverage/core/lcov.info,coverage/content-services/lcov.info,coverage/extensions/lcov.info,coverage/insights/lcov.info,coverage/process-services/lcov.info,coverage/process-services-cloud/lcov.info + +sonar.sourceEncoding=UTF-8