Compare commits

...
192 Commits
Author SHA1 Message Date
Michal Kinas 3496363b8e Release 9.0.0 (#12075)
* Release 9.0.0

* Add missing entry
2026-07-20 13:54:51 +02:00
dependabot[bot]andDomenico Sibilio d25038dc59 build(deps): bump the github-actions group across 2 directories with 8 updates (#12072)
Bumps the github-actions group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` |
| [github/codeql-action/autobuild](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` |
| [crowdin/github-action](https://github.com/crowdin/github-action) | `2.16.3` | `2.16.4` |
| [Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml](https://github.com/alfresco/alfresco-build-tools) | `18.18.0` | `18.19.0` |
| [Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment](https://github.com/alfresco/alfresco-build-tools) | `18.18.0` | `18.19.0` |
| [github/gh-aw-actions/setup](https://github.com/github/gh-aw-actions) | `0.82.7` | `0.82.12` |

Bumps the github-actions group with 1 update in the /.github/actions/setup directory: [Alfresco/alfresco-build-tools/.github/actions/git-latest-tag](https://github.com/alfresco/alfresco-build-tools).


Updates `github/codeql-action/init` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

Updates `github/codeql-action/autobuild` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

Updates `github/codeql-action/analyze` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

Updates `crowdin/github-action` from 2.16.3 to 2.16.4
- [Release notes](https://github.com/crowdin/github-action/releases)
- [Commits](https://github.com/crowdin/github-action/compare/52aa776766211d83d975df51f3b9c53c2f8ba35f...e0c8f73cdc0fafde9396e056c5038217000a32d1)

Updates `Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml` from 18.18.0 to 18.19.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a8bc14631a9ce72275346e536607c4527591112a...1d671f8f10336861c89c67be57c6648d98876103)

Updates `Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment` from 18.18.0 to 18.19.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a8bc14631a9ce72275346e536607c4527591112a...1d671f8f10336861c89c67be57c6648d98876103)

Updates `github/gh-aw-actions/setup` from 0.82.7 to 0.82.12
- [Release notes](https://github.com/github/gh-aw-actions/releases)
- [Changelog](https://github.com/github/gh-aw-actions/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/gh-aw-actions/compare/bf7ba42ce6443bf79fa184c9c6a35de202690bfc...23fd0ef1f0a76a3707df928f9c733abd98e4ec75)

Updates `Alfresco/alfresco-build-tools/.github/actions/git-latest-tag` from 18.18.0 to 18.19.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a8bc14631a9ce72275346e536607c4527591112a...1d671f8f10336861c89c67be57c6648d98876103)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: crowdin/github-action
  dependency-version: 2.16.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml
  dependency-version: 18.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment
  dependency-version: 18.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/gh-aw-actions/setup
  dependency-version: 0.82.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag
  dependency-version: 18.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2026-07-20 11:20:35 +00:00
dependabot[bot]andDomenico Sibilio c348ea32c0 build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 (#12073)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.4.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e...820762786026740c76f36085b0efc47a31fe5020)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2026-07-20 11:19:39 +00:00
dependabot[bot]andDomenico Sibilio 0505b1d5c3 build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 in /.github/actions/setup (#12074)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.4.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e...820762786026740c76f36085b0efc47a31fe5020)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2026-07-20 11:19:01 +00:00
Michal KinasandClaude Opus 4.8 0a19be090e [ACS-12286] Pass includeFields through to getRecentFiles for -recent- (#12067)
* [ACS-12286] Pass includeFields through to getRecentFiles for -recent-

loadFolderByNodeId forwarded includeFields to every custom source except
-recent-, and getRecentFiles had no includeFields parameter, hardcoding the
search include set. Thread includeFields through to the recent-files search
request (de-duplicated, defaults preserved) so callers can request extra
fields such as isFavorite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [ACS-12286] Document includeFields parameter for getRecentFiles

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [ACS-12286] Use typed PersonEntry instead of any in getRecentFiles spec

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 10:03:05 +02:00
AleksanderSklorz b69c3ae1ae [MNT-25230] Displayed modified time for node version (#12066)
* [MNT-25230] Displayed modified time for node version

* [MNT-25230] Addressed copilot comment
2026-07-16 13:11:37 +02:00
ce907417b7 AAE-48166 Compensate for VM/Citrix clock drift in token expiry check (#12024)
* fix: compensate for VM/Citrix clock drift in token expiry check

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* feat(core/auth): add TimeSyncDateTimeProvider for angular-oauth2-oidc clock drift correction

* feat(auth): add periodic clock re-sync to protect against mid-session drift in Citrix/VM environments

- Add startPeriodicSync() and stopPeriodicSync() to TimeSyncService
- Re-sync clock offset every 5 minutes and on document visibility change
- Add security cap (maxAllowedOffsetMs) to reject unreasonably large offsets
- Preserve existing offset on sync failures instead of resetting to 0
- Wire periodic sync start in RedirectAuthService.configureAuth()
- Wire periodic sync stop in RedirectAuthService.logout()
- Add unit tests for periodic sync and offset cap behavior

* feat: replace dedicated time API with passive Date response header interception

- Add `updateClockOffsetFromDateHeader()` to `TimeSyncService` so the clock
  offset can be updated from any HTTP `Date` response header (RFC 7231)
- Make `serverTimeUrl` config optional: `syncClockOffset` is a safe no-op and
  `checkTimeSync` uses the stored `clockOffsetMs` when no URL is configured
- Add `DateHeaderTimeSyncInterceptor` that reads the `Date` header from every
  HTTP response and passively keeps `TimeSyncService.clockOffsetMs` current
- Register the new interceptor in `provideCoreAuth()` / `AuthModule`
- Export `DateHeaderTimeSyncInterceptor` from the public API
- Add unit tests for all new paths

* feat: retry token refresh before checking for clock out-of-sync

- tokenHasExpiredDueToClockOutOfSync$: skip the first "token expired" event
  so the library's automatic refresh has a chance to run before clock drift
  is diagnosed as the root cause
- oauthErrorEventOccurDueToClockOutOfSync$: use scan() to skip the first
  token_refresh_error (allowing one retry) and only check clock sync on the
  second occurrence; all other error types are still checked immediately
- Update test for token expiry: now requires two events before logout
- Replace single token_refresh_error clock-sync test with two tests:
  one verifying no logout on first error, one verifying logout on second

* fix(core): remove duplicate @angular/common/http import in date-header-time-sync interceptor spec

* fix(core): treat empty/whitespace serverTimeUrl as not configured in TimeSyncService

* fix(core): limit DateHeaderTimeSyncInterceptor to IAM API responses only

* refactor: remove tokenHasExpiredDueToClockOutOfSync$ and re-sync clock + refresh token on validation failure

Instead of having a separate observable that detects token expiration due to clock
drift and immediately logs the user out, the oauthErrorEventOccurDueToClockOutOfSync$
now re-syncs the clock offset and attempts a token refresh when clock drift is detected.
Only if the refresh fails after re-syncing does it propagate the error and trigger logout.

* fix(auth): check token validity after clock re-sync before attempting refresh

After re-syncing the clock offset, the code now checks whether the token
is actually still valid using the corrected time (via tokenHasExpired()).
If the token is valid, no refresh is needed — the token only appeared
expired due to clock drift. This avoids the impossible situation of
retrying a token refresh when the triggering error was itself a refresh
error.

* refactor(auth): replace IAM header interceptor with HEAD request to app root for time sync

Instead of passively reading the Date header from IAM responses (which
requires IAM to be reachable and has CORS constraints), the TimeSyncService
now makes a lightweight HEAD request to the application's own root URL
(served by nginx). This is simpler and more reliable because:

- No CORS issues (same origin)
- Nginx always includes a Date header
- HEAD request has minimal payload (no body)
- Works before authentication is established
- No dedicated serverTimeUrl configuration needed

The DateHeaderTimeSyncInterceptor has been removed as it is no longer needed.

* fix(auth): reset tokenRefreshErrorCount on successful token event

The tokenRefreshErrorCount in the oauthErrorEventOccurDueToClockOutOfSync$
stream now resets to 0 when a 'token_received' or 'token_refreshed' event
occurs. This prevents intermittent errors that self-correct from
accumulating toward the clock-drift detection threshold.

* fix(core): provide meaningful error message when API response body is null

When the server returns no response body (e.g., during token expiration,
network interruption, or CORS failures), err.error is null causing
JSON.stringify(null) to produce the unhelpful message "null".

Now we explicitly handle the null case and produce a message like
"401 Unauthorized" instead of "null".

* fix: resync clock before invalidating tokens at startup

At startup, when the first OAuth event fires, the service checks if the
access token is valid. Previously it would immediately clear storage if
the token appeared invalid. This could cause false negatives when the
local clock was out of sync (e.g. VM/Citrix environments).

Now the service first re-syncs the clock offset via TimeSyncService, then
re-evaluates the token validity. Storage is only cleared if the token is
still invalid after the corrected time check.

* Remove maxAllowedOffsetMs from TimeSyncService

* Fix startPeriodicSync call to match updated signature

* WIP

* Add Flag

* AAE-48166 Sync time using server time

* AAE-48166 Fix unit test

* AAE-48166 Fix service

* AAE-48166 Fix service

* AAE-48166 Fix service and add tests

* AAE-48166 Use app root instead of server time url

* AAE-48166 Use oauth2.timeSync config key for time sync gate

* AAE-48166 Keep redirect auth flow unchanged when time sync is disable

* Add oauth2.showDebugInformation and related debug logging for time sync

* AAE-48166 Fix multi-tab OIDC refresh failures by resyncing server time when timeSync enabled

* AAE-48166 Avoid repeated server time calls by caching the result for 2 seconds

* AAE-48166 test(auth): cover timeSync clock sync for implicit flow silent refresh

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Eugenio Romano <eromano@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Diogo Bastos <diogo.bastos@hyland.com>
Co-authored-by: alep85 <amedeo.lepore@hyland.com>
2026-07-16 11:31:15 +02:00
Darren Thornton 4c7765e3fa AAE-46517 Add onRowCountChange form event for Repeatable Sections (#12062)
* AAE-46517 Add onRowCountChange event for Repeatable Sections

* code review fixes for unit test
2026-07-14 18:40:41 -05:00
Alex Molodyh 407a64996e AAE-46248 Format dropdown/radio option labels in display-text expressions (#12045) 2026-07-14 14:54:13 -07:00
dependabot[bot] c0a102f87f build(deps): bump undici from 7.24.7 to 8.7.0 (#12049)
Bumps [undici](https://github.com/nodejs/undici) from 7.24.7 to 8.7.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.24.7...v8.7.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 8.7.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 12:21:55 +01:00
066ef30516 GH auto: Automated Update of Translations from Crowdin (#12044)
* New Crowdin translations by GitHub Action

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: hxpstudiocicduser <hxpstudiocicduser@hyland.com>
Co-authored-by: Denys Vuika <denys.vuika@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-14 12:08:47 +01:00
AleksanderSklorz 01cea60490 [MNT-25230] adw version history does not provide user information (#12050)
* [MNT-25230] Displayed user displayName in version history for specific version

* [MNT-25230] Unit tests

* [MNT-25230] Addressed copilot comment

* [MNT-25230] Addressed copilot comment

* [MNT-25230] Addressed copilot comment

* [MNT-25230] Addressed copilot comment

* [MNT-25230] Addressed copilot comment
2026-07-13 10:38:13 +02:00
dependabot[bot] f438c6ce69 build(deps): bump the github-actions group across 2 directories with 7 updates (#12059)
Bumps the github-actions group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` |
| [github/codeql-action/autobuild](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` |
| [Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml](https://github.com/alfresco/alfresco-build-tools) | `18.15.1` | `18.18.0` |
| [Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment](https://github.com/alfresco/alfresco-build-tools) | `18.15.1` | `18.18.0` |
| [github/gh-aw-actions/setup](https://github.com/github/gh-aw-actions) | `0.82.2` | `0.82.7` |

Bumps the github-actions group with 1 update in the /.github/actions/setup directory: [Alfresco/alfresco-build-tools/.github/actions/git-latest-tag](https://github.com/alfresco/alfresco-build-tools).


Updates `github/codeql-action/init` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9)

Updates `github/codeql-action/autobuild` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9)

Updates `github/codeql-action/analyze` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9)

Updates `Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml` from 18.15.1 to 18.18.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/499eb5d58f3f82a4efa4eaedab26dbecff18328c...a8bc14631a9ce72275346e536607c4527591112a)

Updates `Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment` from 18.15.1 to 18.18.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/499eb5d58f3f82a4efa4eaedab26dbecff18328c...a8bc14631a9ce72275346e536607c4527591112a)

Updates `github/gh-aw-actions/setup` from 0.82.2 to 0.82.7
- [Release notes](https://github.com/github/gh-aw-actions/releases)
- [Changelog](https://github.com/github/gh-aw-actions/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/gh-aw-actions/compare/3fac1cfa7a5a375a6a5eb9839178f6dad7adb60a...bf7ba42ce6443bf79fa184c9c6a35de202690bfc)

Updates `Alfresco/alfresco-build-tools/.github/actions/git-latest-tag` from 18.15.1 to 18.18.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/499eb5d58f3f82a4efa4eaedab26dbecff18328c...a8bc14631a9ce72275346e536607c4527591112a)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml
  dependency-version: 18.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment
  dependency-version: 18.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/gh-aw-actions/setup
  dependency-version: 0.82.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag
  dependency-version: 18.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 09:07:38 +01:00
Denys Vuika 09ef05038c chore: remove deprecated MaterialModule and its references (#12051)
* chore: remove deprecated MaterialModule and its references

* chore: remove MaterialModule exports from public API
2026-07-13 09:07:00 +01:00
Anamika Dey c7bd56f244 AAE-43974 Fix for alfresco-content-app e2e failure (#12055)
* AAE-43974 Fix for alfresco-content-app e2e failure

* AAE-43974 Refactored based on review comments

* AAE-43974 Removing unit test cases written for isError as it is being tested by passwordErrorStateMatcher

* [ci:force] re-trigger CI
2026-07-10 18:53:53 +00:00
Grzegorz Jaśkowski b86e41515e [ACS-12037] Remove Knowledge Discovery from ADF (#12042)
* [ACS-12037] Remove Knowledge Discovery from ADF

* [ACS-12037] Resolve Copilot CR comments

* [ACS-12037] Complete cleanup, revert i18n changes

* [ACS-12037] Cleanup features and APIs related to hxiconnector

* [ACS-12037] Update docs
2026-07-10 15:37:24 +02:00
David Olson 0b35118dee AAE-47880 UI breaks when pasting very large text into text field (#12043) 2026-07-09 10:11:28 -05:00
Michal Kinas fe2b3d85dd [ACS-12108] Introduce signed commits into ADF workflows (#12040) 2026-07-09 15:05:58 +02:00
Anamika DeyandEhsan Rezaei b0dc85422c Improvement/AAE-43974 Refactoring form fields (#11945)
* AAE-43974 Refactoring form fields with mat-error

* AAE-43974 Removed adf-error redundant class from all available places

* AAE-43974 Followed code flow syntax

* AAE-43974 Refactored based on review comments

* AAE-43974 Added dummy test lable

* AAE-43974 Added dummy error message for amount field

* AAE-43974 Refactored multiline widget based on reviewer's comment

* AAE-43974 Error icon style added by mixins

* AAE-43974 Missing Conditions added

* AAE-43974 Added Missing conditions

* AAE-43974 Consistent conditions added and dummy error message added

* AAE-43974 Added subscriptsizing dynamic for testing

* AAE-43974 Reverted Subscriptsizing

* AAE-43974 Added spacing between form fields in mobile view

* AAE-43974 Dummy error message changed

* AAE-43974 Changed error icon allignment for testing

* AAE-43974 Added dummy error message

* AAE-43974 Added form field gap in mobile view and dummy erro message

* AAE-43974 Refactored based on review coemments and changed the error icon allignment

* AAE-43974 Fixed the mixin path

* AAE-43974 Removed dummy error message for amount widget

* AAE-43974 Added adf-error-text class to mat-error for e2e fix

* AAE-43974 adf-error-text class added inside mat-error

* AAE-43974 Whitespace issue resolved

* AAE-43974 Whiespace issue fix

* AAE-43974 Added context pushing logic in text widget

* AAE-43974 Added margin-bottom for regression fix

* AAE-43974 Trying with different margin-bottom

* AAE-43974 Testing regression issue

* AAE-43974 Testing for regression failure

* AAE-43974 Testing Regression failures

* AAE-43974 Test Regression failure

* AAE-43974 Testing multiline Regression failure

* AAE-43974 Testing fix regarding regression failure related to multiline-text widget

* AAE-43974 Test Regression failure for multiline-text widget

* AAE-43974 Testing regression failure for multiline-text

* AAE-43974 Testing regression failure for multi-line

* AAE-43974 Testing regression failure

* AAE-43974 Testing Regression failure

* AAE-43974 Testing regression failure

* AAE-43974 Removed the commented code

* [ci:force] re-trigger CI

---------

Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com>
2026-07-08 18:32:46 +00:00
23f0392c12 AAE-47634 Refactor: switch form service getTask to use runtime bundle API (#12020)
* refactor: switch form service getTask to use runtime bundle API instead of query service

* Update form-cloud.service.ts

* Add TaskDetailsCloudModelRuntimeBundle interface

* Update getTaskById to return TaskDetailsCloudModelRuntimeBundle

* Modify return type of getTaskById method

Updated return type of getTaskById to include TaskDetailsCloudModel.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Refactor TaskDetailsCloudModel by removing fields

Removed unused properties from TaskDetailsCloudModel.

* Update task-cloud.service.ts

* Update task-cloud.service.ts

* fix: add 404 fallback to query service in FormCloudService.getTask for completed tasks

* AAE-47634 getTaskById: call Runtime Bundle first, fall back to Query Service on 404

* AAE-47634 Gate Runtime Bundle task fallback behind ADF_TASK_RUNTIME_BUNDLE_FALLBACK_ENABLED token and drop no longer used taskDetailsSource input

* refactor: update task fetching tests to use async/await and firstValueFrom

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Eugenio Romano <eromano@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: alep85 <amedeo.lepore@hyland.com>
2026-07-08 13:48:09 +00:00
Mykyta Maliarchuk 997303e6a7 [ACS-11325] remove chevron button from tab order in adf-tree (#12041)
* [ACS-11325] remove chevron button from tab order in adf-tree

* [ACS-11325] add unit tests
2026-07-08 10:13:39 +02:00
Adam Świderski 45d1818f04 [ACS-12098] firefox headless race condition viewer fix (#12023)
* [ACS-12098] firefox headless race condition viewer fix

* [ACS-12098] review fixes 1

* [ACS-12098] review fixes 2

* [ACS-12098] review fixes 3

* last firefox headless fixes
2026-07-07 13:21:14 +02:00
dependabot[bot]andDomenico Sibilio 2f50af623d build(deps): bump js-yaml from 3.14.2 to 3.15.0 (#12018)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.2 to 3.15.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.2...3.15.0)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 3.15.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Domenico Sibilio <domenicosibilio@gmail.com>
2026-07-06 13:59:13 +00:00
dependabot[bot] 9c56712328 build(deps): bump the github-actions group across 2 directories with 7 updates (#12037)
Bumps the github-actions group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.36.2` | `4.36.3` |
| [github/codeql-action/autobuild](https://github.com/github/codeql-action) | `4.36.2` | `4.36.3` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.36.2` | `4.36.3` |
| [Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml](https://github.com/alfresco/alfresco-build-tools) | `18.13.0` | `18.15.1` |
| [Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment](https://github.com/alfresco/alfresco-build-tools) | `18.13.0` | `18.15.1` |
| [github/gh-aw-actions/setup](https://github.com/github/gh-aw-actions) | `0.81.6` | `0.82.2` |

Bumps the github-actions group with 1 update in the /.github/actions/setup directory: [Alfresco/alfresco-build-tools/.github/actions/git-latest-tag](https://github.com/alfresco/alfresco-build-tools).


Updates `github/codeql-action/init` from 4.36.2 to 4.36.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

Updates `github/codeql-action/autobuild` from 4.36.2 to 4.36.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

Updates `github/codeql-action/analyze` from 4.36.2 to 4.36.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

Updates `Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml` from 18.13.0 to 18.15.1
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/10cea6c0b390c4f8af21d9dc1670d581bd10319f...499eb5d58f3f82a4efa4eaedab26dbecff18328c)

Updates `Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment` from 18.13.0 to 18.15.1
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/10cea6c0b390c4f8af21d9dc1670d581bd10319f...499eb5d58f3f82a4efa4eaedab26dbecff18328c)

Updates `github/gh-aw-actions/setup` from 0.81.6 to 0.82.2
- [Release notes](https://github.com/github/gh-aw-actions/releases)
- [Changelog](https://github.com/github/gh-aw-actions/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/gh-aw-actions/compare/ba6380cc6e5be5d21677bebe04d52fb48e3abec7...3fac1cfa7a5a375a6a5eb9839178f6dad7adb60a)

Updates `Alfresco/alfresco-build-tools/.github/actions/git-latest-tag` from 18.13.0 to 18.15.1
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/10cea6c0b390c4f8af21d9dc1670d581bd10319f...499eb5d58f3f82a4efa4eaedab26dbecff18328c)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml
  dependency-version: 18.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment
  dependency-version: 18.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/gh-aw-actions/setup
  dependency-version: 0.82.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag
  dependency-version: 18.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 15:34:53 +02:00
Michal Kinas 448e667c52 [MNT-25681] Content node selector panel filtering fixed (#12032)
* [MNT-25681] Content node selector panel filtering fixed

* [MNT-25681] Small cleanup

* [MNT-25681] CR fix
2026-07-03 16:41:39 +02:00
AleksanderSklorz 18e602aa85 [PRODSEC-13253] Increased peerDependencies versions to allow to increase angular version in other projects (#12031)
* [PRODSEC-13253] Increased peerDependencies versions to allow to increase angular version in other projects

* [PRODSEC-13253] Addressec copilot comments
2026-07-03 14:05:13 +02:00
Alfresco Buildandhxpstudiocicduser 53ef0cfc00 New Crowdin translations by GitHub Action (#12021)
Co-authored-by: hxpstudiocicduser <hxpstudiocicduser@hyland.com>
2026-07-03 10:07:27 +01:00
Michal Kinas 4cd8648a05 Adjust release triggers to use cache-writable token (#12030) 2026-07-03 07:56:50 +02:00
Joshua Cain 7f57b3936b AAE-39528 Session timeout features (#12008)
* feat: session timeout features
2026-07-02 12:52:43 -04:00
Michal Kinas 5a30baad99 Release cache read/write fix (#12029) 2026-07-02 18:30:38 +02:00
Michal Kinas 5050c3d974 [ACS-12041] Add debounceTime in PeopleWidgetComponent to limit API calls on every keystroke (#12027) 2026-07-02 17:46:42 +02:00
Michal Kinas d8b36606e2 [MNT-25681] Search refactoring and unification (#12019)
* [MNT-25681] Search refactoring and unification

* [MNT-25681] CR fixes
2026-07-02 17:46:30 +02:00
Vito Albano 37f8fe47ac AAE-46695 Upgrade to pnpm 11.9 (#12028)
* [AAE-46695] Upgrade to pnpm 11.9

* [ci:force] - Checking

* [ci:force] - Changes to package.json should trigger --all
2026-07-02 16:26:55 +01:00
Domenico Sibilio af0d1e4ead AAE-47093 Update Supply Chain Review GH AW to latest (#12025)
[skip ci]
2026-07-02 11:59:47 +02:00
dependabot[bot] 699f45e486 build(deps): bump actions/github-script (#11956)
Bumps [actions/github-script](https://github.com/actions/github-script) from 7.0.1 to 9.0.0.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/60a0d83039c74a4aee543508d2ffcb1c3799cdea...3a2844b7e9c422d3c10d287c895573f7108da1b3)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:28:56 +01:00
Alfresco Buildandhxpstudiocicduser 416f04d6bd New Crowdin translations by GitHub Action (#12003)
Co-authored-by: hxpstudiocicduser <hxpstudiocicduser@hyland.com>
2026-06-30 11:28:33 +01:00
dependabot[bot] 5123e80bd9 build(deps): bump actions/cache/restore (#12014)
Bumps [actions/cache/restore](https://github.com/actions/cache) from 5.0.5 to 6.1.0.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9)

---
updated-dependencies:
- dependency-name: actions/cache/restore
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:27:41 +01:00
dependabot[bot] 283a0ab18a build(deps): bump actions/cache/restore in /.github/actions/setup (#12016)
Bumps [actions/cache/restore](https://github.com/actions/cache) from 5.0.5 to 6.1.0.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9)

---
updated-dependencies:
- dependency-name: actions/cache/restore
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:27:17 +01:00
dependabot[bot] bab668033e build(deps): bump actions/cache/save in /.github/actions/save-nx-cache (#12015)
Bumps [actions/cache/save](https://github.com/actions/cache) from 5.0.5 to 6.1.0.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9)

---
updated-dependencies:
- dependency-name: actions/cache/save
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:12:30 +01:00
dependabot[bot] 1a50dad132 build(deps): bump actions/checkout from 6.0.2 to 7.0.0 (#12002)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:11:49 +01:00
dependabot[bot] d0f9c3d5a4 build(deps): bump the github-actions group across 2 directories with 4 updates (#12013)
Bumps the github-actions group with 3 updates in the / directory: [Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml](https://github.com/alfresco/alfresco-build-tools), [Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment](https://github.com/alfresco/alfresco-build-tools) and [github/gh-aw-actions/setup](https://github.com/github/gh-aw-actions).
Bumps the github-actions group with 1 update in the /.github/actions/setup directory: [Alfresco/alfresco-build-tools/.github/actions/git-latest-tag](https://github.com/alfresco/alfresco-build-tools).


Updates `Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml` from 18.12.0 to 18.13.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1...10cea6c0b390c4f8af21d9dc1670d581bd10319f)

Updates `Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment` from 18.12.0 to 18.13.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1...10cea6c0b390c4f8af21d9dc1670d581bd10319f)

Updates `github/gh-aw-actions/setup` from 0.77.5 to 0.81.4
- [Release notes](https://github.com/github/gh-aw-actions/releases)
- [Changelog](https://github.com/github/gh-aw-actions/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/gh-aw-actions/compare/3ea13c02d765410340d533515cb31a7eef2baaf0...9fba95c4e1e3ce39704ccd39b440f6935715bc09)

Updates `Alfresco/alfresco-build-tools/.github/actions/git-latest-tag` from 18.12.0 to 18.13.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1...10cea6c0b390c4f8af21d9dc1670d581bd10319f)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml
  dependency-version: 18.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment
  dependency-version: 18.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/gh-aw-actions/setup
  dependency-version: 0.81.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag
  dependency-version: 18.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:11:17 +01:00
dependabot[bot] 2808988171 build(deps): bump actions/cache/save (#12017)
Bumps [actions/cache/save](https://github.com/actions/cache) from 5.0.5 to 6.1.0.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9)

---
updated-dependencies:
- dependency-name: actions/cache/save
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 11:10:47 +01:00
Amedeo Lepore bd7f393db9 AAE-47634 Fix block task claim checking status on Runtime Bundle (#12009)
* AAE-47634 Add taskDetailsSource input to read task from

* AAE-47634 Fall back to Query strategy when taskDetailsSource is unsupported

* AAE-47634 Reset loading state when task details request fails

* AAE-47634 Reload task on taskDetailsSource change
2026-06-26 17:10:22 +00:00
d2d6696c05 Migrate to Angular 20, TypeScript 5.9, and Angular Material 20 (#11657)
* chore: migrate to Angular 20, TypeScript 5.9, and supporting packages

chore: migrate to Angular 20, TypeScript 5.9, and supporting packages

This commit migrates the Nx monorepo from Angular 19 to Angular 20
and updates all related dependencies to their compatible versions.

- @angular/core: 19.2.18 → 20.3.9
- @angular/material: 19.2.19 → 20.2.14
- @angular/cdk: 19.2.19 → 20.2.14
- @angular/material-date-fns-adapter: 19.2.19 → 20.2.14
- typescript: 5.8.3 → 5.9.3
- ng-packagr: 19.2.2 → 20.3.2

- @angular-devkit/build-angular: 19.2.19 → 20.3.16
- @angular-devkit/architect: 0.1902.19 → 0.2003.16
- @angular-devkit/core: 19.2.19 → 20.3.16
- @angular-devkit/schematics: 19.2.19 → 20.3.16
- @schematics/angular: 19.2.7 → 20.3.16

- @angular-eslint/eslint-plugin: 19.3.0 → 20.7.0
- @angular-eslint/eslint-plugin-template: 19.3.0 → 20.7.0
- @angular-eslint/template-parser: 19.3.0 → 20.7.0
- @typescript-eslint/eslint-plugin: 6.21.0 → 8.55.0
- @typescript-eslint/parser: 6.21.0 → 8.55.0
- @typescript-eslint/typescript-estree: 8.41.0 → 8.55.0
- @typescript-eslint/utils: ^8.51.0 → 8.55.0

- nx: 22.4.1 → 22.5.1
- @nx/angular: 22.1.3 → 22.5.1
- @nx/eslint-plugin: 22.3.3 → 22.5.1
- @nx/js: 22.1.3 → 22.5.1
- @nx/node: 22.1.3 → 22.5.1
- @nx/storybook: ^20.8.4 → 22.5.1
- @nx/workspace: 22.4.5 → 22.5.1
- @nx/webpack: 22.3.3 → 22.5.1

- storybook: ^10.2.0 → 10.2.8
- @storybook/angular: ^10.2.0 → 10.2.8
- @storybook/addon-themes: ^10.2.0 → 10.2.8

1. **PortalInjector Removal (Angular CDK 20)**
   - Replaced PortalInjector usage with Injector.create()
   - Updated context-menu-overlay.service.ts to use new API

2. **ESLint Configuration**
   - Removed deprecated @typescript-eslint/brace-style rule
   - This rule was removed in @typescript-eslint v8

All libraries build successfully:
-  js-api
-  extensions
-  core
-  content-services
-  process-services
-  process-services-cloud
-  insights

Dependencies were installed using npm install --legacy-peer-deps due to
peer dependency conflicts with @mat-datetimepicker/core which requires
Angular CDK ^19.0.0 but we are using 20.2.14.

- ESLint warnings about @angular-eslint/prefer-inject are expected - this
  is a new recommendation in Angular 20 to use inject() function instead
  of constructor injection. These can be addressed in a follow-up PR.

chore: migrate to Angular 20, TypeScript 5.9, and supporting packages

This commit migrates the Nx monorepo from Angular 19 to Angular 20
and updates all related dependencies to their compatible versions.

- @angular/core: 19.2.18 → 20.3.9
- @angular/material: 19.2.19 → 20.2.14
- @angular/cdk: 19.2.19 → 20.2.14
- @angular/material-date-fns-adapter: 19.2.19 → 20.2.14
- typescript: 5.8.3 → 5.9.3
- ng-packagr: 19.2.2 → 20.3.2

- @angular-devkit/build-angular: 19.2.19 → 20.3.16
- @angular-devkit/architect: 0.1902.19 → 0.2003.16
- @angular-devkit/core: 19.2.19 → 20.3.16
- @angular-devkit/schematics: 19.2.19 → 20.3.16
- @schematics/angular: 19.2.7 → 20.3.16

- @angular-eslint/eslint-plugin: 19.3.0 → 20.7.0
- @angular-eslint/eslint-plugin-template: 19.3.0 → 20.7.0
- @angular-eslint/template-parser: 19.3.0 → 20.7.0
- @typescript-eslint/eslint-plugin: 6.21.0 → 8.55.0
- @typescript-eslint/parser: 6.21.0 → 8.55.0
- @typescript-eslint/typescript-estree: 8.41.0 → 8.55.0
- @typescript-eslint/utils: ^8.51.0 → 8.55.0

- nx: 22.4.1 → 22.5.1
- @nx/angular: 22.1.3 → 22.5.1
- @nx/eslint-plugin: 22.3.3 → 22.5.1
- @nx/js: 22.1.3 → 22.5.1
- @nx/node: 22.1.3 → 22.5.1
- @nx/storybook: ^20.8.4 → 22.5.1
- @nx/workspace: 22.4.5 → 22.5.1
- @nx/webpack: 22.3.3 → 22.5.1

- storybook: ^10.2.0 → 10.2.8
- @storybook/angular: ^10.2.0 → 10.2.8
- @storybook/addon-themes: ^10.2.0 → 10.2.8

1. **PortalInjector Removal (Angular CDK 20)**
   - Replaced PortalInjector usage with Injector.create()
   - Updated context-menu-overlay.service.ts to use new API

2. **ESLint Configuration**
   - Removed deprecated @typescript-eslint/brace-style rule
   - This rule was removed in @typescript-eslint v8

All libraries build successfully:
-  js-api
-  extensions
-  core
-  content-services
-  process-services
-  process-services-cloud
-  insights

Dependencies were installed using npm install --legacy-peer-deps due to
peer dependency conflicts with @mat-datetimepicker/core which requires
Angular CDK ^19.0.0 but we are using 20.2.14.

- ESLint warnings about @angular-eslint/prefer-inject are expected - this
  is a new recommendation in Angular 20 to use inject() function instead
  of constructor injection. These can be addressed in a follow-up PR.

  To fix these automatically, run:
  ng generate @angular/core:inject --path=lib

fix: resolve peer dependency conflicts for CI/CD

- Update @mat-datetimepicker/core from 15.0.2 to 16.0.1 (supports Angular 20)
- Update webpack override to 5.104.1 for consistency
- Add .npmrc with legacy-peer-deps=true for npm ci compatibility
- Fixes npm ci failures in CI/CD pipeline

fix: update webpack to 5.105.0 for Storybook compatibility

- Align webpack version with @angular-devkit/build-angular bundled version
- Fixes Storybook compilation error with webpack instance mismatch
- Removes unnecessary webpack overrides

chore: finalize Angular 20 migration and improve migration prompt

- Marked all migration tasks as completed in the migration plan.
- Added a comprehensive summary of the migration process, including phases, completed tasks, and known issues.
- Introduced an improved migration prompt that addresses critical considerations and provides a detailed migration strategy for Angular 20 and related packages.

fix: update migration prompt and tests for Angular 20 breaking changes

- Enhanced migration prompt with specific instructions for handling Angular CDK Directionality API changes and removal of ng-reflect-* attributes.
- Updated unit tests to replace deprecated ng-reflect-* attribute checks with appropriate Angular testing patterns.
- Adjusted user preferences service to utilize the new directionality API method for setting text direction.

fix: enhance ImgViewerComponent to handle cleanup and prevent errors after destruction

- Added a `destroyed` flag to manage component lifecycle and prevent operations on a destroyed instance.
- Implemented `afterEach` hooks in tests to ensure proper fixture cleanup.
- Updated key event handlers and methods to check for the `destroyed` state before executing actions, improving stability and preventing errors.

feat: update ESLint configuration to include @angular-eslint/prefer-inject rule

- Added the @angular-eslint/prefer-inject rule to .eslintrc.json files in content-services, process-services, and process-services-cloud, promoting the use of the inject() function for dependency injection.
- Made minor adjustments to comments in search-logical-filter.component.ts for clarity.

chore: update ESLint configuration to include @angular-eslint/prefer-inject rule

- Added the @angular-eslint/prefer-inject rule to .eslintrc.json files in extensions, insights, and js-api, promoting the use of the inject() function for dependency injection.
- Removed unnecessary eslint-disable comments in process-list-cloud.component.ts and base-task-list-cloud.component.ts for cleaner code.

remove unnecessary changes

remove useless changes

cleanup useless changes

remove useless changes

Update package.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

chore: update version of @ngx-translate/core to 17.0.0 in package.json and package-lock.json

Update package.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update package.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update .npmrc

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

chore: upgrade apollo-angular and jest packages to support Angular 20

- Upgrade apollo-angular from 10.0.3 to 13.0.0
- Upgrade @apollo/client from 3.13.1 to ^4.0.1
- Upgrade jest packages to v30 (jest, jest-environment-jsdom)
- Upgrade jest-preset-angular from 14.4.2 to 16.1.1
- Add overrides for Angular 20 peer dependency compatibility

chore: downgrade @apollo/client and apollo-angular to compatible versions

chore: downgrade @apollo/client and apollo-angular to compatible versions

chore: remove unused configuration options from jest and tsconfig

chore: refactor window.location mock in oauth2 tests for improved clarity and functionality

chore: enhance oauth2Auth tests and improve hash handling logic

chore: remove @typescript-eslint/brace-style rule from ESLint configuration

chore: add prefer-optional-chain rule to ESLint configuration

chore: update ESLint rules for optional chaining and refactor type definitions

chore: refactor tests to use TestBed for dependency injection in FileViewer and ProcessFormRendering services

chore: update AttachFileWidgetComponent to ensure early return after download

chore: update AttachFileWidgetComponent to ensure early return after download

chore: update unselectFacetBucket method to use optional chaining for safer property access

* chore: clean up package-lock.json and update webpack version in package.json

* [ACS-11306] Corrected main for eslint-angular

* [ACS-11306] Reverted unwanted change

* [ACS-11306] Fixed importing issue on ACA

* [ACS-11306] Updated node-fetch

* [ACS-11306] Reverted last commit

* [ACS-11306] Fixed rendering issue with pdf viewer

* [ACS-11306] Corrected storybook related versions

* Updating dependencies and fixing conflict

* [ACS-11306] Fixed cannot find name Buffer occurred in ACA

* chore: Updating pnpm lock file

* chore: Fixing ESLint issue

* chore: Upgrading to version 20.3.24 to avoid security issue

* chore: Fixing unit test

* chore: Fixing type and exporting missing model

* chore: Fixing type

* Chore: Migrating to Angular 20.3.25 to mitigate security issues

* Fix after rebase

* Removing unused deps

* Aligning deps

* fix create dialog name field hint (#12007)

---------

Co-authored-by: Aleksander Sklorz <Aleksander.Sklorz@hyland.com>
Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com>
Co-authored-by: Grzegorz Jaśkowski <138671284+g-jaskowski@users.noreply.github.com>
2026-06-26 10:10:54 +02:00
David Olson 7546aa91a3 AAE-47577 Form Spinner persists outside of Automate Form (#12005) 2026-06-25 09:58:24 -05:00
Mykyta Maliarchuk 74d67c39a0 [ACS-11317] a11y Fix: Tags interactive controls are not manageable via keyboard (#11845)
* [ACS-11317] Fix a11y: Delete button in create tags popup is not focusable via keyboard

* [ACS-11317] use UnitTestingUtils

* [ACS-11317] cr fixes
2026-06-25 14:23:16 +02:00
Alex Molodyh 20c20f2749 AAE-46247 Add type-aware form field value adapter service (#11968)
* AAE-46247 Add type-aware form field value adapter service
2026-06-23 10:05:53 -07:00
dependabot[bot] 2c3020c7fc build(deps): bump the github-actions group across 2 directories with 6 updates (#12001)
Bumps the github-actions group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github/codeql-action](https://github.com/github/codeql-action) | `4.36.0` | `4.36.2` |
| [crowdin/github-action](https://github.com/crowdin/github-action) | `2.16.2` | `2.16.3` |
| [hyland/github-actions-ensure-sha-pinned-actions](https://github.com/hyland/github-actions-ensure-sha-pinned-actions) | `2.0.0` | `2.0.1` |
| [Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml](https://github.com/alfresco/alfresco-build-tools) | `18.9.0` | `18.12.0` |
| [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) | `18.7.0` | `18.12.0` |

Bumps the github-actions group with 2 updates in the /.github/actions/setup directory: [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) and [pnpm/action-setup](https://github.com/pnpm/action-setup).


Updates `github/codeql-action` from 4.36.0 to 4.36.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7211b7c8077ea37d8641b6271f6a365a22a5fbfa...8aad20d150bbac5944a9f9d289da16a4b0d87c1e)

Updates `crowdin/github-action` from 2.16.2 to 2.16.3
- [Release notes](https://github.com/crowdin/github-action/releases)
- [Commits](https://github.com/crowdin/github-action/compare/8868a33591d21088edfc398968173a3b98d51706...52aa776766211d83d975df51f3b9c53c2f8ba35f)

Updates `hyland/github-actions-ensure-sha-pinned-actions` from 2.0.0 to 2.0.1
- [Release notes](https://github.com/hyland/github-actions-ensure-sha-pinned-actions/releases)
- [Commits](https://github.com/hyland/github-actions-ensure-sha-pinned-actions/compare/7d494b6b53e71f75194d74b4dd890a2266d060b5...7957efb76aba0eec7580a9c0392d3e5bec381359)

Updates `Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml` from 18.9.0 to 18.12.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/4e61fa01622e3f3a1898eb059d9a3af208897515...ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1)

Updates `Alfresco/alfresco-build-tools` from 18.7.0 to 18.12.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a6a8be7429080c132815d0482a55ae4fd28f15ba...ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1)

Updates `Alfresco/alfresco-build-tools` from 18.7.0 to 18.12.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a6a8be7429080c132815d0482a55ae4fd28f15ba...ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1)

Updates `Alfresco/alfresco-build-tools` from 18.7.0 to 18.12.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a6a8be7429080c132815d0482a55ae4fd28f15ba...ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1)

Updates `pnpm/action-setup` from 6.0.8 to 6.0.9
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/0e279bb959325dab635dd2c09392533439d90093...0ebf47130e4866e96fce0953f49152a61190b271)

Updates `Alfresco/alfresco-build-tools` from 18.7.0 to 18.12.0
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/a6a8be7429080c132815d0482a55ae4fd28f15ba...ed80b0eef8e432f517ea1aa51d8a82637c1d1cc1)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml
  dependency-version: 18.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: crowdin/github-action
  dependency-version: 2.16.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: 4.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: hyland/github-actions-ensure-sha-pinned-actions
  dependency-version: 2.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: pnpm/action-setup
  dependency-version: 6.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-23 14:35:07 +02:00
dependabot[bot] 100d348f5e build(deps-dev): bump undici from 8.3.0 to 8.5.0 (#11995)
Bumps [undici](https://github.com/nodejs/undici) from 8.3.0 to 8.5.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v8.3.0...v8.5.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 8.5.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-23 14:23:11 +02:00
Vito Albano b498d5744c [AAE-47470] - Upgrade Pnpm to 11.8.0 (#12004) 2026-06-22 17:14:47 +01:00
Mykyta Maliarchuk 80eef35e1d [ACS-11325] Add keyboard navigation and a11y support for adf-tree component (#11973)
* [ACS-11325] Add keyboard navigation and a11y support for adf-tree component

* [ACS-11325] clean up comments

* [ACS-11325] cr fixes

* [ACS-11325] cr fixes

* [ACS-11325] cr fix

* [ACS-11325] sonar issue

* [ACS-11325] fix lint
2026-06-22 12:08:41 +02:00
Bartosz Sekula 49a3f1e104 AAE-47412 Update suprocesses and linked processes for process instance model (#11996) 2026-06-19 14:05:02 +02:00
Mykyta Maliarchuk 0beaa18452 [ACS-11973] Fix: context menu disappears during bulk upload (#11994) 2026-06-19 10:26:17 +02:00
Alex Molodyh 76fd461741 AAE-47042 Add auto grow support to multiline text widget (#11981) 2026-06-16 07:19:34 -07:00
Vito Albano 78697ee62a [AAE-0000] - Fixed js-api error index.js (#11970)
* [AAE-0000] - Fixed js-api error index.js

* [AAE-46684] - readding js-api bundle
2026-06-16 14:44:52 +02:00
Adam Świderski 43c5bc17fb [ACS-12020] Updated init-aps passwords with secret ones (#11993)
* [ACS-12020] Updated init-aps passwords with secret ones

* [ACS-12020] deleted last hard coded password
2026-06-16 11:36:49 +02:00
Dominik Iwanek cda20e0386 Post-release version bump (#11988) 2026-06-15 14:30:44 +02:00
Adam Świderski 8f5099e822 [ACS-11928] convert ReadStream to Blob before appending to FormData (#11987)
* [ACS-11928] convert ReadStream to Blob before appending to FormData

* [ACS-11928] comments removed from toFormDataValue

* Trigger Build

* [ACS-11928] added unit tests and changed the blob variable name to data

* [ACS-11928] unit tests updated

* [ACS-11928] updated type in multipart form data upload

* [ACS-11928] sonar cloud fix
2026-06-15 13:15:33 +02:00
David Olson 5dd709ed58 AAE-44809 Fix form multi-file attachment - document viewer not updated on file selection (#11980) 2026-06-12 16:53:51 -05:00
Dominik Iwanek 9d353bf271 [ACS-11974] [ACA] Upload new version button is no longer disabled when clicked once (#11977) 2026-06-12 13:45:31 +02:00
Dominik Iwanek 633702860f Post-release version bump (#11984) 2026-06-12 12:59:14 +02:00
Domenico Sibilio bf5b3af285 AAE-47094 Add Stale PR Cleanup workflow (#11983)
[skip ci]
2026-06-12 11:13:03 +02:00
Dominik Iwanek caeaa74704 Release 8.5.0 (#11982) 2026-06-12 10:19:35 +02:00
MichaelaandCursor 7bf0939a49 AAE-46783: rename org secrets to HXPS_GIT_* (#11979)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 07:57:58 +00:00
MichaelaandCursor ec04358796 AAE-46943 Rename git signing secret/vars to HXPS_GIT_* (#11978)
Align the Crowdin commit-signing secret and git identity variables with
the renamed org-level names (HXPS_GIT_COMMIT_SIGNING_PRIVATE_KEY,
HXPS_GIT_USERNAME, HXPS_GIT_EMAIL).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 12:49:04 +00:00
Michaela 49a28b357c AAE-46943 Sign Crowdin translation PR commits with GPG (#11974)
* AAE-46943 Sign Crowdin translation PR commits with GPG

Add GPG signing and the service-account commit identity to the Crowdin
pull workflow so automated-translations-update commits satisfy the
"Require signed commits" branch protection rule.

* AAE-46943 Pass signing key secret through reusable Crowdin workflow

Declare SERVICE_ACCOUNT_SIGNING_KEY in workflow_call.secrets and pass it
from release.yml so commit signing also works when pull-from-crowdin is
invoked as a reusable workflow.
2026-06-11 11:55:13 +00:00
Adam Świderski dd9e58ddaa [ACS-11927] init acs aps scripts update terraform (#11976)
* [ACS-11927] updated init-acs and aps scripts

* [ACS-11927] copilot review fixes 1

* [ACS-11927] handled error catches

* [ACS-11927] last error handled

* [ACS-11927] caught errors stringyfied

* [ACS-11927] scripts made more robust

* [ACS-11927] copilot review fixes 2

* [ACS-11927] eslint fixes 1

* [ACS-11927] eslint fixes 2

* ci:force

* ci:force

* [ACS-11927] copilot review fixes 2
2026-06-11 11:38:01 +00:00
Domenico Sibilio c723e19b6d AAE-46971 Update Supply Chain Review GH AW to latest (#11972)
[skip ci]
2026-06-11 12:26:12 +02:00
David Olson bb6f9b1f3d AAE-46434 Fix disabled stying for people widgets (#11967) 2026-06-09 10:36:08 -05:00
Tomasz Gnyp 7bb219e4dd AAE-46654 Fix - return empty string when no value is provided in card… (#11969)
* AAE-46654 Fix - return empty string when no value is provided in card view text item

* uncomment code
2026-06-09 14:25:49 +02:00
Alfresco BuildandCrowdin Bot 9ec31dd543 New Crowdin translations by GitHub Action (#11966)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-06-09 09:50:26 +01:00
Alex Molodyh 70038bea26 AAE-46246 Format typed values in form display widgets v2 (#11952)
* AAE-46246 Format typed values in form display widgets
2026-06-08 15:24:25 -07:00
dependabot[bot] a445569139 build(deps): bump pnpm/action-setup in /.github/actions/setup (#11965)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4.3.0 to 6.0.8.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/b906affcce14559ad1aafd4ab0e942779e9f58b1...0e279bb959325dab635dd2c09392533439d90093)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: 6.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-08 08:16:29 +01:00
Vito Albano 5ad3dca38d AAE-46684 fix release workflow eslint publish fix provenance (#11963)
* [AAE-46514] - Fix release workflow

* [AAE-46514] - Fix release workflow - devDependencies

* [AAE-46514] - Disabling provenance for Github packages as this is already given from the repo
2026-06-05 00:03:13 +01:00
Vito Albano fd3802f2dc AAE-46684 fix release workflow eslint publish fix (#11962)
* [AAE-46514] - Fix release workflow

* [AAE-46514] - Fix release workflow - devDependencies

* [AAE-46514] - Command parameters are wrong when setting now the options

* [AAE-46514] - It should call the script not the standard command

* [AAE-46514] - fixed path for eslint plugin publish
2026-06-04 23:33:17 +01:00
Vito Albano a8eee9fe3a Improvements/aae 46684 fix release workflow fixed command (#11961)
* [AAE-46514] - Fix release workflow

* [AAE-46514] - Fix release workflow - devDependencies

* [AAE-46514] - Command parameters are wrong when setting now the options

* [AAE-46514] - It should call the script not the standard command
2026-06-04 21:16:11 +01:00
Vito Albano 0a7fa14d0f Improvements/aae 46684 fix release workflow ignore (#11960)
* [AAE-46514] - Fix release workflow

* [AAE-46514] - Fix release workflow - devDependencies

* [AAE-46514] - Ignore git checks on publish
2026-06-04 20:07:09 +01:00
Vito Albano 4dde6d2a45 [AAE-46514] - Fix release workflow (#11959)
* [AAE-46514] - Fix release workflow

* [AAE-46514] - Fix release workflow - devDependencies
2026-06-04 19:50:04 +01:00
Vito Albano 78661f11c5 [AAE-46514] - Migration to PNPM (#11926)
* [AAE-46514] - using by default ignore-scripts and have a trusted list for those who are trusted

* [AAE-46514] - Improved the checks to cover more cases

* [AAE-46514] - Fixed copilot comments

* [AAE-46514] - OTher fixes

* [AAE-46514] - Fixing other improvements and comments

* [AAE-46514] - npmrc should be versioned to enforce the audit

* [AAE-46514] - Improved code

* [AAE-46514] - Removed the check on CI as we have other tools

* [AAE-46514] - Improved check, updated descriptions, skip check on CI as there is already Sonar

* [AAE-46514] - Reduced functions in smaller pieces

* [AAE-46514] - Migrating to Pnpm to increase safety

* [ci:force] - Checking

* [ci:force] - Fixed complexity of the scripts

* [ci:force] - Fixed complexity of the scripts

* [ci:force] - Fixed wrong typing on yml

* [ci:force] - Fixed sonar comments and added correct version to sha pinned action

* [ci:force] - Fixed cache hit for npmn

* [ci:force] - Improved eslint plugin so it can be built with standard action

* [ci:force] - Improved eslint plugin so it can be built with standard action

* [ci:force] - Added minimatch

* [ci:force] - Fixing issues

* [ci:force] - Removed 'run' as it is not needed

* [ci:force] - Using audit in place of custom scripts

* [ci:force] - Fixed vulnerabilities and removed custom scripts in favor of audit --critical

* [ci:force] - Added minimum time for publishing to install

* [ci:force] - Address issue with too new packages

* [ci:force] - Address issue with too new packages
2026-06-04 18:38:22 +01:00
Domenico Sibilio faf9d3faac AAE-46388 Update Supply Chain Review GH AW to latest (#11957)
[skip ci]
2026-06-04 10:25:49 +02:00
Alfresco BuildandCrowdin Bot 75d9845754 New Crowdin translations by GitHub Action (#11955)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-06-03 20:58:50 +01:00
Domenico Sibilio 5c8eb21ab3 AAE-46387 Standardize DependaBot config schedule/grouping (#11953)
[skip ci]
2026-06-03 15:58:53 +02:00
Wojciech Duda 7d76d789b2 AAE-41418 Add process instance id input to task header cloud component (#11897)
* AAE-41418 Add process instance id input to task header cloud component

* AAE-41418 Remove falsy early returns from task header process instance id helpers

* AAE-41418 Move process instance id fallback into task header refresh
2026-06-03 13:35:55 +01:00
Fabian Kindgen a71cc84f11 AAE-46507 Next Task Endpoint (#11943) 2026-06-03 13:24:41 +02:00
dependabot[bot] cdcfab0240 build(deps-dev): bump the typescript-eslint group across 1 directory with 4 updates (#11932)
Bumps the typescript-eslint group with 3 updates in the / directory: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-estree).


Updates `@typescript-eslint/eslint-plugin` from 8.59.4 to 8.60.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.59.4 to 8.60.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.0/packages/parser)

Updates `@typescript-eslint/typescript-estree` from 8.59.4 to 8.60.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-estree/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.0/packages/typescript-estree)

Updates `@typescript-eslint/utils` from 8.59.4 to 8.60.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.0/packages/utils)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.60.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.60.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
- dependency-name: "@typescript-eslint/typescript-estree"
  dependency-version: 8.60.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
- dependency-name: "@typescript-eslint/utils"
  dependency-version: 8.60.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-03 12:17:19 +01:00
dependabot[bot] 5a20501577 build(deps): bump Alfresco/alfresco-build-tools (#11934)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 18.4.0 to 18.7.0.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/ed7779a4bda83d699c1acaf72922ef21636a3dc2...a6a8be7429080c132815d0482a55ae4fd28f15ba)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-03 08:39:49 +01:00
Alex Molodyh 34acdd20cf Revert "AAE-46246 Format typed values in form display widgets (#11935)" (#11951)
This reverts commit f39b9167b8.
2026-06-02 14:38:20 -07:00
Alex Molodyh f39b9167b8 AAE-46246 Format typed values in form display widgets (#11935) 2026-06-02 12:56:23 -07:00
David Olson aa2a357fb2 AAE-46434 Fix read-only field styling on forms (#11928) 2026-06-02 08:54:26 -05:00
Alfresco BuildandCrowdin Bot e52b63eaf9 New Crowdin translations by GitHub Action (#11950)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-06-02 13:51:27 +01:00
Vito AlbanoandClaude Opus 4.5 f9899883dc Revert AAE-46242 crowdin locale mapping changes (#11949)
Reverts the following commits:
- 80e9e51cfa AAE-46242 - Looks like we need to override the mapping as crowding config is not set to this format
- 345e1e69ad AAE-46242 - should use the variable osx_locale to match the format xx-YY
- a2b026ed7e [AAE-46242] - Changed the name convention for translation files to ISO standard naming

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-06-02 13:30:03 +01:00
Darren Thornton 46b2d0380b AAE-45774 Shorten invalid date error message (#11920) 2026-06-02 06:46:02 -05:00
Domenico Sibilio 274ddb3098 AAE-46386 Set DependaBot cooldown for all ecosystems as 3d (#11947)
[skip ci]
2026-06-01 14:54:56 +02:00
Domenico Sibilio f602070f1e AAE-46388 Fix DependaBot config to ignore gh-aw-actions (#11946)
[skip ci]
2026-06-01 12:31:02 +02:00
Vito Albano d206d28f1c [AAE-32905] Fix commit messages commands aren't working (#11922)
* [ci:force] - Checking

* [AAE-32905] - Re enabled ci commands on commit messages

* [ci:force] - Checking
2026-06-01 09:47:45 +01:00
Vito Albano 80e9e51cfa AAE-46242 - Looks like we need to override the mapping as crowding config is not set to this format (#11939) 2026-05-30 14:29:49 +01:00
Vito Albano 345e1e69ad AAE-46242 - should use the variable osx_locale to match the format xx-YY (#11936) 2026-05-30 11:22:31 +01:00
Vito Albano a2b026ed7e [AAE-46242] - Changed the name convention for translation files to ISO standard naming (#11924)
* [AAE-46242] - Changed the name convention for translation files to ISO standard naming

* [AAE-46242] - revert en-GB to en.json

* [AAE-46242] - fixed crowding config

* [AAE-46242] - added fallback fix'

* [AAE-46242] - Added defaultLang missing method

* [AAE-46242] - Fixing unit test

* [AAE-46242] - fixed core unit tests
2026-05-29 19:11:17 +01:00
Domenico Sibilio e40fd2250e AAE-46388 Add Supply Chain Review agentic workflow (#11927)
[skip ci]
2026-05-29 15:55:51 +02:00
cfdd3f9c50 MD3 migration fixes (#11919)
* [ACS-10449] Viewer MD3 fixes

* [ACS-10449] Autocomplete chip MD3 fix

* [ACS-10449] Tabs MD3 fixes

* [ACS-10449] Fix badge sizing

* [ACS-10449] Login page error fix

* [ACS-10449] Fix overlapping options on text next to selectbox

* [ACS-10449] ADF style fixes refactoring I

* [ACS-10449] Breadcrumb and search filter container fixes

* [ACS-10449] User column form field fixes

* [ACS-10449] adapt scroll into view to changes in MD3

* [ACS-10449] Properties panel opened by default

* [ACS-10449] Tag creator fixes

* [ACS-10449] fix metadata property label color

* [ACS-10449] Categories panel fixes

* [ACS-10449] Current aspect on changes fix

* [ACS-10449] Make notification history badge size configurable

* [ACS-10449] Make notification history badge size configurable via config file

---------

Co-authored-by: Aleksander Sklorz <Aleksander.Sklorz@hyland.com>
Co-authored-by: g-jaskowski <grzegorz.jaskowski@hyland.com>
2026-05-29 13:16:03 +02:00
Fabian Kindgen 1314f0751f AAE-46476 Fix sorting functionality of task list retrieval from runtime bundle (#11921) 2026-05-29 07:20:26 +02:00
Denys Vuika f4882e99be Revert "New Crowdin translations by GitHub Action (#11796)" (#11923)
This reverts commit 7a70ae8eb6.
2026-05-28 17:51:05 +01:00
Denys Vuika b5d2de583d build(deps): update 3rd party dependencies (#11916) 2026-05-27 12:23:48 +01:00
Michaela 70f90c65a5 AAE-46392 Fix card view select item crash on numeric initial value (#11917)
Guard autocomplete-only paths and coerce filter text to string so
select properties with numeric values (e.g. priority) no longer throw.
2026-05-26 15:57:37 +00:00
dependabot[bot] e6ef0de7a8 build(deps-dev): bump the typescript-eslint group with 4 updates (#11911)
Bumps the typescript-eslint group with 4 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser), [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-estree) and [@typescript-eslint/utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils).


Updates `@typescript-eslint/eslint-plugin` from 8.57.2 to 8.59.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.57.2 to 8.59.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/parser)

Updates `@typescript-eslint/typescript-estree` from 8.41.0 to 8.59.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-estree/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/typescript-estree)

Updates `@typescript-eslint/utils` from 8.59.3 to 8.59.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/utils)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.59.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.59.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
- dependency-name: "@typescript-eslint/typescript-estree"
  dependency-version: 8.59.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
- dependency-name: "@typescript-eslint/utils"
  dependency-version: 8.59.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: typescript-eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 09:51:32 +01:00
dependabot[bot] 8559d27a04 build(deps): bump qs from 6.14.2 to 6.15.2 in /lib/cli (#11907)
Bumps [qs](https://github.com/ljharb/qs) from 6.14.2 to 6.15.2.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.2...v6.15.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.15.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 09:50:31 +01:00
dependabot[bot] c9b2939588 build(deps): bump qs, body-parser and express (#11908)
Bumps [qs](https://github.com/ljharb/qs), [body-parser](https://github.com/expressjs/body-parser) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.14.2 to 6.15.2
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.2...v6.15.2)

Updates `body-parser` from 1.20.4 to 1.20.5
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/1.20.5/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.20.4...1.20.5)

Updates `express` from 4.22.1 to 4.22.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.2/History.md)
- [Commits](https://github.com/expressjs/express/compare/v4.22.1...v4.22.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.15.2
  dependency-type: indirect
- dependency-name: body-parser
  dependency-version: 1.20.5
  dependency-type: indirect
- dependency-name: express
  dependency-version: 4.22.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 09:50:09 +01:00
dependabot[bot] b69776012f build(deps): bump Alfresco/alfresco-build-tools (#11914)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 18.0.1 to 18.4.0.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/162d01f0dd3d9ead7526be3b046743fae5afb2cd...ed7779a4bda83d699c1acaf72922ef21636a3dc2)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 09:47:02 +01:00
dependabot[bot] 27c62f2632 build(deps-dev): bump @nx/angular from 22.7.2 to 22.7.3 (#11912)
Bumps [@nx/angular](https://github.com/nrwl/nx/tree/HEAD/packages/angular) from 22.7.2 to 22.7.3.
- [Release notes](https://github.com/nrwl/nx/releases)
- [Commits](https://github.com/nrwl/nx/commits/22.7.3/packages/angular)

---
updated-dependencies:
- dependency-name: "@nx/angular"
  dependency-version: 22.7.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 09:46:36 +01:00
dependabot[bot] b8fa940dc9 build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 (#11915)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.5 to 4.36.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/9e0d7b8d25671d64c341c19c0152d693099fb5ba...7211b7c8077ea37d8641b6271f6a365a22a5fbfa)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 09:45:48 +01:00
Alfresco BuildandCrowdin Bot 637b67da59 New Crowdin translations by GitHub Action (#11898)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-26 09:45:25 +01:00
dependabot[bot] cefc666a09 build(deps): bump @tootallnate/once from 2.0.0 to 2.0.1 (#11906)
Bumps [@tootallnate/once](https://github.com/TooTallNate/once) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/TooTallNate/once/releases)
- [Changelog](https://github.com/TooTallNate/once/blob/v2.0.1/CHANGELOG.md)
- [Commits](https://github.com/TooTallNate/once/compare/2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: "@tootallnate/once"
  dependency-version: 2.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-22 07:47:49 +01:00
Denys Vuika f339647f40 refactor: migrate license checks off license-checker (#11905) 2026-05-21 14:18:10 +01:00
Denys Vuika a7fa68056d chore: remove unused @nx/node dependency (#11895) 2026-05-21 11:27:35 +00:00
Denys Vuika 8280aa2f6d chore: update NX packages to version 22.7.2 and related dependencies (#11904)
* chore: update NX packages to version 22.7.2 and related dependencies

* chore: add @nx/jest dependency at version 22.7.2

* chore: remove deprecated @types/pdfjs-dist dependency
2026-05-21 11:35:47 +01:00
Mykyta Maliarchuk 5553aaaefe [MNT-25522] Add support for fileLink icon (#11903)
* [MNT-25522] Add support for fileLink icon

* [MNT-25522] cr fixes
2026-05-21 12:21:46 +02:00
MichaelaandCursor 15814380a5 [ci:force] AAE-46219 [TEST] Revert cli build/installDeps changes from #11880 and #11899 (#11901)
Demonstration revert PR to check whether PRs #11880 and #11899 caused
the recent ADF release failures. The PR pipeline result will indicate
whether reverting the `cli:build` dependsOn edge (#11880) and the
`--omit=prod` install command (#11899) is sufficient to restore green
CI.

Reverts the relevant pieces of:
  - #11880 (e3430ae36e): removes `dependsOn: ["installDeps"]` from
    `cli:build`, and reverts the @typescript-eslint bump from 8.59.3
    back to 8.57.2 / 8.41.0 in package.json + package-lock.json.
    The dependabot `@typescript-eslint/*` grouping config is kept.
  - #11899 (4044fafc39): restores the `cli:installDeps` command back
    to plain `cd lib/cli && npm i` (the `--omit=prod` value is not a
    valid npm flag).

Not intended for merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 15:50:58 +02:00
MichaelaandCursor 4044fafc39 AAE-46219 Skip prod deps in cli:installDeps to unblock release (#11899)
* [ci:force] AAE-46219 Remove redundant installDeps dependency from cli build target

The build target's installDeps dependency is already covered transitively
via bundle -> copyToNodeModules -> installDeps, and the duplicate npm i
caused a race condition that broke the ADF release.

Co-authored-by: Cursor <cursoragent@cursor.com>

* AAE-46219 Skip prod deps in cli:installDeps to unblock release

The release workflow rewrites lib/cli/package.json so @alfresco/js-api
points at an unpublished build-tagged version, then nx triggers
cli:installDeps (cd lib/cli && npm i) which fails ETARGET. tsc only
needs the devDependencies (typescript, @types/ejs, @types/node);
@alfresco/js-api is resolved via the tsconfig "paths" mapping to
dist/libs/js-api, not from node_modules. Adding --omit=prod skips the
unresolvable runtime deps without affecting the published package.

Also restores the build -> installDeps edge so tsc and npm install
do not race in lib/cli/node_modules.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 14:32:01 +02:00
Michal Kinas ece50ac32c [MNT-25149] Card view select item multivalued property support (#11891)
* [MNT-25149] Card view select item multivalued property support

* [MNT-25149] CR fixes

* [MNT-25149] CR fixes

* [MNT-25149] CR fixes
2026-05-20 11:39:42 +02:00
Darren Thornton 1d163c6749 Revert "AAE-44065 Change date picker to match other styles (#11868)" (#11896)
This reverts commit 8309d2dc55.
2026-05-19 14:54:26 -05:00
Denys Vuika 1fbd869902 chore: remove unused eslint-plugin-prefer-arrow (#11894)
Remove eslint-plugin-prefer-arrow dependency as the only rule from this plugin (prefer-arrow/prefer-arrow-functions) was disabled in all ESLint configurations.
2026-05-19 11:13:00 +01:00
Denys Vuika 165d0fc521 chore: remove unused moment dependency (#11893)
Remove moment from devDependencies as it is no longer used in the codebase.
2026-05-19 10:47:36 +01:00
Darren Thornton 64d9f3a6d4 AAE-45774 Show error for date fields if invalid format (#11886)
* AAE-45774 Show error for date fields if invalid format

* apply copilot suggestions
2026-05-18 06:42:59 -05:00
Alfresco BuildandCrowdin Bot 454236873e New Crowdin translations by GitHub Action (#11867)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-18 11:39:09 +01:00
dependabot[bot] 16202197f7 build(deps): bump Alfresco/alfresco-build-tools (#11889)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 17.7.0 to 18.0.1.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/9f51752cb7845dce8e8b13b866c127681f418bb3...162d01f0dd3d9ead7526be3b046743fae5afb2cd)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 18.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-18 11:38:37 +01:00
dependabot[bot] dbdcc3175b build(deps): bump github/codeql-action from 4.35.4 to 4.35.5 (#11890)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.4 to 4.35.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...9e0d7b8d25671d64c341c19c0152d693099fb5ba)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-18 11:38:14 +01:00
dependabot[bot] b1cb7060d1 build(deps): bump @cspell/eslint-plugin from 9.4.0 to 10.0.0 (#11884)
Bumps [@cspell/eslint-plugin](https://github.com/streetsidesoftware/cspell/tree/HEAD/packages/cspell-eslint-plugin) from 9.4.0 to 10.0.0.
- [Release notes](https://github.com/streetsidesoftware/cspell/releases)
- [Changelog](https://github.com/streetsidesoftware/cspell/blob/main/packages/cspell-eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/streetsidesoftware/cspell/commits/v10.0.0/packages/cspell-eslint-plugin)

---
updated-dependencies:
- dependency-name: "@cspell/eslint-plugin"
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-18 11:37:55 +01:00
dependabot[bot] fc55aa0a44 build(deps-dev): bump react from 19.2.4 to 19.2.6 (#11888)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 19.2.4 to 19.2.6.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-18 11:37:17 +01:00
dependabot[bot] b8c115a725 build(deps-dev): bump sass-loader from 16.0.7 to 16.0.8 (#11885)
Bumps [sass-loader](https://github.com/webpack/sass-loader) from 16.0.7 to 16.0.8.
- [Release notes](https://github.com/webpack/sass-loader/releases)
- [Changelog](https://github.com/webpack/sass-loader/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/sass-loader/compare/v16.0.7...v16.0.8)

---
updated-dependencies:
- dependency-name: sass-loader
  dependency-version: 16.0.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-15 15:58:55 +02:00
Alex Molodyh 9e106b006c AAE-43881 Fix for form rules not applying when new [data] comes in (#11879) 2026-05-14 08:47:42 -07:00
Darren Thornton 8309d2dc55 AAE-44065 Change date picker to match other styles (#11868)
* AAE-44065 Change date picker to match other styles

* Apply Copilot suggestions
2026-05-13 12:12:21 -05:00
dependabot[bot] a21908a782 build(deps-dev): bump @typescript-eslint/typescript-estree (#11883)
Bumps the typescript-eslint group with 1 update: [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-estree).


Updates `@typescript-eslint/typescript-estree` from 8.41.0 to 8.59.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-estree/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/typescript-estree)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/typescript-estree"
  dependency-version: 8.59.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: typescript-eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-13 11:00:28 +02:00
MichaelaandCursor e3430ae36e AAE-45695 Group @typescript-eslint/* packages in dependabot (#11880)
* [AAE-45695] Group @typescript-eslint/* packages in dependabot

@typescript-eslint/parser and @typescript-eslint/eslint-plugin must be
bumped together (matching versions) due to a peer-dependency between
them. Grouping all @typescript-eslint/* packages ensures Dependabot
updates them in lock-step instead of opening separate PRs that fail
npm ci with a peer-dep conflict.

Co-authored-by: Cursor <cursoragent@cursor.com>

* [ci:force] AAE-45695 Bump @typescript-eslint/parser and eslint-plugin to 8.59.3

Bump both packages together (peer-dep requires matching versions) to
unblock the Dependabot bump that was previously failing.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 09:43:21 +00:00
dependabot[bot] 7bf7610cf5 build(deps): bump @babel/plugin-transform-modules-systemjs (#11871)
Bumps [@babel/plugin-transform-modules-systemjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs) from 7.29.0 to 7.29.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.4/packages/babel-plugin-transform-modules-systemjs)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-modules-systemjs"
  dependency-version: 7.29.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 11:08:23 +02:00
dependabot[bot] 57ec1ab835 build(deps): bump Alfresco/alfresco-build-tools from 17.6.0 to 17.7.0 in /.github/actions/setup (#11876)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 17.6.0 to 17.7.0.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/8d76614b374e521d792b4a1c9827409960b66bae...9f51752cb7845dce8e8b13b866c127681f418bb3)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 17.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 07:54:41 +00:00
Michal Kinas 1860fefd42 [MNT-25647] Handle facets label wrapped in quotes (#11866)
* [MNT-25647] Handle facets label wrapped in quotes

* [MNT-25647] CR fix
2026-05-12 08:34:35 +02:00
dependabot[bot] e5eb90f93b build(deps-dev): bump fast-uri from 3.1.0 to 3.1.2 (#11870)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.2)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 17:12:25 +01:00
dependabot[bot] c9464581e8 build(deps-dev): bump @nx/node from 22.6.5 to 22.7.1 (#11875)
Bumps [@nx/node](https://github.com/nrwl/nx/tree/HEAD/packages/node) from 22.6.5 to 22.7.1.
- [Release notes](https://github.com/nrwl/nx/releases)
- [Commits](https://github.com/nrwl/nx/commits/22.7.1/packages/node)

---
updated-dependencies:
- dependency-name: "@nx/node"
  dependency-version: 22.7.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 17:11:45 +01:00
dependabot[bot] 53abaaf246 build(deps): bump github/codeql-action from 4.35.3 to 4.35.4 (#11877)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.3 to 4.35.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e46ed2cbd01164d986452f91f178727624ae40d7...68bde559dea0fdcac2102bfdf6230c5f70eb485e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 14:23:28 +00:00
Vito Albano 9fe4006a0d AAE-45391 Lazy loading and improvements for pdfJS (#11869)
* [AAE-45391] - Lazy loading some of the big external libs

* [AAE-45391] - Added some extra units to pdfjs viewer

* [AAE-45391] - Some improement on viewer component

* [AAE-45391] - Fixed the way it was redered to a newer angular system

* [AAE-45391] - Fixed the way it was redered to a newer angular system

* [AAE-45391] - fixed schematic

* [AAE-45391] - Added some docs for the schematics as well

* [AAE-37328] - Fixed comment on missing provider
2026-05-11 14:17:39 +01:00
Denys Vuika 62fb51e910 Update CODEOWNERS 2026-05-07 15:30:50 +01:00
Ehsan Rezaei b7783d2259 AAE-39830 Removing Material components color property (#11865)
* AAE-39830 Removing Material components color property

* AAE-39830 Style with class instead of color

* AAE-39830 Updating header component doc

* AAE-39830 Updating toolbar component doc

* AAE-39830 Removed unused theme variable and updated doc
2026-05-07 14:25:14 +02:00
Vito Albano 410490158f AAE-30881 Remove jsrassign (#11863)
* [AAE-30881] - Remove jsrassign as dep

* [AAE-30881] - Remove jsrassign as dep

* [AAE-30881] - upgrade oidc package

* [AAE-30881] - added unit tests

* [AAE-30881] - fixing security issue

* [AAE-30881] - Fixed sonarcloud issue

* [AAE-30881] - Fixed sonarcloud issue
2026-05-07 10:37:29 +01:00
Vito Albano 57bf066164 AAE-30882 Remove superagent for fetch (#11856)
* [AAE-30882] - Remove superagent for fetch

* [AAE-30882] - Fixing comments

* [AAE-30882] - fixde failing unit tests

* [AAE-30882] - fixde failing unit tests

* [AAE-30882] - fixd sonarcloud comment
2026-05-07 09:12:07 +01:00
Ehsan Rezaei 9cdacf3ebf AAE-45312 Removing propagate job from release workflow (#11864)
* AAE-45312 Removing propagate job from release workflow

* AAE-45312 Removing from doc
2026-05-06 10:30:15 +00:00
Tomek Hanaj 8821980913 AAE-38566 Remove globals mixin (#11798)
* [AAE-38566] moved styles for mat-calendar to components

* [AAE-38482] moved styles for mat-datetimepicker to components

* [AAE-38482] removed mixin globals

* [AAE-38482] removed mat-calendar styles

* [AAE-38482] removed mat-datetimepicker styles

* [AAE-38482] removed calendar related selectors
2026-05-06 10:40:38 +02:00
Fabian Kindgen a73b100fae AAE-45003 Extend task cloud services (#11850) 2026-05-06 09:45:29 +02:00
Darren Thornton 2649cdea2d AAE-44003 Allow manual input for date field (#11830)
* AAE-44003 Allow manual input for date field

* copilot suggestions

* code review update

* code review update
2026-05-05 10:14:15 -05:00
Vito Albano 3a543d8a0a AAE-32905 Rework pr pipeline (#11853)
* [AAE-32905] - Improve ADF workflow

* [ci:force]

* [AAE-32905] - Improve cache use

* [AAE-32905] - Improve cache use

* [AAE-32905] - Improved workflows

* [AAE-32905] - Checking cache

* [AAE-32905] - Checking cache

* [AAE-32905] - Fix cli

* [AAE-32905] - Fix cache

* [AAE-32905] - Fix cache

* [AAE-32905] - Fix cache

* [AAE-32905] - improving workflow and adding some storybook tests

* [AAE-32905] - improving workflow and adding some storybook tests

* [AAE-32905] - Added more improvements

* [AAE-32905] - Added more improvements

* [AAE-32905] - bugfix

* [AAE-32905] - Added missing part to the cache

* [AAE-32905] - bugfix

* [AAE-32905] - fixed cache poisoning

* [AAE-32905] - timing jobs

* [AAE-32905] - chosen to build all together as it's more efficient

* [AAE-32905] - Fixed script injection issue
2026-05-05 13:16:36 +01:00
Ehsan Rezaei 3fc59b2358 AAE-45216 Removing custom theme from core (#11862)
* AAE-45216 Removing custom theme from core

* AAE-45216 Removing custom theme from assets
2026-05-05 10:33:09 +02:00
dependabot[bot] d7487e30bd build(deps): bump Alfresco/alfresco-build-tools (#11857)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 17.6.0 to 17.6.1.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/8d76614b374e521d792b4a1c9827409960b66bae...f95467b62527ce087c9a1b7e55c467061cf827a0)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 17.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 08:15:52 +01:00
dependabot[bot] b6d292df2b build(deps): bump Alfresco/alfresco-build-tools from 17.6.0 to 17.6.1 (#11858)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 17.6.0 to 17.6.1.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/8d76614b374e521d792b4a1c9827409960b66bae...f95467b62527ce087c9a1b7e55c467061cf827a0)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 17.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 08:15:31 +01:00
dependabot[bot] 992f4779fc build(deps): bump github/codeql-action from 4.35.2 to 4.35.3 (#11859)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...e46ed2cbd01164d986452f91f178727624ae40d7)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 08:14:08 +01:00
Ehsan Rezaei 337b82e988 AAE-45215 Removing unused breadcrumb theme (#11861) 2026-05-05 08:13:41 +01:00
Vito Albano 0faa2e1a56 [AAE-0000] - fixed run for process-service-cloud (#11855)
* [AAE-0000] - fixed run for process-service-cloud

* [AAE-0000] - Stabilising process cloud tests
2026-05-04 23:35:25 +01:00
Adam Świderski d6262eafc6 [ACS-11628] small for for init-acs-env.ts (#11860) 2026-05-04 11:23:02 +00:00
Alfresco BuildandCrowdin Bot bba9a0afe2 New Crowdin translations by GitHub Action (#11854)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-01 14:50:36 +01:00
Alex Molodyh d3ad66d25b AAE-44435 Fix incorrect Start process button on user task forms (#11837) 2026-04-30 12:39:28 -07:00
Alfresco BuildandCrowdin Bot b49513e9c2 New Crowdin translations by GitHub Action (#11848)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-30 16:49:53 +01:00
Ehsan Rezaei aa2de3bde6 AAE-45173 Adding background color to tooltip card (#11852) 2026-04-30 15:18:38 +00:00
Joshua Cain d1d06a68bc AAE-44098 Bottom tab navigation buttons (#11834)
* feat: enable tab navigation buttons

* feat: better strings and button positioning

* feat: reduce overall padding

* feat: adjust buttons based on ux mockups

* test: add some tests

* fix: build error

* fix: rename property to showBottomTabNavButtons for clarity

* feat: simplify changes

* test: copilot suggestion

* fix: prevent upstream visual regression issues.

* fix: copilot suggestions

* fix: height change
2026-04-29 15:12:06 -04:00
dependabot[bot] a394222c54 build(deps-dev): bump @xmldom/xmldom from 0.8.12 to 0.8.13 (#11833)
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.8.12 to 0.8.13.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.8.12...0.8.13)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-version: 0.8.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-29 11:57:37 +02:00
Diogo Bastos 0a6da1ba13 AAE-45076 Fix svg icon style (#11849) 2026-04-28 17:01:31 +01:00
Alfresco BuildandCrowdin Bot 7853121080 New Crowdin translations by GitHub Action (#11831)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-28 12:09:09 +01:00
Vito Albano d3ac5362ba AAE-44946 - Sending also previous value to allow valuation and valida… (#11836)
* AAE-44946 - Sending also previous value to allow valuation and validation

* AAE-44946 - Sending also previous value to allow valuation and validation

* AAE-44749 - Fixed wrong subscribe in test

* AAE-45038 - Fixing logs and unit tests
2026-04-28 11:24:05 +01:00
Bartosz Sekula ddb8adc0e4 AAE-44752 Add type to ProcessInstanceCloud (#11847) 2026-04-27 16:14:02 +02:00
Ehsan Rezaei 85005c9c1c AAE-44987 Applying color and background to sidenav (#11846) 2026-04-27 12:49:17 +02:00
dependabot[bot] 67b4486b44 build(deps): bump Alfresco/alfresco-build-tools from 17.2.0 to 17.6.0 in /.github/actions/setup (#11840)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 17.2.0 to 17.6.0.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/c00625b5f30db226fb0634299effc4cd15fdd7bb...8d76614b374e521d792b4a1c9827409960b66bae)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 17.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 11:09:20 +02:00
dependabot[bot] a4f4f5eb47 build(deps): bump actions/setup-node from 6.3.0 to 6.4.0 in /.github/actions/setup (#11841)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/53b83947a5a98c8d113130e565377fae1a50d02f...48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 11:09:00 +02:00
dependabot[bot] 02009108e9 build(deps): bump crowdin/github-action from 2.16.0 to 2.16.2 (#11842)
Bumps [crowdin/github-action](https://github.com/crowdin/github-action) from 2.16.0 to 2.16.2.
- [Release notes](https://github.com/crowdin/github-action/releases)
- [Commits](https://github.com/crowdin/github-action/compare/7ca9c452bfe9197d3bb7fa83a4d7e2b0c9ae835d...8868a33591d21088edfc398968173a3b98d51706)

---
updated-dependencies:
- dependency-name: crowdin/github-action
  dependency-version: 2.16.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 11:08:43 +02:00
dependabot[bot] e7c5e5371b build(deps): bump Alfresco/alfresco-build-tools from 17.2.0 to 17.6.0 (#11843)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 17.2.0 to 17.6.0.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/c00625b5f30db226fb0634299effc4cd15fdd7bb...8d76614b374e521d792b4a1c9827409960b66bae)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 17.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 11:08:13 +02:00
dependabot[bot] 5a032945bc build(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (#11844)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/53b83947a5a98c8d113130e565377fae1a50d02f...48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 11:05:37 +02:00
AleksanderSklorz 407c6c1829 [ACS-11350] keyboard navigation user incorrect focus order after collapsing the left navigation menu (#11835)
* [ACS-11350] Fixed focus after collapsing navigation menu

* [ACS-11350] Unit tests

* [ACS-11350] Addressed copilot comments

* [ACS-11350] Addressed copilot comment

* [ACS-11350] Addressed copilot comment
2026-04-24 12:34:26 +02:00
Joshua Cain e3fc03c58d Revert "AAE-44098 Bottom Tab nav buttons (#11801)" (#11832)
This reverts commit 7864f1a8e0.
2026-04-23 11:39:17 +00:00
Mykyta Maliarchuk 510a813ed2 [ACS-11472] Fix file icon is not updated for version renditions (#11807)
* [ACS-11472] Fix file icon is not updated for version renditions

* [ACS-11472] cr fixes
2026-04-23 13:27:14 +02:00
Joshua Cain 7864f1a8e0 AAE-44098 Bottom Tab nav buttons (#11801)
* feat: enable tab navigation buttons
2026-04-22 14:28:00 -04:00
Darren Thornton c09edd71ff AAE-44761 Remove unused imports (#11829) 2026-04-22 06:41:40 -05:00
64826c3a99 AAE-40649 Material Design 3 migration (#11286)
* AAE-38957 Cleanup code from color assignments on Material elements (#11266)

* AAE-38646   cleanup core lib from custom variables (#11259)

* AAE-38646 General cleanup of custom variables from core lib

* AAE-38646 Cleanup some of the remaining variables

* AAE-38646 Last color-mix removal

* AAE-38646 Reduce amount of customizations

* AAE-38646 apply overrides, reduce customization

* AAE-38646 modify remaining styles

* AAE-38646 Fix override assignemnts

* AAE-38646 Address comments, cleanup unused

* AAE-38978 Cleanup process-services-cloud lib from custom css variables (#11295)

* AAE-38978 Cleanup custom variables inside process-services-cloud lib

* AAE-38978 Adjust rich text widget styling

* AAE-38978 Comment fixes

* AAE-38980 Cleanup insights lib from custom css variables (#11314)

* AAE-38980 Cleanup insights lib from custom css variables

* AAE-38980 Removed unnecessarily specific selector

* AAE-38979 Cleanup content-services lib from custom css variables (#11313)

* AAE-38979 Remove/replace variable and hardcoded customizations

* AAE-38979 Cleanup unused @use and @import statements

* AAE-39159 Cleanup process-services lib from custom css variables (#11316)

* AAE-39159 Cleanup process-services lib from custom css variables

* AAE-39159 Fix import and build

* Fix build

* Remove leftover button customization

* fix missing brace

* AAE-39748 Pagination font size match md3

* fix incorrect html templates after rebase

* swap leftover variables

* fix units

* copilot comments

* visual regression result fixes

* CSX-204 Update card view components (#11358)

* CSX-535 Update background color on readonly for card view selectitem (#11799)

* remove invalid color test

* add stylelint rule

---------

Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com>
Co-authored-by: Ricardo Dias <ricardo.dias@hyland.com>
2026-04-22 10:02:17 +01:00
AleksanderSklorz 423c646bac Post release version bump (#11828)
* Post release version bump

* Post release version bump

* Post release version bump

* Post release bump
2026-04-22 10:57:08 +02:00
AleksanderSklorz d1bda4f898 Release 8.4.1 (#11827)
* Release 8.4.1

* Release 8.4.1
2026-04-21 12:01:35 +02:00
AleksanderSklorz 03f04bf118 Release 8.4.0 (#11826)
* Release 8.4.0

* Release 8.4.0

* Release 8.4.0

* Release 8.4.0
2026-04-21 11:08:40 +02:00
dependabot[bot] 0dd3e454f5 build(deps): bump actions/cache from 5.0.4 to 5.0.5 in /.github/actions/download-node-modules-and-artifacts (#11820)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 14:32:15 +02:00
dependabot[bot] 025e3cf636 build(deps): bump Alfresco/alfresco-build-tools from 17.1.0 to 17.2.0 in /.github/actions/setup (#11821)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 14:32:01 +02:00
dependabot[bot] 07455c4217 build(deps): bump actions/cache from 5.0.4 to 5.0.5 in /.github/actions/upload-node-modules-and-artifacts (#11822)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 14:31:47 +02:00
dependabot[bot] 9beeaeed8d build(deps): bump actions/cache from 5.0.4 to 5.0.5 in /.github/actions/setup (#11823)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 14:31:32 +02:00
dependabot[bot] a86f0790da build(deps): bump github/codeql-action from 4.35.1 to 4.35.2 (#11824)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 14:31:09 +02:00
dependabot[bot] 86e8fb75d0 build(deps): bump Alfresco/alfresco-build-tools from 17.1.0 to 17.2.0 (#11825)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 14:30:43 +02:00
Dominik Iwanek af95723f30 [ACS-11589] [ACA] info drawer test-area does not show full text (#11816) 2026-04-20 10:33:14 +02:00
Denys Vuika d70ae599c7 Fix security vulnerabilities in npm dependencies (#11815)
* Update package dependencies: remove unused 'picomatch' and 'minimatch' modules from package-lock.json, and add specific versions for 'picomatch', 'minimatch', 'path-to-regexp', and 'serialize-javascript' in package.json.

* Upgrade nx and @nx/workspace to fix minimatch vulnerabilities

- Upgrade nx from 22.4.1 to 22.6.3
- Upgrade @nx/workspace from 22.4.5 to 22.6.3
- Remove minimatch override to maintain Karma compatibility

This resolves the high severity minimatch vulnerabilities while
keeping tests functional.

* Refactor nx.json: Consolidate sharedGlobals array and add analytics flag

- Merged multiple lines in the sharedGlobals array for better readability.
- Added an analytics flag set to false for configuration.

* Update package dependencies: bump @nx packages to version 22.6.5 [ci:force]

* Add test specifications for feature flags and user initial pipe [ci:force]

- Introduced new selectors for feature flag components in `features.directive.spec.ts` and `not-features.directive.spec.ts`.
- Added an injectable sanitizer class in `user-initial.pipe.spec.ts` to enhance testing capabilities.
- Created a new log file `out.txt` to capture Karma test execution details and warnings.
2026-04-16 13:35:42 +01:00
Alfresco BuildandCrowdin Bot e2ae224924 New Crowdin translations by GitHub Action (#11810)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-16 07:45:07 -04:00
Denys Vuika 07c6a4d923 Remove jasmine-spec-reporter dependency from package.json and package-lock.json (#11814) 2026-04-16 12:23:50 +01:00
Denys Vuika 6fc8dda887 Remove mocha and jasmine-ajax dependencies (#11813) 2026-04-16 10:20:49 +01:00
830 changed files with 48454 additions and 50946 deletions
-1
View File
@@ -102,7 +102,6 @@ module.exports = {
],
'@typescript-eslint/member-ordering': 'off',
'@typescript-eslint/no-empty-function': 'off',
'prefer-arrow/prefer-arrow-functions': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'prefer-promise-reject-errors': 'error',
'brace-style': 'off',
+1
View File
@@ -0,0 +1 @@
.github/workflows/*.lock.yml linguist-generated=true merge=ours
+3 -3
View File
@@ -4,15 +4,15 @@
# the repo. Unless a later match takes precedence,
# these users will be requested for
# review when someone opens a pull request.
* @eromano @popovicsandras @DenysVuika
* @eromano
# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
# modifies JS files, only @js-owner and not the global
# owner(s) will be requested for a review.
/e2e/ @eromano @cristinaj
/e2e/ @eromano
# The `docs/*` pattern will match files like
# `docs/getting-started.md` but not further nested files like
# `docs/build-app/troubleshooting.md`.
/docs/ @m-hulbert @eromano
/docs/ @eromano
+22 -5
View File
@@ -12,9 +12,14 @@ runs:
- name: base vars
shell: bash
run: |
if [ -n "${GITHUB_BASE_REF:-}" ]; then
BASE_HASH=$(git merge-base "origin/${GITHUB_BASE_REF}" HEAD 2>/dev/null || git rev-parse HEAD)
else
BASE_HASH=$(git rev-parse HEAD)
fi
{
echo "GIT_HASH=$(git rev-parse HEAD)";
echo "BASE_HASH=$(git merge-base origin/${GITHUB_BASE_REF} HEAD)";
echo "BASE_HASH=${BASE_HASH}";
echo "HEAD_HASH=HEAD";
echo "HEAD_COMMIT_HASH=${GH_COMMIT}";
echo "NX_CALCULATION_FLAGS=--all";
@@ -25,10 +30,22 @@ runs:
- name: affected:* flag parser
shell: bash
if: ${{ contains(github.event.head_commit.message , '[affected:*]') }}
env:
EVENT_NAME: ${{ github.event_name }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
echo "Setting up CI to run with commit flag [affected:*] flag."
echo "BREAK_ACTION=true" >> $GITHUB_ENV
# Get commit message safely from git to avoid script injection
# For PRs, use the PR head SHA; for other events use HEAD
if [ "$EVENT_NAME" == "pull_request" ] && [ -n "$PR_HEAD_SHA" ]; then
COMMIT_MSG=$(git log -1 --format=%B "$PR_HEAD_SHA" 2>/dev/null || echo "")
else
COMMIT_MSG=$(git log -1 --format=%B 2>/dev/null || echo "")
fi
if echo "$COMMIT_MSG" | grep -qF "[affected:*]"; then
echo "Setting up CI to run with commit flag [affected:*] flag."
echo "BREAK_ACTION=true" >> $GITHUB_ENV
fi
- name: PULL_REQUEST event
if: ${{ env.BREAK_ACTION == false && github.event_name == 'pull_request' && !github.event.pull_request.merged }}
@@ -43,7 +60,7 @@ runs:
} >> $GITHUB_ENV
- name: RELEASE on master/develop patch branch
if: ${{ env.BREAK_ACTION == false && github.event.pull_request.merged }}
if: ${{ env.BREAK_ACTION == false && (github.event.pull_request.merged || github.event_name == 'push') }}
shell: bash
env:
REF_NAME: ${{ github.ref_name }}
+1 -1
View File
@@ -12,7 +12,7 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
name: Create git tag
env:
TAG_NAME: ${{ inputs.tagName }}
@@ -4,7 +4,7 @@ runs:
using: "composite"
steps:
- name: Restore dist from cache
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: dist
key: dist-${{ github.run_id }}-${{ github.run_attempt }}
@@ -13,7 +13,7 @@ runs:
fail-on-cache-miss: true
- name: Restore nxcache from cache
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: nxcache
key: nxcache-${{ github.run_id }}-${{ github.run_attempt }}
@@ -22,7 +22,7 @@ runs:
fail-on-cache-miss: true
- name: Restore node_modules from cache
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: node_modules
key: node-modules-${{ github.run_id }}-${{ github.run_attempt }}
+2 -2
View File
@@ -23,8 +23,8 @@ runs:
env:
DRY_RUN_FLAG: ${{ inputs.dry-run-flag }}
run: |
if [[ '$DRY_RUN_FLAG' == 'true' ]]; then
echo "dryrun=--dryrun" >> $GITHUB_OUTPUT;
if [[ "$DRY_RUN_FLAG" == 'true' ]]; then
echo "dryrun=--dry-run" >> $GITHUB_OUTPUT;
echo "enabling dryrun"
else
echo "dryrun=" >> $GITHUB_OUTPUT;
+17
View File
@@ -0,0 +1,17 @@
name: 'Save Nx Cache'
description: 'Save Nx cache and dist outputs only when the job succeeds'
inputs:
cache-suffix:
description: 'Must match the cache-suffix used in the setup action'
required: true
runs:
using: "composite"
steps:
- name: Save nx cache
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
nxcache
.nx
dist
key: ${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-${{ hashFiles('nx.json') }}-${{ github.sha }}
+35 -21
View File
@@ -1,8 +1,12 @@
name: 'Setup'
description: 'Initialize cache, env var load'
inputs:
enable-node-modules-cache:
description: 'enable caching for node modules'
cache-suffix:
description: 'Suffix to make Nx cache key unique per job (e.g. matrix project name)'
required: false
default: 'default'
full-setup:
description: 'Run git-latest-tag, npm-tag, and before-install (requires fetch-depth: 0). Set to false for matrix jobs that only need node/cache.'
required: false
type: boolean
default: 'true'
@@ -18,33 +22,43 @@ outputs:
runs:
using: "composite"
steps:
- name: install NPM
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Set consistent machine ID for Nx cache
shell: bash
run: echo "nx-github-actions" | sudo tee /etc/machine-id > /dev/null
- name: Setup pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: '.nvmrc'
cache-dependency-path: package-lock.json
cache: 'pnpm'
- name: get latest tag sha
if: ${{ inputs.full-setup == 'true' }}
id: tag-sha
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@d2fd6744fbbb6a0c874c1e28f5374210e2743c2f # v17.1.0
# CACHE
- name: Node Modules cache
id: node-modules-cache
if: ${{ inputs.enable-node-modules-cache == 'true' }}
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
env:
cache-name: node-modules-cache
with:
path: |
node_modules
key: .npm-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
.npm-${{ runner.os }}-build-${{ env.cache-name }}-
.npm-${{ runner.os }}-build-
.npm-${{ runner.os }}-
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@1d671f8f10336861c89c67be57c6648d98876103 # v18.19.0
- name: load "NPM TAG"
if: ${{ inputs.full-setup == 'true' }}
id: set-npm-tag
uses: ./.github/actions/set-npm-tag
- name: Install dependencies
shell: bash
run: pnpm install --frozen-lockfile
- name: Security audit
shell: bash
run: pnpm audit --audit-level=critical
- name: Restore nx cache
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
nxcache
.nx
dist
key: ${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-${{ hashFiles('nx.json') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-${{ hashFiles('nx.json') }}-
${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-
- name: before install script
if: ${{ inputs.full-setup == 'true' }}
uses: ./.github/actions/before-install
with:
act: ${{ inputs.act }}
@@ -5,19 +5,19 @@ runs:
using: "composite"
steps:
- name: Save dist to cache
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: dist
key: dist-${{ github.run_id }}-${{ github.run_attempt }}
- name: Save nxcache to cache
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: nxcache
key: nxcache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Save node_modules to cache
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: node_modules
key: node-modules-${{ github.run_id }}-${{ github.run_attempt }}
+29 -33
View File
@@ -6,6 +6,8 @@ updates:
interval: "weekly"
day: "sunday"
time: "07:00"
cooldown:
default-days: 3
open-pull-requests-limit: 5
target-branch: develop
groups:
@@ -21,44 +23,38 @@ updates:
nrwl:
patterns:
- "@nrwl/*"
typescript-eslint:
patterns:
- "@typescript-eslint/*"
ignore:
- dependency-name: "pdfjs-dist"
- dependency-name: "@types/*"
- dependency-name: "typescript"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/before-install"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/download-node-modules-and-artifacts"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/enable-dryrun"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/get-latest-tag-sha"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/npm-check-bundle"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/set-npm-tag"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/setup"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/.github/actions/upload-node-modules-and-artifacts"
directories:
- "/"
- "/.github/actions/before-install"
- "/.github/actions/create-git-tag"
- "/.github/actions/download-node-modules-and-artifacts"
- "/.github/actions/enable-dryrun"
- "/.github/actions/get-latest-tag-sha"
- "/.github/actions/npm-check-bundle"
- "/.github/actions/save-nx-cache"
- "/.github/actions/set-npm-tag"
- "/.github/actions/setup"
- "/.github/actions/upload-node-modules-and-artifacts"
schedule:
interval: "weekly"
cooldown:
default-days: 3
groups:
github-actions:
patterns:
- "*"
update-types:
- "minor"
- "patch"
ignore:
# Managed by gh aw add. Version-locked to the gh-aw compiler; do not bump.
- dependency-name: "github/gh-aw-actions"
+39
View File
@@ -0,0 +1,39 @@
name: "Build Lib Workflow"
on:
workflow_call:
inputs:
base_ref:
description: 'Base branch for affected calculation'
required: false
type: string
default: 'develop'
env:
NODE_OPTIONS: "--max-old-space-size=5120"
jobs:
build:
name: "Build affected libs"
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Setup environment
id: setup-env
uses: ./.github/actions/setup
with:
cache-suffix: build
full-setup: 'false'
- name: Build affected libs
env:
BASE_REF: ${{ inputs.base_ref }}
run: pnpm nx affected --target=build --base=origin/$BASE_REF --head=HEAD --configuration=production --exclude=stories
- name: Save nx cache
if: ${{ success() }}
uses: ./.github/actions/save-nx-cache
with:
cache-suffix: build
+4 -4
View File
@@ -22,7 +22,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@@ -30,7 +30,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # 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@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
uses: github/codeql-action/autobuild@7188fc363630916deb702c7fdcf4e481b751f97a # 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@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v3.29.5
+10 -1
View File
@@ -8,13 +8,22 @@ jobs:
runs-on: ubuntu-latest
if: github.event.registry_package.package_type == 'npm' && github.event.registry_package.name == 'adf-core'
steps:
- name: Generate app token
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.GH_APP_ENGINEERING_CONTRIB_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_ENGINEERING_CONTRIB_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: alfresco-apps
permission-contents: write
- name: Dispatch event to monorepo
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PACKAGE_NAME: ${{ github.event.registry_package.name }}
PACKAGE_VERSION: ${{ github.event.registry_package.package_version.name }}
with:
github-token: ${{ secrets.PAT_WRITE_PKG }}
github-token: ${{ steps.app-token.outputs.token }}
retries: 3
script: |
const payload = {
+18 -5
View File
@@ -5,21 +5,31 @@ on:
workflow_dispatch:
workflow_call:
secrets:
BOT_GITHUB_TOKEN:
GH_APP_ENGINEERING_CONTRIB_PRIVATE_KEY:
required: true
CROWDIN_TRANSLATIONS_TOKEN:
required: true
HXPS_GIT_COMMIT_SIGNING_PRIVATE_KEY:
required: true
jobs:
pull-from-crowdin:
runs-on: ubuntu-latest
steps:
- name: Generate app token
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.GH_APP_ENGINEERING_CONTRIB_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_ENGINEERING_CONTRIB_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: develop
token: ${{ secrets.BOT_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
- name: Pull translations from Crowdin
uses: crowdin/github-action@7ca9c452bfe9197d3bb7fa83a4d7e2b0c9ae835d # v2.16.0
uses: crowdin/github-action@e0c8f73cdc0fafde9396e056c5038217000a32d1 # v2.16.4
with:
skip_ref_checkout: true
upload_sources: false
@@ -28,6 +38,9 @@ jobs:
localization_branch_name: automated-translations-update
pull_request_title: "GH auto: Automated Update of Translations from Crowdin"
pull_request_base_branch_name: develop
github_user_name: ${{ vars.HXPS_GIT_USERNAME }}
github_user_email: ${{ vars.HXPS_GIT_EMAIL }}
gpg_private_key: ${{ secrets.HXPS_GIT_COMMIT_SIGNING_PRIVATE_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TRANSLATIONS_TOKEN }}
+216 -173
View File
@@ -31,249 +31,295 @@ concurrency:
cancel-in-progress: true
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
GH_COMMIT: ${{ github.sha }}
GH_BUILD_NUMBER: ${{ github.run_id }}
LOG_LEVEL: "ERROR"
NODE_OPTIONS: "--max-old-space-size=5120"
jobs:
pre-checks:
runs-on: ubuntu-latest
outputs:
code-changed: ${{ steps.path-filter.outputs.code-changed }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Ensure SHA pinned actions
uses: hyland/github-actions-ensure-sha-pinned-actions@7d494b6b53e71f75194d74b4dd890a2266d060b5 # v2.0.0
uses: hyland/github-actions-ensure-sha-pinned-actions@7957efb76aba0eec7580a9c0392d3e5bec381359 # v2.0.1
- name: Check package-lock.json version
- name: Check pnpm-lock.yaml version
run: |
if [[ $(jq '.lockfileVersion == 3' package-lock.json) == "true" ]] ; then
echo "package-lock.json has a correct version"
if [[ -f "pnpm-lock.yaml" ]]; then
LOCKFILE_VERSION=$(grep "^lockfileVersion:" pnpm-lock.yaml | cut -d"'" -f2)
if [[ "$LOCKFILE_VERSION" == "9.0" ]]; then
echo "pnpm-lock.yaml has correct version: $LOCKFILE_VERSION"
else
echo "pnpm-lock.yaml must be version 9.0, found: $LOCKFILE_VERSION"
exit 1
fi
else
echo "package-lock must be version 3"
echo "pnpm-lock.yaml is missing"
exit 1
fi
- name: Detect code changes
id: path-filter
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ "${{ github.event_name }}" != "pull_request" ]; then
echo "Not a PR event — assuming code changed"
echo "code-changed=true" >> $GITHUB_OUTPUT
exit 0
fi
FILES=$(gh api /repos/$GITHUB_REPOSITORY/pulls/${{ github.event.pull_request.number }}/files --paginate --jq '.[].filename')
CODE_CHANGED="false"
while IFS= read -r file; do
case "$file" in
*.md|docs/*|.github/*.md|.github/CODEOWNERS|.github/dependabot.yml|LICENSE*|NOTICE*|.editorconfig|.gitattributes)
;;
*)
CODE_CHANGED="true"
break
;;
esac
done <<< "$FILES"
echo "code-changed=$CODE_CHANGED" >> $GITHUB_OUTPUT
echo "Code changed: $CODE_CHANGED"
check-if-pr-is-approved:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
if: ${{ github.event_name == 'pull_request' }}
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 1
- name: Get branch name
uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@d2fd6744fbbb6a0c874c1e28f5374210e2743c2f # v17.1.0
- name: Save commit message
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@d2fd6744fbbb6a0c874c1e28f5374210e2743c2f # v17.1.0
with:
header-only: true
- name: ci:force flag parser
shell: bash
- name: Check if PR approval can be skipped
id: skip-check
env:
EVENT_NAME: ${{ github.event_name }}
ACTOR: ${{ github.actor }}
DEVEL_FLAG: ${{ inputs.devel }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
if [ "$EVENT_NAME" == "schedule" ] || [ "$ACTOR" == "dependabot[bot]" ]; then
echo -e "\033[32mci:force check can be skipped\033[0m"
skip_check="true"
elif [[ "$COMMIT_MESSAGE" == *"[ci:force]"* ]]; then
echo -e "\033[32m[ci:force] flag detected. No need for approval.\033[0m"
skip_check="true"
skip="false"
# Get commit message safely from git to avoid script injection
if [ "$EVENT_NAME" == "pull_request" ] && [ -n "$PR_HEAD_SHA" ]; then
COMMIT_MESSAGE=$(git log -1 --format=%B "$PR_HEAD_SHA" 2>/dev/null || echo "")
else
COMMIT_MESSAGE=$(git log -1 --format=%B 2>/dev/null || echo "")
fi
if [ "$EVENT_NAME" == "schedule" ] || [ "$EVENT_NAME" == "workflow_dispatch" ]; then
echo -e "\033[32mSchedule/dispatch event — skipping approval check\033[0m"
skip="true"
elif [ "$ACTOR" == "dependabot[bot]" ] || [ "$ACTOR" == "alfresco-build" ]; then
echo -e "\033[32mCommit by $ACTOR — skipping approval check\033[0m"
skip="true"
elif echo "$PR_TITLE" | grep -qF "[ci:force]"; then
echo -e "\033[32m[ci:force] flag detected in PR title — skipping approval check\033[0m"
skip="true"
elif echo "$COMMIT_MESSAGE" | grep -qF "[ci:force]"; then
echo -e "\033[32m[ci:force] flag detected in commit message — skipping approval check\033[0m"
skip="true"
elif [[ "$DEVEL_FLAG" == "true" ]]; then
echo -e "\033[32mDevel flag — skipping approval check\033[0m"
skip="true"
fi
echo "skip=$skip" >> $GITHUB_OUTPUT
- name: Get PR number
if: ${{ github.event_name != 'schedule' && github.event_name != 'workflow_dispatch' }}
uses: kamatama41/get-pr-number-action@ff143e03abaa79d346ca5407d49d335b5def979e # v1.0.1
id: action
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: show pr number
shell: bash
if: ${{ steps.skip-check.outputs.skip != 'true' }}
id: pr-number
env:
PR_NUMBER: ${{ steps.action.outputs.number }}
GH_TOKEN: ${{ github.token }}
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
if [ -z "$PR_NUMBER" ]; then
PR_NUMBER=$(gh pr view --json number --jq '.number' 2>/dev/null || echo "")
fi
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "PR: $PR_NUMBER"
- name: check if pr is approved
- name: Check if PR is approved
if: ${{ steps.skip-check.outputs.skip != 'true' && steps.pr-number.outputs.pr_number != '' }}
env:
DEVEL_FLAG: ${{ inputs.devel }}
GH_TOKEN: ${{ github.token }}
skip_check: "false"
EVENT_NAME: ${{ github.event_name }}
ACTOR: ${{ github.actor }}
PR_NUMBER: ${{ steps.action.outputs.number }}
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
run: |
if [ "$EVENT_NAME" == "schedule" ] || [ "$ACTOR" == "dependabot[bot]" ]; then
echo -e "\033[32mci:force check can be skipped\033[0m"
skip_check="true"
elif [[ "$COMMIT_MESSAGE" == *"[ci:force]"* ]]; then
echo -e "\033[32m[ci:force] flag detected. No need for approval.\033[0m"
skip_check="true"
fi
if [ "$ACTOR" == "dependabot[bot]" ] || [ "$ACTOR" == "alfresco-build" ]; then
echo -e "\033[32mCommit by $ACTOR. No need for approval.\033[0m"
skip_check="true"
fi
if [ "$EVENT_NAME" == "schedule" ] || [ "$EVENT_NAME" == "workflow_dispatch" ]; then
echo -e "\033[32mSchedule event\033[0m"
skip_check="true"
fi
if [[ "$DEVEL_FLAG" == "true" ]]; then
echo -e "\033[32mDevel flag\033[0m"
skip_check="true"
fi
if [ "$skip_check" == "false" ]; then
echo "Checking PR approval"
prNumber=$PR_NUMBER
echo "PR: $prNumber"
checkApproval=$(gh api /repos/$GITHUB_REPOSITORY/pulls/$prNumber/reviews | jq '.[] | select(.state == "APPROVED") | .user.login')
if [[ $checkApproval ]]; then
echo -e "\033[32mPR approved\033[0m"
else
echo -e "\033[31mPR NOT approved\033[0m"
exit 1
fi
echo "Checking approval for PR: $PR_NUMBER"
checkApproval=$(gh api /repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews | jq '.[] | select(.state == "APPROVED") | .user.login')
if [[ $checkApproval ]]; then
echo -e "\033[32mPR approved\033[0m"
else
echo -e "\033[31mPR NOT approved\033[0m"
exit 1
fi
setup:
# long timeout required when cache has to be recreated
timeout-minutes: 30
name: "Setup"
runs-on: ubuntu-latest
needs: [check-if-pr-is-approved, pre-checks]
if: ${{ needs.pre-checks.outputs.code-changed == 'true' }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0 # Fetch all history for all tags and branches
- uses: ./.github/actions/setup
- name: install
run: |
npm ci
npm run bundle:js-api
npm run bundle:cli
- uses: ./.github/actions/upload-node-modules-and-artifacts
unit-tests:
timeout-minutes: 30
name: "Unit tests: ${{ matrix.unit-tests.name }}"
runs-on: ubuntu-latest
needs: [setup]
strategy:
fail-fast: false
# max-parallel: 4
matrix:
unit-tests:
- name: js-api
exclude: "core,insights,content-services,process-services,process-services-cloud,eslint-plugin-eslint-angular"
- name: content-services
exclude: "insights,core,extensions,process-services,process-services-cloud,eslint-plugin-eslint-angular,js-api"
- name: core
exclude: "insights,content-services,process-services,process-services-cloud,eslint-plugin-eslint-angular,js-api"
- name: insights
exclude: "core,extensions,content-services,process-services-cloud,process-services,eslint-plugin-eslint-angular,js-api"
- name: process-services
exclude: "core,extensions,content-services,process-services-cloud,insights,eslint-plugin-eslint-angular,js-api"
- name: process-services-cloud
exclude: "insights,core,extensions,content-services,process-services$,eslint-plugin-eslint-angular,js-api"
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
fetch-depth: 0
- name: Setup environment
id: setup-env
uses: ./.github/actions/setup
with:
fetch-depth: 0 # Fetch all history for all tags and branches
- uses: ./.github/actions/setup
- uses: ./.github/actions/download-node-modules-and-artifacts
- name: Run unit tests
env:
EXCLUDE_PATTERN: ${{ matrix.unit-tests.exclude }}
cache-suffix: setup
- name: Bundle
run: |
/usr/bin/xvfb-run --auto-servernum npm run test:affected -- $NX_CALCULATION_FLAGS --exclude=$EXCLUDE_PATTERN
pnpm bundle:js-api
pnpm bundle:cli
- name: Save nx cache
if: ${{ success() }}
uses: ./.github/actions/save-nx-cache
with:
cache-suffix: setup
lint:
# long timeout required when cache has to be recreated
timeout-minutes: 30
name: "Lint"
runs-on: ubuntu-latest
needs: [setup]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0 # Fetch all history for all tags and branches
- uses: ./.github/actions/setup
- uses: ./.github/actions/download-node-modules-and-artifacts
- run: npm run lint:affected -- $NX_CALCULATION_FLAGS
fetch-depth: 0
- name: Setup environment
id: setup-env
uses: ./.github/actions/setup
with:
cache-suffix: lint
full-setup: 'false'
- name: Run lint
env:
BASE_REF: ${{ github.base_ref || 'develop' }}
run: pnpm nx affected --target=lint --base=origin/$BASE_REF --head=HEAD
- name: Save nx cache
if: ${{ success() }}
uses: ./.github/actions/save-nx-cache
with:
cache-suffix: lint
build-libs:
# long timeout required when cache has to be recreated
timeout-minutes: 30
name: "Build libs"
runs-on: ubuntu-latest
trigger-build:
name: "Build Libs"
needs: [setup]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0 # Fetch all history for all tags and branches
- uses: ./.github/actions/setup
- uses: ./.github/actions/download-node-modules-and-artifacts
- run: NX_REJECT_UNKNOWN_LOCAL_CACHE=0 npm run build:affected -- $NX_CALCULATION_FLAGS --prod
- uses: ./.github/actions/upload-node-modules-and-artifacts
uses: ./.github/workflows/build-lib-workflow.yml
with:
base_ref: ${{ github.base_ref || 'develop' }}
build-storybook:
timeout-minutes: 30
name: "Build storybook"
runs-on: ubuntu-latest
name: "Build Storybook"
needs: [setup]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0 # Fetch all history for all tags and branches
- uses: ./.github/actions/setup
- uses: ./.github/actions/download-node-modules-and-artifacts
- run: npm run build-storybook
- uses: ./.github/actions/upload-node-modules-and-artifacts
fetch-depth: 0
- name: Setup environment
id: setup-env
uses: ./.github/actions/setup
with:
cache-suffix: storybook
full-setup: 'false'
- name: Build Storybook
env:
BASE_REF: ${{ github.base_ref || 'develop' }}
run: |
pnpm nx affected --target=build-storybook --base=origin/$BASE_REF --head=HEAD --configuration=ci
- name: Save nx cache
if: ${{ success() }}
uses: ./.github/actions/save-nx-cache
with:
cache-suffix: storybook
trigger-unit-tests:
name: "Unit Tests"
needs: [setup]
uses: ./.github/workflows/unit-test-workflow.yml
with:
base_ref: ${{ github.base_ref || 'develop' }}
PR-size-check:
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Check PR size
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
const additions = pr.additions;
const deletions = pr.deletions;
const totalChanges = additions + deletions;
const changedFiles = pr.changed_files;
let size = 'S';
if (totalChanges > 1000 || changedFiles > 30) size = 'XL';
else if (totalChanges > 500 || changedFiles > 20) size = 'L';
else if (totalChanges > 200 || changedFiles > 10) size = 'M';
core.summary
.addHeading('PR Size: ' + size, 3)
.addTable([
[{data: 'Metric', header: true}, {data: 'Count', header: true}],
['Files changed', String(changedFiles)],
['Additions', '+' + String(additions)],
['Deletions', '-' + String(deletions)],
['Total changes', String(totalChanges)],
]);
if (size === 'XL') {
core.summary.addRaw('⚠️ This PR is very large. Consider splitting it into smaller PRs for easier review.');
}
await core.summary.write();
if (size === 'XL') {
core.warning('This PR has ' + totalChanges + ' changes across ' + changedFiles + ' files. Consider splitting it for easier review.');
}
PR-forbidden-labels:
if: ${{ inputs.cron-run == '' || inputs.cron-run == 'false' }}
runs-on: ubuntu-latest
steps:
- id: checkoutRepo
name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- name: PR contains forbidden labels
id: pr-forbidden
- name: Check for forbidden labels
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const issueHasLabels = require('./scripts/github/update/check-issue-has-label.js');
const checkLabels = ['next version ➡️', 'do not merge🙅🏻‍♂️'];
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const labels = issue.labels?.map(item => item.name) || [];
const forbidden = ['next version ➡️', 'do not merge🙅🏻‍♂️'];
const hasLabel = await issueHasLabels({github, context, checkLabels})
if(hasLabel) {
if (forbidden.some(l => labels.includes(l))) {
core.setFailed('The PR contains a forbidden label! You are not allowed to merge until the label is there.');
}
- name: Check value after
env:
STEP_RESULT: ${{ toJson(steps.pr-forbidden.*.result) }}
HAS_FAILURE: ${{ contains(toJson(steps.pr-forbidden.*.result), 'failure') }}
run: |
echo "Step result: $STEP_RESULT"
echo "Has failure: $HAS_FAILURE"
finalize:
if: ${{ always() }}
@@ -284,16 +330,13 @@ jobs:
check-if-pr-is-approved,
pre-checks,
setup,
unit-tests,
trigger-unit-tests,
lint,
build-libs,
trigger-build,
build-storybook,
PR-forbidden-labels,
]
steps:
- name: Check job execution status
if: >-
${{
contains(needs.*.result, 'failure')
|| contains(needs.*.result, 'cancelled')
}}
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the latest code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Automatic Rebase
+25 -56
View File
@@ -1,13 +1,6 @@
name: "release"
on:
workflow_call:
inputs:
dry-run-flag:
description: 'enable dry-run on artifact push'
required: false
type: boolean
default: true
workflow_dispatch:
inputs:
dry-run-flag:
@@ -15,13 +8,10 @@ on:
required: false
type: boolean
default: true
pull_request:
types: [closed]
push:
branches:
- develop
- develop-patch*
push:
branches:
- master
- master-patch-*
@@ -34,8 +24,6 @@ concurrency:
cancel-in-progress: false
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
GH_COMMIT: ${{ github.sha }}
GH_BUILD_NUMBER: ${{ github.run_id }}
LOG_LEVEL: "ERROR"
@@ -44,22 +32,23 @@ env:
jobs:
setup:
timeout-minutes: 20
if: github.event.pull_request.merged == true || github.ref_name == 'master' || github.ref_name == 'master-patch-*' || github.event_name == 'workflow_dispatch'
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
name: "Setup"
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- uses: ./.github/actions/setup
with:
enable-node-modules-cache: false
- name: install
run: |
npm ci
npm run bundle:js-api
npm run bundle:cli
pnpm install --frozen-lockfile
pnpm bundle:js-api
pnpm bundle:cli
- uses: ./.github/actions/upload-node-modules-and-artifacts
release-npm:
@@ -67,21 +56,20 @@ jobs:
outputs:
release_version: ${{ steps.set-version.outputs.release_version }}
timeout-minutes: 30
if: github.event.pull_request.merged == true || github.ref_name == 'master' || github.ref_name == 'master-patch-*' || github.event_name == 'workflow_dispatch'
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC
contents: read
packages: write
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- id: setup
uses: ./.github/actions/setup
with:
enable-node-modules-cache: false
- id: set-dryrun
uses: ./.github/actions/enable-dryrun
with:
@@ -100,24 +88,24 @@ jobs:
setMigrations();
- name: build libraries
run: |
npm run build:libs
npm run build:schematics
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
pnpm build:libs
pnpm build:schematics
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
name: release libraries GH registry
with:
node-version-file: '.nvmrc'
registry-url: 'https://npm.pkg.github.com'
scope: '@alfresco'
- run: npm run publish -- --tag=${{ steps.setup.outputs.npm-tag }}
- run: pnpm run publish --tag ${{ steps.setup.outputs.npm-tag }} --provenance=false ${{ steps.set-dryrun.outputs.dryrun }}
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
name: release libraries Npm registry
with:
node-version-file: '.nvmrc'
registry-url: 'https://${{ vars.NPM_REGISTRY_ADDRESS }}'
scope: '@alfresco'
- run: npm run publish -- --tag=${{ steps.setup.outputs.npm-tag }}
- run: pnpm run publish --tag ${{ steps.setup.outputs.npm-tag }} ${{ steps.set-dryrun.outputs.dryrun }}
create-git-tag:
runs-on: ubuntu-latest
@@ -128,41 +116,21 @@ jobs:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
- uses: './.github/actions/create-git-tag'
with:
tagName: ${{ needs.release-npm.outputs.release_version }}
propagate:
needs: [release-npm]
if: ${{ contains(toJson(github.event.pull_request.labels.*.name), 'hxp-upstream') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: HxP upstream invoke
uses: the-actions-org/workflow-dispatch@3133c5d135c7dbe4be4f9793872b6ef331b53bc7 # v4.0.0
with:
repo: Alfresco/hxp-frontend-apps
ref: develop
workflow: upstream-adf.yml
token: ${{ secrets.ALFRESCO_BUILD_GH_TOKEN }}
wait-for-completion: false
inputs: >
{
"tag_version": "alpha"
}
npm-check-bundle:
needs: [release-npm]
timeout-minutes: 15
if: github.event.pull_request.merged == true || github.ref_name == 'master' || github.ref_name == 'master-patch-*' || github.event_name == 'workflow_dispatch'
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: ./.github/actions/npm-check-bundle
push-translation-keys-to-crowdin:
@@ -176,10 +144,10 @@ jobs:
actions: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Push Source Files to Crowdin
uses: crowdin/github-action@7ca9c452bfe9197d3bb7fa83a4d7e2b0c9ae835d # v2.16.0
uses: crowdin/github-action@e0c8f73cdc0fafde9396e056c5038217000a32d1 # v2.16.4
with:
upload_sources: true
upload_sources_args: --delete-obsolete
@@ -191,8 +159,9 @@ jobs:
name: Run Crowdin pull pipeline for up-to-date sync
uses: ./.github/workflows/pull-from-crowdin.yml
secrets:
BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
GH_APP_ENGINEERING_CONTRIB_PRIVATE_KEY: ${{ secrets.GH_APP_ENGINEERING_CONTRIB_PRIVATE_KEY }}
CROWDIN_TRANSLATIONS_TOKEN: ${{ secrets.CROWDIN_TRANSLATIONS_TOKEN }}
HXPS_GIT_COMMIT_SIGNING_PRIVATE_KEY: ${{ secrets.HXPS_GIT_COMMIT_SIGNING_PRIVATE_KEY }}
finalize:
if: always()
+14
View File
@@ -0,0 +1,14 @@
name: Stale PR Cleanup
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
permissions:
pull-requests: write
issues: write
jobs:
stale-pr-cleanup:
uses: Alfresco/alfresco-build-tools/.github/workflows/stale-pr-cleanup.yml@1d671f8f10336861c89c67be57c6648d98876103 # v18.19.0
@@ -0,0 +1,31 @@
name: Supply Chain Review - PR Instructions
on:
pull_request:
types: [opened, reopened, synchronize]
paths:
- "package.json"
- "pnpm-lock.yaml"
- "**/package.json"
- "pom.xml"
- "**/pom.xml"
jobs:
instructions:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: Alfresco/alfresco-build-tools/.github/actions/github-upsert-comment@1d671f8f10336861c89c67be57c6648d98876103 # v18.19.0
with:
comment-identifier: supply-chain-review-instructions
comment-body: |
## 🔒 Supply Chain Security
This PR modifies dependencies. To run a security analysis, comment:
```
/supply-chain-review
```
The analysis will check for vulnerabilities, typosquatting, maintainer takeovers, and other supply chain risks.
File diff suppressed because one or more lines are too long
+358
View File
@@ -0,0 +1,358 @@
---
on:
slash_command:
name: supply-chain-review
reaction: rocket
permissions:
contents: read
pull-requests: read
engine:
id: copilot
model: gpt-5-mini
tools:
github:
toolsets: [context, pull_requests, repos]
network:
allowed:
- defaults
- node
- java
- api.osv.dev
- api.scorecard.dev
- search.maven.org
safe-outputs:
add-comment:
hide-older-comments: true
add-labels:
allowed: [security:low, security:medium, security:high]
remove-labels:
allowed: [security:low, security:medium, security:high]
submit-pull-request-review:
source: Alfresco/alfresco-build-tools/.github/workflows/supply-chain-review.md@7479d99410acb8b63f78a5b17abb3b8ebec3a66d
---
# Supply Chain Review
You are a supply chain security analyst reviewing a pull request for dependency changes.
Your goal is to identify any dependency additions or upgrades and produce a thorough risk assessment for each change, covering known vulnerabilities, typosquatting, maintainer takeover, install script abuse, version anomalies, source code changes, and project health.
You are the primary and only analysis engine. There is no secondary check. Be thorough but calibrated: false positives erode trust, but missed threats have severe consequences.
## Step 1 — Identify Dependency Changes
Read the pull request diff and find all modified dependency files (`package.json`, `package-lock.json`, `pom.xml`, `yarn.lock`, `build.gradle`, etc.). For each changed dependency extract:
- Package name (including scope/groupId if applicable)
- Ecosystem (`npm` or `maven`)
- Old version (or mark as `NEW DEPENDENCY` if newly added)
- New version
If no dependency files were changed, post a brief PR comment stating that no dependency changes were detected and no review is needed, then stop.
## Step 1b — Filter Internal Dependencies
Before collecting external data, identify and exclude internal/private dependencies that cannot be resolved by public APIs.
**Internal dependency namespaces (skip these):**
- **Maven**: Any dependency with a `groupId` starting with `com.hyland.`, `org.alfresco.`, or `org.activiti.`
- **npm**: Any package under the `@hyland/`, `@hylandsoftware/`, or `@alfresco/` scopes
For each internal dependency found:
1. Remove it from the analysis pipeline — do NOT query OSV.dev, OpenSSF Scorecard, or registry APIs for these packages (they will fail or return irrelevant data).
2. Record the package name (with `@` replaced by `(at)` for GitHub comment compatibility), ecosystem, old version, and new version in a separate "Internal Dependencies (Skipped)" list.
3. Continue with Step 2 only for the remaining external/public dependencies.
If ALL changed dependencies are internal, skip Steps 2-4 and proceed directly to Step 5, posting a report that lists the internal dependencies and notes that no external supply chain analysis was performed.
## Step 2 — Collect Data for Each Dependency
For every changed dependency, gather the following data. Fetch all data sources in parallel where possible. If any request fails or returns no data, note it and continue — missing data alone is not proof of malice, but factor it into your confidence level.
### 2a. Known Vulnerabilities (OSV.dev)
Query the OSV.dev API for vulnerabilities affecting the **new** version:
- **npm**: `POST https://api.osv.dev/v1/query` with body `{"package":{"name":"<package-name>","ecosystem":"npm"},"version":"<new-version>"}`
- **Maven**: `POST https://api.osv.dev/v1/query` with body `{"package":{"name":"<groupId>:<artifactId>","ecosystem":"Maven"},"version":"<new-version>"}`
Record all returned vulnerability IDs, severity ratings, and summaries. CRITICAL and HIGH severity CVEs in the new version are the most urgent signal.
### 2b. OpenSSF Scorecard
Fetch the project health score. First determine the source repository from the package metadata (see 2c), then query:
`GET https://api.scorecard.dev/projects/github.com/{owner}/{repo}`
Record the overall score (0-10) and individual check results. Pay special attention to: Maintained, Code-Review, Vulnerabilities, Branch-Protection, Signed-Releases. A score below 3 is very concerning; below 5 warrants caution. If the package has no linked source repository, the scorecard will be unavailable — this is itself a risk signal.
### 2c. Package Metadata (Registry)
**For npm packages**, fetch:
`GET https://registry.npmjs.org/<package-name>`
From the full registry document, extract for BOTH the old and new versions:
- `versions[<version>]._npmUser` — the publisher
- `versions[<version>].maintainers` — the maintainer list
- `versions[<version>].scripts` — lifecycle scripts (`preinstall`, `install`, `postinstall`)
- `versions[<version>].dependencies` — runtime dependencies
- `time[<version>]` — publish timestamp
- `repository` — source repository URL
Also extract the `time` object to build a version history (last 10 versions with publish dates).
**For Maven packages**, fetch:
`GET https://central.sonatype.com/api/v1/search?q=g:<groupId>+AND+a:<artifactId>&sort=published&limit=10`
For POM details (build plugins, dependencies): `GET https://repo1.maven.org/maven2/<groupId-as-path>/<artifactId>/<version>/<artifactId>-<version>.pom`
### 2d. Source Code Diff and Release Notes
Use the PR diff itself to review the actual file changes for dependency manifest files. Additionally, if a source repository is identified (from 2c), fetch release notes and compare tags:
- Release notes: `GET https://api.github.com/repos/{owner}/{repo}/releases/tags/v<new-version>` (try with and without the `v` prefix)
- For a code-level diff between old and new versions: `GET https://api.github.com/repos/{owner}/{repo}/compare/v<old-version>...v<new-version>` (try with and without the `v` prefix)
## Step 3 — Analyze Against Threat Taxonomy
Evaluate each dependency against ALL of the following threat categories. Not every category applies to every package — use judgment.
### 3a. Known Vulnerabilities
Assess the severity and exploitability of any CVEs or advisories returned from OSV.dev. CRITICAL and HIGH severity vulnerabilities in the new version are the most urgent signal. Also check whether the upgrade itself fixes known vulnerabilities in the old version (a positive signal).
### 3b. Typosquatting / Name Confusion
Determine if the package name could be a typosquatting attempt targeting a well-known package. Consider:
- Levenshtein distance to popular packages (e.g., `lodas` vs `lodash`)
- Dash/underscore/separator swaps (e.g., `my_package` vs `my-package`)
- Suffix variants (e.g., `express-js`, `express.js`)
- Scope squatting for npm (e.g., `@attacker/lodash` vs `lodash`)
- GroupId squatting for Maven (e.g., `org.apach.commons` vs `org.apache.commons`)
Use your knowledge of the ecosystem to identify plausible targets. Reason from your training data about popular packages.
### 3c. Maintainer Takeover
Compare the publisher and maintainer metadata between the old and new versions. Red flags:
- Publisher changed between versions (different `_npmUser`)
- Old maintainers removed and replaced
- New publisher has no prior history with the package
- Classic pattern: publisher change + maintainer removal (like the event-stream incident)
### 3d. Install Script Abuse
**For npm**: Analyze lifecycle scripts (`preinstall`, `install`, `postinstall`) from the registry metadata. Red flags:
- Scripts that download and execute remote code (`curl`, `wget`, `http://`)
- `eval()`, `Function()`, `child_process` usage
- Environment variable access (`process.env`) for credential theft
- Base64/hex decoding of payloads
- Access to sensitive paths (`~/.ssh`, `~/.aws`, `~/.npmrc`, `/etc/passwd`)
- Network calls (`dns.lookup`, `net.connect`) for exfiltration
- Scripts that are NEW in this version (not present in the old version) are especially suspicious
**For Maven**: Look for dangerous build plugins in POM changes:
- `exec-maven-plugin`, `maven-antrun-plugin` with `<exec>`
- `<extensions>true</extensions>` on untrusted plugins
- Download plugins, Groovy/script plugins
### 3e. Version Anomalies
Analyze the version change pattern and history from the registry metadata:
- Major version jumps (skipping 1+ major versions)
- Version downgrade (new version < old version)
- Stable to prerelease transition
- Very recent publish (less than 48 hours old) — could indicate a rush to distribute malicious code
- Rapid successive publishes (many versions in a short window)
- Long dormancy then sudden publish (more than 1 year gap) — may indicate account takeover
### 3f. Source Code Changes
If source diffs are available (from the GitHub compare API or the PR diff itself), analyze for:
- Obfuscated code (minified without source maps, hex/unicode escapes, string concatenation to hide function names)
- Data exfiltration (network calls sending `process.env`, API keys, tokens to external endpoints)
- Filesystem access outside the package directory
- Dynamic code execution (`eval()`, `Function()`, `vm.runInNewContext`, `WebAssembly.instantiate`)
- Encoded payloads (Base64/hex decoded and executed at runtime)
- Inconsistency between release notes and actual changes (changelog says "bug fix" but diff adds network calls)
- Cryptocurrency mining patterns
- Suspicious new transitive dependencies
### 3g. Project Health
Interpret the OpenSSF Scorecard data:
- Overall score below 3/10 is very concerning
- Score below 5/10 warrants caution
- Pay attention to specific failing checks: Maintained, Code-Review, Vulnerabilities, Branch-Protection, Signed-Releases
- Missing scorecard data (no source repo linked) is itself a risk signal
### 3h. Missing Source Repository
A package with no linked source repository prevents code audit and is a risk signal, especially combined with other concerns.
### 3i. Tag Poisoning / Build Provenance
Evaluate whether the published artifact can be traced back to a verified source commit. This category covers attacks where a legitimate-looking version tag is manipulated to distribute malicious code.
#### Tag-to-Registry Provenance Mismatch
Check whether the git tag for the new version corresponds to the published artifact:
- Compare the tag commit date with the registry publish timestamp. A discrepancy of more than a few hours (allowing for CI/CD pipeline time) is suspicious.
- If the source diff between the tag and the previous tag includes changes not documented in release notes, flag as suspicious.
#### Mutable/Moved Tags
Check if the tag appears to have been recreated:
- Use `GET https://api.github.com/repos/{owner}/{repo}/git/refs/tags/{tag}` to get the tag reference.
- For annotated tags, use `GET https://api.github.com/repos/{owner}/{repo}/git/tags/{sha}` to check the tag object and its `tagger.date`.
- If the tag creation date is significantly newer than the commit it points to (e.g., more than 7 days), this may indicate the tag was deleted and recreated pointing to a different commit.
#### Unsigned Tags
Determine tag type and signing status:
- **Annotated + signed tags** (GPG or SSH signature present) — strongest integrity signal.
- **Annotated but unsigned tags** — moderate integrity; the tag is immutable but unverified.
- **Lightweight tags** — weakest integrity; easily moved without trace. Flag as a risk signal for high-profile or security-critical packages.
For the tag object, check the `verification` field in the GitHub API response for signature status.
#### Build Provenance / Attestation
Check for SLSA provenance attestations or Sigstore signatures:
**For npm packages**: Query `GET https://registry.npmjs.org/-/npm/v1/attestations/<package-name>@<new-version>`. If attestations are present, verify:
- The `predicateType` matches a known SLSA provenance type
- The `subject` digest matches the published package tarball
- The build was performed by a trusted CI system (e.g., GitHub Actions)
**For Maven packages**: Check if Sigstore `.sigstore` bundle files exist alongside the artifact at:
`GET https://repo1.maven.org/maven2/<groupId-as-path>/<artifactId>/<version>/<artifactId>-<version>.jar.sigstore`
The absence of provenance attestations on a high-profile package (>1000 weekly downloads for npm, or widely used in the ecosystem) is a moderate risk signal. Packages that previously published with provenance but stopped doing so are especially suspicious.
#### Tag Mimicry on Forks
Verify that the source repository URL in registry metadata points to the canonical repository:
- Cross-reference the `repository` field from package metadata (Step 2c) with the GitHub API response.
- If the repository URL points to a fork rather than the original project, flag as HIGH risk — this may indicate a hijacked tag on a lookalike fork.
- Check that the repository owner matches known maintainers of the package.
## Step 4 — Score and Classify Risk
Assign a risk score (0-100) to each dependency using these guidelines:
| Priority | Signal | Typical Impact |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| Highest | Known CRITICAL/HIGH CVEs in new version, confirmed typosquatting, malicious code in diff, build provenance mismatch (tag points to different code than published artifact), tag mimicry on fork | 60+ points |
| High | Maintainer takeover pattern (publisher changed + old maintainers removed), dangerous install scripts, known compromised package, moved/recreated tag with different commit, provenance attestations removed from package that previously had them | 20-40 points |
| Medium | Low OpenSSF Scorecard (< 3), publisher changed (without full takeover), new install scripts, very recent publish (< 48h), obfuscated code in diff, unsigned lightweight tags on security-critical packages, absence of provenance on high-profile packages | 10-20 points |
| Lower | Scorecard 3-5, version anomalies, missing source repository, long dormancy, rapid publishes, tag date slightly newer than commit (within 7 days), annotated but unsigned tags | 5-10 points |
These are guidelines, not rigid formulas. Use judgment to combine signals — multiple medium signals can compound into a high-risk assessment.
**Risk level thresholds**: 0-20 = LOW, 21-50 = MEDIUM, 51-80 = HIGH, 81-100 = CRITICAL.
If no suspicious patterns are found, assign a score of 0-10 and risk level LOW. Most legitimate upgrades should score LOW.
## Step 5 — Post Findings as PR Comment
Post a structured report in the following format.
**CRITICAL: Sanitize all `@` symbols before posting**
GitHub enforces a maximum of 10 mentions per comment. Package names containing `@` (like `@hyland/core`, `@alfresco/js-api`) are interpreted as user/team mentions and trigger this limit, causing comment post failures.
**Before generating the comment text**:
1. Replace **every** `@` symbol in package names with `(at)` — e.g., `@hyland/core``(at)hyland/core`
2. Apply this transformation to ALL occurrences: table cells, headings, inline code blocks, findings sections, reason columns
3. This applies to both external and internal dependencies
4. Do NOT skip this step — even if only a few packages are affected, GitHub counts all `@` symbols
```txt
## Supply Chain Security Review
| Package | Ecosystem | Old Version | New Version | Risk Score | Risk Level |
|---------|-----------|-------------|-------------|------------|------------|
| example | npm | 1.0.0 | 2.0.0 | 5 | LOW |
### Internal Dependencies (Skipped)
| Package | Ecosystem | Old Version | New Version | Reason |
|-------------------|-----------|-------------|-------------|---------------------------------|
| (at)hyland/core | npm | 3.1.0 | 3.2.0 | Internal ((at)hyland/* scope) |
_These dependencies are internal packages not available on public registries. External API checks were skipped._
### Findings
#### `<package-name-sanitized>` (<old-version> -> <new-version>) — <RISK_LEVEL>
**Risk Score**: <score>/100
<If findings exist, list each one:>
**<Category>** (<severity>) — <title>
<detailed explanation with specific evidence>
<If no findings:>
No suspicious patterns detected. Routine upgrade.
---
### Data Collection Notes
<List any APIs that were unavailable or returned errors, so reviewers know what was and wasn't checked.>
---
### Overall Risk: <highest risk level across all dependencies>
**Recommendation**: <approve|review|block>
- **approve**: LOW risk, routine upgrade, no concerns found
- **review**: MEDIUM risk, a human should examine specific findings before merging
- **block**: HIGH/CRITICAL risk, should not be merged without security team review
```
## Step 6 — Apply Label and Review Status
- First, remove any `security:low`, `security:medium`, or `security:high` labels already present on the PR from a previous review — this PR may have been reviewed before (e.g., after a new commit), and stale risk labels must not remain alongside the new one.
- Then apply a label to the PR based on the highest risk level found:
- `security:low` for LOW risk
- `security:medium` for MEDIUM risk
- `security:high` for HIGH or CRITICAL risk
- If the highest risk level is HIGH or CRITICAL, submit a pull request review requesting changes, with a summary of the critical findings.
- If the risk is MEDIUM, submit a pull request review as a comment, noting that human review is recommended.
- If the risk is LOW, do not submit a review — the PR comment is sufficient.
## Important Guidelines
- **Never approve or merge the PR** — all actions are advisory or blocking only. A human always makes the merge decision.
- Be specific in findings — cite exact data (vulnerability ID, maintainer name, script content, file path, API response) rather than vague warnings.
- For Maven packages, adapt npm-specific checks appropriately (e.g., install scripts become build plugin analysis, maintainer metadata may be limited).
- When a package is a NEW dependency (no old version), pay extra attention to project health, name legitimacy, and install scripts since there is no historical baseline to compare against.
- If data collection fails for all external APIs, still analyze the PR diff directly and provide the best assessment you can with available information, noting the limitations clearly.
- For tag poisoning checks, not all packages will have provenance attestations — this is still an emerging practice. Weight the absence of attestations proportionally to the package's profile and criticality. Do not flag low-download utility packages for missing provenance.
- When checking tag dates, allow for reasonable CI/CD pipeline delays (up to a few hours between tag push and publish). Only flag significant discrepancies (days or weeks).
+81
View File
@@ -0,0 +1,81 @@
name: "Unit Tests Workflow"
on:
workflow_call:
inputs:
base_ref:
description: 'Base branch for affected calculation'
required: false
type: string
default: 'develop'
jobs:
generate-affected-matrix:
name: "Generate affected matrix"
runs-on: ubuntu-latest
outputs:
unitMatrix: ${{ steps.set-matrix.outputs.unitMatrix }}
hasProjects: ${{ steps.set-matrix.outputs.hasProjects }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Setup environment
id: setup-env
uses: ./.github/actions/setup
with:
cache-suffix: test-matrix
- name: Generate affected projects matrix
id: set-matrix
env:
BASE_REF: ${{ inputs.base_ref }}
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)
echo "Affected projects for UNIT: $AFFECTED_UNIT"
if [ -z "$AFFECTED_UNIT" ]; then
echo "No affected projects found"
echo "hasProjects=false" >> $GITHUB_OUTPUT
echo "unitMatrix=[]" >> $GITHUB_OUTPUT
else
UNIT_MATRIX_JSON=$(echo "$AFFECTED_UNIT" | xargs -n1 | jq -R -s -c 'split("\n") | map(select(length > 0)) | map({ "project": . })')
echo "Matrix UNIT: $UNIT_MATRIX_JSON"
echo "hasProjects=true" >> $GITHUB_OUTPUT
echo "unitMatrix=$UNIT_MATRIX_JSON" >> $GITHUB_OUTPUT
fi
- name: Save nx cache
if: ${{ success() }}
uses: ./.github/actions/save-nx-cache
with:
cache-suffix: test-matrix
unit-tests:
timeout-minutes: 30
runs-on: ubuntu-latest
needs: generate-affected-matrix
if: ${{ needs.generate-affected-matrix.outputs.hasProjects == 'true' }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.generate-affected-matrix.outputs.unitMatrix) }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup environment
id: setup-env
uses: ./.github/actions/setup
with:
cache-suffix: test-${{ matrix.project }}
full-setup: 'false'
- name: Run unit tests for ${{ matrix.project }}
env:
NODE_OPTIONS: "--max-old-space-size=5120"
run: |
xvfb-run --auto-servernum pnpm nx run ${{ matrix.project }}:test
- name: Save nx cache
if: ${{ success() }}
uses: ./.github/actions/save-nx-cache
with:
cache-suffix: test-${{ matrix.project }}
+1 -1
View File
@@ -8,7 +8,6 @@ bundles
dist
tmp
temp
*.npmrc
.history
.ng_pkg_build/
coverage/
@@ -24,3 +23,4 @@ nxcache
.husky
.cursor/rules/nx-rules.mdc
.github/instructions/nx.instructions.md
lib/eslint-angular/dist/
+1
View File
@@ -1,4 +1,5 @@
#!/bin/sh
export NODE_OPTIONS=--max_old_space_size=8192
lint-staged
+5
View File
@@ -0,0 +1,5 @@
# Fail on high severity vulnerabilities during audit
audit-level=high
# Use exact versions to prevent unexpected updates
save-exact=true
+6
View File
@@ -1,6 +1,12 @@
{
"extends": ["stylelint-config-standard-scss"],
"rules": {
"custom-property-pattern": [
"^(mat-sys|mdc)",
{
"message": "Use only Angular Material system variables (--mat-sys-*, --mdc-*)"
}
],
"color-function-notation": "legacy",
"alpha-value-notation": "number",
"color-no-invalid-hex": true,
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"meterian.meterian-heidi"
]
}
+23
View File
@@ -21,6 +21,29 @@ for full details on what you may need to install before using ADF.
- [Node Version Manager](docs/tutorials/nvm.md)
- [CORS guide](ALFRESCOCORS.md)
## Installation
This project uses **pnpm** for package management with built-in supply chain attack protection.
```bash
pnpm install # install all packages
pnpm run add <package> # add a new package (with security check)
```
### Supply Chain Security
**Layer 1: pnpm script blocking**
- All lifecycle scripts (postinstall, etc.) are blocked by default
- Only trusted packages in `pnpm-workspace.yaml` can run scripts
- Protects during `pnpm install` and `pnpm add`
**Layer 2: Security database check**
- `pnpm run add` checks packages against OSV and GitHub Advisory databases BEFORE installing
- Pre-commit hook blocks commits containing known malicious packages
**Layer 3: npm blocked**
- Running `npm install` will fail - enforces pnpm usage
## Components
You can find the sources for all ADF components in the [`lib`](/lib) folder.
+9 -2
View File
@@ -351,7 +351,6 @@ for more information about installing and using the source code.
| Name | Description | Source link |
| ---- | ----------- | ----------- |
| [Agent Service](content-services/services/agent.service.md) | Manages agents in Content Services. | [Source](../lib/content-services/src/lib/agent/services/agent.service.ts) |
| [Audit Service](content-services/services/audit.service.md) | Manages Audit apps and entries. | [Source](../lib/content-services/src/lib/audit/audit.service.ts) |
| [Card View Content Update Service](content-services/services/card-view-content-update.service.md) | Manages Card View properties in the content services environment. Implements BaseCardViewContentUpdate. | [Source](../lib/content-services/src/lib/common/services/card-view-content-update.service.ts) | |
| [Category tree datasource service](content-services/services/category-tree-datasource.service.md) | Datasource service for category tree. | [Source](../lib/content-services/src/lib/category/services/category-tree-datasource.service.ts) |
@@ -367,7 +366,6 @@ for more information about installing and using the source code.
| [Node Comments Service](content-services/services/node-comments.service.md) | Adds and retrieves comments for nodes in Content Services. | [Source](../lib/content-services/src/lib/node-comments/services/node-comments.service.ts) |
| [Node permission dialog service](content-services/services/node-permission-dialog.service.md) | Displays dialogs to let the user set node permissions. | [Source](../lib/content-services/src/lib/permission-manager/services/node-permission-dialog.service.ts) |
| [Node Permission service](content-services/services/node-permission.service.md) | Manages role permissions for content nodes. | [Source](../lib/content-services/src/lib/permission-manager/services/node-permission.service.ts) |
| [Search Ai Service](content-services/services/search-ai.service.md) | Manages search AI in Content Services. | [Source](../lib/content-services/src/lib/search-ai/services/search-ai.service.ts) |
| [Search filter service](content-services/services/search-filter.service.md) | Registers widgets for use with the Search Filter component. | [Source](../lib/content-services/src/lib/search/services/search-filter.service.ts) |
| [Search Query Builder service](content-services/services/search-query-builder.service.md) | Stores information from all the custom search and faceted search widgets, compiles and runs the final search query. | [Source](../lib/content-services/src/lib/search/services/search-query-builder.service.ts) |
| [Security Controls service](content-services/services/security-controls.service.md) | Manages security groups & marks in Content Services. | [Source](../lib/content-services/src/lib/security/services/security-controls-groups-marks-security.service.ts) |
@@ -567,3 +565,12 @@ Contains all custom rules used by ESLint.
<!--eslint-angular end-->
[(Back to Contents)](#contents)
## Notes
### Knowledge Discovery removal (v9.0.0)
The Knowledge Discovery components, services, and APIs have been removed as of version 9.0.0.
The integrated Knowledge Discovery features have been replaced with a section in the side navigation panel containing a link to the standalone Knowledge Discovery UI application in higher level apps such as ACA and ADW.
If you were using those features, please consider cleaning Local Storage in your browser as *aiReferences* entry may remain.
+62
View File
@@ -0,0 +1,62 @@
# CI Commands and Labels
Reference for flags and labels that control CI behavior on pull requests.
## PR Title Flags
Include these flags anywhere in the **PR title** to modify CI behavior.
| Flag | Effect |
|------|--------|
| `[ci:force]` | Skips the PR approval check, allowing the full pipeline to run without an approved review. Useful for testing CI changes on draft PRs. |
Example: `[AAE-12345] Fix pagination component [ci:force]`
## Commit Message Flags
Include these flags in a **commit message** to modify CI behavior.
| Flag | Effect |
|------|--------|
| `[ci:force]` | Skips the PR approval check (same as PR title flag). |
| `[affected:*]` | Forces all Nx targets to run against all projects, ignoring the affected calculation. Equivalent to `--all`. |
## PR Labels
Labels applied to the PR that affect CI behavior.
| Label | Effect |
|-------|--------|
| `do not merge` | Blocks the PR from passing the finalize check. CI will fail until the label is removed. |
| `next version` | Same as above - blocks the PR from merging. Used to hold PRs for the next release cycle. |
## Automatic Skip Conditions
The approval check is automatically skipped for:
- **Scheduled runs** (`schedule` event)
- **Workflow dispatch** (`workflow_dispatch` event)
- **Dependabot PRs** (actor is `dependabot[bot]`)
- **Build bot PRs** (actor is `alfresco-build`)
- **Devel flag** (when `devel: true` is passed via `workflow_call`)
## Path-Based Filtering
PRs that only modify non-code files skip the build, test, and lint jobs entirely. Files considered non-code:
- Markdown files (`*.md`)
- Documentation (`docs/`)
- `LICENSE`, `NOTICE`
- `.editorconfig`, `.gitattributes`
- `.github/CODEOWNERS`, `.github/dependabot.yml`
## PR Size Check
Every PR gets an automatic size classification displayed in the job summary:
| Size | Criteria |
|------|----------|
| **S** | < 200 total changes and < 10 files |
| **M** | 200-500 total changes or 10-20 files |
| **L** | 500-1000 total changes or 20-30 files |
| **XL** | > 1000 total changes or > 30 files (warning annotation added) |
@@ -46,9 +46,9 @@ Implements a [search widget](../../../lib/content-services/src/lib/search/models
| field | string | Field to apply the query fragment to. Required value |
| pattern | string | Regular expression pattern to restrict the format of the input text |
| placeholder | string | Text displayed in the widget when the input string is empty |
| searchSuffix | string | Text to append always in the search of a string |
| searchPrefix | string | Text to prepend always in the search of a string |
| allowUpdateOnChange | `boolean` | Enable/Disable the update fire event when text has been changed. By default is true. |
| searchSuffix | string | Text to append in the search of a string. Only applied when wildcard matching is enabled (the `search-wildcards-enabled` app config flag, default `true`). |
| searchPrefix | string | Text to prepend in the search of a string. Only applied when wildcard matching is enabled (the `search-wildcards-enabled` app config flag, default `true`). |
| allowUpdateOnChange | `boolean` | Enable/Disable firing the search update when the text changes. Defaults to `false`; when disabled the search runs only when the user submits the value. |
| hideDefaultAction | boolean | Show/hide the widget actions. By default is false. |
## Details
@@ -13,7 +13,6 @@ Update the current node by adding/removing the inherited permissions.
```html
<button mat-raised-button
color="primary"
adf-inherit-permission [nodeId]="nodeId"
(updated)="onUpdatedPermissions($node)">PERMISSION</button>
```
@@ -115,8 +115,8 @@ that will be used when performing the actual query.
Every query fragment is stored and retrieved using its widget `id`.
It is your responsibility to format the query correctly.
Once your change to the query is finished, update the context and call the `update` method
to inform other components about the change:
Once your change to the query is finished, update the context and call the `execute` method
to rebuild and run the query so the results reflect your change:
```ts
@Component({...})
@@ -126,12 +126,15 @@ export class MyComponent implements SearchWidget, OnInit {
onUIChanged() {
this.context.queryFragments[this.id] = `some query`;
this.context.update();
void this.context.execute();
}
}
```
> **Note:** Earlier versions called `this.context.update()` here. The `update()` method and the
> `updated` stream have been removed; call `this.context.execute()` directly instead.
When executed, your fragment will be injected into the resulting query based on the category order in the application configuration file.
```text
@@ -1,27 +0,0 @@
---
Title: Agent service
Added: v7.0.0-alpha.3
Status: Active
Last reviewed: 2024-07-12
---
# [Agent service](../../../lib/content-services/src/lib/agent/services/agent.service.ts "Defined in agent.service.ts")
Manages agents in Content Services.<br/>
<b>In order to use this service, you need to have the HX Insights Connector (additional ACS module) installed.</b>
## Class members
### Methods
- **getAgents**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AgentPaging`](../../../lib/js-api/src/api/content-rest-api/docs/AgentsApi.md#agentpaging)`>`<br/>
Gets all agents.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AgentPaging`](../../../lib/js-api/src/api/content-rest-api/docs/AgentsApi.md#agentpaging)`>` - AgentPaging object containing the agents.
## Details
See the
[Agents API](../../../lib/js-api/src/api/content-rest-api/docs/AgentsApi.md) for more information about the types returned by [Agent
service](agent.service.md) methods and for the implementation of the REST API the service is
based on.
@@ -23,11 +23,12 @@ Manages Document List information that is specific to a user.
- _node:_ `any` - Node object
- _nodeId:_ `string` - ID of the node object
- **Returns** `string` - ID value
- **getRecentFiles**(personId: `string`, pagination: [`PaginationModel`](../../../lib/core/src/lib/models/pagination.model.ts), filters?: `string[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>`<br/>
- **getRecentFiles**(personId: `string`, pagination: [`PaginationModel`](../../../lib/core/src/lib/models/pagination.model.ts), filters?: `string[]`, includeFields: `string[]` = `[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>`<br/>
Gets files recently accessed by a user.
- _personId:_ `string` - ID of the user
- _pagination:_ [`PaginationModel`](../../../lib/core/src/lib/models/pagination.model.ts) - Specifies how to paginate the results
- _filters:_ `string[]` - (Optional) Specifies additional filters to apply (joined with **AND**)
- _includeFields:_ `string[]` - List of data field names to include in the results
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>` - List of nodes for the recently used files
- **hasCorrespondingNodeIds**(nodeId: `string`): `boolean`<br/>
Does the well-known alias have a corresponding node ID?
@@ -2,7 +2,7 @@
Title: Document List service
Added: v2.0.0
Status: Active
Last reviewed: 2019-01-16
Last reviewed: 2026-06-16
---
# Document List Service
@@ -21,10 +21,11 @@ import { DocumentListService } from '@alfresco/adf-core';
### Events
| Name | Description |
|-------------------|-------------------------------------------------|
| `reload$` | Emits when the document list should be reloaded |
| `resetSelection$` | Emits when the selection should be reset |
| Name | Description |
|-------------------|----------------------------------------------------------------------------------------------|
| `reload$` | Emits when the document list should be reloaded. |
| `resetSelection$` | Emits when the selection should be reset. |
| `reloadSilently$` | Emits when the document list should be reloaded **without** resetting the current selection. |
### Methods
@@ -32,6 +33,8 @@ import { DocumentListService } from '@alfresco/adf-core';
Reloads the document list.
- **resetSelection**(): `void`<br/>
Resets the selection.
- **reloadSilently**(): `void`<br/>
Reloads the document list **without** resetting the current selection.
- **copyNode**(nodeId: `string`, targetParentId: `string`): `Observable<NodeEntry>`<br/>
Copy a node to destination node
- _nodeId:_ `string` - The id of the node to be copied
@@ -1,43 +0,0 @@
---
Title: Search Ai service
Added: v7.0.0-alpha.3
Status: Active
Last reviewed: 2024-07-12
---
# [Search Ai service](../../../lib/content-services/src/lib/search-ai/services/search-ai.service.ts "Defined in search-ai.service.ts")
Manages search AI in Content Services.
<b>In order to use this service, you need to have the HX Insights Connector (additional ACS module) installed.</b>
## Class members
### Methods
- **updateSearchAiInputState**(state: `SearchAiInputState`): `void`<br/>
Update the state of the search AI input.
- _state:_ `SearchAiInputState` - The new state of the search AI input.
- **ask**(question: [`QuestionRequest`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#questionrequest)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`QuestionModel`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#questionmodel)`>`<br/>
Ask a question to the AI.
- _question:_ [`QuestionRequest`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#questionrequest) - The question to ask.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`QuestionModel`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#questionmodel)`>` - QuestionModel object containing information about questions.
- **getAnswer**(questionId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AiAnswerEntry`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#aianswerentry)`>`<br/>
Get an answer to specific question.
- _questionId:_ `string` - The ID of the question to get an answer for.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AiAnswerEntry`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#aianswerentry)`>` - AiAnswerEntry object containing the answer.
- **getConfig**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`KnowledgeRetrievalConfigEntry`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#knowledgeretrievalconfigentry)`>`<br/>
Get the knowledge retrieval configuration.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`KnowledgeRetrievalConfigEntry`](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md#knowledgeretrievalconfigentry)`>` - KnowledgeRetrievalConfigEntry object containing the configuration.
- **checkSearchAvailability**(selectedNodesState: `SelectionState`, maxSelectedNodes: `number`): `string`<br/>
Check if using of search is possible (if all conditions are met).
- _selectedNodesState:_ `SelectionState` - information about selected nodes.
- _maxSelectedNodes:_ `number` - max number of selected nodes. Default 100.
- **Returns** `string` - string with error if any condition is not met, empty string otherwise.
## Details
See the
[Search Ai API](../../../lib/js-api/src/api/content-rest-api/docs/SearchAiApi.md) for more information about the types returned by [Search Ai
service](search-ai.service.md) methods and for the implementation of the REST API the service is
based on.
@@ -2,7 +2,7 @@
Title: Search Query Builder service
Added: v2.3.0
Status: Active
Last reviewed: 2019-03-19
Last reviewed: 2026-06-29
---
# [Search Query Builder service](../../../lib/content-services/src/lib/search/services/search-query-builder.service.ts "Defined in search-query-builder.service.ts")
@@ -11,6 +11,17 @@ Stores information from all the custom search and faceted search widgets, compil
## Class members
### Properties
| Name | Type | Description |
| ----------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| userQuery | `string` | The raw query string typed by the user. Setting it stores the value, records it in `filterRawParams` and recomputes `parsedQuery` according to the current `searchMode`. |
| parsedQuery | `string` (read-only) | The query derived from `userQuery`. In `regular` mode the user terms are expanded against the configured fields (see `app:fields`) and optionally wildcarded; in `formula` mode it is identical to `userQuery`. |
| searchMode | `'regular' \| 'formula'` | Controls how `userQuery` is turned into `parsedQuery`. `regular` (default) parses the user input into a field query; `formula` uses the user input verbatim as an AFTS expression. |
| selectedConfigurationId | `string` | Id of the currently active search configuration. Setting it also records the value in `filterRawParams`. |
| encodedQuery | `string` (read-only) | The Base64-encoded `filterRawParams`, produced by `encodeQuery()` and written to the `q` route query parameter. |
| wildcardsEnabled | `boolean` (read-only) | Reads the `search-wildcards-enabled` app config flag (default `true`). When enabled, query terms are suffixed with `*` so partial matches are returned. |
### Methods
- **addFilterQuery**(query: `string`)<br/>
@@ -25,9 +36,10 @@ Stores information from all the custom search and faceted search widgets, compil
- **Returns** `SearchRequest` - The finished query
- **encodeQuery**()<br/>
Encodes query shards stored in `filterRawParams` property.
- **execute**(queryBody?: `SearchRequest`)<br/>
Builds and executes the current query.
- _queryBody:_ `SearchRequest` - (Optional)
- **execute**(updateQueryParams: `boolean` = `true`, queryBody?: `SearchRequest`)<br/>
Builds and executes the current query, then emits the result on the `executed` stream.
- _updateQueryParams:_ `boolean` - (Optional) When `true` (default) the encoded query is written to the `q` route query parameter. Pass `false` to execute without updating the URL.
- _queryBody:_ `SearchRequest` - (Optional) Pre-built query to execute instead of building one from the current state.
- **getDefaultConfiguration**(): [`SearchConfiguration`](../../../lib/content-services/src/lib/search/models/search-configuration.interface.ts)`|undefined`<br/>
- **Returns** [`SearchConfiguration`](../../../lib/content-services/src/lib/search/models/search-configuration.interface.ts)`|undefined` -
@@ -70,6 +82,11 @@ Stores information from all the custom search and faceted search widgets, compil
- **Returns** `boolean` -
- **isOperator**(input: `string`): `boolean`<br/>
Checks whether the supplied string is a logical `AND` or `OR` operator. Used when parsing a multi-word user query in `regular` search mode.
- _input:_ `string` - String to check
- **Returns** `boolean` - `true` if the trimmed string is `AND` or `OR`, otherwise `false`
- **loadConfiguration**(): [`SearchConfiguration`](../../../lib/content-services/src/lib/search/models/search-configuration.interface.ts)<br/>
- **Returns** [`SearchConfiguration`](../../../lib/content-services/src/lib/search/models/search-configuration.interface.ts) -
@@ -86,7 +103,10 @@ Stores information from all the custom search and faceted search widgets, compil
Removes an existing bucket from a field.
- _field:_ [`FacetField`](../../../lib/content-services/src/lib/search/models/facet-field.interface.ts) - The target field
- _bucket:_ [`FacetFieldBucket`](../../../lib/content-services/src/lib/search/models/facet-field-bucket.interface.ts) - Bucket to remove
- **resetToDefaults**()<br/>
- **resetToDefaults**(withNavigate: `boolean` = `false`, resetUserQuery: `boolean` = `true`)<br/>
Resets the query builder back to the default search configuration.
- _withNavigate:_ `boolean` - (Optional) When `true`, clears the `q` route query parameter while resetting. Defaults to `false`.
- _resetUserQuery:_ `boolean` - (Optional) When `true` (default), the `userQuery` and its parsed form are cleared. Pass `false` to keep the current user query while resetting the rest of the options.
- **search**(queryBody: `SearchRequest`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ResultSetPaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/search-rest-api/docs/ResultSetPaging.md)`>`<br/>
@@ -97,14 +117,13 @@ Stores information from all the custom search and faceted search widgets, compil
- _scope:_ `RequestScope` -
- **update**(queryBody?: `SearchRequest`)<br/>
Builds the current query and triggers the `updated` event.
- _queryBody:_ `SearchRequest` - (Optional)
- **updateSearchQueryParams**() <br/>
Encodes the query and navigates to existing search route adding encoded query as a search param.
- **updateSelectedConfiguration**(index: `number`)<br/>
- _index:_ `number` -
- **updateSelectedConfiguration**(id: `string`, resetFilters: `boolean` = `true`, shouldExecute: `boolean` = `true`)<br/>
Switches the active search configuration to the one matching the supplied id (only relevant when multiple configurations are provided).
- _id:_ `string` - Id of the configuration to select
- _resetFilters:_ `boolean` - (Optional) When `true` (default), the current search options are reset before applying the new configuration. Pass `false` to keep them.
- _shouldExecute:_ `boolean` - (Optional) When `true` (default), the query is executed immediately after switching configuration.
## Details
@@ -127,10 +146,6 @@ You can use custom widgets to populate and edit the following parts of the resul
```ts
constructor(queryBuilder: SearchQueryBuilderService) {
queryBuilder.updated.subscribe(query => {
this.queryBuilder.execute();
});
queryBuilder.executed.subscribe(data => {
this.onDataLoaded(data);
});
@@ -138,6 +153,29 @@ constructor(queryBuilder: SearchQueryBuilderService) {
}
```
To run a search, build the query state (for example by setting `userQuery` or by letting a
search widget update `queryFragments`) and then call `execute()`. The result is delivered
through the `executed` stream.
```ts
this.queryBuilder.userQuery = 'invoice';
void this.queryBuilder.execute();
```
> **Note:** Earlier versions exposed an `updated` stream and an `update()` method that built the
> query and emitted it so that a subscriber could call `execute()`. Both have been removed; build
> the query state and call `execute()` directly instead.
### Search modes
The builder supports two search modes, selected through the `searchMode` property:
- **regular** (default) - the text in `userQuery` is treated as user input and parsed into a
field query. The query is split into terms, each term is matched against the fields listed in
the `app:fields` search configuration entry (falling back to `cm:name`), and a `*` wildcard is
appended when wildcards are enabled. Bare `AND`/`OR` words are preserved as operators.
- **formula** - the text in `userQuery` is used verbatim as an [AFTS](https://docs.alfresco.com/content-services/latest/develop/search-api/) expression, allowing callers that already build their own query syntax to bypass parsing.
> **Note:** From ADF 3.0.0, the query contains the `"facetFormat": "V2"` parameter so that all the responses have the same structure whether they come from search queries containing facetFields, facetQueries, grouped facetQueries or facetIntervals.
## Runtime Configuration
@@ -351,7 +351,6 @@ while the data for the table is loading:
<!--Add your custom loading template here-->
<mat-progress-spinner
class="adf-document-list-loading-margin"
[color]="'primary'"
[mode]="'indeterminate'">
</mat-progress-spinner>
</ng-template>
+2 -3
View File
@@ -16,7 +16,6 @@ Reusable header for Alfresco applications.
title="title"
logo="logo.svg"
[redirectUrl]="'/home'"
color="primary"
(clicked)=toggleMenu($event)>
</adf-layout-header>
```
@@ -38,7 +37,7 @@ body of the element:
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| color | [`ThemePalette`](https://github.com/angular/components/blob/master/src/material/core/common-behaviors/color.ts) | | Background color for the header. It can be any hex color code or one of the Material theme colors: 'primary', 'accent' or 'warn'. |
| backgroundColor | [`string`] | Background color for the header. It can be any hex color code or CSS variable. |
| expandedSidenav | `boolean` | true | expandedSidenav: Toggles the expanded state of the component. |
| logo | `string` | | Path to an image file for the application logo. |
| position | `string` | "start" | The side of the page that the drawer is attached to (can be 'start' or 'end') |
@@ -58,5 +57,5 @@ body of the element:
## Details
This component displays a customizable header that can be reused. Use the input properties to
configure the left side (title, button) and the primary color of the header. The right part of the
configure the left side (title, button) and the background color of the header. The right part of the
header can contain other components which are transcluded in the header component.
@@ -27,6 +27,21 @@ The main purpose of the [Notification history component](../../core/components/n
| maxNotifications | `number` | 5 | Maximum number of notifications to display. The rest will remain hidden until load more is clicked |
| menuPositionX | [`MenuPositionX`](https://github.com/angular/components/blob/master/src/material/menu/menu-positions.ts) | "after" | Custom choice for opening the menu at the bottom. Can be `before` or `after`. |
| menuPositionY | [`MenuPositionY`](https://github.com/angular/components/blob/master/src/material/menu/menu-positions.ts) | "below" | Custom choice for opening the menu at the bottom. Can be `above` or `below`. |
| badgeSize | [`MatBadgeSize`](https://v19.material.angular.dev/components/badge/api#MatBadgeSize) | `small` | Badge size. Can be `small`, `medium` or `large`. |
### App config
You can set a default badge size in `app.config.json`:
```json
{
"notification": {
"badgeSize": "medium"
}
}
```
The `notification.badgeSize` value is applied on init when the `badgeSize` input is not set explicitly on the component.
## See also
-17
View File
@@ -19,7 +19,6 @@ Simple container for headers, titles, actions and breadcrumbs.
- [Properties](#properties)
- [Details](#details)
- [Dropdown menu](#dropdown-menu)
- [Custom color](#custom-color)
- [See also](#see-also)
## Basic Usage
@@ -74,7 +73,6 @@ pushed to the right by a spacer:
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| color | [`ThemePalette`](https://github.com/angular/components/blob/master/src/material/core/common-behaviors/color.ts) | | Toolbar color. Can be changed to empty value (default), `primary`, `accent` or `warn`. |
| title | `string` | "" | Toolbar title. |
## Details
@@ -116,21 +114,6 @@ when you click the menu button:
![](../../docassets/images/adf-toolbar-04.png)
### Custom color
Besides the default color you can use 'primary', 'accent', or 'warn' values:
You might also want to change colors to follow your application's color
[theme](../../user-guide/theming.md):
For example:
![](../../docassets/images/adf-toolbar-05.png)
![](../../docassets/images/adf-toolbar-06.png)
![](../../docassets/images/adf-toolbar-07.png)
## See also
- [Toolbar Divider component](toolbar-divider.component.md)
@@ -95,7 +95,7 @@ Let's say we have an upload button as follows:
```html
<div>
<button mat-button color="accent" mat-mini-fab (click)="fileInput.click()">
<button mat-button mat-mini-fab (click)="fileInput.click()">
<mat-icon>attachment</mat-icon>
</button>
<input hidden type="file" #fileInput (change)="onUploadFile($event)"/>
+3
View File
@@ -61,3 +61,6 @@ The pages linked below contain the licenses for all third party dependencies of
- [ADF 8.2.0](license-info-8.2.0.md)
- [ADF 8.2.1](license-info-8.2.1.md)
- [ADF 8.3.1](license-info-8.3.1.md)
- [ADF 8.4.1](license-info-8.4.1.md)
- [ADF 8.5.0](license-info-8.5.0.md)
- [ADF 9.0.0](license-info-9.0.0.md)
+48
View File
@@ -0,0 +1,48 @@
---
Title: License info, alfresco-ng2-components 8.4.1
---
# License information for alfresco-ng2-components 8.4.1
This page lists all third party libraries the project depends on.
## Libraries
| Name | Version | License |
| --- | --- | --- |
| [@angular/animations](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/cdk](https://github.com/angular/components) | 19.2.19 | [MIT](https://opensource.org/license/mit/) |
| [@angular/common](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/compiler](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/core](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/forms](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/material-date-fns-adapter](https://github.com/angular/components) | 19.2.19 | [MIT](https://opensource.org/license/mit/) |
| [@angular/material](https://github.com/angular/components) | 19.2.19 | [MIT](https://opensource.org/license/mit/) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/platform-browser](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/router](https://github.com/angular/angular) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@apollo/client](https://github.com/apollographql/apollo-client) | 3.13.1 | [MIT](https://opensource.org/license/mit/) |
| [@cspell/eslint-plugin](https://github.com/streetsidesoftware/cspell) | 9.4.0 | [MIT](https://opensource.org/license/mit/) |
| [@mat-datetimepicker/core](https://github.com/kuhnroyal/mat-datetimepicker) | 15.0.2 | [MIT](https://opensource.org/license/mit/) |
| [@ngx-translate/core](https://github.com/ngx-translate/core) | 17.0.0 | [MIT](https://opensource.org/license/mit/) |
| [angular-oauth2-oidc-jwks](https://github.com/manfredsteyer/angular-oauth2-oidc) | 17.0.2 | [MIT](https://opensource.org/license/mit/) |
| [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc) | 17.0.2 | [MIT](https://opensource.org/license/mit/) |
| [apollo-angular](https://github.com/kamilkisiela/apollo-angular) | 10.0.3 | [MIT](https://opensource.org/license/mit/) |
| [chart.js](https://github.com/chartjs/Chart.js) | 4.4.4 | [MIT](https://opensource.org/license/mit/) |
| [cropperjs](https://github.com/fengyuanchen/cropperjs) | 1.6.2 | [MIT](https://opensource.org/license/mit/) |
| [date-fns](https://github.com/date-fns/date-fns) | 2.30.0 | [MIT](https://opensource.org/license/mit/) |
| dotenv-expand | 5.1.0 | [BSD-2-Clause](https://opensource.org/licenses/BSD-2-Clause) |
| editorjs-html | 4.0.5 | [MIT](https://opensource.org/license/mit/) |
| [eventemitter3](https://github.com/primus/eventemitter3) | 5.0.4 | [MIT](https://opensource.org/license/mit/) |
| [graphql-ws](https://github.com/enisdenjo/graphql-ws) | 6.0.7 | [MIT](https://opensource.org/license/mit/) |
| [material-icons](https://github.com/marella/material-icons) | 1.13.14 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [minimatch-browser](https://github.com/isaacs/minimatch) | 1.0.0 | [ISC](https://www.isc.org/licenses/) |
| [ng2-charts](https://github.com/valor-software/ng2-charts) | 4.1.1 | [ISC](https://www.isc.org/licenses/) |
| [node-fetch](https://github.com/node-fetch/node-fetch) | 3.3.2 | [MIT](https://opensource.org/license/mit/) |
| [pdfjs-dist](https://github.com/mozilla/pdf.js) | 5.1.91 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [raphael](https://github.com/DmitryBaranovskiy/raphael) | 2.3.0 | [MIT](https://opensource.org/license/mit/) |
| [rxjs](https://github.com/reactivex/rxjs) | 7.8.2 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [superagent](https://github.com/ladjs/superagent) | 9.0.2 | [MIT](https://opensource.org/license/mit/) |
| [tslib](https://github.com/Microsoft/tslib) | 2.8.1 | [0BSD](http://landley.net/toybox/license.html) |
| [zone.js](https://github.com/angular/angular) | 0.15.0 | [MIT](https://opensource.org/license/mit/) |
+79
View File
@@ -0,0 +1,79 @@
---
Title: License info, alfresco-ng2-components 8.5.0
---
# License information for alfresco-ng2-components 8.5.0
This page lists all third party libraries the project depends on.
## Libraries
| Name | Version | License |
| --- | --- | --- |
| [@angular/animations](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/cdk](https://github.com/angular/components.git) | 19.2.19 | [MIT](https://opensource.org/license/mit/) |
| [@angular/common](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/compiler](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/core](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/forms](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/material](https://github.com/angular/components.git) | 19.2.19 | [MIT](https://opensource.org/license/mit/) |
| [@angular/material-date-fns-adapter](https://github.com/angular/components.git) | 19.2.19 | [MIT](https://opensource.org/license/mit/) |
| [@angular/platform-browser](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@angular/router](git+https://github.com/angular/angular.git) | 19.2.20 | [MIT](https://opensource.org/license/mit/) |
| [@apollo/client](git+https://github.com/apollographql/apollo-client.git) | 3.13.1 | [MIT](https://opensource.org/license/mit/) |
| [@babel/runtime](https://github.com/babel/babel.git) | 7.26.10 | [MIT](https://opensource.org/license/mit/) |
| [@cspell/eslint-plugin](https://github.com/streetsidesoftware/cspell.git) | 10.0.0 | [MIT](https://opensource.org/license/mit/) |
| [@graphql-typed-document-node/core](git@github.com:dotansimha/graphql-typed-document-node.git) | 3.2.0 | [MIT](https://opensource.org/license/mit/) |
| [@mat-datetimepicker/core](https://github.com/kuhnroyal/mat-datetimepicker.git) | 15.0.2 | [MIT](https://opensource.org/license/mit/) |
| [@napi-rs/canvas](git+https://github.com/Brooooooklyn/canvas.git) | 0.1.100 | [MIT](https://opensource.org/license/mit/) |
| [@napi-rs/canvas-darwin-arm64](git+https://github.com/Brooooooklyn/canvas.git) | 0.1.100 | [MIT](https://opensource.org/license/mit/) |
| [@ngx-translate/core](https://github.com/ngx-translate/core) | 17.0.0 | [MIT](https://opensource.org/license/mit/) |
| [@wry/caches](git+https://github.com/benjamn/wryware.git) | 1.0.1 | [MIT](https://opensource.org/license/mit/) |
| [@wry/context](git+https://github.com/benjamn/wryware.git) | 0.7.4 | [MIT](https://opensource.org/license/mit/) |
| [@wry/equality](git+https://github.com/benjamn/wryware.git) | 0.5.7 | [MIT](https://opensource.org/license/mit/) |
| [@wry/trie](git+https://github.com/benjamn/wryware.git) | 0.5.0 | [MIT](https://opensource.org/license/mit/) |
| [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc) | 19.0.0 | [MIT](https://opensource.org/license/mit/) |
| [apollo-angular](https://github.com/kamilkisiela/apollo-angular) | 10.0.3 | [MIT](https://opensource.org/license/mit/) |
| [balanced-match](git://github.com/juliangruber/balanced-match.git) | 1.0.2 | [MIT](https://opensource.org/license/mit/) |
| [brace-expansion](git://github.com/juliangruber/brace-expansion.git) | 1.1.15 | [MIT](https://opensource.org/license/mit/) |
| [brace-expansion](git://github.com/juliangruber/brace-expansion.git) | 2.1.1 | [MIT](https://opensource.org/license/mit/) |
| [concat-map](git://github.com/substack/node-concat-map.git) | 0.0.1 | [MIT](https://opensource.org/license/mit/) |
| [cropperjs](git+https://github.com/fengyuanchen/cropperjs.git) | 1.6.2 | [MIT](https://opensource.org/license/mit/) |
| [date-fns](https://github.com/date-fns/date-fns) | 2.30.0 | [MIT](https://opensource.org/license/mit/) |
| dotenv-expand | 5.1.0 | [BSD-2-Clause](https://opensource.org/licenses/BSD-2-Clause) |
| editorjs-html | 4.0.5 | [MIT](https://opensource.org/license/mit/) |
| [eve-raphael](https://github.com/tomasAlabes/eve.git) | 0.5.0 | UNKNOWN |
| [eventemitter3](git://github.com/primus/eventemitter3.git) | 5.0.4 | [MIT](https://opensource.org/license/mit/) |
| [fetch-blob](https://github.com/node-fetch/fetch-blob.git) | 3.2.0 | [MIT](https://opensource.org/license/mit/) |
| [formdata-polyfill](git+https://jimmywarting@github.com/jimmywarting/FormData.git) | 4.0.10 | [MIT](https://opensource.org/license/mit/) |
| [graphql-tag](git+https://github.com/apollographql/graphql-tag.git) | 2.12.6 | [MIT](https://opensource.org/license/mit/) |
| [graphql-ws](git+https://github.com/enisdenjo/graphql-ws.git) | 6.0.8 | [MIT](https://opensource.org/license/mit/) |
| [hoist-non-react-statics](git://github.com/mridgway/hoist-non-react-statics.git) | 3.3.2 | [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) |
| [js-tokens](lydell/js-tokens) | 4.0.0 | [MIT](https://opensource.org/license/mit/) |
| [lodash-es](lodash/lodash) | 4.18.1 | [MIT](https://opensource.org/license/mit/) |
| [loose-envify](git://github.com/zertosh/loose-envify.git) | 1.4.0 | [MIT](https://opensource.org/license/mit/) |
| [material-icons](git+https://github.com/marella/material-icons.git) | 1.13.14 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [minimatch](git://github.com/isaacs/minimatch.git) | 5.1.9 | [ISC](https://www.isc.org/licenses/) |
| [minimatch-browser](git://github.com/isaacs/minimatch.git) | 1.0.0 | [ISC](https://www.isc.org/licenses/) |
| [ng2-charts](git+https://github.com/valor-software/ng2-charts.git) | 4.1.1 | [ISC](https://www.isc.org/licenses/) |
| [node-domexception](git+https://github.com/jimmywarting/node-domexception.git) | 1.0.0 | [MIT](https://opensource.org/license/mit/) |
| [node-fetch](https://github.com/node-fetch/node-fetch.git) | 3.3.2 | [MIT](https://opensource.org/license/mit/) |
| [object-assign](sindresorhus/object-assign) | 4.1.1 | [MIT](https://opensource.org/license/mit/) |
| [optimism](git+https://github.com/benjamn/optimism.git) | 0.18.1 | [MIT](https://opensource.org/license/mit/) |
| [pdfjs-dist](git+https://github.com/mozilla/pdf.js.git) | 5.1.91 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [prop-types](facebook/prop-types) | 15.8.1 | [MIT](https://opensource.org/license/mit/) |
| [raphael](git://github.com/DmitryBaranovskiy/raphael.git) | 2.3.0 | [MIT](https://opensource.org/license/mit/) |
| [react-is](https://github.com/facebook/react.git) | 16.13.1 | [MIT](https://opensource.org/license/mit/) |
| [regenerator-runtime](https://github.com/facebook/regenerator/tree/main/packages/runtime) | 0.14.1 | [MIT](https://opensource.org/license/mit/) |
| [rehackt](git+https://github.com/phryneas/rehackt.git) | 0.1.0 | [MIT](https://opensource.org/license/mit/) |
| [rxjs](https://github.com/reactivex/rxjs.git) | 7.8.2 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [symbol-observable](blesh/symbol-observable) | 4.0.0 | [MIT](https://opensource.org/license/mit/) |
| [ts-invariant](git+https://github.com/apollographql/invariant-packages.git) | 0.10.3 | [MIT](https://opensource.org/license/mit/) |
| [tslib](https://github.com/Microsoft/tslib.git) | 2.8.1 | [0BSD](http://landley.net/toybox/license.html) |
| [uuid](https://github.com/uuidjs/uuid.git) | 14.0.0 | [MIT](https://opensource.org/license/mit/) |
| [web-streams-polyfill](git+https://github.com/MattiasBuelens/web-streams-polyfill.git) | 3.3.3 | [MIT](https://opensource.org/license/mit/) |
| [zen-observable](zenparsing/zen-observable) | 0.8.15 | [MIT](https://opensource.org/license/mit/) |
| [zen-observable-ts](git+https://github.com/apollographql/zen-observable-ts.git) | 1.2.5 | [MIT](https://opensource.org/license/mit/) |
| [zone.js](git://github.com/angular/angular.git) | 0.15.0 | [MIT](https://opensource.org/license/mit/) |
+81
View File
@@ -0,0 +1,81 @@
---
Title: License info, alfresco-ng2-components 9.0.0
---
# License information for alfresco-ng2-components 9.0.0
This page lists all third party libraries the project depends on.
## Libraries
| Name | Version | License |
| --- | --- | --- |
| [@angular-eslint/bundled-angular-compiler](https://github.com/angular-eslint/angular-eslint.git) | 20.7.0 | [MIT](https://opensource.org/license/mit/) |
| [@angular-eslint/utils](https://github.com/angular-eslint/angular-eslint.git) | 20.7.0 | [MIT](https://opensource.org/license/mit/) |
| [@angular/animations](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/cdk](https://github.com/angular/components.git) | 20.2.14 | [MIT](https://opensource.org/license/mit/) |
| [@angular/common](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/compiler](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/core](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/forms](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/material](https://github.com/angular/components.git) | 20.2.14 | [MIT](https://opensource.org/license/mit/) |
| [@angular/material-date-fns-adapter](https://github.com/angular/components.git) | 20.2.14 | [MIT](https://opensource.org/license/mit/) |
| [@angular/platform-browser](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@angular/router](git+https://github.com/angular/angular.git) | 20.3.25 | [MIT](https://opensource.org/license/mit/) |
| [@apollo/client](git+https://github.com/apollographql/apollo-client.git) | 3.13.1 | [MIT](https://opensource.org/license/mit/) |
| [@babel/runtime](https://github.com/babel/babel.git) | 7.26.10 | [MIT](https://opensource.org/license/mit/) |
| [@cspell/eslint-plugin](https://github.com/streetsidesoftware/cspell.git) | 10.0.0 | [MIT](https://opensource.org/license/mit/) |
| [@graphql-typed-document-node/core](git@github.com:dotansimha/graphql-typed-document-node.git) | 3.2.0 | [MIT](https://opensource.org/license/mit/) |
| [@mat-datetimepicker/core](https://github.com/kuhnroyal/mat-datetimepicker.git) | 16.0.1 | [MIT](https://opensource.org/license/mit/) |
| [@napi-rs/canvas](git+https://github.com/Brooooooklyn/canvas.git) | 0.1.100 | [MIT](https://opensource.org/license/mit/) |
| [@napi-rs/canvas-darwin-arm64](git+https://github.com/Brooooooklyn/canvas.git) | 0.1.100 | [MIT](https://opensource.org/license/mit/) |
| [@ngx-translate/core](https://github.com/ngx-translate/core) | 17.0.0 | [MIT](https://opensource.org/license/mit/) |
| [@wry/caches](git+https://github.com/benjamn/wryware.git) | 1.0.1 | [MIT](https://opensource.org/license/mit/) |
| [@wry/context](git+https://github.com/benjamn/wryware.git) | 0.7.4 | [MIT](https://opensource.org/license/mit/) |
| [@wry/equality](git+https://github.com/benjamn/wryware.git) | 0.5.7 | [MIT](https://opensource.org/license/mit/) |
| [@wry/trie](git+https://github.com/benjamn/wryware.git) | 0.5.0 | [MIT](https://opensource.org/license/mit/) |
| [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc) | 19.0.0 | [MIT](https://opensource.org/license/mit/) |
| [apollo-angular](https://github.com/kamilkisiela/apollo-angular) | 11.0.0 | [MIT](https://opensource.org/license/mit/) |
| [balanced-match](git://github.com/juliangruber/balanced-match.git) | 1.0.2 | [MIT](https://opensource.org/license/mit/) |
| [brace-expansion](git://github.com/juliangruber/brace-expansion.git) | 1.1.15 | [MIT](https://opensource.org/license/mit/) |
| [brace-expansion](git://github.com/juliangruber/brace-expansion.git) | 2.1.1 | [MIT](https://opensource.org/license/mit/) |
| [concat-map](git://github.com/substack/node-concat-map.git) | 0.0.1 | [MIT](https://opensource.org/license/mit/) |
| [cropperjs](git+https://github.com/fengyuanchen/cropperjs.git) | 1.6.2 | [MIT](https://opensource.org/license/mit/) |
| [date-fns](https://github.com/date-fns/date-fns) | 2.30.0 | [MIT](https://opensource.org/license/mit/) |
| dotenv-expand | 5.1.0 | [BSD-2-Clause](https://opensource.org/licenses/BSD-2-Clause) |
| editorjs-html | 4.0.5 | [MIT](https://opensource.org/license/mit/) |
| [eve-raphael](https://github.com/tomasAlabes/eve.git) | 0.5.0 | UNKNOWN |
| [eventemitter3](git://github.com/primus/eventemitter3.git) | 5.0.4 | [MIT](https://opensource.org/license/mit/) |
| [fetch-blob](https://github.com/node-fetch/fetch-blob.git) | 3.2.0 | [MIT](https://opensource.org/license/mit/) |
| [formdata-polyfill](git+https://jimmywarting@github.com/jimmywarting/FormData.git) | 4.0.10 | [MIT](https://opensource.org/license/mit/) |
| [graphql-tag](git+https://github.com/apollographql/graphql-tag.git) | 2.12.7 | [MIT](https://opensource.org/license/mit/) |
| [graphql-ws](git+https://github.com/enisdenjo/graphql-ws.git) | 6.0.8 | [MIT](https://opensource.org/license/mit/) |
| [hoist-non-react-statics](git://github.com/mridgway/hoist-non-react-statics.git) | 3.3.2 | [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) |
| [js-tokens](lydell/js-tokens) | 4.0.0 | [MIT](https://opensource.org/license/mit/) |
| [lodash-es](lodash/lodash) | 4.18.1 | [MIT](https://opensource.org/license/mit/) |
| [loose-envify](git://github.com/zertosh/loose-envify.git) | 1.4.0 | [MIT](https://opensource.org/license/mit/) |
| [material-icons](git+https://github.com/marella/material-icons.git) | 1.13.14 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [minimatch](git://github.com/isaacs/minimatch.git) | 5.1.9 | [ISC](https://www.isc.org/licenses/) |
| [minimatch-browser](git://github.com/isaacs/minimatch.git) | 1.0.0 | [ISC](https://www.isc.org/licenses/) |
| [ng2-charts](git+https://github.com/valor-software/ng2-charts.git) | 4.1.1 | [ISC](https://www.isc.org/licenses/) |
| [node-domexception](git+https://github.com/jimmywarting/node-domexception.git) | 1.0.0 | [MIT](https://opensource.org/license/mit/) |
| [node-fetch](https://github.com/node-fetch/node-fetch.git) | 3.3.2 | [MIT](https://opensource.org/license/mit/) |
| [object-assign](sindresorhus/object-assign) | 4.1.1 | [MIT](https://opensource.org/license/mit/) |
| [optimism](git+https://github.com/benjamn/optimism.git) | 0.18.1 | [MIT](https://opensource.org/license/mit/) |
| [pdfjs-dist](git+https://github.com/mozilla/pdf.js.git) | 5.1.91 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [prop-types](facebook/prop-types) | 15.8.1 | [MIT](https://opensource.org/license/mit/) |
| [raphael](git://github.com/DmitryBaranovskiy/raphael.git) | 2.3.0 | [MIT](https://opensource.org/license/mit/) |
| [react-is](https://github.com/facebook/react.git) | 16.13.1 | [MIT](https://opensource.org/license/mit/) |
| [regenerator-runtime](https://github.com/facebook/regenerator/tree/main/packages/runtime) | 0.14.1 | [MIT](https://opensource.org/license/mit/) |
| [rehackt](git+https://github.com/phryneas/rehackt.git) | 0.1.0 | [MIT](https://opensource.org/license/mit/) |
| [rxjs](https://github.com/reactivex/rxjs.git) | 7.8.2 | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [symbol-observable](blesh/symbol-observable) | 4.0.0 | [MIT](https://opensource.org/license/mit/) |
| [ts-invariant](git+https://github.com/apollographql/invariant-packages.git) | 0.10.3 | [MIT](https://opensource.org/license/mit/) |
| [tslib](https://github.com/Microsoft/tslib.git) | 2.8.1 | [0BSD](http://landley.net/toybox/license.html) |
| [uuid](https://github.com/uuidjs/uuid.git) | 14.0.1 | [MIT](https://opensource.org/license/mit/) |
| [web-streams-polyfill](git+https://github.com/MattiasBuelens/web-streams-polyfill.git) | 3.3.3 | [MIT](https://opensource.org/license/mit/) |
| [zen-observable](zenparsing/zen-observable) | 0.8.15 | [MIT](https://opensource.org/license/mit/) |
| [zen-observable-ts](git+https://github.com/apollographql/zen-observable-ts.git) | 1.2.5 | [MIT](https://opensource.org/license/mit/) |
| [zone.js](git://github.com/angular/angular.git) | 0.15.0 | [MIT](https://opensource.org/license/mit/) |
@@ -89,7 +89,7 @@ The template defined inside `empty-form` will be shown when no form definition i
| path | `string` | | Path of the folder where the metadata will be stored. |
| processInstanceId | `string` | | ProcessInstanceId id to fetch corresponding form and values. |
| readOnly | `boolean` | false | Toggle readonly state of the form. Forces all form widgets to render as readonly if enabled. |
| showCompleteButton | `boolean` | true | Toggle rendering of the `Complete` outcome button. |
| showCompleteButton | `boolean` | false | Toggle rendering of the `Complete` outcome button. |
| showRefreshButton | `boolean` | true | Toggle rendering of the `Refresh` button. |
| showSaveButton | `boolean` | true | Toggle rendering of the `Save` outcome button. |
| showTitle | `boolean` | true | Toggle rendering of the form title. |
+3
View File
@@ -9,6 +9,9 @@ The first **General Availability** release was v2.0.0.
## General Availability
- [9.0.0](RelNote-9.0.0.md)
- [8.5.0](RelNote-8.5.0.md)
- [8.4.1](RelNote-8.4.1.md)
- [8.3.1](RelNote-8.3.1.md)
- [8.2.1](RelNote-8.2.1.md)
- [8.2.0](RelNote-8.2.0.md)
+40
View File
@@ -0,0 +1,40 @@
---
Title: Changelog for alfresco-ng2-components v8.4.1
---
# Changelog
- [af95723f30](https://github.com/Alfresco/alfresco-ng2-components/commit/af95723f30) [ACS-11589] [ACA] info drawer test-area does not show full text (#11816)
- [d70ae599c7](https://github.com/Alfresco/alfresco-ng2-components/commit/d70ae599c7) Fix security vulnerabilities in npm dependencies (#11815)
- [07c6a4d923](https://github.com/Alfresco/alfresco-ng2-components/commit/07c6a4d923) Remove jasmine-spec-reporter dependency from package.json and package-lock.json (#11814)
- [6fc8dda887](https://github.com/Alfresco/alfresco-ng2-components/commit/6fc8dda887) Remove mocha and jasmine-ajax dependencies (#11813)
- [48eb258311](https://github.com/Alfresco/alfresco-ng2-components/commit/48eb258311) AAE-44184 Colspan setting on form fields is ignored or not properly applied (#11800)
- [32850a0ce8](https://github.com/Alfresco/alfresco-ng2-components/commit/32850a0ce8) [MNT-25185] Display authority name instead of id if provided (#11809)
- [8a6bcac29e](https://github.com/Alfresco/alfresco-ng2-components/commit/8a6bcac29e) [ACS-11506]: moved aria-live region (#11808)
- [8ce0561ef5](https://github.com/Alfresco/alfresco-ng2-components/commit/8ce0561ef5) AAE-44086 Unify styling and coloring of errors in forms (#11797)
- [69a9dc1386](https://github.com/Alfresco/alfresco-ng2-components/commit/69a9dc1386) AAE-44002 Allow user input for date and datetime fields (#11791)
- [70a6f42649](https://github.com/Alfresco/alfresco-ng2-components/commit/70a6f42649) AAE-40741 Form rule `Validate form` doesn&#39;t do anything (#11788)
- [74252797b7](https://github.com/Alfresco/alfresco-ng2-components/commit/74252797b7) AAE-28918 Fix for start process button is enabled when required widgets are read only without value (#11781)
- [79871455f4](https://github.com/Alfresco/alfresco-ng2-components/commit/79871455f4) [ACS-10242] SR: Personal files: Filter by Size popup announces entire content instead of dialog title (#11782)
- [d7a8f03dbf](https://github.com/Alfresco/alfresco-ng2-components/commit/d7a8f03dbf) AAE-43749 Added date formatting according to locale (#11769)
- [a3e13da3a4](https://github.com/Alfresco/alfresco-ng2-components/commit/a3e13da3a4) [ACS-10280]: Keyboard Navigation: Search: Unnecessary stops in the results table using the Tab key (#11736)
- [565db01819](https://github.com/Alfresco/alfresco-ng2-components/commit/565db01819) [MNT-25635] Search filter autocomplete search for tags when input changes (#11780)
- [f321b74be0](https://github.com/Alfresco/alfresco-ng2-components/commit/f321b74be0) AAE-21162 Add deploymentCompletion property to ApplicationInstance model (#11784)
- [28fe6d3a76](https://github.com/Alfresco/alfresco-ng2-components/commit/28fe6d3a76) AAE-43710 Fix form field spacing misalignments (#11763)
- [d526d31425](https://github.com/Alfresco/alfresco-ng2-components/commit/d526d31425) AAE-34137 Fix for disabling `complete` button on the form after declining form confirmation dialog (#11766)
- [e97439f09b](https://github.com/Alfresco/alfresco-ng2-components/commit/e97439f09b) AAE-43391 Disable &#39;Start process&#39; and &#39;Complete&#39; when whitespace is entered into required form fields (#11760)
- [bdd4b687c6](https://github.com/Alfresco/alfresco-ng2-components/commit/bdd4b687c6) AAE-43290 updating the minor version for angular in ADF (#11752)
- [46989ae081](https://github.com/Alfresco/alfresco-ng2-components/commit/46989ae081) [ACS-11319] Move tree actions menu item buttons inside the component (#11749)
- [a50dfd050d](https://github.com/Alfresco/alfresco-ng2-components/commit/a50dfd050d) CSX-460 Revert Remove excess disabled attribute PR (#11748)
- [e57910f5c3](https://github.com/Alfresco/alfresco-ng2-components/commit/e57910f5c3) [ACS-11271] Rebranding of FE apps (#11746)
- [3bea95b8e0](https://github.com/Alfresco/alfresco-ng2-components/commit/3bea95b8e0) Revert &#34;[ACS-10219] add class selector (#11387)&#34; (#11745)
- [adce4cabf5](https://github.com/Alfresco/alfresco-ng2-components/commit/adce4cabf5) [MNT-25447] Fix: Viewing preview renditions for versions fails (#11747)
- [ebf742c54b](https://github.com/Alfresco/alfresco-ng2-components/commit/ebf742c54b) AAE-43331 Expand adf-icon (#11744)
- [759d206302](https://github.com/Alfresco/alfresco-ng2-components/commit/759d206302) HXIDP-6471 Provide start process variables to custom screen (#11712)
- [a865372819](https://github.com/Alfresco/alfresco-ng2-components/commit/a865372819) [ACS-10267] Announce titles for repository info as headings (#11728)
- [2bab587876](https://github.com/Alfresco/alfresco-ng2-components/commit/2bab587876) [ACS-11205] Bring back removed getter (#11735)
- [e325ad3871](https://github.com/Alfresco/alfresco-ng2-components/commit/e325ad3871) AAE-39678 Apply visibility conditions if dependent field&#39;s value is changed with form rules (#11729)
- [a8ae3d3b4e](https://github.com/Alfresco/alfresco-ng2-components/commit/a8ae3d3b4e) AAE-42908 Evaluate expressions for rich-text-display list types (#11726)
- [bc41c33ba8](https://github.com/Alfresco/alfresco-ng2-components/commit/bc41c33ba8) [ACS-11205] Add LazyApi decorator (#11711)
- [83e80906d8](https://github.com/Alfresco/alfresco-ng2-components/commit/83e80906d8) [ACS-11213] upgrade ngx translate to v17 (#11719)
- [ef5944a09c](https://github.com/Alfresco/alfresco-ng2-components/commit/ef5944a09c) Post-release version bump (#11734)
+83
View File
@@ -0,0 +1,83 @@
---
Title: Changelog for alfresco-ng2-components v8.5.0
---
# Changelog
- [ec04358796](https://github.com/Alfresco/alfresco-ng2-components/commit/ec04358796) AAE-46943 Rename git signing secret/vars to HXPS_GIT_* (#11978)
- [49a28b357c](https://github.com/Alfresco/alfresco-ng2-components/commit/49a28b357c) AAE-46943 Sign Crowdin translation PR commits with GPG (#11974)
- [dd9e58ddaa](https://github.com/Alfresco/alfresco-ng2-components/commit/dd9e58ddaa) [ACS-11927] init acs aps scripts update terraform (#11976)
- [c723e19b6d](https://github.com/Alfresco/alfresco-ng2-components/commit/c723e19b6d) AAE-46971 Update Supply Chain Review GH AW to latest (#11972)
- [bb6f9b1f3d](https://github.com/Alfresco/alfresco-ng2-components/commit/bb6f9b1f3d) AAE-46434 Fix disabled stying for people widgets (#11967)
- [7bb219e4dd](https://github.com/Alfresco/alfresco-ng2-components/commit/7bb219e4dd) AAE-46654 Fix - return empty string when no value is provided in card… (#11969)
- [70038bea26](https://github.com/Alfresco/alfresco-ng2-components/commit/70038bea26) AAE-46246 Format typed values in form display widgets v2 (#11952)
- [5ad3dca38d](https://github.com/Alfresco/alfresco-ng2-components/commit/5ad3dca38d) AAE-46684 fix release workflow eslint publish fix provenance (#11963)
- [fd3802f2dc](https://github.com/Alfresco/alfresco-ng2-components/commit/fd3802f2dc) AAE-46684 fix release workflow eslint publish fix (#11962)
- [a8eee9fe3a](https://github.com/Alfresco/alfresco-ng2-components/commit/a8eee9fe3a) Improvements/aae 46684 fix release workflow fixed command (#11961)
- [0a7fa14d0f](https://github.com/Alfresco/alfresco-ng2-components/commit/0a7fa14d0f) Improvements/aae 46684 fix release workflow ignore (#11960)
- [4dde6d2a45](https://github.com/Alfresco/alfresco-ng2-components/commit/4dde6d2a45) [AAE-46514] - Fix release workflow (#11959)
- [78661f11c5](https://github.com/Alfresco/alfresco-ng2-components/commit/78661f11c5) [AAE-46514] - Migration to PNPM (#11926)
- [faf9d3faac](https://github.com/Alfresco/alfresco-ng2-components/commit/faf9d3faac) AAE-46388 Update Supply Chain Review GH AW to latest (#11957)
- [5c8eb21ab3](https://github.com/Alfresco/alfresco-ng2-components/commit/5c8eb21ab3) AAE-46387 Standardize DependaBot config schedule/grouping (#11953)
- [7d76d789b2](https://github.com/Alfresco/alfresco-ng2-components/commit/7d76d789b2) AAE-41418 Add process instance id input to task header cloud component (#11897)
- [a71cc84f11](https://github.com/Alfresco/alfresco-ng2-components/commit/a71cc84f11) AAE-46507 Next Task Endpoint (#11943)
- [34acdd20cf](https://github.com/Alfresco/alfresco-ng2-components/commit/34acdd20cf) Revert &#34;AAE-46246 Format typed values in form display widgets (#11935)&#34; (#11951)
- [f39b9167b8](https://github.com/Alfresco/alfresco-ng2-components/commit/f39b9167b8) AAE-46246 Format typed values in form display widgets (#11935)
- [aa2a357fb2](https://github.com/Alfresco/alfresco-ng2-components/commit/aa2a357fb2) AAE-46434 Fix read-only field styling on forms (#11928)
- [f9899883dc](https://github.com/Alfresco/alfresco-ng2-components/commit/f9899883dc) Revert AAE-46242 crowdin locale mapping changes (#11949)
- [46b2d0380b](https://github.com/Alfresco/alfresco-ng2-components/commit/46b2d0380b) AAE-45774 Shorten invalid date error message (#11920)
- [274ddb3098](https://github.com/Alfresco/alfresco-ng2-components/commit/274ddb3098) AAE-46386 Set DependaBot cooldown for all ecosystems as 3d (#11947)
- [f602070f1e](https://github.com/Alfresco/alfresco-ng2-components/commit/f602070f1e) AAE-46388 Fix DependaBot config to ignore gh-aw-actions (#11946)
- [d206d28f1c](https://github.com/Alfresco/alfresco-ng2-components/commit/d206d28f1c) [AAE-32905] Fix commit messages commands aren&#39;t working (#11922)
- [80e9e51cfa](https://github.com/Alfresco/alfresco-ng2-components/commit/80e9e51cfa) AAE-46242 - Looks like we need to override the mapping as crowding config is not set to this format (#11939)
- [345e1e69ad](https://github.com/Alfresco/alfresco-ng2-components/commit/345e1e69ad) AAE-46242 - should use the variable osx_locale to match the format xx-YY (#11936)
- [a2b026ed7e](https://github.com/Alfresco/alfresco-ng2-components/commit/a2b026ed7e) [AAE-46242] - Changed the name convention for translation files to ISO standard naming (#11924)
- [e40fd2250e](https://github.com/Alfresco/alfresco-ng2-components/commit/e40fd2250e) AAE-46388 Add Supply Chain Review agentic workflow (#11927)
- [cfdd3f9c50](https://github.com/Alfresco/alfresco-ng2-components/commit/cfdd3f9c50) MD3 migration fixes (#11919)
- [1314f0751f](https://github.com/Alfresco/alfresco-ng2-components/commit/1314f0751f) AAE-46476 Fix sorting functionality of task list retrieval from runtime bundle (#11921)
- [f4882e99be](https://github.com/Alfresco/alfresco-ng2-components/commit/f4882e99be) Revert &#34;New Crowdin translations by GitHub Action (#11796)&#34; (#11923)
- [b5d2de583d](https://github.com/Alfresco/alfresco-ng2-components/commit/b5d2de583d) build(deps): update 3rd party dependencies (#11916)
- [70f90c65a5](https://github.com/Alfresco/alfresco-ng2-components/commit/70f90c65a5) AAE-46392 Fix card view select item crash on numeric initial value (#11917)
- [f339647f40](https://github.com/Alfresco/alfresco-ng2-components/commit/f339647f40) refactor: migrate license checks off license-checker (#11905)
- [a7fa68056d](https://github.com/Alfresco/alfresco-ng2-components/commit/a7fa68056d) chore: remove unused @nx/node dependency (#11895)
- [8280aa2f6d](https://github.com/Alfresco/alfresco-ng2-components/commit/8280aa2f6d) chore: update NX packages to version 22.7.2 and related dependencies (#11904)
- [5553aaaefe](https://github.com/Alfresco/alfresco-ng2-components/commit/5553aaaefe) [MNT-25522] Add support for fileLink icon (#11903)
- [15814380a5](https://github.com/Alfresco/alfresco-ng2-components/commit/15814380a5) [ci:force] AAE-46219 [TEST] Revert cli build/installDeps changes from #11880 and #11899 (#11901)
- [4044fafc39](https://github.com/Alfresco/alfresco-ng2-components/commit/4044fafc39) AAE-46219 Skip prod deps in cli:installDeps to unblock release (#11899)
- [ece50ac32c](https://github.com/Alfresco/alfresco-ng2-components/commit/ece50ac32c) [MNT-25149] Card view select item multivalued property support (#11891)
- [1d163c6749](https://github.com/Alfresco/alfresco-ng2-components/commit/1d163c6749) Revert &#34;AAE-44065 Change date picker to match other styles (#11868)&#34; (#11896)
- [1fbd869902](https://github.com/Alfresco/alfresco-ng2-components/commit/1fbd869902) chore: remove unused eslint-plugin-prefer-arrow (#11894)
- [165d0fc521](https://github.com/Alfresco/alfresco-ng2-components/commit/165d0fc521) chore: remove unused moment dependency (#11893)
- [64d9f3a6d4](https://github.com/Alfresco/alfresco-ng2-components/commit/64d9f3a6d4) AAE-45774 Show error for date fields if invalid format (#11886)
- [9e106b006c](https://github.com/Alfresco/alfresco-ng2-components/commit/9e106b006c) AAE-43881 Fix for form rules not applying when new [data] comes in (#11879)
- [8309d2dc55](https://github.com/Alfresco/alfresco-ng2-components/commit/8309d2dc55) AAE-44065 Change date picker to match other styles (#11868)
- [e3430ae36e](https://github.com/Alfresco/alfresco-ng2-components/commit/e3430ae36e) AAE-45695 Group @typescript-eslint/* packages in dependabot (#11880)
- [1860fefd42](https://github.com/Alfresco/alfresco-ng2-components/commit/1860fefd42) [MNT-25647] Handle facets label wrapped in quotes (#11866)
- [9fe4006a0d](https://github.com/Alfresco/alfresco-ng2-components/commit/9fe4006a0d) AAE-45391 Lazy loading and improvements for pdfJS (#11869)
- [62fb51e910](https://github.com/Alfresco/alfresco-ng2-components/commit/62fb51e910) Update CODEOWNERS
- [b7783d2259](https://github.com/Alfresco/alfresco-ng2-components/commit/b7783d2259) AAE-39830 Removing Material components color property (#11865)
- [410490158f](https://github.com/Alfresco/alfresco-ng2-components/commit/410490158f) AAE-30881 Remove jsrassign (#11863)
- [57bf066164](https://github.com/Alfresco/alfresco-ng2-components/commit/57bf066164) AAE-30882 Remove superagent for fetch (#11856)
- [9cdacf3ebf](https://github.com/Alfresco/alfresco-ng2-components/commit/9cdacf3ebf) AAE-45312 Removing propagate job from release workflow (#11864)
- [8821980913](https://github.com/Alfresco/alfresco-ng2-components/commit/8821980913) AAE-38566 Remove globals mixin (#11798)
- [a73b100fae](https://github.com/Alfresco/alfresco-ng2-components/commit/a73b100fae) AAE-45003 Extend task cloud services (#11850)
- [2649cdea2d](https://github.com/Alfresco/alfresco-ng2-components/commit/2649cdea2d) AAE-44003 Allow manual input for date field (#11830)
- [3a543d8a0a](https://github.com/Alfresco/alfresco-ng2-components/commit/3a543d8a0a) AAE-32905 Rework pr pipeline (#11853)
- [3fc59b2358](https://github.com/Alfresco/alfresco-ng2-components/commit/3fc59b2358) AAE-45216 Removing custom theme from core (#11862)
- [337b82e988](https://github.com/Alfresco/alfresco-ng2-components/commit/337b82e988) AAE-45215 Removing unused breadcrumb theme (#11861)
- [0faa2e1a56](https://github.com/Alfresco/alfresco-ng2-components/commit/0faa2e1a56) [AAE-0000] - fixed run for process-service-cloud (#11855)
- [d6262eafc6](https://github.com/Alfresco/alfresco-ng2-components/commit/d6262eafc6) [ACS-11628] small for for init-acs-env.ts (#11860)
- [d3ad66d25b](https://github.com/Alfresco/alfresco-ng2-components/commit/d3ad66d25b) AAE-44435 Fix incorrect Start process button on user task forms (#11837)
- [aa2de3bde6](https://github.com/Alfresco/alfresco-ng2-components/commit/aa2de3bde6) AAE-45173 Adding background color to tooltip card (#11852)
- [d1d06a68bc](https://github.com/Alfresco/alfresco-ng2-components/commit/d1d06a68bc) AAE-44098 Bottom tab navigation buttons (#11834)
- [0a6da1ba13](https://github.com/Alfresco/alfresco-ng2-components/commit/0a6da1ba13) AAE-45076 Fix svg icon style (#11849)
- [d3ac5362ba](https://github.com/Alfresco/alfresco-ng2-components/commit/d3ac5362ba) AAE-44946 - Sending also previous value to allow valuation and valida… (#11836)
- [ddb8adc0e4](https://github.com/Alfresco/alfresco-ng2-components/commit/ddb8adc0e4) AAE-44752 Add type to ProcessInstanceCloud (#11847)
- [85005c9c1c](https://github.com/Alfresco/alfresco-ng2-components/commit/85005c9c1c) AAE-44987 Applying color and background to sidenav (#11846)
- [407c6c1829](https://github.com/Alfresco/alfresco-ng2-components/commit/407c6c1829) [ACS-11350] keyboard navigation user incorrect focus order after collapsing the left navigation menu (#11835)
- [e3fc03c58d](https://github.com/Alfresco/alfresco-ng2-components/commit/e3fc03c58d) Revert &#34;AAE-44098 Bottom Tab nav buttons (#11801)&#34; (#11832)
- [510a813ed2](https://github.com/Alfresco/alfresco-ng2-components/commit/510a813ed2) [ACS-11472] Fix file icon is not updated for version renditions (#11807)
- [7864f1a8e0](https://github.com/Alfresco/alfresco-ng2-components/commit/7864f1a8e0) AAE-44098 Bottom Tab nav buttons (#11801)
- [c09edd71ff](https://github.com/Alfresco/alfresco-ng2-components/commit/c09edd71ff) AAE-44761 Remove unused imports (#11829)
- [64826c3a99](https://github.com/Alfresco/alfresco-ng2-components/commit/64826c3a99) AAE-40649 Material Design 3 migration (#11286)
- [423c646bac](https://github.com/Alfresco/alfresco-ng2-components/commit/423c646bac) Post release version bump (#11828)
+48
View File
@@ -0,0 +1,48 @@
---
Title: Changelog for alfresco-ng2-components v9.0.0
---
# Changelog
- [0a19be090e](git@github.com:Alfresco/alfresco-ng2-components/commit/0a19be090e) [ACS-12286] Pass includeFields through to getRecentFiles for -recent- (#12067)
- [b69c3ae1ae](git@github.com:Alfresco/alfresco-ng2-components/commit/b69c3ae1ae) [MNT-25230] Displayed modified time for node version (#12066)
- [ce907417b7](git@github.com:Alfresco/alfresco-ng2-components/commit/ce907417b7) AAE-48166 Compensate for VM/Citrix clock drift in token expiry check (#12024)
- [4c7765e3fa](git@github.com:Alfresco/alfresco-ng2-components/commit/4c7765e3fa) AAE-46517 Add onRowCountChange form event for Repeatable Sections (#12062)
- [407a64996e](git@github.com:Alfresco/alfresco-ng2-components/commit/407a64996e) AAE-46248 Format dropdown/radio option labels in display-text expressions (#12045)
- [01cea60490](git@github.com:Alfresco/alfresco-ng2-components/commit/01cea60490) [MNT-25230] adw version history does not provide user information (#12050)
- [09ef05038c](git@github.com:Alfresco/alfresco-ng2-components/commit/09ef05038c) chore: remove deprecated MaterialModule and its references (#12051)
- [c7bd56f244](git@github.com:Alfresco/alfresco-ng2-components/commit/c7bd56f244) AAE-43974 Fix for alfresco-content-app e2e failure (#12055)
- [b86e41515e](git@github.com:Alfresco/alfresco-ng2-components/commit/b86e41515e) [ACS-12037] Remove Knowledge Discovery from ADF (#12042)
- [0b35118dee](git@github.com:Alfresco/alfresco-ng2-components/commit/0b35118dee) AAE-47880 UI breaks when pasting very large text into text field (#12043)
- [fe2b3d85dd](git@github.com:Alfresco/alfresco-ng2-components/commit/fe2b3d85dd) [ACS-12108] Introduce signed commits into ADF workflows (#12040)
- [b0dc85422c](git@github.com:Alfresco/alfresco-ng2-components/commit/b0dc85422c) Improvement/AAE-43974 Refactoring form fields (#11945)
- [23f0392c12](git@github.com:Alfresco/alfresco-ng2-components/commit/23f0392c12) AAE-47634 Refactor: switch form service getTask to use runtime bundle API (#12020)
- [997303e6a7](git@github.com:Alfresco/alfresco-ng2-components/commit/997303e6a7) [ACS-11325] remove chevron button from tab order in adf-tree (#12041)
- [45d1818f04](git@github.com:Alfresco/alfresco-ng2-components/commit/45d1818f04) [ACS-12098] firefox headless race condition viewer fix (#12023)
- [448e667c52](git@github.com:Alfresco/alfresco-ng2-components/commit/448e667c52) [MNT-25681] Content node selector panel filtering fixed (#12032)
- [18e602aa85](git@github.com:Alfresco/alfresco-ng2-components/commit/18e602aa85) [PRODSEC-13253] Increased peerDependencies versions to allow to increase angular version in other projects (#12031)
- [4cd8648a05](git@github.com:Alfresco/alfresco-ng2-components/commit/4cd8648a05) Adjust release triggers to use cache-writable token (#12030)
- [7f57b3936b](git@github.com:Alfresco/alfresco-ng2-components/commit/7f57b3936b) AAE-39528 Session timeout features (#12008)
- [5a30baad99](git@github.com:Alfresco/alfresco-ng2-components/commit/5a30baad99) Release cache read/write fix (#12029)
- [5050c3d974](git@github.com:Alfresco/alfresco-ng2-components/commit/5050c3d974) [ACS-12041] Add debounceTime in PeopleWidgetComponent to limit API calls on every keystroke (#12027)
- [d8b36606e2](git@github.com:Alfresco/alfresco-ng2-components/commit/d8b36606e2) [MNT-25681] Search refactoring and unification (#12019)
- [37f8fe47ac](git@github.com:Alfresco/alfresco-ng2-components/commit/37f8fe47ac) AAE-46695 Upgrade to pnpm 11.9 (#12028)
- [af0d1e4ead](git@github.com:Alfresco/alfresco-ng2-components/commit/af0d1e4ead) AAE-47093 Update Supply Chain Review GH AW to latest (#12025)
- [bd7f393db9](git@github.com:Alfresco/alfresco-ng2-components/commit/bd7f393db9) AAE-47634 Fix block task claim checking status on Runtime Bundle (#12009)
- [d2d6696c05](git@github.com:Alfresco/alfresco-ng2-components/commit/d2d6696c05) Migrate to Angular 20, TypeScript 5.9, and Angular Material 20 (#11657)
- [7546aa91a3](git@github.com:Alfresco/alfresco-ng2-components/commit/7546aa91a3) AAE-47577 Form Spinner persists outside of Automate Form (#12005)
- [74d67c39a0](git@github.com:Alfresco/alfresco-ng2-components/commit/74d67c39a0) [ACS-11317] a11y Fix: Tags interactive controls are not manageable via keyboard (#11845)
- [20c20f2749](git@github.com:Alfresco/alfresco-ng2-components/commit/20c20f2749) AAE-46247 Add type-aware form field value adapter service (#11968)
- [b498d5744c](git@github.com:Alfresco/alfresco-ng2-components/commit/b498d5744c) [AAE-47470] - Upgrade Pnpm to 11.8.0 (#12004)
- [80eef35e1d](git@github.com:Alfresco/alfresco-ng2-components/commit/80eef35e1d) [ACS-11325] Add keyboard navigation and a11y support for adf-tree component (#11973)
- [49a3f1e104](git@github.com:Alfresco/alfresco-ng2-components/commit/49a3f1e104) AAE-47412 Update suprocesses and linked processes for process instance model (#11996)
- [0beaa18452](git@github.com:Alfresco/alfresco-ng2-components/commit/0beaa18452) [ACS-11973] Fix: context menu disappears during bulk upload (#11994)
- [76fd461741](git@github.com:Alfresco/alfresco-ng2-components/commit/76fd461741) AAE-47042 Add auto grow support to multiline text widget (#11981)
- [78697ee62a](git@github.com:Alfresco/alfresco-ng2-components/commit/78697ee62a) [AAE-0000] - Fixed js-api error index.js (#11970)
- [43c5bc17fb](git@github.com:Alfresco/alfresco-ng2-components/commit/43c5bc17fb) [ACS-12020] Updated init-aps passwords with secret ones (#11993)
- [cda20e0386](git@github.com:Alfresco/alfresco-ng2-components/commit/cda20e0386) Post-release version bump (#11988)
- [8f5099e822](git@github.com:Alfresco/alfresco-ng2-components/commit/8f5099e822) [ACS-11928] convert ReadStream to Blob before appending to FormData (#11987)
- [5dd709ed58](git@github.com:Alfresco/alfresco-ng2-components/commit/5dd709ed58) AAE-44809 Fix form multi-file attachment - document viewer not updated on file selection (#11980)
- [9d353bf271](git@github.com:Alfresco/alfresco-ng2-components/commit/9d353bf271) [ACS-11974] [ACA] Upload new version button is no longer disabled when clicked once (#11977)
- [633702860f](git@github.com:Alfresco/alfresco-ng2-components/commit/633702860f) Post-release version bump (#11984)
- [bf5b3af285](git@github.com:Alfresco/alfresco-ng2-components/commit/bf5b3af285) AAE-47094 Add Stale PR Cleanup workflow (#11983)
+44
View File
@@ -13,6 +13,50 @@ The authType parameter specifies the authentication method, with BASIC and OAUTH
"authType": "OAUTH"
}
```
## Session Timeout
ADF can track user activity and show a countdown dialog before logging out an idle authenticated session. Register the feature with `provideSessionTimeout` in your application providers:
```ts
import { ApplicationConfig } from '@angular/core';
import { provideSessionTimeout } from '@alfresco/adf-core';
export const appConfig: ApplicationConfig = {
providers: [
provideSessionTimeout({
enabled: true,
idleTimeoutMs: 30 * 60 * 1000,
dialogTimeoutMs: 60 * 1000
})
]
};
```
The same values can be configured in `app.config.json` with the `sessionTimeout` key:
```json
{
"sessionTimeout": {
"enabled": true,
"idleTimeoutMs": 1800000,
"dialogTimeoutMs": 60000
}
}
```
Registering `provideSessionTimeout` enables the feature: `enabled` defaults to `true`, so the countdown is active unless you set `enabled` to `false` in `app.config.json` or in the options passed to `provideSessionTimeout`. The default idle timeout is 30 minutes, and the default dialog timeout is 60 seconds. Values passed to `provideSessionTimeout` take precedence over values from `app.config.json`.
Applications can defer startup until another async condition is enabled:
```ts
provideSessionTimeout({
startWhen: () => featureService.isOn$('session-timeout-feature')
});
```
Whether the user clicks **Log out** in the countdown dialog or leaves it unanswered until the countdown elapses, the normal logout flow runs and the user is redirected to the configured IdP/login page. The same logout is broadcast to other tabs so every session ends together.
# OAuth2 Configuration
OAuth2 is a protocol that allows the application to authorize operations without exposing user credentials. The configuration includes several parameters essential for setting up OAuth2 authentication.
+2 -3
View File
@@ -90,7 +90,6 @@ export class YourSearchComponent implements OnInit {
ngOnInit() {
this.queryBuilder.resetToDefaults();
this.queryBuilder.updated.subscribe(() => void this.queryBuilder.execute());
this.queryBuilder.executed.subscribe((data) => {
this.queryBuilder.paging.skipCount = 0;
this.onSearchResultLoaded(data);
@@ -103,7 +102,7 @@ export class YourSearchComponent implements OnInit {
onSearchQueryChanged(string: string) {
this.queryBuilder.userQuery = decodeURIComponent(string);
this.queryBuilder.update();
void this.queryBuilder.execute();
}
async onPaginationChanged(pagination: Pagination) {
@@ -111,7 +110,7 @@ export class YourSearchComponent implements OnInit {
maxItems: pagination.maxItems,
skipCount: pagination.skipCount
};
this.queryBuilder.update();
void this.queryBuilder.execute();
}
}
```
@@ -16,6 +16,7 @@ This page describes how you can configure the search configuration.
- [Steps Involved In Search Configuration](#steps-involved-in-search-configuration)
- [Configuration](#configuration)
- [Extra fields and filter queries](#extra-fields-and-filter-queries)
- [Search modes and wildcards](#search-modes-and-wildcards)
- [Sorting](#sorting)
- [Categories and widgets](#categories-and-widgets)
- [Facet Fields](#facet-fields)
@@ -267,6 +268,44 @@ settings:
Note that the entries of the `filterQueries` array are joined using the `AND` operator.
### Search modes and wildcards
When a user types free text into a search input, the [Search Query Builder Service](../../content-services/services/search-query-builder.service.md) turns that text (its `userQuery`) into the final query according to the configured *search mode*:
- **regular** (default) - the user input is parsed into a field query. Each term is matched
against the fields listed in the `app:fields` array (falling back to `cm:name` when it is not
set), and a `*` wildcard is appended to each term when wildcards are enabled. Words that are
exactly `AND` or `OR` are preserved as logical operators.
- **formula** - the user input is passed through verbatim as an
[AFTS](https://docs.alfresco.com/content-services/latest/develop/search-api/) expression. Use
this mode when the caller already builds valid query syntax.
The `app:fields` entry lists the fields used to expand a `regular` user query:
```json
{
"search": {
...
"app:fields": ["cm:name", "cm:title", "cm:description"]
...
}
}
```
For example, with the configuration above and wildcards enabled, the user query `report` is
expanded to `(cm:name:"report*" OR cm:title:"report*" OR cm:description:"report*")`.
Wildcard matching is controlled by the top-level `search-wildcards-enabled` flag in
`app.config.json` (default `true`). When set to `false`, terms are matched exactly and the
trailing `*` is not added (this also disables the `searchPrefix`/`searchSuffix` of the
[Search text component](../content-services/components/search-text.component.md)):
```json
{
"search-wildcards-enabled": false
}
```
### Sorting
The Sorting configuration section consists of two blocks:
+3 -18
View File
@@ -40,21 +40,6 @@ ADF is based on Angular Material library, which offers solutions for theming you
If you already setup Angular Material theming in the application you use ADF in, there is no need for taking additional steps to theme ADF components - colors, typography and other parts of the theme will be taken from your setup.
## Customizing deprecated theme variables
Currently we have an amount of custom variables around components to mange libraries look and feel consistently and globally.
While they are getting deprecated to be replaced with [Angular Material system variables](https://material.angular.dev/guide/system-variables), for seamless integration with Angular Material's theming, you can provide values for those variables inside the `:root` element.
For example:
```css
:root {
--theme-primary-color: --mat-sys-primary;
--theme-accent-color: --mat-sys-tertiary;
}
```
**No new variables should be added to the project**
[Reference list of overridable variables](https://github.com/Alfresco/alfresco-ng2-components/blob/29d341cc3b6a0842a776464027dcb1154875a8f0/lib/core/src/lib/styles/_index.scss#L25)
## Default reusable class
@@ -73,14 +58,14 @@ For example:
Avoid adding css variables with names related to components:
```
--my-component-nr-xxx-background-color: mat.get-color-from-palette($primary, 50), // bad
--theme-primary-color-50: mat.get-color-from-palette($primary, 50) // good
--my-component-nr-xxx-background-color: var(--mat-sys-primary), // bad
--theme-primary-color-50: var(--mat-sys-primary) // good
```
Avoid adding css variables with custom values, values should come from the theme:
```
--new-variable: yellow // bad
--new-variable: mat.get-color-from-palette($primary, 50), // good
--new-variable: var(--mat-sys-primary), // good
```
When styling components use Angular Material system variables (colors, typography, elevation):
+2 -2
View File
@@ -61,8 +61,8 @@ backend services have been tested with each released version of ADF.
<!--7.0.0-alpha.3 start-->
- [AgentService](content-services/services/agent.service.md)
- [SearchAiService](content-services/services/search-ai.service.md)
- AgentService — removed, see [Notes](README.md#knowledge-discovery-removal-v900)
- SearchAiService — removed, see [Notes](README.md#knowledge-discovery-removal-v900)
<!--7.0.0-alpha.3 end-->
+3
View File
@@ -58,3 +58,6 @@ The pages linked below contain the audit for all third party dependencies of ADF
- [ADF 8.2.0](audit-info-8.2.0.md)
- [ADF 8.2.1](audit-info-8.2.1.md)
- [ADF 8.3.1](audit-info-8.3.1.md)
- [ADF 8.4.1](audit-info-8.4.1.md)
- [ADF 8.5.0](audit-info-8.5.0.md)
- [ADF 9.0.0](audit-info-9.0.0.md)
+23
View File
@@ -0,0 +1,23 @@
---
Title: Audit info, alfresco-ng2-components 8.4.1
---
# Audit information for alfresco-ng2-components 8.4.1
This page lists the security audit of the dependencies this project depends on.
## Risks
- Critical risk: 0
- High risk: 0
- Moderate risk: 0
- Low risk: 0
Dependencies analyzed:
## Libraries
| Severity | Module | Vulnerable versions |
| --- | --- | --- |
+23
View File
@@ -0,0 +1,23 @@
---
Title: Audit info, alfresco-ng2-components 8.4.1
---
# Audit information for alfresco-ng2-components 8.5.0
This page lists the security audit of the dependencies this project depends on.
## Risks
- Critical risk: 0
- High risk: 0
- Moderate risk: 0
- Low risk: 0
Dependencies analyzed:
## Libraries
| Severity | Module | Vulnerable versions |
| --- | --- | --- |
+23
View File
@@ -0,0 +1,23 @@
---
Title: Audit info, alfresco-ng2-components 9.0.0
---
# Audit information for alfresco-ng2-components 9.0.0
This page lists the security audit of the dependencies this project depends on.
## Risks
- Critical risk: 0
- High risk: 0
- Moderate risk: 0
- Low risk: 0
Dependencies analyzed: 297
## Libraries
| Severity | Module | Vulnerable versions |
| --- | --- | --- |
-1
View File
@@ -10,7 +10,6 @@
"createDefaultProgram": true
},
"rules": {
"prefer-arrow/prefer-arrow-functions": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/naming-convention": "warn",
"quote-props": "off",
-1239
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-cli",
"description": "Alfresco ADF cli and utils",
"version": "8.4.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"bin": {
"adf-cli": "bin/adf-cli",
@@ -22,9 +22,8 @@
"unlink": "cd ../../dist/libs/cli && npm unlink"
},
"dependencies": {
"@alfresco/js-api": ">=9.2.0",
"@alfresco/js-api": ">=9.5.0",
"ejs": "^3.1.10",
"license-checker": "^25.0.1",
"node-fetch": "^2.7.0",
"spdx-license-list": "^5.0.0"
},
+3 -1
View File
@@ -7,6 +7,7 @@
"targets": {
"build": {
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/libs/cli"],
"options": {
"command": "cd lib/cli && npm run dist"
},
@@ -30,6 +31,7 @@
},
"copyToNodeModules": {
"executor": "nx:run-commands",
"cache": false,
"options": {
"commands": [
{
@@ -62,7 +64,7 @@
"cwd": "dist/libs/cli",
"commands": [
{
"command": "npm publish --tag {args.tag}",
"command": "pnpm publish --no-git-checks --tag {args.tag}",
"forwardAllArgs": true
}
]
+192
View File
@@ -0,0 +1,192 @@
/*!
* @license
* Copyright © 2005-2025 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.
*/
const fs = require('node:fs');
const path = require('node:path');
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
function resolvePackageJson(packageName, fromDirectory) {
try {
return require.resolve(`${packageName}/package.json`, {
paths: [fromDirectory]
});
} catch {
return '';
}
}
function getRepositoryUrl(repository) {
if (typeof repository === 'string') {
return repository;
}
if (repository && typeof repository === 'object' && typeof repository.url === 'string') {
return repository.url;
}
return '';
}
function getRawLicenseExpression(packageJson) {
if (typeof packageJson.license === 'string' && packageJson.license.trim()) {
return packageJson.license.trim();
}
if (packageJson.license && typeof packageJson.license === 'object' && typeof packageJson.license.type === 'string') {
return packageJson.license.type.trim();
}
if (Array.isArray(packageJson.licenses)) {
const values = packageJson.licenses
.map((entry) => {
if (typeof entry === 'string') {
return entry.trim();
}
if (entry && typeof entry === 'object' && typeof entry.type === 'string') {
return entry.type.trim();
}
return '';
})
.filter(Boolean);
if (values.length > 0) {
return values.join(' OR ');
}
}
return 'UNKNOWN';
}
function extractLicenseTokens(rawExpression) {
const tokens = (rawExpression || '').match(/[A-Za-z0-9-.+]+/g) || [];
const operators = new Set(['AND', 'OR', 'WITH']);
return tokens.map((token) => token.toUpperCase()).filter((token) => !operators.has(token));
}
function hasDeniedLicense(rawExpression, denyList) {
const licenseTokens = extractLicenseTokens(rawExpression);
return denyList.some((rule) => {
const normalizedRule = (rule || '').trim().toUpperCase();
if (!normalizedRule) {
return false;
}
// Treat common copyleft family keywords as SPDX id prefixes.
if (normalizedRule === 'GPL' || normalizedRule === 'LGPL' || normalizedRule === 'AGPL') {
return licenseTokens.some((token) => token === normalizedRule || token.startsWith(`${normalizedRule}-`));
}
// Support explicit wildcard rules like "GPL-*".
if (normalizedRule.endsWith('*')) {
const prefix = normalizedRule.slice(0, -1);
return prefix.length > 0 && licenseTokens.some((token) => token.startsWith(prefix));
}
// Otherwise require exact SPDX token match.
return licenseTokens.includes(normalizedRule);
});
}
function getDependencyNames(packageJson) {
return Array.from(new Set([...Object.keys(packageJson.dependencies || {}), ...Object.keys(packageJson.optionalDependencies || {})]));
}
function collectProductionLicenses(packagePath, options = {}) {
const packageJsonFile = readJson(packagePath);
const mainDependencies = getDependencyNames(packageJsonFile);
const packageDirectory = path.dirname(packagePath);
const missingRepositories = options.missingRepositories || {};
const denyList = options.denyList || [];
const queue = mainDependencies.map((name) => ({
name,
fromDirectory: packageDirectory
}));
const visited = new Set();
const packages = [];
const deniedPackages = [];
for (const current of queue) {
const packageJsonPath = resolvePackageJson(current.name, current.fromDirectory);
if (!packageJsonPath || !fs.existsSync(packageJsonPath)) {
continue;
}
const currentPackage = readJson(packageJsonPath);
const name = currentPackage.name || current.name;
const version = currentPackage.version || 'unknown';
const packageFolder = path.dirname(packageJsonPath);
const uniqueKey = `${name}@${version}:${packageFolder}`;
if (visited.has(uniqueKey)) {
continue;
}
visited.add(uniqueKey);
const rawLicenseExpression = getRawLicenseExpression(currentPackage);
const packageKey = `${name}@${version}`;
const repository = getRepositoryUrl(currentPackage.repository) || missingRepositories[name] || '';
const record = {
key: packageKey,
name,
version,
repository,
rawLicenseExpression,
dependencies: currentPackage.dependencies || {},
optionalDependencies: currentPackage.optionalDependencies || {}
};
packages.push(record);
if (hasDeniedLicense(rawLicenseExpression, denyList)) {
deniedPackages.push(`${packageKey}: ${rawLicenseExpression}`);
}
const dependencies = getDependencyNames(currentPackage);
for (const dependencyName of dependencies) {
queue.push({
name: dependencyName,
fromDirectory: packageFolder
});
}
}
packages.sort((a, b) => {
const nameCompare = a.name.localeCompare(b.name);
if (nameCompare !== 0) {
return nameCompare;
}
return a.version.localeCompare(b.version);
});
return { packages, deniedPackages };
}
module.exports = {
collectProductionLicenses
};
+2 -2
View File
@@ -98,8 +98,8 @@ Options:
const packageDir = path.dirname(packagePath);
// Use spawnSync with array arguments for safer command execution (prevents shell injection)
// Cross-platform: npm is available on PATH on all platforms (Windows, macOS, Linux)
const result = spawnSync('npm', ['audit', '--json', '--prod'], {
// Cross-platform: pnpm is available on PATH on all platforms (Windows, macOS, Linux)
const result = spawnSync('pnpm', ['audit', '--json', '--prod'], {
cwd: packageDir,
encoding: 'utf-8',
// shell: false is the default and more secure (no shell interpretation)
+269 -140
View File
@@ -28,12 +28,16 @@ interface InitAcsEnvArgs {
username?: string;
password?: string;
}
const MAX_RETRY = 10;
let counter = 0;
const TIMEOUT = 6000;
const RETRY_DELAY_MS = 6000;
const ACS_DEFAULT = require('./resources').ACS_DEFAULT;
let alfrescoJsApi: AlfrescoApi;
let nodesApi: NodesApi;
let uploadApi: UploadApi;
let sharedlinksApi: SharedlinksApi;
let favoritesApi: FavoritesApi;
/**
* Init ACS environment command
@@ -46,7 +50,6 @@ Usage: init-acs-env [options]
Initialize ACS environment
Options:
-v, --version Output the version number
--host <host> Remote environment host
--clientId <id> SSO client (default: "alfresco")
-p, --password <pass> Password
@@ -56,11 +59,6 @@ Options:
exit(0);
}
if (argv.includes('-v') || argv.includes('--version')) {
console.log('0.1.0');
exit(0);
}
const { values } = parseArgs({
args: argv.slice(2),
options: {
@@ -92,160 +90,293 @@ Options:
await checkEnv(opts);
logger.info(`***** Step initialize ACS *****`);
logger.info('***** Step initialize ACS *****');
await initializeDefaultFiles();
}
/**
* Setup default files
* Initialize default files. Creates the e2e folder and ensures each file
* exists with its required state (locked, shared, favorite).
* Idempotent: only creates/modifies what is missing.
*/
async function initializeDefaultFiles() {
const e2eFolder = ACS_DEFAULT.e2eFolder;
const parentFolder = await createFolder(e2eFolder.name, '-my-');
const parentFolderId = parentFolder.entry.id;
const e2eFolderName: string = ACS_DEFAULT.e2eFolder.name;
for (let j = 0; j < ACS_DEFAULT.files.length; j++) {
const fileInfo = ACS_DEFAULT.files[j];
switch (fileInfo.action) {
case 'UPLOAD': {
await uploadFile(fileInfo.name, parentFolderId);
break;
}
case 'LOCK': {
const fileToLock = await uploadFile(fileInfo.name, parentFolderId);
await lockFile(fileToLock.entry.id);
break;
}
case 'SHARE': {
const fileToShare = await uploadFile(fileInfo.name, parentFolderId);
await shareFile(fileToShare.entry.id);
break;
}
case 'FAVORITE': {
const fileToFav = await uploadFile(fileInfo.name, parentFolderId);
await favoriteFile(fileToFav.entry.id);
break;
}
default: {
logger.error('No action found for file ', fileInfo.name, parentFolderId);
break;
}
}
}
}
/**
* Create folder
*
* @param folderName folder name
* @param parentId parent folder id
*/
async function createFolder(folderName: string, parentId: string) {
let createdFolder: NodeEntry;
const body = {
name: folderName,
nodeType: 'cm:folder'
};
let parentFolder: NodeEntry;
try {
createdFolder = await new NodesApi(alfrescoJsApi).createNode(parentId, body, { overwrite: true });
parentFolder = await withRetry(() => ensureFolder(e2eFolderName, '-my-'), `ensure folder ${e2eFolderName}`);
} catch (error: any) {
logger.warn(`Skipping file initialization: test-data folder could not be created: ${formatError(error)}`);
return;
}
logger.info(`Folder ${folderName} was created`);
} catch (err) {
if (err.status === 409) {
const relativePath = `/${folderName}`;
createdFolder = await new NodesApi(alfrescoJsApi).getNode('-my-', { relativePath });
}
const parentFolderId = getEntryId(parentFolder, `folder ${e2eFolderName}`);
for (const fileInfo of ACS_DEFAULT.files) {
await withRetry(() => processFile(fileInfo, parentFolderId), `initialize ${fileInfo.name}`);
}
return createdFolder;
}
/**
* Upload file
*
* @param fileName file name
* @param fileDestination destination path
* Process a single file: upload if missing, then apply its action (lock/share/favorite).
* @param fileInfo file descriptor from ACS_DEFAULT
* @param fileInfo.name file name
* @param fileInfo.action action to apply (LOCK, SHARE, FAVORITE)
* @param parentFolderId parent folder node id
*/
async function uploadFile(fileName: string, fileDestination: string): Promise<NodeEntry> {
async function processFile(fileInfo: { name: string; action: string }, parentFolderId: string) {
const existingNode = await findNodeByRelativePath(parentFolderId, fileInfo.name);
let nodeId: string;
if (existingNode?.entry?.id) {
logger.info(`File ${fileInfo.name} already exists, verifying required state.`);
nodeId = existingNode.entry.id;
} else {
const createdNode = await uploadFile(fileInfo.name, parentFolderId);
nodeId = getEntryId(createdNode, `file ${fileInfo.name}`);
}
switch (fileInfo.action) {
case 'LOCK':
await ensureLocked(nodeId, fileInfo.name, existingNode?.entry?.isLocked);
break;
case 'SHARE':
await ensureShared(nodeId, fileInfo.name);
break;
case 'FAVORITE':
await ensureFavorite(nodeId, fileInfo.name);
break;
default:
break;
}
}
/**
* Ensure a folder exists under the given parent. Creates it if missing.
* Handles 409 conflict (race condition) by fetching the existing folder.
* @param folderName folder name
* @param parentId parent node id
* @returns the folder node entry
*/
async function ensureFolder(folderName: string, parentId: string): Promise<NodeEntry> {
const existingFolder = await findNodeByRelativePath(parentId, folderName);
if (existingFolder?.entry?.id) {
if (!existingFolder.entry.isFolder) {
throw new Error(
`Cannot use ${folderName} as test-data folder: a non-folder node with that name already exists (nodeType: ${existingFolder.entry.nodeType}, id: ${existingFolder.entry.id}).`
);
}
logger.info(`Folder ${folderName} already exists.`);
return existingFolder;
}
try {
const createdFolder = await nodesApi.createNode(parentId, { name: folderName, nodeType: 'cm:folder' }, { overwrite: true });
logger.info(`Folder ${folderName} was created`);
return createdFolder;
} catch (error: any) {
if (error?.status === 409) {
const conflictingFolder = await findNodeByRelativePath(parentId, folderName);
if (conflictingFolder?.entry?.id) {
if (!conflictingFolder.entry.isFolder) {
throw new Error(
`Cannot use ${folderName} as test-data folder: a non-folder node with that name already exists (nodeType: ${conflictingFolder.entry.nodeType}, id: ${conflictingFolder.entry.id}).`
);
}
logger.info(`Folder ${folderName} already exists.`);
return conflictingFolder;
}
}
throw new Error(`Failed to ensure folder ${folderName}: ${formatError(error)}`);
}
}
/**
* Find a node by relative path under a parent. Returns null if not found (404).
* @param parentId parent node id
* @param fileName relative path / file name
* @returns the node entry or null if not found
*/
async function findNodeByRelativePath(parentId: string, fileName: string): Promise<NodeEntry | null> {
try {
return await nodesApi.getNode(parentId, { relativePath: `/${fileName}`, include: ['isLocked'] });
} catch (error: any) {
if (error?.status === 404) {
return null;
}
throw new Error(`Failed to fetch ${fileName}: ${formatError(error)}`);
}
}
/**
* Upload a file to the given destination folder.
* @param fileName file name
* @param destinationId destination folder node id
* @returns the uploaded node entry
*/
async function uploadFile(fileName: string, destinationId: string): Promise<NodeEntry> {
const filePath = `../resources/content/${fileName}`;
const file = createReadStream(path.join(__dirname, filePath));
let uploadedFile: NodeEntry;
try {
uploadedFile = await new UploadApi(alfrescoJsApi).uploadFile(file, '', fileDestination, null, {
const uploadedFile = await uploadApi.uploadFile(file, '', destinationId, null, {
name: fileName,
nodeType: 'cm:content',
renditions: 'doclib',
overwrite: true
});
logger.info(`File ${fileName} was uploaded`);
} catch (err) {
logger.error(`Failed to upload file with error: `, err.stack);
return uploadedFile;
} catch (error: any) {
throw new Error(`Failed to upload ${fileName}: ${formatError(error)}`);
}
return uploadedFile;
}
/**
* Lock file node
*
* Ensure a file is locked. Skips if already locked.
* @param nodeId node id
* @param fileName file name (for logging)
* @param isAlreadyLocked whether the node is already locked
*/
async function lockFile(nodeId: string): Promise<NodeEntry> {
const data = {
type: 'ALLOW_OWNER_CHANGES'
};
async function ensureLocked(nodeId: string, fileName: string, isAlreadyLocked = false) {
if (isAlreadyLocked) {
logger.info(`File ${fileName} is already locked.`);
return;
}
try {
const result = new NodesApi(alfrescoJsApi).lockNode(nodeId, data);
logger.info('File was locked');
return result;
} catch (error) {
logger.error('Failed to lock file with error: ', error.stack);
return null;
await nodesApi.lockNode(nodeId, { type: 'ALLOW_OWNER_CHANGES' });
logger.info(`File ${fileName} was locked`);
} catch (error: any) {
throw new Error(`Failed to lock ${fileName}: ${formatError(error)}`);
}
}
/**
* Share file node
*
* Ensure a file is shared. Handles 409 (already shared) gracefully.
* @param nodeId node id
* @param fileName file name (for logging)
*/
async function shareFile(nodeId: string) {
const data = {
nodeId
};
async function ensureShared(nodeId: string, fileName: string) {
try {
await new SharedlinksApi(alfrescoJsApi).createSharedLink(data);
logger.info('File was shared');
} catch (error) {
logger.error('Failed to share file with error: ', error.stack);
}
}
/**
* Favorite file node
*
* @param nodeId node id
*/
async function favoriteFile(nodeId: string) {
const data = {
target: {
['file']: {
guid: nodeId
}
await sharedlinksApi.createSharedLink({ nodeId });
logger.info(`File ${fileName} was shared`);
} catch (error: any) {
if (error?.status === 409) {
logger.info(`File ${fileName} is already shared.`);
return;
}
};
try {
await new FavoritesApi(alfrescoJsApi).createFavorite('-me-', data);
logger.info('File was add to favorites');
} catch (error) {
logger.error('Failed to add the file to favorites with error: ', error.stack);
throw new Error(`Failed to share ${fileName}: ${formatError(error)}`);
}
}
/**
* Check environment state
*
* @param opts command options
* Ensure a file is favorite. Handles 409 (already favorite) gracefully.
* @param nodeId node id
* @param fileName file name (for logging)
*/
async function checkEnv(opts: InitAcsEnvArgs) {
async function ensureFavorite(nodeId: string, fileName: string) {
try {
await favoritesApi.createFavorite('-me-', {
target: {
file: {
guid: nodeId
}
}
});
logger.info(`File ${fileName} was added to favorites`);
} catch (error: any) {
if (error?.status === 409) {
logger.info(`File ${fileName} is already a favorite.`);
return;
}
throw new Error(`Failed to favorite ${fileName}: ${formatError(error)}`);
}
}
/**
* Extract entry id from a node response. Throws if missing.
* @param nodeEntry node entry response
* @param label label for error message
* @returns the node id
*/
function getEntryId(nodeEntry: NodeEntry, label: string): string {
const nodeId = nodeEntry?.entry?.id;
if (nodeId) {
return nodeId;
}
throw new Error(`Missing ACS response entry for ${label}.`);
}
/**
* Format an error for logging.
* @param error error object
* @returns formatted error string
*/
function formatError(error: any): string {
if (!error) {
return 'Unknown error';
}
if (typeof error === 'string') {
return error;
}
try {
return error?.message || error?.stack || JSON.stringify(error);
} catch {
return 'Unknown error (unable to serialize)';
}
}
/**
* Retry wrapper for transient failures.
* @param fn async function to execute
* @param label label for logging
* @param maxAttempts maximum retry attempts
* @returns the result of the function
*/
async function withRetry<T>(fn: () => Promise<T>, label: string, maxAttempts = 3): Promise<T> {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error: any) {
if (attempt === maxAttempts) {
logger.error(`${label}: failed after ${maxAttempts} attempts: ${formatError(error)}`);
throw error;
}
logger.warn(`${label}: attempt ${attempt} failed, retrying in ${RETRY_DELAY_MS / 1000}s: ${formatError(error)}`);
await wait(RETRY_DELAY_MS);
}
}
throw new Error(`${label}: exhausted all ${maxAttempts} attempts`);
}
/**
* Async delay.
* @param ms milliseconds to wait
* @returns a promise that resolves after the delay
*/
function wait(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Check environment state and authenticate. Retries on transient failures.
* @param opts command options
* @param attempt current attempt number
*/
async function checkEnv(opts: InitAcsEnvArgs, attempt = 1) {
try {
alfrescoJsApi = new AlfrescoApi({
provider: 'ALL',
@@ -260,31 +391,29 @@ async function checkEnv(opts: InitAcsEnvArgs) {
},
contextRoot: 'alfresco'
});
await alfrescoJsApi.login(opts.username, opts.password);
} catch (e) {
if (e.error.code === 'ETIMEDOUT') {
logger.error('The env is not reachable. Terminating');
exit(1);
nodesApi = new NodesApi(alfrescoJsApi);
uploadApi = new UploadApi(alfrescoJsApi);
sharedlinksApi = new SharedlinksApi(alfrescoJsApi);
favoritesApi = new FavoritesApi(alfrescoJsApi);
} catch (error: any) {
const errorCode = error?.error?.code;
if (errorCode === 'ETIMEDOUT' || error?.status === 504) {
logger.warn('Login attempt timed out or received a gateway error, environment may still be starting up.');
} else {
logger.error('Login error, environment down or inaccessible.');
}
logger.error('Login error environment down or inaccessible');
counter++;
if (MAX_RETRY === counter) {
if (attempt >= MAX_RETRY) {
logger.error('Give up');
exit(1);
} else {
logger.error(`Retry in 1 minute attempt N ${counter}`);
sleep(TIMEOUT);
await checkEnv(opts);
}
logger.warn(`Retry in ${RETRY_DELAY_MS / 1000} seconds, attempt ${attempt}`);
await wait(RETRY_DELAY_MS);
await checkEnv(opts, attempt + 1);
}
}
/**
* Perform a delay
*
* @param delay timeout in milliseconds
*/
function sleep(delay: number) {
const start = new Date().getTime();
while (new Date().getTime() < start + delay) {}
}
+151 -87
View File
@@ -30,8 +30,11 @@ import { parseArgs } from 'node:util';
import { spawnSync } from 'node:child_process';
import { createReadStream } from 'node:fs';
import * as path from 'path';
import { config } from 'dotenv';
import { logger } from './logger';
config({ path: path.resolve(__dirname, '../../../.env') });
interface InitApsEnvArgs {
host?: string;
clientId?: string;
@@ -40,12 +43,12 @@ interface InitApsEnvArgs {
license?: string;
}
const MAX_RETRY = 10;
let counter = 0;
const TIMEOUT = 6000;
const RETRY_DELAY_MS = 6000;
const TENANT_DEFAULT_ID = 1;
const TENANT_DEFAULT_NAME = 'default';
const CONTENT_DEFAULT_NAME = 'adw-content';
const ACTIVITI_APPS = require('./resources').ACTIVITI_APPS;
const E2E_USER_PASSWORD = process.env.HR_USER_PASSWORD;
let alfrescoJsApi: AlfrescoApi;
@@ -60,7 +63,6 @@ Usage: init-aps-env [options]
Initialize APS environment
Options:
-v, --version Output the version number
--host <host> Remote environment host
--clientId <id> SSO client (default: "alfresco")
-p, --password <pass> Password
@@ -71,11 +73,6 @@ Options:
exit(0);
}
if (argv.includes('-v') || argv.includes('--version')) {
console.log('0.1.0');
exit(0);
}
const { values } = parseArgs({
args: argv.slice(2),
options: {
@@ -111,6 +108,14 @@ Options:
await checkEnv(opts);
const e2eAppReady = await ensureE2eApplicationDeployed();
if (e2eAppReady) {
logger.info(`APS environment already initialized (terraform). Skipping.`);
return;
}
await alfrescoJsApi.login(opts.username, opts.password);
logger.info(`***** Step 1 - Check License *****`);
let licenceUploaded = false;
@@ -146,25 +151,24 @@ Options:
logger.info(`***** Step 4 - Create users *****`);
const users = await getDefaultApsUsersFromRealm(opts);
if (tenantId && users && users.length > 0) {
for (let i = 0; i < users.length; i++) {
await createUsers(tenantId, users[i]);
for (const user of users) {
await createUsers(tenantId, user);
}
for (let i = 0; i < users.length; i++) {
logger.info('Impersonate user: ' + users[i].username);
await alfrescoJsApi.login(users[i].username, 'password');
await authorizeUserToContentRepo(opts, users[i]);
for (const user of users) {
logger.info('Impersonate user: ' + user.username);
await alfrescoJsApi.login(user.username, E2E_USER_PASSWORD);
await authorizeUserToContentRepo(opts, user);
const defaultUser = 'hruser';
if (users[i].username.includes(defaultUser)) {
logger.info(`***** Step initialize APS apps for user ${defaultUser} *****`);
if (user.username.includes('hruser')) {
logger.info(`***** Step initialize APS apps for user hruser *****`);
await initializeDefaultApps();
}
}
} else {
logger.info('Something went wrong. Was not able to create the users');
}
} catch (error) {
logger.error(`Aps something went wrong. Tenant id ${tenantId}`, error);
} catch (error: any) {
logger.error(`Aps something went wrong. Tenant id ${tenantId}: ${formatError(error)}`);
exit(1);
}
} else {
@@ -173,15 +177,56 @@ Options:
}
}
/**
* Ensure e2e-Application is deployed for hruser.
* If the app is already present, returns true (skip full init).
* If hruser can log in but the app is missing, imports, publishes and deploys it.
* Returns false only if hruser cannot log in or deployment fails.
* @returns `true` if app is deployed, otherwise `false`
*/
async function ensureE2eApplicationDeployed(): Promise<boolean> {
try {
await alfrescoJsApi.login('hruser', E2E_USER_PASSWORD);
const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApi);
const availableApps = await runtimeAppDefinitionsApi.getAppDefinitions();
const e2eApp = availableApps.data?.filter((app) => app.name?.includes('e2e-Application'));
if (e2eApp && e2eApp.length > 0) {
logger.info(`e2e-Application is already deployed for hruser`);
return true;
}
logger.info(`e2e-Application not found for hruser - uploading and deploying it now`);
const appDefinition = await importPublishApp('e2e-Application');
if (appDefinition?.appDefinition?.id) {
await deployApp(appDefinition.appDefinition.id);
const verifyApps = await runtimeAppDefinitionsApi.getAppDefinitions();
const deployed = verifyApps.data?.some((app) => app.name?.includes('e2e-Application'));
if (deployed) {
logger.info(`e2e-Application successfully deployed for hruser`);
return true;
}
logger.info(`e2e-Application deployment could not be verified - proceeding with full initialization`);
return false;
}
logger.info(`Failed to import/deploy e2e-Application for hruser - proceeding with full initialization`);
return false;
} catch (error: any) {
logger.info(`Unable to verify APS state for hruser - proceeding with initialization: ${formatError(error)}`);
return false;
}
}
/**
* Initialise default applications
*/
async function initializeDefaultApps() {
for (let x = 0; x < ACTIVITI_APPS.apps.length; x++) {
const appInfo = ACTIVITI_APPS.apps[x];
for (const appInfo of ACTIVITI_APPS.apps) {
const isDeployed = await isDefaultAppDeployed(appInfo.name);
if (isDeployed !== undefined && !isDeployed) {
const appDefinition = await importPublishApp(`${appInfo.name}`);
if (!isDeployed) {
const appDefinition = await importPublishApp(appInfo.name);
if (!appDefinition?.appDefinition?.id) {
logger.error(`Failed to import app ${appInfo.name}, skipping deployment.`);
continue;
}
await deployApp(appDefinition.appDefinition.id);
} else {
logger.info(`***** App ${appInfo.name} already deployed *****`);
@@ -190,11 +235,11 @@ async function initializeDefaultApps() {
}
/**
* Check environment
*
* Check environment state and authenticate. Retries on transient failures.
* @param opts command options
* @param attempt current attempt number
*/
async function checkEnv(opts: InitApsEnvArgs) {
async function checkEnv(opts: InitApsEnvArgs, attempt = 1) {
try {
alfrescoJsApi = new AlfrescoApi({
provider: 'ALL',
@@ -210,27 +255,28 @@ async function checkEnv(opts: InitApsEnvArgs) {
}
});
await alfrescoJsApi.login(opts.username, opts.password);
} catch (e) {
if (e.error.code === 'ETIMEDOUT') {
logger.error('The env is not reachable. Terminating');
exit(1);
} catch (error: any) {
const errorCode = error?.error?.code;
if (errorCode === 'ETIMEDOUT' || error?.status === 504) {
logger.warn('Login attempt timed out or received a gateway error, environment may still be starting up.');
} else {
logger.error('Login error, environment down or inaccessible.');
}
logger.info('Login error environment down or inaccessible');
counter++;
if (MAX_RETRY === counter) {
if (attempt >= MAX_RETRY) {
logger.error('Give up');
exit(1);
} else {
logger.error(`Retry in 1 minute attempt N ${counter}`);
sleep(TIMEOUT);
await checkEnv(opts);
}
logger.warn(`Retry in ${RETRY_DELAY_MS / 1000} seconds, attempt ${attempt}`);
await wait(RETRY_DELAY_MS);
await checkEnv(opts, attempt + 1);
}
}
/**
* Check if the default tenant is present
*
* @param tenantId tenant id
* @param tenantName tenant name
* @returns `true` if tenant is found, otherwise `false`
@@ -241,7 +287,7 @@ async function hasDefaultTenant(tenantId: number, tenantName: string): Promise<b
try {
const adminTenantsApi = new AdminTenantsApi(alfrescoJsApi);
tenant = await adminTenantsApi.getTenant(tenantId);
} catch (error) {
} catch {
logger.info(`Aps: does not have tenant with id: ${tenantId}`);
return false;
}
@@ -258,8 +304,8 @@ async function hasDefaultTenant(tenantId: number, tenantName: string): Promise<b
/**
* Create default tenant
*
* @param tenantName tenant name
* @returns the tenant id or null
*/
async function createDefaultTenant(tenantName: string) {
const tenantPost = {
@@ -273,28 +319,27 @@ async function createDefaultTenant(tenantName: string) {
const tenant = await adminTenantsApi.createTenant(tenantPost);
logger.info(`APS: Tenant ${tenantName} created with id: ${tenant.id}`);
return tenant.id;
} catch (error) {
logger.info(`APS: not able to create the default tenant: ${JSON.parse(error.message)}`);
} catch (error: any) {
logger.info(`APS: not able to create the default tenant: ${formatError(error)}`);
return null;
}
}
/**
* Create users
*
* @param tenantId tenant id
* @param user user object
* @returns the created user
*/
async function createUsers(tenantId: number, user: any) {
logger.info(`Create user ${user.email} on tenant: ${tenantId}`);
const passwordCamelCase = 'Password';
const userJson = new UserRepresentation({
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
status: 'active',
type: 'enterprise',
password: passwordCamelCase,
password: E2E_USER_PASSWORD,
tenantId
});
@@ -303,15 +348,15 @@ async function createUsers(tenantId: number, user: any) {
const userInfo = await adminUsersApi.createNewUser(userJson);
logger.info(`APS: User ${userInfo.email} created with id: ${userInfo.id}`);
return user;
} catch (error) {
logger.info(`APS: not able to create the default user: ${error.message}`);
} catch (error: any) {
logger.info(`APS: not able to create the default user: ${formatError(error)}`);
}
}
/**
* Update Activiti license
*
* @param opts command options
* @returns `true` if license uploaded successfully, otherwise `false`
*/
async function updateLicense(opts: InitApsEnvArgs) {
const fileContent = createReadStream(path.join(__dirname, '/activiti.lic'));
@@ -330,15 +375,14 @@ async function updateLicense(opts: InitApsEnvArgs) {
);
logger.info(`Aps License uploaded!`);
return true;
} catch (error) {
logger.error(`Aps License failed!`, error.message);
} catch (error: any) {
logger.error(`Aps License failed! ${formatError(error)}`);
return false;
}
}
/**
* Check if default application is deployed
*
* @param appName application name
* @returns `true` if application is deployed, otherwise `false`
*/
@@ -349,18 +393,18 @@ async function isDefaultAppDeployed(appName: string): Promise<boolean> {
const availableApps = await runtimeAppDefinitionsApi.getAppDefinitions();
const defaultApp = availableApps.data?.filter((app) => app.name?.includes(appName));
return defaultApp && defaultApp.length > 0;
} catch (error) {
logger.error(`Aps app failed to import/Publish!`);
} catch (error: any) {
logger.error(`Failed to check if ${appName} is deployed: ${formatError(error)}`);
return false;
}
}
/**
* Import and publish the application
*
* @param appName application name
* @returns the app definition result
*/
async function importPublishApp(appName: string): Promise<AppDefinitionUpdateResultRepresentation> {
async function importPublishApp(appName: string): Promise<AppDefinitionUpdateResultRepresentation | null> {
const appNameExtension = `../resources/${appName}.zip`;
logger.info(`Import app ${appNameExtension}`);
const pathFile = path.join(__dirname, appNameExtension);
@@ -371,15 +415,14 @@ async function importPublishApp(appName: string): Promise<AppDefinitionUpdateRes
const result = await appDefinitionsApi.importAndPublishApp(fileContent, { renewIdmEntries: true });
logger.info(`Aps app imported and published!`);
return result;
} catch (error) {
logger.error(`Aps app failed to import/Publish!`, error.message);
} catch (error: any) {
logger.error(`Aps app failed to import/Publish! ${formatError(error)}`);
return null;
}
}
/**
* Deploy application
*
* @param appDefinitionId app definition id
*/
async function deployApp(appDefinitionId: number) {
@@ -392,15 +435,15 @@ async function deployApp(appDefinitionId: number) {
const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApi);
await runtimeAppDefinitionsApi.deployAppDefinitions(body);
logger.info(`Aps app deployed`);
} catch (error) {
logger.error(`Aps app failed to deploy!`);
} catch (error: any) {
logger.error(`Aps app failed to deploy: ${formatError(error)}`);
}
}
/**
* Checks if Activiti app has license
*
* @param opts command options
* @returns `true` if license is valid, otherwise `false`
*/
async function hasLicense(opts: InitApsEnvArgs): Promise<boolean> {
try {
@@ -415,13 +458,13 @@ async function hasLicense(opts: InitApsEnvArgs): Promise<boolean> {
['application/json'],
['application/json']
);
if (license && license.status === 'valid') {
if (license?.status === 'valid') {
logger.info(`Aps has a valid License!`);
return true;
}
logger.info(`Aps does NOT have a valid License!`);
return false;
} catch (error) {
} catch {
logger.error(`Aps not able to check the license`);
return false;
}
@@ -429,8 +472,8 @@ async function hasLicense(opts: InitApsEnvArgs): Promise<boolean> {
/**
* Get default users from the realm
*
* @param opts command options
* @returns array of default APS users or null
*/
async function getDefaultApsUsersFromRealm(opts: InitApsEnvArgs) {
try {
@@ -449,18 +492,18 @@ async function getDefaultApsUsersFromRealm(opts: InitApsEnvArgs) {
const apsDefaultUsers = users.filter((user) => usernamesOfApsDefaultUsers.includes(user.username));
logger.info(`Keycloak found ${apsDefaultUsers.length} users`);
return apsDefaultUsers;
} catch (error) {
logger.error(`APS: not able to fetch user: ${error.message}`);
} catch (error: any) {
logger.error(`APS: not able to fetch user: ${formatError(error)}`);
return null;
}
}
/**
* Validate that ACS repo for Activiti is present
*
* @param opts command options
* @param tenantId tenant id
* @param contentName content service name
* @returns `true` if content repo is present, otherwise `false`
*/
async function isContentRepoPresent(opts: InitApsEnvArgs, tenantId: number, contentName: string): Promise<boolean> {
try {
@@ -476,18 +519,18 @@ async function isContentRepoPresent(opts: InitApsEnvArgs, tenantId: number, cont
['application/json']
);
return !!contentRepos.data.find((repo) => repo.name === contentName);
} catch (error) {
logger.error(`APS: not able to create content: ${error.message}`);
return null;
} catch (error: any) {
logger.error(`APS: not able to check content repo: ${formatError(error)}`);
return false;
}
}
/**
* Add content service with basic auth
*
* @param opts command options
* @param tenantId tenant id
* @param name content name
* @returns the created content repo
*/
async function addContentRepoWithBasic(opts: InitApsEnvArgs, tenantId: number, name: string) {
logger.info(`Create Content with name ${name} and basic auth`);
@@ -517,14 +560,13 @@ async function addContentRepoWithBasic(opts: InitApsEnvArgs, tenantId: number, n
);
logger.info(`Content created!`);
return content;
} catch (error) {
logger.error(`APS: not able to create content: ${error.message}`);
} catch (error: any) {
logger.error(`APS: not able to create content: ${formatError(error)}`);
}
}
/**
* Authorize activiti user to ACS repo
*
* @param opts command options
* @param user user object
*/
@@ -551,22 +593,22 @@ async function authorizeUserToContentRepo(opts: InitApsEnvArgs, user: any) {
}
}
return;
} catch (error) {
logger.error(`APS: not able to authorize content: ${error.message}`);
} catch (error: any) {
logger.error(`APS: not able to authorize content: ${formatError(error)}`);
}
}
/**
* Authorize user with content using basic auth
*
* @param opts command options
* @param username username
* @param contentId content id
* @returns the authorized content
*/
async function authorizeUserToContentWithBasic(opts: InitApsEnvArgs, username: string, contentId: string) {
logger.info(`Authorize ${username} on contentId: ${contentId} in basic auth`);
try {
const body = { username, password: 'password' };
const body = { username, password: E2E_USER_PASSWORD };
const content = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${opts.host}/activiti-app/api/enterprise/integration/alfresco/${contentId}/account`,
'POST',
@@ -580,15 +622,15 @@ async function authorizeUserToContentWithBasic(opts: InitApsEnvArgs, username: s
);
logger.info(`User authorized!`);
return content;
} catch (error) {
logger.error(`APS: not able to authorize content: ${error.message}`);
} catch (error: any) {
logger.error(`APS: not able to authorize content: ${formatError(error)}`);
}
}
/**
* Download APS license file
*
* @param apsLicensePath path to license file
* @returns `true` if download succeeded, otherwise `false`
*/
async function downloadLicenseFile(apsLicensePath: string) {
const args = [`s3`, `cp`, apsLicensePath, `./`];
@@ -606,11 +648,33 @@ async function downloadLicenseFile(apsLicensePath: string) {
}
/**
* Perform a delay
*
* @param delay timeout in milliseconds
* Format an error for logging.
* @param error error object
* @returns formatted error string
*/
function sleep(delay: number) {
const start = new Date().getTime();
while (new Date().getTime() < start + delay) {}
function formatError(error: any): string {
if (!error) {
return 'Unknown error';
}
if (typeof error === 'string') {
return error;
}
try {
return error?.message || error?.stack || JSON.stringify(error);
} catch {
return 'Unknown error (unable to serialize)';
}
}
/**
* Async delay.
* @param ms milliseconds to wait
* @returns a promise that resolves after the delay
*/
function wait(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
main();
+60 -67
View File
@@ -21,10 +21,11 @@ import { argv, exit } from 'node:process';
import { parseArgs } from 'node:util';
import * as path from 'path';
import * as fs from 'fs';
import * as checker from 'license-checker';
import * as licenseList from 'spdx-license-list';
import * as ejs from 'ejs';
const { collectProductionLicenses } = require('../resources/license-collector.cjs');
interface LicensesCommandArgs {
package?: string;
outDir?: string;
@@ -34,7 +35,14 @@ interface PackageInfo {
name: string;
description: string;
version: string;
dependencies: Record<string, string>;
dependencies?: Record<string, string>;
}
interface PackageInfoWithMetadata {
name: string;
version: string;
licenseExp: string;
repository?: string;
}
const nonStandardLicenses = {
@@ -93,6 +101,17 @@ function getPackageFile(packagePath: string): PackageInfo {
}
}
function toLinkedLicenseExpression(rawExpression: string): string {
return rawExpression.replace(/\*/g, '').replace(/[a-zA-Z0-9\-.]+/g, (match: string) => {
const lowerMatch = match.toLowerCase();
if (lowerMatch !== 'and' && lowerMatch !== 'or' && lowerMatch !== 'with') {
return licenseWithMDLinks(match);
}
return match;
});
}
/**
* Licenses command
*
@@ -155,76 +174,50 @@ Options:
return new Promise((resolve, reject) => {
// eslint-disable-next-line no-console
console.info(`Checking ${packagePath}`);
const packageJsonFile = getPackageFile(packagePath);
const mainDependencies = Object.keys(packageJsonFile.dependencies || {});
const licenseScan = collectProductionLicenses(packagePath, {
denyList: ['GPL'],
missingRepositories
});
checker.init(
const filteredPackages: Record<string, PackageInfoWithMetadata> = {};
for (const pack of licenseScan.packages) {
filteredPackages[pack.key] = {
name: pack.name,
version: pack.version,
licenseExp: toLinkedLicenseExpression(pack.rawLicenseExpression),
repository: pack.repository
};
}
if (licenseScan.deniedPackages.length > 0) {
const deniedError = new Error(`Denied licenses found:\n${licenseScan.deniedPackages.join('\n')}`);
console.error(deniedError.message);
reject(deniedError);
return;
}
const packageJson: PackageInfo = getPackageFile(packagePath);
ejs.renderFile(
templatePath,
{
start: workingDir,
production: true,
failOn: 'GPL'
filteredPackages,
projVersion: packageJson.version,
projName: packageJson.name
},
(err: any, packages: any[]) => {
if (err) {
console.error(err);
reject(err);
{},
(ejsError: unknown, mdText: string) => {
if (ejsError) {
console.error(ejsError);
reject(ejsError);
} else {
const filteredPackages = {};
const outputPath = path.resolve(options.outDir || workingDir);
const outputFile = path.join(outputPath, `license-info-${packageJson.version}.md`);
// eslint-disable-next-line guard-for-in
for (const packageName in packages) {
const pack = packages[packageName];
const lastAtSignPos = packageName.lastIndexOf('@');
const basePackageName = packageName.substring(0, lastAtSignPos);
if (mainDependencies.includes(basePackageName)) {
pack['licenseExp'] = pack['licenses']
.toString()
.replace(/\*/g, '')
.replace(/[a-zA-Z0-9\-.]+/g, (match: string) => {
const lowerMatch = match.toLowerCase();
if (lowerMatch !== 'and' && lowerMatch !== 'or' && lowerMatch !== 'with') {
return licenseWithMDLinks(match);
} else {
return match;
}
});
filteredPackages[packageName] = pack;
}
if (!pack['repository'] && missingRepositories[basePackageName]) {
pack['repository'] = missingRepositories[basePackageName];
filteredPackages[packageName] = pack;
}
}
const packageJson: PackageInfo = getPackageFile(packagePath);
ejs.renderFile(
templatePath,
{
filteredPackages,
projVersion: packageJson.version,
projName: packageJson.name
},
{},
(ejsError: any, mdText: string) => {
if (ejsError) {
console.error(ejsError);
reject(ejsError);
} else {
const outputPath = path.resolve(options.outDir || workingDir);
const outputFile = path.join(outputPath, `license-info-${packageJson.version}.md`);
fs.writeFileSync(outputFile, mdText);
// eslint-disable-next-line no-console
console.log(`Report saved as ${outputFile}`);
resolve(0);
}
}
);
fs.writeFileSync(outputFile, mdText);
// eslint-disable-next-line no-console
console.log(`Report saved as ${outputFile}`);
resolve(0);
}
}
);
+3 -9
View File
@@ -29,7 +29,7 @@ module.exports = function (config) {
{ pattern: 'lib/config/app.config.json', included: false, served: true, watched: false }
],
frameworks: ['jasmine-ajax', 'jasmine', '@angular-devkit/build-angular'],
frameworks: ['jasmine', '@angular-devkit/build-angular'],
proxies: {
'/assets/images/': '/base/lib/core/src/lib/assets/images/',
@@ -42,13 +42,11 @@ module.exports = function (config) {
},
plugins: [
require('karma-jasmine-ajax'),
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma'),
require('karma-mocha-reporter')
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false,
@@ -61,10 +59,6 @@ module.exports = function (config) {
suppressAll: true // removes the duplicated traces
},
mochaReporter: {
ignoreSkipped: process.env.KARMA_IGNORE_SKIPPED === 'true'
},
coverageReporter: {
dir: join(__dirname, '../../coverage/content-services'),
subdir: '.',
@@ -86,7 +80,7 @@ module.exports = function (config) {
}
},
reporters: ['mocha', 'kjhtml'],
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: constants.LOG_INFO,
+13 -13
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-content-services",
"description": "Alfresco ADF content services",
"version": "8.4.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -11,19 +11,19 @@
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
},
"peerDependencies": {
"@angular/animations": ">=14.1.3",
"@angular/cdk": ">=14.1.2",
"@angular/common": ">=14.1.3",
"@angular/compiler": ">=14.1.3",
"@angular/core": ">=14.1.3",
"@angular/forms": ">=14.1.3",
"@angular/material": ">=14.1.2",
"@angular/platform-browser": ">=14.1.3",
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=9.3.1",
"@angular/animations": ">=20.3.25",
"@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/material": ">=20.2.14",
"@angular/platform-browser": ">=20.3.25",
"@angular/platform-browser-dynamic": ">=20.3.25",
"@angular/router": ">=20.3.25",
"@alfresco/js-api": ">=10.0.0",
"@ngx-translate/core": ">=17.0.0",
"@alfresco/adf-core": ">=8.3.1"
"@alfresco/adf-core": ">=9.0.0"
},
"keywords": [
"content-services",
+2 -2
View File
@@ -43,7 +43,7 @@
"options": {
"commands": [
{
"command": "stylelint lib/content-services/**/*.scss --config stylelint-config.json"
"command": "stylelint \"lib/content-services/**/*.scss\" --config .stylelintrc.json"
}
]
}
@@ -55,7 +55,7 @@
"cwd": "dist/libs/content-services",
"commands": [
{
"command": "npm publish --tag {args.tag}",
"command": "pnpm publish --no-git-checks --tag {args.tag}",
"forwardAllArgs": true
}
]
@@ -0,0 +1,7 @@
@mixin adf-error-icon {
font-size: 16px;
width: 16px;
height: 16px;
margin-right: 4px;
vertical-align: text-bottom;
}
@@ -1,18 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 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.
*/
export * from './public-api';
@@ -1,18 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 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.
*/
export * from './services/agent.service';
@@ -1,67 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 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 { AgentService } from './agent.service';
import { Agent, AgentPaging } from '@alfresco/js-api';
const agent1: Agent = {
id: '1',
name: 'HR Agent',
description: 'Your Claims Doc Agent streamlines the extraction, analysis, and management of data from insurance claims documents.',
avatarUrl: ''
};
const agent2: Agent = {
id: '2',
name: 'Policy Agent',
description: 'Your Claims Doc Agent streamlines the extraction, analysis, and management of data from insurance claims documents.',
avatarUrl: ''
};
const agentPagingObjectMock: AgentPaging = {
list: {
entries: [
{
entry: agent1
},
{
entry: agent2
}
]
}
};
const agentListMock: Agent[] = [agent1, agent2];
describe('AgentService', () => {
let agentService: AgentService;
beforeEach(() => {
agentService = TestBed.inject(AgentService);
});
it('should load agents', (done) => {
spyOn(agentService.agentsApi, 'getAgents').and.returnValue(Promise.resolve(agentPagingObjectMock));
agentService.getAgents().subscribe((pagingResponse) => {
expect(pagingResponse).toEqual(agentListMock);
expect(agentService.agentsApi.getAgents).toHaveBeenCalled();
done();
});
});
});
@@ -1,58 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 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 { Injectable, inject } from '@angular/core';
import { Agent, AgentsApi, LazyApi } from '@alfresco/js-api';
import { BehaviorSubject, from, Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services';
@Injectable({
providedIn: 'root'
})
export class AgentService {
private readonly apiService = inject(AlfrescoApiService);
private readonly agents = new BehaviorSubject<Agent[]>([]);
@LazyApi((self: AgentService) => new AgentsApi(self.apiService.getInstance()))
declare readonly agentsApi: AgentsApi;
agents$ = this.agents.asObservable();
/**
* Gets all agents from cache. If cache is empty, fetches agents from backend.
*
* @returns Agent[] list containing agents.
*/
getAgents(): Observable<Agent[]> {
return this.agents$.pipe(
switchMap((agentsList) => {
if (agentsList.length) {
return of(agentsList);
}
return from(this.agentsApi.getAgents()).pipe(
map((paging) => {
const agentEntries = paging.list.entries.map((agentEntry) => agentEntry.entry);
this.agents.next(agentEntries);
return agentEntries;
})
);
})
);
}
}
@@ -9,8 +9,7 @@ adf-aspect-list-dialog {
}
.adf-aspect-list-dialog-title {
font-size: large;
font-weight: 200;
font: var(--mat-sys-headline-medium);
margin-top: 0;
}
@@ -44,11 +43,6 @@ adf-aspect-list-dialog {
margin-bottom: 8px;
.adf-aspect-property-table {
.adf-aspect-property-table-cell {
font-size: smaller;
color: var(--adf-theme-foreground-text-color-087);
}
.adf-aspect-property-table-column {
&-name {
width: 30%;
@@ -23,7 +23,7 @@ $dialog-list-height: calc(65vh - ($dialog-title-height + $dialog-information-hei
&-aspect-list-container {
max-height: $dialog-list-height;
overflow: auto;
border: 1px solid var(--adf-theme-foreground-text-color-007);
border: 1px solid var(--mat-sys-outline-variant);
.adf-aspect-list-check-button {
margin-right: 5px;
@@ -35,11 +35,11 @@ $dialog-list-height: calc(65vh - ($dialog-title-height + $dialog-information-hei
.adf-accordion-aspect-list-item {
padding-left: 14px;
display: flex;
box-shadow: 0 2px 2px -1px var(--adf-theme-foreground-text-color-007);
box-shadow: var(--mat-sys-level2);
&.adf-hover {
&:hover {
background-color: var(--adf-theme-background-hover-color);
background-color: var(--mat-sys-surface-container);
}
}
}
@@ -47,8 +47,6 @@ $dialog-list-height: calc(65vh - ($dialog-title-height + $dialog-information-hei
.adf-accordion-aspect-list-expansion-panel {
margin: 0;
width: 100%;
box-shadow: none;
background: border-box;
#{ms.$mat-checkbox-background} {
height: 16px;
@@ -56,13 +54,13 @@ $dialog-list-height: calc(65vh - ($dialog-title-height + $dialog-information-hei
}
&-header {
font-size: smaller;
font: var(--mat-sys-body-small);
padding-left: 0;
height: 48px;
}
&-header-title {
color: var(--theme-secondary-text);
color: var(--mat-sys-on-secondary-container);
}
&-header-description {
@@ -82,8 +80,7 @@ $dialog-list-height: calc(65vh - ($dialog-title-height + $dialog-information-hei
.adf-aspect-property-table-column-name,
.adf-aspect-property-table-column-title,
.adf-aspect-property-table-column-data-type {
font-size: 12px;
color: var(--adf-theme-foreground-text-color-064);
font: var(--mat-sys-body-small);
}
.adf-aspect-property-table-column {
@@ -1,11 +1,8 @@
.adf-breadcrumb {
display: flex;
flex: 1;
line-height: 24px;
font-size: var(--theme-body-1-font-size);
font-weight: 600;
letter-spacing: -0.2px;
color: var(--adf-theme-foreground-text-color-064);
font: var(--mat-sys-body-medium);
color: var(--mat-sys-on-surface);
overflow: hidden;
&-container {
@@ -35,7 +32,7 @@
margin-right: 5px;
&:focus {
color: var(--theme-primary-color);
color: var(--mat-sys-primary);
outline: none;
}
@@ -44,11 +41,11 @@
}
&-arrow {
font-size: var(--theme-adf-icon-1-font-size);
font: var(--mat-sys-body-small);
position: absolute;
left: 4px;
top: 4px;
color: white;
color: var(--mat-sys-on-secondary);
z-index: 2;
}
@@ -70,30 +67,21 @@
padding-right: 2px;
overflow: hidden;
display: flex;
line-height: 33px;
font-size: var(--theme-body-1-font-size);
font-weight: 600;
letter-spacing: -0.2px;
align-items: center;
font: var(--mat-sys-body-medium);
text-align: left;
color: var(--adf-theme-foreground-text-color-064);
color: var(--mat-sys-on-secondary-container);
flex: 0 1 auto;
min-width: 35px;
margin-top: auto;
text-overflow: ellipsis;
&:hover,
&.adf-active {
color: var(--adf-theme-foreground-text-color-064);
}
&.adf-active {
color: var(--adf-theme-foreground-text-color-087);
color: var(--mat-sys-on-surface);
}
&-chevron {
opacity: 1;
margin-top: 9px;
font-size: var(--theme-adf-icon-1-font-size);
font: var(--mat-sys-body-small);
}
&-anchor {
@@ -110,7 +98,7 @@
text-align: start;
&:focus {
outline: 1px solid var(--theme-accent-color-a200);
outline: 1px solid var(--mat-sys-outline-variant);
outline-offset: -1px;
}
}
@@ -6,11 +6,8 @@ $dropdown-horizontal-offset: 30px;
&-dropdown-breadcrumb {
display: flex;
flex: 1;
line-height: 24px;
font-size: var(--theme-body-1-font-size);
font-weight: 600;
letter-spacing: -0.2px;
color: var(--adf-theme-foreground-text-color-064);
font: var(--mat-sys-body-medium);
color: var(--mat-sys-on-secondary-container);
overflow: hidden;
margin-top: 10px;
@@ -36,7 +33,7 @@ $dropdown-horizontal-offset: 30px;
width: 25px;
&:focus {
color: var(--theme-primary-color);
color: var(--mat-sys-primary);
outline: none;
}
}
@@ -61,12 +58,12 @@ $dropdown-horizontal-offset: 30px;
text-overflow: ellipsis;
display: inline-block;
width: 75%;
color: var(--adf-theme-foreground-text-color);
color: var(--mat-sys-on-surface);
}
&-dropdown-breadcrumb-path-option.adf-dropdown-breadcrumb-path-option-node {
padding: 0 12px;
font-size: var(--theme-caption-font-size);
font-size: var(--mat-sys-body-small-size);
}
&-dropdown-breadcrumb-path-option.adf-dropdown-breadcrumb-path-option-node:first-child {
@@ -99,5 +96,6 @@ $dropdown-horizontal-offset: 30px;
}
#{ms.$cdk-overlay-pane}:has(> .adf-breadcrumb-dropdown-panel) {
margin-top: 12px;
min-width: fit-content;
}
@@ -10,7 +10,7 @@
(keyup.enter)="addCategory()"
adf-auto-focus
/>
<mat-error
<mat-error
*ngIf="categoryNameControl.invalid && categoryNameControl.touched"
data-automation-id="categories-error-message">
{{ categoryNameErrorMessageKey | translate }}
@@ -1,5 +1,3 @@
@use '../../mat-selectors.scss' as ms;
.adf-categories-management {
margin: 5px 0;
@@ -13,6 +11,7 @@
justify-content: space-between;
align-items: center;
word-break: break-word;
font: var(--mat-sys-body-medium);
}
.adf-categories-padded {
@@ -35,23 +34,11 @@
height: 100%;
overflow-wrap: anywhere;
padding: 5px 0;
font-size: 14px;
background-color: inherit;
color: inherit;
&:not(#{ms.$mat-list-item-disabled}):hover {
cursor: pointer;
background: var(--adf-theme-mat-grey-color-a200);
}
& span {
padding: 0;
}
}
.adf-existing-categories-label {
font-size: 10px;
color: var(--theme-secondary-text-color);
font: var(--mat-sys-body-small);
color: var(--mat-sys-on-secondary-container);
margin-bottom: 2px;
}
@@ -64,12 +51,8 @@
min-height: 22vh;
.adf-create-category-label {
color: var(--theme-primary-color);
color: var(--mat-sys-primary);
cursor: pointer;
overflow-wrap: anywhere;
}
#{ms.$mat-list-item-disabled} #{ms.$mat-list-item-primary-text} {
opacity: 1;
}
}
@@ -124,7 +124,7 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
this._categoryNameControlVisible = categoryNameControlVisible;
if (categoryNameControlVisible) {
setTimeout(() => {
this.categoryNameInputElement.nativeElement.scrollIntoView();
this.categoryNameInputElement.nativeElement.scrollIntoView({ block: 'nearest' });
});
this._existingCategoriesPanelVisible = true;
} else {
@@ -210,6 +210,13 @@ describe('ContentService', () => {
expect(contentService.getNodeIcon(node)).toContain('assets/images/ft_ic_ms_word.svg');
});
it('should resolve file link icon for app:filelink node', () => {
node.isFolder = false;
node.isFile = true;
node.nodeType = 'app:filelink';
expect(contentService.getNodeIcon(node)).toContain('assets/images/ft_ic_file_link.svg');
});
it('should resolve fallback file icon for unknown node', () => {
node.isFolder = false;
node.isFile = false;
@@ -151,6 +151,9 @@ export class ContentService {
return this.getFolderIcon(node);
}
if (node?.isFile) {
if (node?.nodeType === 'app:filelink') {
return this.thumbnailService.getMimeTypeIcon('fileLink');
}
return this.thumbnailService.getMimeTypeIcon(node?.content?.mimeType);
}
return this.thumbnailService.getDefaultMimeTypeIcon();
@@ -26,8 +26,6 @@ import { FileModel, FileUploadStatus } from '../../common/models/file.model';
import { AlfrescoApiService } from '../../services';
import { AlfrescoApiServiceMock } from '../../mock';
declare let jasmine: any;
describe('UploadService', () => {
let service: UploadService;
let appConfigService: AppConfigService;
@@ -35,6 +33,40 @@ describe('UploadService', () => {
const mockProductInfo = new BehaviorSubject<RepositoryInfo>(null);
const createMockPromiseWithEvents = (responseData?: any, shouldError = false) => {
const handlers: any = {};
const promise: any = new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldError) {
if (handlers.error) {
handlers.error(responseData || { status: 404 });
}
reject(responseData);
} else {
if (handlers.success) {
handlers.success(responseData);
}
resolve(responseData);
}
}, 0);
});
promise.on = (event: string, handler: (data?: any) => void) => {
handlers[event] = handler;
return promise;
};
promise.abort = () => {
if (handlers.abort) {
handlers.abort();
}
};
promise.catch = (handler: (error: any) => void) => Promise.prototype.catch.call(promise, handler);
return promise;
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
@@ -75,14 +107,9 @@ describe('UploadService', () => {
uploadFileSpy = spyOn(service.uploadApi, 'uploadFile').and.callThrough();
jasmine.Ajax.install();
mockProductInfo.next({ status: { isThumbnailGenerationEnabled: true } } as RepositoryInfo);
});
afterEach(() => {
jasmine.Ajax.uninstall();
});
it('should return an empty queue if no elements are added', () => {
expect(service.getQueue().length).toEqual(0);
});
@@ -153,53 +180,49 @@ describe('UploadService', () => {
it('should make XHR done request after the file is added in the queue', (done) => {
const emitter = new EventEmitter();
const mockResponse = { entry: { id: 'node-id' } };
const mockPromise = createMockPromiseWithEvents(mockResponse);
uploadFileSpy.and.returnValue(mockPromise);
const emitterDisposable = emitter.subscribe((e) => {
expect(e.value).toBe('File uploaded');
expect(e.value).toEqual(mockResponse);
emitterDisposable.unsubscribe();
done();
});
const fileFake = new FileModel({ name: 'fake-name', size: 10 } as File, { parentId: '-root-', path: 'fake-dir' });
service.addToQueue(fileFake);
service.uploadFilesInTheQueue(emitter);
const request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe(
'http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children?autoRename=true&include=allowableOperations'
);
expect(request.method).toBe('POST');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'text/plain',
responseText: 'File uploaded'
});
expect(uploadFileSpy).toHaveBeenCalled();
});
it('should make XHR error request after an error occur', (done) => {
const emitter = new EventEmitter();
const mockPromise = createMockPromiseWithEvents({ status: 404 }, true);
uploadFileSpy.and.returnValue(mockPromise);
const emitterDisposable = emitter.subscribe((e) => {
expect(e.value).toBe('Error file uploaded');
emitterDisposable.unsubscribe();
done();
});
const fileFake = new FileModel({ name: 'fake-name', size: 10 } as File, { parentId: '-root-' });
service.addToQueue(fileFake);
service.uploadFilesInTheQueue(null, emitter);
expect(jasmine.Ajax.requests.mostRecent().url).toBe(
'http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children?autoRename=true&include=allowableOperations'
);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 404,
contentType: 'text/plain',
responseText: 'Error file uploaded'
});
expect(uploadFileSpy).toHaveBeenCalled();
});
it('should abort file only if it is safe to abort', (done) => {
const emitter = new EventEmitter();
const mockPromise = createMockPromiseWithEvents();
uploadFileSpy.and.returnValue(mockPromise);
const emitterDisposable = emitter.subscribe((event) => {
expect(event.value).toEqual('File aborted');
emitterDisposable.unsubscribe();
@@ -217,22 +240,18 @@ describe('UploadService', () => {
it('should let file complete and then delete node if it is not safe to abort', (done) => {
const emitter = new EventEmitter();
const mockUploadResponse = { entry: { id: 'myNodeId' } };
const mockPromise = createMockPromiseWithEvents(mockUploadResponse);
uploadFileSpy.and.returnValue(mockPromise);
const deleteNodeSpy = spyOn(service.nodesApi, 'deleteNode').and.returnValue(Promise.resolve());
const emitterDisposable = emitter.subscribe((event) => {
expect(event.value).toEqual('File deleted');
emitterDisposable.unsubscribe();
const deleteRequest = jasmine.Ajax.requests.mostRecent();
expect(deleteRequest.url).toBe(
'http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/myNodeId?permanent=true'
);
expect(deleteRequest.method).toBe('DELETE');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'text/plain',
responseText: 'File deleted'
});
done();
if (event.value === 'File deleted') {
expect(deleteNodeSpy).toHaveBeenCalledWith('myNodeId', { permanent: true });
emitterDisposable.unsubscribe();
done();
}
});
const fileFake = new FileModel({ name: 'fake-name', size: 10 } as File);
@@ -241,41 +260,30 @@ describe('UploadService', () => {
const file = service.getQueue();
service.cancelUpload(...file);
const request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe(
'http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children?autoRename=true&include=allowableOperations'
);
expect(request.method).toBe('POST');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json',
responseText: {
entry: {
id: 'myNodeId'
}
}
});
});
it('should delete node version when cancelling the upload of the new file version', (done) => {
const emitter = new EventEmitter();
const mockUploadResponse = {
entry: {
id: 'myNodeId',
properties: {
'cm:versionLabel': '1.1'
}
}
};
const mockPromise = createMockPromiseWithEvents(mockUploadResponse);
spyOn(service.nodesApi, 'updateNodeContent').and.returnValue(mockPromise);
const deleteVersionSpy = spyOn(service.versionsApi, 'deleteVersion').and.returnValue(Promise.resolve());
const emitterDisposable = emitter.subscribe((event) => {
expect(event.value).toEqual('File deleted');
emitterDisposable.unsubscribe();
const deleteRequest = jasmine.Ajax.requests.mostRecent();
expect(deleteRequest.url).toBe('http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/myNodeId/versions/1.1');
expect(deleteRequest.method).toBe('DELETE');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'text/plain',
responseText: 'File deleted'
});
done();
if (event.value === 'File deleted') {
expect(deleteVersionSpy).toHaveBeenCalledWith('myNodeId', '1.1');
emitterDisposable.unsubscribe();
done();
}
});
const fileFake = new FileModel({ name: 'fake-name', size: 10 } as File, null, 'fakeId');
@@ -284,23 +292,6 @@ describe('UploadService', () => {
const file = service.getQueue();
service.cancelUpload(...file);
const request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toContain('ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/fakeId/content?include=allowableOperations');
expect(request.method).toBe('PUT');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json',
responseText: {
entry: {
id: 'myNodeId',
properties: {
'cm:versionLabel': '1.1'
}
}
}
});
});
it('If newVersion is set, name should be a param', () => {
@@ -331,26 +322,27 @@ describe('UploadService', () => {
it('should use custom root folder ID given to the service', (done) => {
const emitter = new EventEmitter();
const mockResponse = { entry: { id: 'node-id' } };
const mockPromise = createMockPromiseWithEvents(mockResponse);
uploadFileSpy.and.returnValue(mockPromise);
const emitterDisposable = emitter.subscribe((e) => {
expect(e.value).toBe('File uploaded');
expect(e.value).toEqual(mockResponse);
emitterDisposable.unsubscribe();
done();
});
const filesFake = new FileModel({ name: 'fake-file-name', size: 10 } as File, { parentId: '123', path: 'fake-dir' });
service.addToQueue(filesFake);
service.uploadFilesInTheQueue(emitter);
const request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toContain(
'/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/123/children?autoRename=true&include=allowableOperations'
expect(uploadFileSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ name: 'fake-file-name' }),
'fake-dir',
'123',
jasmine.any(Object),
jasmine.any(Object)
);
expect(request.method).toBe('POST');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'text/plain',
responseText: 'File uploaded'
});
});
describe('versioningEnabled', () => {
@@ -437,6 +429,13 @@ describe('UploadService', () => {
});
it('should start downloading the next one if a file of the list is aborted', (done) => {
const mockResponse1 = { entry: { id: 'node-id-1' } };
const mockResponse2 = { entry: { id: 'node-id-2' } };
const mockPromise1 = createMockPromiseWithEvents(mockResponse1);
const mockPromise2 = createMockPromiseWithEvents(mockResponse2);
uploadFileSpy.and.returnValues(mockPromise1, mockPromise2);
service.fileUploadAborted.subscribe((e) => {
expect(e).not.toBeNull();
});
@@ -10,18 +10,9 @@
&-footer.adf-content-metadata-card-view-footer {
margin: 0;
padding: 8px 12px;
border-top: 1px solid var(--adf-theme-foreground-text-color-007);
display: flex;
place-content: stretch space-between;
align-items: stretch;
max-height: 100%;
button {
color: var(--adf-theme-foreground-text-color-064);
&:hover {
color: var(--adf-theme-foreground-text-color-087);
}
}
}
}
@@ -37,7 +37,6 @@
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-general-info-metadata"
[disabled]="!hasMetadataChanged || invalidProperties.size > 0">
<mat-icon adf-icon="check" />
@@ -92,15 +91,14 @@
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-tags-metadata"
data-automation-id="save-tags-metadata"
[disabled]="!hasMetadataChanged">
<mat-icon adf-icon="check" />
</button>
</div>
</adf-content-metadata-header>
</mat-expansion-panel-header>
<div *ngIf="currentPanel.panelTitle === DefaultPanels.TAGS && editedPanelTitle !== DefaultPanels.TAGS"
<div *ngIf="currentPanel.panelTitle === DefaultPanels.TAGS && editedPanelTitle !== DefaultPanels.TAGS && !showEmptyTagMessage"
class="adf-metadata-properties-tags">
<adf-dynamic-chip-list [chips]="tagsToDisplay" [showDelete]="false" />
</div>
@@ -156,8 +154,7 @@
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-categories-metadata"
data-automation-id="save-categories-metadata"
[disabled]="!hasMetadataChanged">
<mat-icon adf-icon="check" />
</button>
@@ -238,8 +235,7 @@
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-metadata"
data-automation-id="save-metadata"
[disabled]="!hasMetadataChanged || invalidProperties.size > 0">
<mat-icon adf-icon="check" />
</button>
@@ -5,48 +5,26 @@ $panel-properties-height: 56px !default;
.adf {
&-metadata-properties {
.adf-content-metadata-panel {
box-shadow: none;
border: 1px solid var(--adf-metadata-property-panel-border-color);
border-radius: 12px;
margin: 12px;
.adf-property-list .adf-property .adf-property-field {
.adf-property-value:not(.adf-card-view-selectitem .adf-property-value) {
&:is(textarea) {
padding-top: 6px;
}
}
label {
font-size: 19px;
line-height: 24px;
font: var(--mat-sys-headline-small);
}
}
}
.adf-metadata-properties-header {
height: $panel-properties-height;
padding: 0 12px;
border-radius: 12px 12px 0 0;
&.adf-metadata-properties-header-expanded {
border-bottom: 1px solid var(--adf-metadata-property-panel-border-color);
}
}
.adf-metadata-properties-expansion-panel,
.adf-metadata-categories-header {
display: block;
margin-top: 16px;
}
.adf-metadata-properties-tags,
.adf-metadata-no-item-added {
margin-top: 16px;
}
.adf-edit-icon-buttons {
color: var(--adf-theme-foreground-text-color-064);
color: var(--mat-sys-on-secondary-container);
}
#{ms.$mat-chip} {
@@ -58,13 +36,14 @@ $panel-properties-height: 56px !default;
.mat-mdc-chip-action-label {
overflow: hidden;
}
/* stylelint-enable selector-class-pattern */
}
}
.adf-metadata-no-item-added {
word-break: break-all;
font-size: 15px;
font: var(--mat-sys-body-small);
padding: 0 0 0 12px;
}
@@ -78,23 +57,5 @@ $panel-properties-height: 56px !default;
&-metadata-action-buttons {
display: flex;
justify-content: space-evenly;
&-clear {
color: var(--adf-metadata-action-button-clear-color);
}
}
&-metadata-categories-header {
.adf-categories-button {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 15px;
height: $panel-properties-height;
[hidden] {
visibility: hidden;
}
}
}
}
@@ -208,7 +208,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
this.loadProperties(this.node);
this.verifyAllowableOperations();
this.currentPanel.panelTitle = this.displayAspect ?? this.DefaultPanels.PROPERTIES;
this.currentPanel.panelTitle = this.displayAspect && this.displayAspect !== '' ? this.displayAspect : this.DefaultPanels.PROPERTIES;
this.currentPanel.expanded = true;
}
@@ -277,7 +277,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
this.loadProperties(this.node);
}
if (changes.displayAspect?.currentValue) {
if (changes.displayAspect?.currentValue && changes.displayAspect.currentValue !== '') {
this.currentPanel.panelTitle = changes.displayAspect.currentValue;
this.currentPanel.expanded = true;
}
@@ -367,6 +367,33 @@ describe('PropertyGroupTranslatorService', () => {
expect(cardViewProperty.value).toBe('two');
});
it('should translate property for type LIST constraint with multivalued property', () => {
const definition: Definition = {
properties: [
{
id: 'FAS:PLAGUE',
constraints: [
{
type: 'LIST',
parameters: {
allowedValues: ['one', 'two', 'three']
}
}
]
} as Constraint
]
};
property.dataType = 'd:text';
property.multiValued = true;
propertyValues = { 'FAS:PLAGUE': ['one', 'three'] };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, definition);
const cardViewProperty = cardViewGroup[0].properties[0] as CardViewSelectItemModel<string>;
expect(cardViewProperty instanceof CardViewSelectItemModel).toBeTruthy();
expect(cardViewProperty.multivalued).toBe(true);
expect(cardViewProperty.value).toEqual(['one', 'three']);
});
it('should translate content type properties into card items', () => {
const propertyBase = {
id: 'fk:brendonstare',
@@ -120,7 +120,7 @@ export class PropertyGroupTranslatorService {
if (this.isListOfValues(propertyDefinition.constraints)) {
const options = propertyDefinition.constraints[0].parameters.allowedValues.map((value) => ({ key: value, label: value }));
const properties = Object.assign(propertyDefinition, { options$: of(options) });
const properties = Object.assign(propertyDefinition, { options$: of(options), multivalued: isMultiValued });
cardViewItemProperty = new CardViewSelectItemModel(properties);
} else {
@@ -206,5 +206,9 @@ describe('ContentNodeDialogService', () => {
expect(testContentNodeSelectorComponentData.isSelectionValid(testData.node)).toBe(testData.expected);
});
});
it('should scope the search to folders by disabling files in the result', () => {
expect(testContentNodeSelectorComponentData.showFilesInResult).toBe(false);
});
});
});
@@ -154,7 +154,8 @@ export class ContentNodeDialogService {
where: '(isFolder=true)',
isSelectionValid: this.isCopyMoveSelectionValid.bind(this),
excludeSiteContent: excludeSiteContent || ContentNodeDialogService.nonDocumentSiteContent,
select
select,
showFilesInResult: false
};
const dialogRef = this.openContentNodeDialog(data, 'adf-content-node-selector-dialog', '630px');
@@ -196,7 +197,8 @@ export class ContentNodeDialogService {
imageResolver: this.imageResolver.bind(this),
isSelectionValid: this.hasAllowableOperationsOnNodeFolder.bind(this),
where: '(isFolder=true)',
select
select,
showFilesInResult: false
};
const dialogRef = this.openContentNodeDialog(data, 'adf-content-node-selector-dialog', '630px');
@@ -19,14 +19,13 @@ import { DebugElement } from '@angular/core';
import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Node, NodeEntry, NodePaging, RequestScope, ResultSetPaging, SiteEntry, SitePaging, SitePagingList } from '@alfresco/js-api';
import { of } from 'rxjs';
import { of, Subject } from 'rxjs';
import { ContentNodeSelectorPanelComponent } from './content-node-selector-panel.component';
import { DocumentListService } from '../../document-list/services/document-list.service';
import { DocumentListComponent } from '../../document-list/components/document-list.component';
import { CustomResourcesService } from '../../document-list/services/custom-resources.service';
import { NodeEntryEvent, ShareDataRow } from '../../document-list';
import { SearchQueryBuilderService } from '../../search';
import { mockSearchRequest } from '../../mock/search-query.mock';
import { SitesService } from '../../common/services/sites.service';
import { NodesApiService } from '../../common/services/nodes-api.service';
import { UnitTestingUtils } from '../../../../../core/src/lib/testing/unit-testing-utils';
@@ -161,43 +160,70 @@ describe('ContentNodeSelectorPanelComponent', () => {
});
it('should the user query get updated when the user types in the search input', fakeAsync(() => {
const updateSpy = spyOn(searchQueryBuilderService, 'update');
typeToSearchBox('search-term');
tick(debounceSearch);
fixture.detectChanges();
expect(updateSpy).toHaveBeenCalled();
expect(searchSpy).toHaveBeenCalled();
expect(searchQueryBuilderService.userQuery).toEqual('(search-term*)');
expect(component.searchTerm).toEqual('search-term');
}));
it('should set the query builder search mode to formula when the user types in the search input', fakeAsync(() => {
typeToSearchBox('search-term');
tick(debounceSearch);
fixture.detectChanges();
expect(searchQueryBuilderService.searchMode).toEqual('formula');
}));
it('should add the wildcard suffix to the user query when wildcards are enabled', fakeAsync(() => {
spyOnProperty(searchQueryBuilderService, 'wildcardsEnabled', 'get').and.returnValue(true);
typeToSearchBox('search-term');
tick(debounceSearch);
fixture.detectChanges();
expect(searchQueryBuilderService.userQuery).toEqual('(search-term*)');
}));
it('should NOT add the wildcard suffix to the user query when wildcards are disabled', fakeAsync(() => {
spyOnProperty(searchQueryBuilderService, 'wildcardsEnabled', 'get').and.returnValue(false);
typeToSearchBox('search-term');
tick(debounceSearch);
fixture.detectChanges();
expect(searchQueryBuilderService.userQuery).toEqual('(search-term)');
}));
it('should perform a search when the search request gets updated and it is defined', fakeAsync(() => {
typeToSearchBox('search-term');
tick(debounceSearch);
fixture.detectChanges();
expect(searchSpy).toHaveBeenCalledWith(false, mockSearchRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
}));
it('should NOT perform a search and clear the results when the search request gets updated and it is NOT defined', async () => {
it('should NOT perform a search and clear the results when the search input is empty', fakeAsync(() => {
spyOn(component, 'clearSearch');
searchQueryBuilderService.userQuery = '';
searchQueryBuilderService.update();
typeToSearchBox('');
tick(debounceSearch);
fixture.detectChanges();
await fixture.whenStable();
expect(searchSpy).not.toHaveBeenCalled();
expect(component.clearSearch).toHaveBeenCalled();
});
}));
it('should reset the search term when clicking the clear icon', async () => {
component.searchTerm = 'search-term';
searchQueryBuilderService.userQuery = 'search-term';
spyOn(component, 'clearSearch');
spyOn(component, 'clear').and.callThrough();
fixture.detectChanges();
const clearIcon = getSearchIcon('clear');
@@ -207,7 +233,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(searchQueryBuilderService.userQuery).toEqual('');
expect(component.searchTerm).toEqual('');
expect(component.clearSearch).toHaveBeenCalled();
expect(component.clear).toHaveBeenCalled();
});
it('should load the results by calling the search api on search change', fakeAsync(() => {
@@ -216,22 +242,21 @@ describe('ContentNodeSelectorPanelComponent', () => {
tick(debounceSearch);
fixture.detectChanges();
expect(searchSpy).toHaveBeenCalledWith(false, mockSearchRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
}));
it('should the query include the show files filterQuery', fakeAsync(() => {
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
component.showFilesInResult = true;
typeToSearchBox('search-term');
const expectedRequest = mockSearchRequest;
expectedRequest.filterQueries.push({
query: `TYPE:'cm:folder' OR TYPE:'cm:content'`
});
const expectedRequest = `TYPE:'cm:folder' OR TYPE:'cm:content'`;
tick(debounceSearch);
fixture.detectChanges();
expect(searchSpy).toHaveBeenCalledWith(false, expectedRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(expectedRequest);
}));
it('should reset the currently chosen node in case of starting a new search', fakeAsync(() => {
@@ -253,6 +278,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
});
it('should perform a search when selecting a site with the correct query', fakeAsync(() => {
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
typeToSearchBox('search-term');
tick(debounceSearch);
@@ -261,14 +287,41 @@ describe('ContentNodeSelectorPanelComponent', () => {
component.siteChanged({ entry: { guid: 'namek' } } as SiteEntry);
const expectedRequest = mockSearchRequest;
expectedRequest.filterQueries = [{ query: `ANCESTOR:'workspace://SpacesStore/namek'` }];
const expectedRequest = `ANCESTOR:'workspace://SpacesStore/namek'`;
expect(searchSpy.calls.count()).toBe(2);
expect(searchSpy).toHaveBeenCalledWith(false, expectedRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(expectedRequest);
}));
it('should remove the previous site filter query when changing the selected site', fakeAsync(() => {
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
spyOn(searchQueryBuilderService, 'removeFilterQuery').and.callThrough();
typeToSearchBox('search-term');
tick(debounceSearch);
component.siteChanged({ entry: { guid: 'namek' } } as SiteEntry);
component.siteChanged({ entry: { guid: 'vegeta' } } as SiteEntry);
expect(searchQueryBuilderService.removeFilterQuery).toHaveBeenCalledWith(`ANCESTOR:'workspace://SpacesStore/namek'`);
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(`ANCESTOR:'workspace://SpacesStore/vegeta'`);
expect(searchQueryBuilderService.filterQueries).toEqual([{ query: `ANCESTOR:'workspace://SpacesStore/vegeta'` }]);
}));
it('should browse the selected site folder without searching when no search term is present', fakeAsync(() => {
expect(searchSpy.calls.count()).toBe(0);
component.siteChanged({ entry: { guid: 'namek' } } as SiteEntry);
tick(debounceSearch);
expect(searchSpy).not.toHaveBeenCalled();
expect(component.searchTerm).toBe('');
expect(component.folderIdToShow).toBe('namek');
expect(component.showingSearchResults).toBe(false);
}));
it('should create the query with the right parameters on changing the site selectBox value from a custom dropdown menu', fakeAsync(() => {
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
component.dropdownSiteList = { list: { entries: [{ entry: { guid: '-sites-' } }, { entry: { guid: 'namek' } }] } } as SitePaging;
component.documentList.folderNode = { id: 'fakeNodeId', isFolder: true, path: {} } as Node;
fixture.detectChanges();
@@ -281,17 +334,12 @@ describe('ContentNodeSelectorPanelComponent', () => {
component.siteChanged({ entry: { guid: '-sites-' } } as SiteEntry);
const expectedRequest = mockSearchRequest;
expectedRequest.filterQueries = [
{
query: `ANCESTOR:'workspace://SpacesStore/-sites-' OR ANCESTOR:'workspace://SpacesStore/123456testId' OR ANCESTOR:'workspace://SpacesStore/09876543testId'`
}
];
const expectedRequest = `ANCESTOR:'workspace://SpacesStore/-sites-' OR ANCESTOR:'workspace://SpacesStore/123456testId' OR ANCESTOR:'workspace://SpacesStore/09876543testId'`;
expect(searchSpy).toHaveBeenCalled();
expect(searchSpy.calls.count()).toBe(2);
expect(searchSpy).toHaveBeenCalledWith(false, mockSearchRequest);
expect(searchSpy).toHaveBeenCalledWith(false, expectedRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(expectedRequest);
}));
it('should get the corresponding node ids on search when a known alias is selected from dropdown', fakeAsync(() => {
@@ -321,6 +369,29 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(getCorrespondingNodeIdsSpy.calls.mostRecent().args[0]).toEqual('-sites-');
}));
it('should execute the search only after the corresponding node ids filter query is applied for aliases', fakeAsync(() => {
component.documentList.folderNode = { id: 'fakeNodeId', isFolder: true, path: {} } as Node;
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
const nodeIds$ = new Subject<string[]>();
getCorrespondingNodeIdsSpy.and.returnValue(nodeIds$.asObservable());
typeToSearchBox('vegeta');
tick(debounceSearch);
searchSpy.calls.reset();
component.siteChanged({ entry: { guid: '-sites-' } } as SiteEntry);
expect(searchSpy).not.toHaveBeenCalled();
nodeIds$.next(['123456testId']);
nodeIds$.complete();
const expectedRequest = `ANCESTOR:'workspace://SpacesStore/-sites-' OR ANCESTOR:'workspace://SpacesStore/123456testId'`;
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(expectedRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
}));
it('should NOT get the corresponding node ids on search when NOTHING is selected from dropdown', fakeAsync(() => {
component.dropdownSiteList = { list: { entries: [{ entry: { guid: '-sites-' } }, { entry: { guid: 'namek' } }] } } as SitePaging;
fixture.detectChanges();
@@ -395,7 +466,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(component.clear).toHaveBeenCalled();
}));
it('should clear the search field, nodes and chosenNode when clicking on the X (clear) icon', async () => {
it('should reset the search term and user query when clearing the search', async () => {
component.chosenNode = [entry];
component.nodePaging = {
@@ -404,32 +475,31 @@ describe('ContentNodeSelectorPanelComponent', () => {
}
};
component.searchTerm = 'piccolo';
searchQueryBuilderService.userQuery = 'piccolo';
component.showingSearchResults = true;
component.clear();
expect(component.searchTerm).toBe('');
expect(component.nodePaging).toEqual(null);
expect(component.chosenNode).toBeNull();
expect(component.showingSearchResults).toBeFalsy();
expect(searchQueryBuilderService.userQuery).toBe('');
expect(searchSpy).toHaveBeenCalledWith(false);
});
it('should the query restrict the search to the currentFolderId in case is defined', fakeAsync(() => {
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
component.currentFolderId = 'my-root-id';
component.restrictRootToCurrentFolderId = true;
component.ngOnInit();
typeToSearchBox('search-term');
tick(debounceSearch);
const expectedRequest = mockSearchRequest;
expectedRequest.filterQueries = [{ query: `ANCESTOR:'workspace://SpacesStore/my-root-id'` }];
const expectedRequest = `ANCESTOR:'workspace://SpacesStore/my-root-id'`;
expect(searchSpy).toHaveBeenCalledWith(false, expectedRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(expectedRequest);
}));
it('should emit showingSearch event with true while searching', async () => {
searchQueryBuilderService.userQuery = 'mock-search-term';
searchQueryBuilderService.update();
spyOn(customResourcesService, 'hasCorrespondingNodeIds').and.returnValue(true);
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
@@ -454,8 +524,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(showingSearchSpy).toHaveBeenCalledWith(false);
}));
it('should emit showingResults event with false when clicking on the X (clear) icon', async () => {
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
it('should re-run the query with an empty user query when clicking on the X (clear) icon', async () => {
component.chosenNode = [entry];
component.nodePaging = {
@@ -464,17 +533,16 @@ describe('ContentNodeSelectorPanelComponent', () => {
}
};
component.searchTerm = 'piccolo';
component.showingSearchResults = true;
searchQueryBuilderService.userQuery = 'piccolo';
component.clear();
expect(component.showingSearchResults).toBe(false);
expect(showingSearchSpy).toHaveBeenCalledWith(false);
expect(component.searchTerm).toBe('');
expect(searchQueryBuilderService.userQuery).toBe('');
expect(searchSpy).toHaveBeenCalledWith(false);
});
it('should emit showingResults event with false if search api fails', async () => {
searchQueryBuilderService.userQuery = 'mock-search-term';
searchQueryBuilderService.update();
getCorrespondingNodeIdsSpy.and.throwError('Failed');
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
await searchQueryBuilderService.execute(true, { query: { query: 'search' } });
@@ -488,15 +556,17 @@ describe('ContentNodeSelectorPanelComponent', () => {
});
it('should the query restrict the search to the site and not to the currentFolderId in case is changed', async () => {
spyOn(searchQueryBuilderService, 'addFilterQuery').and.callThrough();
component.searchTerm = 'search-term';
searchQueryBuilderService.userQuery = 'search-term*';
component.currentFolderId = 'my-root-id';
component.restrictRootToCurrentFolderId = true;
component.siteChanged({ entry: { guid: 'my-site-id' } } as SiteEntry);
const expectedRequest = mockSearchRequest;
expectedRequest.filterQueries = [{ query: `ANCESTOR:'workspace://SpacesStore/my-site-id'` }];
const expectedRequest = `ANCESTOR:'workspace://SpacesStore/my-site-id'`;
expect(searchSpy).toHaveBeenCalledWith(false, expectedRequest);
expect(searchSpy).toHaveBeenCalledWith(false);
expect(searchQueryBuilderService.addFilterQuery).toHaveBeenCalledWith(expectedRequest);
});
it('should restrict the breadcrumb to the currentFolderId in case restrictedRoot is true', async () => {
@@ -563,10 +633,12 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(searchSpy.calls.count()).toBe(2);
component.clear();
typeToSearchBox('');
tick(debounceSearch);
expect(component.searchTerm).toBe('');
expect(component.folderIdToShow).toBe('namek');
flush();
}));
it('should show the current folder content instead of search results if search was not performed', async () => {
@@ -638,25 +710,23 @@ describe('ContentNodeSelectorPanelComponent', () => {
fixture.detectChanges();
const documentList = testingUtils.getByCSS('[data-automation-id="content-node-selector-document-list"]');
expect(documentList).not.toBeNull();
expect(component.hasValidQuery).toEqual(true);
expect(documentList.componentInstance.currentFolderId).toBeNull();
done();
}, 300);
});
it('should not show the result list when results are returned but there is no search term typed', (done) => {
searchQueryBuilderService.userQuery = '';
searchQueryBuilderService.update();
it('should not run a search nor show the result list when there is no search term typed', fakeAsync(() => {
spyOn(component, 'clearSearch').and.callThrough();
setTimeout(() => {
triggerSearchResults(fakeResultSetPaging);
fixture.detectChanges();
typeToSearchBox('');
tick(debounceSearch);
fixture.detectChanges();
expect(component.hasValidQuery).toEqual(false);
expect(component.showingSearchResults).toEqual(false);
done();
}, 300);
});
expect(searchSpy).not.toHaveBeenCalled();
expect(component.clearSearch).toHaveBeenCalled();
expect(component.showingSearchResults).toEqual(false);
flush();
}));
it('should highlight the results when search was performed in the next timeframe', (done) => {
typeToSearchBox('My');
@@ -673,7 +743,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
}, 300);
});
it('should show the default text instead of result list if search was cleared', (done) => {
it('should reset the search term and re-run an empty query when the clear button is clicked', (done) => {
typeToSearchBox();
setTimeout(() => {
@@ -683,12 +753,13 @@ describe('ContentNodeSelectorPanelComponent', () => {
fixture.whenStable().then(() => {
const clearButton = getSearchIcon('clear');
expect(clearButton).not.toBeNull();
searchSpy.calls.reset();
clearButton.triggerEventHandler('click', {});
fixture.detectChanges();
const documentList = testingUtils.getByCSS('[data-automation-id="content-node-selector-document-list"]');
expect(documentList).not.toBeNull();
expect(documentList.componentInstance.currentFolderId).toBe('cat-girl-nuku-nuku');
expect(component.searchTerm).toBe('');
expect(searchQueryBuilderService.userQuery).toBe('');
expect(searchSpy).toHaveBeenCalledWith(false);
done();
});
}, 300);
@@ -709,20 +780,20 @@ describe('ContentNodeSelectorPanelComponent', () => {
flush();
}));
it('should set the folderIdToShow to the default "currentFolderId" if siteId is undefined', (done) => {
it('should reset the folder to the selected site and fall back to currentFolderId when site is undefined', () => {
component.siteChanged({ entry: { guid: 'Kame-Sennin Muten Roshi' } } as SiteEntry);
component.resetFolderToShow();
fixture.detectChanges();
let documentList = testingUtils.getByCSS('[data-automation-id="content-node-selector-document-list"]');
expect(documentList.componentInstance.currentFolderId).toBe('Kame-Sennin Muten Roshi');
component.siteChanged({ entry: { guid: undefined } } as SiteEntry);
component.resetFolderToShow();
fixture.detectChanges();
documentList = testingUtils.getByCSS('[data-automation-id="content-node-selector-document-list"]');
expect(documentList.componentInstance.currentFolderId).toBe('cat-girl-nuku-nuku');
done();
});
describe('Pagination "Load more" button', () => {
@@ -752,7 +823,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
});
it('should set its loading state to true to perform a new search', async () => {
component.prepareDialogForNewSearch(mockSearchRequest);
component.prepareDialogForNewSearch();
fixture.detectChanges();
await fixture.whenStable();
@@ -764,13 +835,14 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(paginationLoading).not.toBeNull();
});
it('Should infinite pagination target be null when we use it for search ', fakeAsync(() => {
it('Should keep the document list as infinite pagination target while searching', fakeAsync(() => {
component.showingSearchResults = true;
typeToSearchBox('shenron');
tick(debounceSearch);
fixture.detectChanges();
expect(component.target).toBeNull();
expect(component.target).toEqual(component.documentList);
flush();
}));
it('Should infinite pagination target be present when search finish', () => {
@@ -1,31 +1,17 @@
@use '../../mat-selectors.scss' as ms;
/* stylelint-disable no-descending-specificity */
$content-node-selector-thumbnail-width: 35px !default;
$content-node-selector-thumbnail-max-width: 40px !default;
h2.adf-search-results-label {
flex: 1;
font-weight: 600;
font-size: var(--theme-body-1-font-size);
font-style: normal;
font-stretch: normal;
line-height: 1.43;
letter-spacing: -0.2px;
color: var(--adf-theme-foreground-text-color-087);
}
#{ms.$mdc-dialog} {
#{ms.$mat-dialog-surface}:is(div) {
padding-bottom: 0;
}
font: var(--mat-sys-body-medium);
}
.adf-content-node-selector-panel {
.adf-toolbar .adf-toolbar-container.adf-toolbar-container-row {
max-height: 48px;
border-bottom-width: 0;
font-size: var(--theme-body-1-font-size);
font-size: var(--mat-sys-body-medium-size);
height: auto;
}
}
@@ -46,14 +32,14 @@ h2.adf-search-results-label {
width: 100%;
margin-bottom: 15px;
.adf-content-node-selector-content-input-icon {
color: var(--adf-theme-foreground-icon-color-054);
.adf-content-node-selector-content-input-icon:is(mat-icon) {
color: var(--mat-sys-on-secondary-container);
}
.adf-content-node-selector-search-clear-button {
.adf-content-node-selector-content-input-icon {
&:hover {
color: var(--adf-theme-foreground-base-color);
color: var(--mat-sys-on-surface);
}
}
}
@@ -74,20 +60,16 @@ h2.adf-search-results-label {
outline: none;
.adf-dropdown-breadcrumb-icon {
color: var(--adf-theme-foreground-base-color-045);
&:hover {
color: var(--adf-theme-foreground-base-color-065);
}
color: var(--mat-sys-on-secondary-container);
}
&:focus .adf-dropdown-breadcrumb-icon {
color: var(--theme-primary-color);
color: var(--mat-sys-primary);
}
}
.adf-dropdown-breadcrumb-item-chevron {
color: var(--adf-theme-foreground-base-color-045);
color: var(--mat-sys-on-secondary-container);
}
}
@@ -95,7 +77,7 @@ h2.adf-search-results-label {
&-list {
height: 40vh;
overflow: auto;
border: 1px solid var(--adf-theme-foreground-text-color-007);
border: 1px solid var(--mat-sys-outline-variant);
border-top: 0;
position: relative;
@@ -106,7 +88,7 @@ h2.adf-search-results-label {
}
.adf-highlight {
color: var(--theme-primary-color);
color: var(--mat-sys-primary);
}
.adf-datatable-list {
@@ -122,7 +104,7 @@ h2.adf-search-results-label {
}
.adf-datatable-selected > svg {
fill: var(--theme-primary-color);
fill: var(--mat-sys-primary);
}
.adf-no-content-container.adf-datatable-cell {
@@ -270,7 +270,6 @@ describe('ContentNodeSelectorPanelComponent', () => {
it('should not show the breadcrumb if search was performed as last action', async () => {
searchQueryBuilderService.userQuery = 'mock-search-term';
searchQueryBuilderService.update();
triggerSearchResults(fakeResultSetPaging);
fixture.detectChanges();
@@ -291,7 +290,6 @@ describe('ContentNodeSelectorPanelComponent', () => {
it('should show the breadcrumb in search results for a valid node selection', async () => {
searchQueryBuilderService.userQuery = 'mock-search-term';
searchQueryBuilderService.update();
triggerSearchResults(fakeResultSetPaging);
const chosenNode = new Node({ path: { elements: [{ name: 'one' }] } });
@@ -306,7 +304,6 @@ describe('ContentNodeSelectorPanelComponent', () => {
it('should show the breadcrumb in search results even for an invalid node selection', async () => {
component.isSelectionValid = (node: Node) => node.isFile;
searchQueryBuilderService.userQuery = 'mock-search-term';
searchQueryBuilderService.update();
triggerSearchResults(fakeResultSetPaging);
const chosenNode = new Node({ path: { elements: [{ name: 'fake-path' }] }, isFile: false, isFolder: true });

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