From 08f2c1f4789cc06123c602eb6ae081e7ff4ce7cb Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Tue, 21 Apr 2026 10:38:28 +0200 Subject: [PATCH 1/6] Initial commit From 02e426d8cb0daf0a923446dfc4b3657ab5d53a29 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Tue, 21 Apr 2026 11:27:06 +0200 Subject: [PATCH 2/6] UoE/fix: resolve lint duplicates, missing HALLink in thumbnail spec, and Store provider in file-download-link spec Also sorts imports via eslint --fix and adds a short PR7 fix README. --- PR7-FIX-README.md | 95 +++++++++++++++++++ .../core/data/access-status-data.service.ts | 2 +- src/app/core/shared/bitstream.model.ts | 4 +- .../file-download-link.component.spec.ts | 3 +- .../access-status-badge.component.ts | 2 +- src/app/thumbnail/thumbnail.component.spec.ts | 2 + .../file-download-link.component.ts | 2 +- .../file-section/file-section.component.ts | 14 +-- .../file-download-link.component.ts | 2 +- 9 files changed, 107 insertions(+), 19 deletions(-) create mode 100644 PR7-FIX-README.md diff --git a/PR7-FIX-README.md b/PR7-FIX-README.md new file mode 100644 index 00000000000..8c8e4015b6d --- /dev/null +++ b/PR7-FIX-README.md @@ -0,0 +1,95 @@ +# PR #7 – GitHub Actions fix summary + +This document summarizes the changes made to get the failing GitHub Actions +build green for PR [#7](https://github.com/dataquest-dev/uoe-dspace-datashare-angular/pull/7) +(branch `uoe-fix-github-actions-it-2`). + +## Initial state + +The `Build` workflow (`.github/workflows/build.yml`) was failing on the +`tests (18.x)` matrix job. The `tests (20.x)` job was skipped (fail-fast on +the earlier job). The workflow runs the following steps in order: + +1. `yarn install --frozen-lockfile` +2. `yarn build:lint` +3. `yarn test:lint:nobuild` +4. `yarn lint:nobuild --quiet` ← **failing here** +5. `yarn check-circ-deps` +6. `yarn build:prod` +7. `yarn test:headless` (unit tests) +8. e2e / SSR tests + +Reproducing locally showed the build stopped at step 4 and, after that was +fixed, at step 7 (unit tests). + +## Root causes + +### 1. Lint (step 4) – 41 errors + +Most errors came from a single file, +`src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts`, +which contained a duplicated block of imports appended after a previous +import group. This caused cascading errors: + +- `import/no-duplicates` +- `no-redeclare` (names imported twice) +- `import-newlines/enforce` +- `unused-imports/no-unused-imports` (an obsolete `followLink` import) + +A handful of other files only failed `simple-import-sort/imports`, fixable +by ESLint itself. + +### 2. Unit tests (step 7) – 7 failing specs + +- `src/app/thumbnail/thumbnail.component.spec.ts`: the `Bitstream._links` + type was extended with a required `accessStatus: HALLink` field (see + `src/app/core/shared/bitstream.model.ts`), but the two `_links` fixtures + in this spec weren’t updated, failing TypeScript compilation + (`TS2741: Property 'accessStatus' is missing`). Karma then reported + "Found 1 load error" and all 5364 tests were blocked. +- `src/app/shared/file-download-link/file-download-link.component.spec.ts`: + after adding `ThemedAccessStatusBadgeComponent` to the standalone + component’s `imports`, instantiating the component inside tests pulled + in `ThemeService`, which requires `Store` (NgRx). The test bed did not + provide one, producing + `NullInjectorError: No provider for Store!` on six tests. + +## Fixes applied + +- Removed the duplicated import block (and unused `followLink`) in + `src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts`. +- Ran `yarn lint:nobuild --fix` to resolve the remaining + `simple-import-sort/imports` issues across: + - `src/app/core/data/access-status-data.service.ts` + - `src/app/core/shared/bitstream.model.ts` + - `src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts` + - `src/themes/custom/app/shared/file-download-link/file-download-link.component.ts` + - `src/themes/datashare/app/shared/file-download-link/file-download-link.component.ts` +- Added the missing `accessStatus: { href: 'accessStatus.url' }` entry to + both `_links` fixtures in `src/app/thumbnail/thumbnail.component.spec.ts`. +- Extended the existing `overrideComponent(... remove: { imports: [...] })` + in `src/app/shared/file-download-link/file-download-link.component.spec.ts` + to also remove `ThemedAccessStatusBadgeComponent`, removing the + `ThemeService → Store` dependency from the test component and restoring + the original test isolation pattern used for `RouterLink`. + +## Local verification + +- `yarn lint:nobuild --quiet` → `All files pass linting.` +- `yarn test:lint:nobuild` → `97 specs, 0 failures`. +- `yarn build:prod` → succeeds (only tsconfig "unused file" warnings, same as + on the base branch). +- `yarn test:headless` → `5364 SUCCESS, 2 skipped`. + +`yarn check-circ-deps` only fails locally on Windows PowerShell because of +the single-quote pattern in `package.json`; on the Linux CI runners it +executes normally. + +The e2e Cypress tests (step 8) were not previously reached in CI and depend +on a full DSpace REST backend started via docker-compose; they were not +changed by this PR. + +## Commit + +All changes were committed to the PR branch `uoe-fix-github-actions-it-2` +only, as requested. diff --git a/src/app/core/data/access-status-data.service.ts b/src/app/core/data/access-status-data.service.ts index d6361dd3516..1563e10e97c 100644 --- a/src/app/core/data/access-status-data.service.ts +++ b/src/app/core/data/access-status-data.service.ts @@ -4,8 +4,8 @@ import { AccessStatusObject } from 'src/app/shared/object-collection/shared/badg import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Bitstream } from '../shared/bitstream.model'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Item } from '../shared/item.model'; import { BaseDataService } from './base/base-data.service'; import { RemoteData } from './remote-data'; diff --git a/src/app/core/shared/bitstream.model.ts b/src/app/core/shared/bitstream.model.ts index 506212b0f97..7bc6ef964b7 100644 --- a/src/app/core/shared/bitstream.model.ts +++ b/src/app/core/shared/bitstream.model.ts @@ -5,13 +5,13 @@ import { } from 'cerialize'; import { Observable } from 'rxjs'; +import { AccessStatusObject } from '../../shared/object-collection/shared/badges/access-status-badge/access-status.model'; +import { ACCESS_STATUS } from '../../shared/object-collection/shared/badges/access-status-badge/access-status.resource-type'; import { link, typedObject, } from '../cache/builders/build-decorators'; import { RemoteData } from '../data/remote-data'; -import { AccessStatusObject } from '../../shared/object-collection/shared/badges/access-status-badge/access-status.model'; -import { ACCESS_STATUS } from '../../shared/object-collection/shared/badges/access-status-badge/access-status.resource-type'; import { BITSTREAM } from './bitstream.resource-type'; import { BitstreamFormat } from './bitstream-format.model'; import { BITSTREAM_FORMAT } from './bitstream-format.resource-type'; diff --git a/src/app/shared/file-download-link/file-download-link.component.spec.ts b/src/app/shared/file-download-link/file-download-link.component.spec.ts index d14ab8ac0d1..5aff0118c55 100644 --- a/src/app/shared/file-download-link/file-download-link.component.spec.ts +++ b/src/app/shared/file-download-link/file-download-link.component.spec.ts @@ -21,6 +21,7 @@ import { Bitstream } from '../../core/shared/bitstream.model'; import { Item } from '../../core/shared/item.model'; import { URLCombiner } from '../../core/url-combiner/url-combiner'; import { getItemModuleRoute } from '../../item-page/item-page-routing-paths'; +import { ThemedAccessStatusBadgeComponent } from '../object-collection/shared/badges/access-status-badge/themed-access-status-badge.component'; import { ActivatedRouteStub } from '../testing/active-router.stub'; import { RouterLinkDirectiveStub } from '../testing/router-link-directive.stub'; import { FileDownloadLinkComponent } from './file-download-link.component'; @@ -66,7 +67,7 @@ describe('FileDownloadLinkComponent', () => { ], }) .overrideComponent(FileDownloadLinkComponent, { - remove: { imports: [RouterLink] }, + remove: { imports: [RouterLink, ThemedAccessStatusBadgeComponent] }, add: { imports: [RouterLinkDirectiveStub] }, }) .compileComponents(); diff --git a/src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts b/src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts index 7ca5800a803..4c53f3598de 100644 --- a/src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts +++ b/src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts @@ -21,8 +21,8 @@ import { LinkService } from '../../../../../core/cache/builders/link.service'; import { Bitstream } from '../../../../../core/shared/bitstream.model'; import { Item } from '../../../../../core/shared/item.model'; import { getFirstSucceededRemoteDataPayload } from '../../../../../core/shared/operators'; -import { followLink } from '../../../../utils/follow-link-config.model'; import { hasValue } from '../../../../empty.util'; +import { followLink } from '../../../../utils/follow-link-config.model'; import { AccessStatusObject } from './access-status.model'; @Component({ diff --git a/src/app/thumbnail/thumbnail.component.spec.ts b/src/app/thumbnail/thumbnail.component.spec.ts index 38eceb84276..3698a103efb 100644 --- a/src/app/thumbnail/thumbnail.component.spec.ts +++ b/src/app/thumbnail/thumbnail.component.spec.ts @@ -288,6 +288,7 @@ describe('ThumbnailComponent', () => { format: { href: 'format.url' }, content: { href: CONTENT }, thumbnail: undefined, + accessStatus: { href: 'accessStatus.url' }, }; comp.thumbnail = thumbnail; }); @@ -324,6 +325,7 @@ describe('ThumbnailComponent', () => { format: { href: 'format.url' }, content: { href: CONTENT }, thumbnail: undefined, + accessStatus: { href: 'accessStatus.url' }, }; }); diff --git a/src/themes/custom/app/shared/file-download-link/file-download-link.component.ts b/src/themes/custom/app/shared/file-download-link/file-download-link.component.ts index 8bf76056d5e..2f5a887d60e 100644 --- a/src/themes/custom/app/shared/file-download-link/file-download-link.component.ts +++ b/src/themes/custom/app/shared/file-download-link/file-download-link.component.ts @@ -8,8 +8,8 @@ import { Component } from '@angular/core'; import { RouterLink } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; -import { ThemedAccessStatusBadgeComponent } from '../../../../../app/shared/object-collection/shared/badges/access-status-badge/themed-access-status-badge.component'; import { FileDownloadLinkComponent as BaseComponent } from '../../../../../app/shared/file-download-link/file-download-link.component'; +import { ThemedAccessStatusBadgeComponent } from '../../../../../app/shared/object-collection/shared/badges/access-status-badge/themed-access-status-badge.component'; @Component({ selector: 'ds-themed-file-download-link', diff --git a/src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts b/src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts index 895dfc9107c..e9d32d5d139 100644 --- a/src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts +++ b/src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts @@ -18,11 +18,13 @@ import { } from 'rxjs'; import { DSONameService } from '../../../../../../../app/core/breadcrumbs/dso-name.service'; +import { AccessStatusDataService } from '../../../../../../../app/core/data/access-status-data.service'; import { BitstreamDataService } from '../../../../../../../app/core/data/bitstream-data.service'; import { PaginatedList } from '../../../../../../../app/core/data/paginated-list.model'; import { RemoteData } from '../../../../../../../app/core/data/remote-data'; import { PaginationService } from '../../../../../../../app/core/pagination/pagination.service'; import { Bitstream } from '../../../../../../../app/core/shared/bitstream.model'; +import { getFirstCompletedRemoteData } from '../../../../../../../app/core/shared/operators'; import { DownloadLinkService } from '../../../../../../../app/datashare/download-link.service'; import { FileSectionComponent as BaseComponent } from '../../../../../../../app/item-page/simple/field-components/file-section/file-section.component'; import { GenericItemPageFieldComponent } from '../../../../../../../app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component'; @@ -34,18 +36,6 @@ import { import { ThemedFileDownloadLinkComponent } from '../../../../../../../app/shared/file-download-link/themed-file-download-link.component'; import { ThemedLoadingComponent } from '../../../../../../../app/shared/loading/themed-loading.component'; import { MetadataFieldWrapperComponent } from '../../../../../../../app/shared/metadata-field-wrapper/metadata-field-wrapper.component'; -import { FileSizePipe } from '../../../../../../../app/shared/utils/file-size-pipe'; -import { VarDirective } from '../../../../../../../app/shared/utils/var.directive'; -import { getFirstCompletedRemoteData } from '../../../../../../../app/core/shared/operators'; -import { filter, map, Observable, switchMap, tap } from 'rxjs'; -import { RemoteData } from '../../../../../../../app/core/data/remote-data'; -import { PaginatedList } from '../../../../../../../app/core/data/paginated-list.model'; -import { Bitstream } from '../../../../../../../app/core/shared/bitstream.model'; -import { hasValue, isEmpty } from '../../../../../../../app/shared/empty.util'; -import { PaginationComponentOptions } from '../../../../../../../app/shared/pagination/pagination-component-options.model'; -import { followLink } from '../../../../../../../app/shared/utils/follow-link-config.model'; -import { BitstreamDataService } from '../../../../../../../app/core/data/bitstream-data.service'; -import { AccessStatusDataService } from '../../../../../../../app/core/data/access-status-data.service'; import { NotificationsService } from '../../../../../../../app/shared/notifications/notifications.service'; import { PaginationComponent } from '../../../../../../../app/shared/pagination/pagination.component'; import { PaginationComponentOptions } from '../../../../../../../app/shared/pagination/pagination-component-options.model'; diff --git a/src/themes/datashare/app/shared/file-download-link/file-download-link.component.ts b/src/themes/datashare/app/shared/file-download-link/file-download-link.component.ts index 8bf76056d5e..2f5a887d60e 100644 --- a/src/themes/datashare/app/shared/file-download-link/file-download-link.component.ts +++ b/src/themes/datashare/app/shared/file-download-link/file-download-link.component.ts @@ -8,8 +8,8 @@ import { Component } from '@angular/core'; import { RouterLink } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; -import { ThemedAccessStatusBadgeComponent } from '../../../../../app/shared/object-collection/shared/badges/access-status-badge/themed-access-status-badge.component'; import { FileDownloadLinkComponent as BaseComponent } from '../../../../../app/shared/file-download-link/file-download-link.component'; +import { ThemedAccessStatusBadgeComponent } from '../../../../../app/shared/object-collection/shared/badges/access-status-badge/themed-access-status-badge.component'; @Component({ selector: 'ds-themed-file-download-link', From 8a37503ca8c03a3897d102f8b9680d5ea5c059da Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Tue, 21 Apr 2026 12:21:10 +0200 Subject: [PATCH 3/6] Removed unnecesary file --- PR7-FIX-README.md | 95 ----------------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 PR7-FIX-README.md diff --git a/PR7-FIX-README.md b/PR7-FIX-README.md deleted file mode 100644 index 8c8e4015b6d..00000000000 --- a/PR7-FIX-README.md +++ /dev/null @@ -1,95 +0,0 @@ -# PR #7 – GitHub Actions fix summary - -This document summarizes the changes made to get the failing GitHub Actions -build green for PR [#7](https://github.com/dataquest-dev/uoe-dspace-datashare-angular/pull/7) -(branch `uoe-fix-github-actions-it-2`). - -## Initial state - -The `Build` workflow (`.github/workflows/build.yml`) was failing on the -`tests (18.x)` matrix job. The `tests (20.x)` job was skipped (fail-fast on -the earlier job). The workflow runs the following steps in order: - -1. `yarn install --frozen-lockfile` -2. `yarn build:lint` -3. `yarn test:lint:nobuild` -4. `yarn lint:nobuild --quiet` ← **failing here** -5. `yarn check-circ-deps` -6. `yarn build:prod` -7. `yarn test:headless` (unit tests) -8. e2e / SSR tests - -Reproducing locally showed the build stopped at step 4 and, after that was -fixed, at step 7 (unit tests). - -## Root causes - -### 1. Lint (step 4) – 41 errors - -Most errors came from a single file, -`src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts`, -which contained a duplicated block of imports appended after a previous -import group. This caused cascading errors: - -- `import/no-duplicates` -- `no-redeclare` (names imported twice) -- `import-newlines/enforce` -- `unused-imports/no-unused-imports` (an obsolete `followLink` import) - -A handful of other files only failed `simple-import-sort/imports`, fixable -by ESLint itself. - -### 2. Unit tests (step 7) – 7 failing specs - -- `src/app/thumbnail/thumbnail.component.spec.ts`: the `Bitstream._links` - type was extended with a required `accessStatus: HALLink` field (see - `src/app/core/shared/bitstream.model.ts`), but the two `_links` fixtures - in this spec weren’t updated, failing TypeScript compilation - (`TS2741: Property 'accessStatus' is missing`). Karma then reported - "Found 1 load error" and all 5364 tests were blocked. -- `src/app/shared/file-download-link/file-download-link.component.spec.ts`: - after adding `ThemedAccessStatusBadgeComponent` to the standalone - component’s `imports`, instantiating the component inside tests pulled - in `ThemeService`, which requires `Store` (NgRx). The test bed did not - provide one, producing - `NullInjectorError: No provider for Store!` on six tests. - -## Fixes applied - -- Removed the duplicated import block (and unused `followLink`) in - `src/themes/datashare/app/item-page/simple/field-components/file-section/file-section.component.ts`. -- Ran `yarn lint:nobuild --fix` to resolve the remaining - `simple-import-sort/imports` issues across: - - `src/app/core/data/access-status-data.service.ts` - - `src/app/core/shared/bitstream.model.ts` - - `src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts` - - `src/themes/custom/app/shared/file-download-link/file-download-link.component.ts` - - `src/themes/datashare/app/shared/file-download-link/file-download-link.component.ts` -- Added the missing `accessStatus: { href: 'accessStatus.url' }` entry to - both `_links` fixtures in `src/app/thumbnail/thumbnail.component.spec.ts`. -- Extended the existing `overrideComponent(... remove: { imports: [...] })` - in `src/app/shared/file-download-link/file-download-link.component.spec.ts` - to also remove `ThemedAccessStatusBadgeComponent`, removing the - `ThemeService → Store` dependency from the test component and restoring - the original test isolation pattern used for `RouterLink`. - -## Local verification - -- `yarn lint:nobuild --quiet` → `All files pass linting.` -- `yarn test:lint:nobuild` → `97 specs, 0 failures`. -- `yarn build:prod` → succeeds (only tsconfig "unused file" warnings, same as - on the base branch). -- `yarn test:headless` → `5364 SUCCESS, 2 skipped`. - -`yarn check-circ-deps` only fails locally on Windows PowerShell because of -the single-quote pattern in `package.json`; on the Linux CI runners it -executes normally. - -The e2e Cypress tests (step 8) were not previously reached in CI and depend -on a full DSpace REST backend started via docker-compose; they were not -changed by this PR. - -## Commit - -All changes were committed to the PR branch `uoe-fix-github-actions-it-2` -only, as requested. From 68264e7060b9bcba0de996b55a18d8f8709c8b53 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Tue, 21 Apr 2026 13:20:59 +0200 Subject: [PATCH 4/6] fix(a11y): remove presentational wrappers from edit-metadata table to satisfy aria-required-children --- .../dso-edit-metadata-field-values.component.html | 4 ++-- .../dso-edit-metadata/dso-edit-metadata.component.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component.html index aee9fb980cf..3f0408ab536 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component.html @@ -1,6 +1,6 @@
- - +
- + Date: Tue, 21 Apr 2026 13:59:27 +0200 Subject: [PATCH 5/6] fix(a11y): mark edit-metadata header row with role=row and columnheader --- .gitignore | 2 ++ .../dso-edit-metadata-headers.component.html | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ce44f6b3fbe..1ef086673ef 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ package-lock.json junit.xml /src/mirador-viewer/config.local.js + +FIX-PROGRESS.md diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-headers/dso-edit-metadata-headers.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-headers/dso-edit-metadata-headers.component.html index ecaf2aa7443..b5de8146f3e 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-headers/dso-edit-metadata-headers.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-headers/dso-edit-metadata-headers.component.html @@ -1,6 +1,6 @@ -
-
{{ dsoType + '.edit.metadata.headers.field' | translate }}
-
+
+
{{ dsoType + '.edit.metadata.headers.field' | translate }}
+
{{ dsoType + '.edit.metadata.headers.value' | translate }}
{{ dsoType + '.edit.metadata.headers.language' | translate }}
From 92bbb2650e9ed4d75963cd8a043b8b942fc96b25 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Tue, 21 Apr 2026 14:49:47 +0200 Subject: [PATCH 6/6] Revert gitignore changes --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1ef086673ef..ce44f6b3fbe 100644 --- a/.gitignore +++ b/.gitignore @@ -42,5 +42,3 @@ package-lock.json junit.xml /src/mirador-viewer/config.local.js - -FIX-PROGRESS.md