diff --git a/.eslintrc.json b/.eslintrc.json index 50a9be3d59..4cc8c6dbc5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -11,7 +11,13 @@ "eslint-plugin-jsonc", "eslint-plugin-rxjs", "eslint-plugin-simple-import-sort", - "eslint-plugin-import-newlines" + "eslint-plugin-import-newlines", + "eslint-plugin-jsonc", + "dspace-angular-ts", + "dspace-angular-html" + ], + "ignorePatterns": [ + "lint/test/fixture" ], "overrides": [ { @@ -21,7 +27,8 @@ "parserOptions": { "project": [ "./tsconfig.json", - "./cypress/tsconfig.json" + "./cypress/tsconfig.json", + "./lint/tsconfig.json" ], "createDefaultProgram": true }, @@ -38,7 +45,10 @@ "error", 2, { - "SwitchCase": 1 + "SwitchCase": 1, + "ignoredNodes": [ + "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key" + ] } ], "max-classes-per-file": [ @@ -212,6 +222,15 @@ "@typescript-eslint/no-unsafe-return": "off", "@typescript-eslint/restrict-template-expressions": "off", "@typescript-eslint/require-await": "off", + "@typescript-eslint/no-base-to-string": [ + "error", + { + "ignoredTypeNames": [ + "ResourceType", + "Error" + ] + } + ], "deprecation/deprecation": "warn", @@ -238,7 +257,12 @@ "method" ], - "rxjs/no-nested-subscribe": "off" // todo: go over _all_ cases + "rxjs/no-nested-subscribe": "off", // todo: go over _all_ cases + + // Custom DSpace Angular rules + "dspace-angular-ts/themed-component-classes": "error", + "dspace-angular-ts/themed-component-selectors": "error", + "dspace-angular-ts/themed-component-usages": "error" } }, { @@ -253,7 +277,10 @@ "createDefaultProgram": true }, "rules": { - "prefer-const": "off" + "prefer-const": "off", + + // Custom DSpace Angular rules + "dspace-angular-ts/themed-component-usages": "error" } }, { @@ -262,7 +289,11 @@ ], "extends": [ "plugin:@angular-eslint/template/recommended" - ] + ], + "rules": { + // Custom DSpace Angular rules + "dspace-angular-html/themed-component-usages": "error" + } }, { "files": [ diff --git a/.gitattributes b/.gitattributes index 406640bfcc..b5ad93b1bc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,4 +13,7 @@ *.css eol=lf *.scss eol=lf *.html eol=lf -*.svg eol=lf \ No newline at end of file +*.svg eol=lf + +# Generated documentation should have LF line endings to reduce git noise +docs/lint/**/*.md eol=lf \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6ffa5e004..4f2a84ce8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -85,8 +85,14 @@ jobs: - name: Install Yarn dependencies run: yarn install --frozen-lockfile + - name: Build lint plugins + run: yarn run build:lint + + - name: Run lint plugin tests + run: yarn run test:lint:nobuild + - name: Run lint - run: yarn run lint --quiet + run: yarn run lint:nobuild --quiet - name: Check for circular dependencies run: yarn run check-circ-deps diff --git a/angular.json b/angular.json index 98463fa732..5f0204249b 100644 --- a/angular.json +++ b/angular.json @@ -266,6 +266,8 @@ "options": { "lintFilePatterns": [ "src/**/*.ts", + "cypress/**/*.ts", + "lint/**/*.ts", "src/**/*.html", "src/**/*.json5" ] diff --git a/cypress/e2e/item-template.cy.ts b/cypress/e2e/item-template.cy.ts new file mode 100644 index 0000000000..5f5b21a16a --- /dev/null +++ b/cypress/e2e/item-template.cy.ts @@ -0,0 +1,15 @@ +const ADD_TEMPLATE_ITEM_PAGE = '/collections/'.concat(Cypress.env('DSPACE_TEST_COLLECTION')).concat('/itemtemplate'); + +describe('Item Template', () => { + beforeEach(() => { + cy.visit(ADD_TEMPLATE_ITEM_PAGE); + cy.loginViaForm(Cypress.env('DSPACE_TEST_ADMIN_USER'), Cypress.env('DSPACE_TEST_ADMIN_PASSWORD')); + }); + + it('should load properly', () => { + cy.contains('.ds-header-row .lbl-cell', 'Field', { timeout: 10000 }).should('exist').should('be.visible'); + cy.contains('.ds-header-row b', 'Value', { timeout: 10000 }).should('exist').should('be.visible'); + cy.contains('.ds-header-row b', 'Lang', { timeout: 10000 }).should('exist').should('be.visible'); + cy.contains('.ds-header-row b', 'Edit', { timeout: 10000 }).should('exist').should('be.visible'); + }); +}); diff --git a/cypress/e2e/login-modal.cy.ts b/cypress/e2e/login-modal.cy.ts index 190f3ff927..3d978dfaca 100644 --- a/cypress/e2e/login-modal.cy.ts +++ b/cypress/e2e/login-modal.cy.ts @@ -3,31 +3,31 @@ import { testA11y } from 'cypress/support/utils'; const page = { openLoginMenu() { // Click the "Log In" dropdown menu in header - cy.get('ds-themed-header [data-test="login-menu"]').click(); + cy.get('ds-header [data-test="login-menu"]').click(); }, openUserMenu() { // Once logged in, click the User menu in header - cy.get('ds-themed-header [data-test="user-menu"]').click(); + cy.get('ds-header [data-test="user-menu"]').click(); }, submitLoginAndPasswordByPressingButton(email, password) { // Enter email - cy.get('ds-themed-header [data-test="email"]').type(email); + cy.get('ds-header [data-test="email"]').type(email); // Enter password - cy.get('ds-themed-header [data-test="password"]').type(password); + cy.get('ds-header [data-test="password"]').type(password); // Click login button - cy.get('ds-themed-header [data-test="login-button"]').click(); + cy.get('ds-header [data-test="login-button"]').click(); }, submitLoginAndPasswordByPressingEnter(email, password) { // In opened Login modal, fill out email & password, then click Enter - cy.get('ds-themed-header [data-test="email"]').type(email); - cy.get('ds-themed-header [data-test="password"]').type(password); - cy.get('ds-themed-header [data-test="password"]').type('{enter}'); + cy.get('ds-header [data-test="email"]').type(email); + cy.get('ds-header [data-test="password"]').type(password); + cy.get('ds-header [data-test="password"]').type('{enter}'); }, submitLogoutByPressingButton() { // This is the POST command that will actually log us out cy.intercept('POST', '/server/api/authn/logout').as('logout'); // Click logout button - cy.get('ds-themed-header [data-test="logout-button"]').click(); + cy.get('ds-header [data-test="logout-button"]').click(); // Wait until above POST command responds before continuing // (This ensures next action waits until logout completes) cy.wait('@logout'); @@ -102,10 +102,10 @@ describe('Login Modal', () => { page.openLoginMenu(); // Registration link should be visible - cy.get('ds-themed-header [data-test="register"]').should('be.visible'); + cy.get('ds-header [data-test="register"]').should('be.visible'); // Click registration link & you should go to registration page - cy.get('ds-themed-header [data-test="register"]').click(); + cy.get('ds-header [data-test="register"]').click(); cy.location('pathname').should('eq', '/register'); cy.get('ds-register-email').should('exist'); @@ -119,10 +119,10 @@ describe('Login Modal', () => { page.openLoginMenu(); // Forgot password link should be visible - cy.get('ds-themed-header [data-test="forgot"]').should('be.visible'); + cy.get('ds-header [data-test="forgot"]').should('be.visible'); // Click link & you should go to Forgot Password page - cy.get('ds-themed-header [data-test="forgot"]').click(); + cy.get('ds-header [data-test="forgot"]').click(); cy.location('pathname').should('eq', '/forgot'); cy.get('ds-forgot-email').should('exist'); diff --git a/cypress/e2e/search-navbar.cy.ts b/cypress/e2e/search-navbar.cy.ts index b168219916..0613e5e712 100644 --- a/cypress/e2e/search-navbar.cy.ts +++ b/cypress/e2e/search-navbar.cy.ts @@ -1,15 +1,15 @@ const page = { fillOutQueryInNavBar(query) { // Click the magnifying glass - cy.get('ds-themed-header [data-test="header-search-icon"]').click(); + cy.get('ds-header [data-test="header-search-icon"]').click(); // Fill out a query in input that appears - cy.get('ds-themed-header [data-test="header-search-box"]').type(query); + cy.get('ds-header [data-test="header-search-box"]').type(query); }, submitQueryByPressingEnter() { - cy.get('ds-themed-header [data-test="header-search-box"]').type('{enter}'); + cy.get('ds-header [data-test="header-search-box"]').type('{enter}'); }, submitQueryByPressingIcon() { - cy.get('ds-themed-header [data-test="header-search-icon"]').click(); + cy.get('ds-header [data-test="header-search-icon"]').click(); }, }; diff --git a/docker/README.md b/docker/README.md index d0cee3f52a..64d8ddc2c5 100644 --- a/docker/README.md +++ b/docker/README.md @@ -20,7 +20,7 @@ the Docker compose scripts in this 'docker' folder. ### Dockerfile -This Dockerfile is used to build a *development* DSpace 7 Angular UI image, published as 'dspace/dspace-angular' +This Dockerfile is used to build a *development* DSpace Angular UI image, published as 'dspace/dspace-angular' ``` docker build -t dspace/dspace-angular:latest . @@ -46,11 +46,11 @@ A default/demo version of this image is built *automatically*. ## 'docker' directory - docker-compose.yml - - Starts DSpace Angular with Docker Compose from the current branch. This file assumes that a DSpace 7 REST instance will also be started in Docker. + - Starts DSpace Angular with Docker Compose from the current branch. This file assumes that a DSpace REST instance will also be started in Docker. - docker-compose-rest.yml - - Runs a published instance of the DSpace 7 REST API - persists data in Docker volumes + - Runs a published instance of the DSpace REST API - persists data in Docker volumes - docker-compose-ci.yml - - Runs a published instance of the DSpace 7 REST API for CI testing. The database is re-populated from a SQL dump on each startup. + - Runs a published instance of the DSpace REST API for CI testing. The database is re-populated from a SQL dump on each startup. - cli.yml - Docker compose file that provides a DSpace CLI container to work with a running DSpace REST container. - cli.assetstore.yml @@ -71,7 +71,7 @@ docker-compose -f docker/docker-compose.yml build This command provides a quick way to start both the frontend & backend from this single codebase ``` -docker-compose -p d7 -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d +docker-compose -p d8 -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d ``` Keep in mind, you may also start the backend by cloning the 'DSpace/DSpace' GitHub repository separately. See the next section. @@ -86,14 +86,14 @@ _The system will be started in 2 steps. Each step shares the same docker network From 'DSpace/DSpace' clone (build first as needed): ``` -docker-compose -p d7 up -d +docker-compose -p d8 up -d ``` NOTE: More detailed instructions on starting the backend via Docker can be found in the [Docker Compose instructions for the Backend](https://github.com/DSpace/DSpace/blob/main/dspace/src/main/docker-compose/README.md). From 'DSpace/dspace-angular' clone (build first as needed) ``` -docker-compose -p d7 -f docker/docker-compose.yml up -d +docker-compose -p d8 -f docker/docker-compose.yml up -d ``` At this point, you should be able to access the UI from http://localhost:4000, @@ -107,19 +107,19 @@ This allows you to run the Angular UI in *production* mode, pointing it at the d ``` docker-compose -f docker/docker-compose-dist.yml pull docker-compose -f docker/docker-compose-dist.yml build -docker-compose -p d7 -f docker/docker-compose-dist.yml up -d +docker-compose -p d8 -f docker/docker-compose-dist.yml up -d ``` ## Ingest test data from AIPDIR Create an administrator ``` -docker-compose -p d7 -f docker/cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en +docker-compose -p d8 -f docker/cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en ``` Load content from AIP files ``` -docker-compose -p d7 -f docker/cli.yml -f ./docker/cli.ingest.yml run --rm dspace-cli +docker-compose -p d8 -f docker/cli.yml -f ./docker/cli.ingest.yml run --rm dspace-cli ``` ## Alternative Ingest - Use Entities dataset @@ -127,12 +127,12 @@ _Delete your docker volumes or use a unique project (-p) name_ Start DSpace with Database Content from a database dump ``` -docker-compose -p d7 -f docker/docker-compose.yml -f docker/docker-compose-rest.yml -f docker/db.entities.yml up -d +docker-compose -p d8 -f docker/docker-compose.yml -f docker/docker-compose-rest.yml -f docker/db.entities.yml up -d ``` Load assetstore content and trigger a re-index of the repository ``` -docker-compose -p d7 -f docker/cli.yml -f docker/cli.assetstore.yml run --rm dspace-cli +docker-compose -p d8 -f docker/cli.yml -f docker/cli.assetstore.yml run --rm dspace-cli ``` ## End to end testing of the REST API (runs in GitHub Actions CI). @@ -140,5 +140,5 @@ _In this instance, only the REST api runs in Docker using the Entities dataset. This command is only really useful for testing our Continuous Integration process. ``` -docker-compose -p d7ci -f docker/docker-compose-ci.yml up -d +docker-compose -p d8ci -f docker/docker-compose-ci.yml up -d ``` diff --git a/docker/docker-compose-ci.yml b/docker/docker-compose-ci.yml index 07993e20c6..fef7330ba1 100644 --- a/docker/docker-compose-ci.yml +++ b/docker/docker-compose-ci.yml @@ -33,6 +33,7 @@ services: # Tell Statistics to commit all views immediately instead of waiting on Solr's autocommit. # This allows us to generate statistics in e2e tests so that statistics pages can be tested thoroughly. solr__D__statistics__P__autoCommit: 'false' + LOGGING_CONFIG: /dspace/config/log4j2-container.xml image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-latest-test}" depends_on: - dspacedb @@ -60,15 +61,19 @@ services: # NOTE: This is customized to use our loadsql image, so that we are using a database with existing test data dspacedb: container_name: dspacedb + image: "${DOCKER_OWNER:-dspace}/dspace-postgres-pgcrypto:${DSPACE_VER:-latest-loadsql}" environment: # This LOADSQL should be kept in sync with the LOADSQL in # https://github.com/DSpace/DSpace/blob/main/dspace/src/main/docker-compose/db.entities.yml # This SQL is available from https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data LOADSQL: https://github.com/DSpace-Labs/AIP-Files/releases/download/demo-entities-data/dspace7-entities-data.sql PGDATA: /pgdata - image: dspace/dspace-postgres-pgcrypto:loadsql + POSTGRES_PASSWORD: dspace networks: - dspacenet + ports: + - published: 5432 + target: 5432 stdin_open: true tty: true volumes: @@ -105,6 +110,8 @@ services: cp -r /opt/solr/server/solr/configsets/statistics/* statistics precreate-core qaevent /opt/solr/server/solr/configsets/qaevent cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent + precreate-core suggestion /opt/solr/server/solr/configsets/suggestion + cp -r /opt/solr/server/solr/configsets/suggestion/* suggestion exec solr -f volumes: assetstore: diff --git a/docker/docker-compose-rest.yml b/docker/docker-compose-rest.yml index e1577ec837..6267b32bbe 100644 --- a/docker/docker-compose-rest.yml +++ b/docker/docker-compose-rest.yml @@ -29,8 +29,9 @@ services: # __D__ => "-" (e.g. google__D__metadata => google-metadata) # dspace.dir, dspace.server.url, dspace.ui.url and dspace.name dspace__P__dir: /dspace - dspace__P__server__P__url: http://localhost:8080/server - dspace__P__ui__P__url: http://localhost:4000 + # Uncomment to set a non-default value for dspace.server.url or dspace.ui.url + # dspace__P__server__P__url: http://localhost:8080/server + # dspace__P__ui__P__url: http://localhost:4000 dspace__P__name: 'DSpace Started with Docker Compose' # db.url: Ensure we are using the 'dspacedb' image for our database db__P__url: 'jdbc:postgresql://dspacedb:5432/dspace' @@ -39,6 +40,7 @@ services: # proxies.trusted.ipranges: This setting is required for a REST API running in Docker to trust requests # from the host machine. This IP range MUST correspond to the 'dspacenet' subnet defined above. proxies__P__trusted__P__ipranges: '172.23.0' + LOGGING_CONFIG: /dspace/config/log4j2-container.xml image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-latest-test}" depends_on: - dspacedb @@ -50,6 +52,7 @@ services: stdin_open: true tty: true volumes: + # Keep DSpace assetstore directory between reboots - assetstore:/dspace/assetstore # Ensure that the database is ready BEFORE starting tomcat # 1. While a TCP connection to dspacedb port 5432 is not available, continue to sleep @@ -65,9 +68,11 @@ services: # DSpace database container dspacedb: container_name: dspacedb + # Uses a custom Postgres image with pgcrypto installed + image: "${DOCKER_OWNER:-dspace}/dspace-postgres-pgcrypto:${DSPACE_VER:-latest}" environment: PGDATA: /pgdata - image: "${DOCKER_OWNER:-dspace}/dspace-postgres-pgcrypto:${DSPACE_VER:-latest}" + POSTGRES_PASSWORD: dspace networks: - dspacenet ports: @@ -113,6 +118,8 @@ services: cp -r /opt/solr/server/solr/configsets/statistics/* statistics precreate-core qaevent /opt/solr/server/solr/configsets/qaevent cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent + precreate-core suggestion /opt/solr/server/solr/configsets/suggestion + cp -r /opt/solr/server/solr/configsets/suggestion/* suggestion exec solr -f volumes: assetstore: diff --git a/docs/lint/html/index.md b/docs/lint/html/index.md new file mode 100644 index 0000000000..15d693843c --- /dev/null +++ b/docs/lint/html/index.md @@ -0,0 +1,4 @@ +[DSpace ESLint plugins](../../../lint/README.md) > HTML rules +_______ + +- [`dspace-angular-html/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via the selector of their `ThemedComponent` wrapper class diff --git a/docs/lint/html/rules/themed-component-usages.md b/docs/lint/html/rules/themed-component-usages.md new file mode 100644 index 0000000000..a04fe1c770 --- /dev/null +++ b/docs/lint/html/rules/themed-component-usages.md @@ -0,0 +1,110 @@ +[DSpace ESLint plugins](../../../../lint/README.md) > [HTML rules](../index.md) > `dspace-angular-html/themed-component-usages` +_______ + +Themeable components should be used via the selector of their `ThemedComponent` wrapper class + +This ensures that custom themes can correctly override _all_ instances of this component. +The only exception to this rule are unit tests, where we may want to use the base component in order to keep the test setup simple. + + +_______ + +[Source code](../../../../lint/src/rules/html/themed-component-usages.ts) + +### Examples + + +#### Valid code + +##### use no-prefix selectors in HTML templates + +```html + + + +``` + +##### use no-prefix selectors in TypeScript templates + +```html +@Component({ + template: '' +}) +class Test { +} +``` + +##### use no-prefix selectors in TypeScript test templates + +Filename: `lint/test/fixture/src/test.spec.ts` + +```html +@Component({ + template: '' +}) +class Test { +} +``` + +##### base selectors are also allowed in TypeScript test templates + +Filename: `lint/test/fixture/src/test.spec.ts` + +```html +@Component({ + template: '' +}) +class Test { +} +``` + + + + +#### Invalid code & automatic fixes + +##### themed override selectors are not allowed in HTML templates + +```html + + + +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper's selector +Themeable components should be used via their ThemedComponent wrapper's selector +Themeable components should be used via their ThemedComponent wrapper's selector +``` + +Result of `yarn lint --fix`: +```html + + + +``` + + +##### base selectors are not allowed in HTML templates + +```html + + + +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper's selector +Themeable components should be used via their ThemedComponent wrapper's selector +Themeable components should be used via their ThemedComponent wrapper's selector +``` + +Result of `yarn lint --fix`: +```html + + + +``` + + + diff --git a/docs/lint/ts/index.md b/docs/lint/ts/index.md new file mode 100644 index 0000000000..ed060c946e --- /dev/null +++ b/docs/lint/ts/index.md @@ -0,0 +1,6 @@ +[DSpace ESLint plugins](../../../lint/README.md) > TypeScript rules +_______ + +- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes +- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention +- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class diff --git a/docs/lint/ts/rules/themed-component-classes.md b/docs/lint/ts/rules/themed-component-classes.md new file mode 100644 index 0000000000..1f4ec72801 --- /dev/null +++ b/docs/lint/ts/rules/themed-component-classes.md @@ -0,0 +1,257 @@ +[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-classes` +_______ + +Formatting rules for themeable component classes + +- All themeable components must be standalone. +- The base component must always be imported in the `ThemedComponent` wrapper. This ensures that it is always sufficient to import just the wrapper whenever we use the component. + + +_______ + +[Source code](../../../../lint/src/rules/ts/themed-component-classes.ts) + +### Examples + + +#### Valid code + +##### Regular non-themeable component + +```typescript +@Component({ + selector: 'ds-something', + standalone: true, +}) +class Something { +} +``` + +##### Base component + +```typescript +@Component({ + selector: 'ds-base-test-themable', + standalone: true, +}) +class TestThemeableTomponent { +} +``` + +##### Wrapper component + +Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [ + TestThemeableComponent, + ], +}) +class ThemedTestThemeableTomponent extends ThemedComponent { +} +``` + +##### Override component + +Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-themed-test-themable', + standalone: true, +}) +class Override extends BaseComponent { +} +``` + + + + +#### Invalid code & automatic fixes + +##### Base component must be standalone + +```typescript +@Component({ + selector: 'ds-base-test-themable', +}) +class TestThemeableComponent { +} +``` +Will produce the following error(s): +``` +Themeable components must be standalone +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-base-test-themable', + standalone: true, +}) +class TestThemeableComponent { +} +``` + + +##### Wrapper component must be standalone and import base component + +Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-test-themable', +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` +Will produce the following error(s): +``` +Themeable component wrapper classes must be standalone and import the base class +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` + + +##### Wrapper component must import base component (array present but empty) + +Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` +Will produce the following error(s): +``` +Themed component wrapper classes must only import the base class +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` + + +##### Wrapper component must import base component (array is wrong) + +Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts` + +```typescript +import { SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [ + SomethingElse, + ], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` +Will produce the following error(s): +``` +Themed component wrapper classes must only import the base class +``` + +Result of `yarn lint --fix`: +```typescript +import { SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` + + +##### Wrapper component must import base component (array is wrong) + +Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts` + +```typescript +import { Something, SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [ + SomethingElse, + ], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` +Will produce the following error(s): +``` +Themed component wrapper classes must only import the base class +``` + +Result of `yarn lint --fix`: +```typescript +import { Something, SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` + + +##### Override component must be standalone + +Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-themed-test-themable', +}) +class Override extends BaseComponent { +} +``` +Will produce the following error(s): +``` +Themeable components must be standalone +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-themed-test-themable', + standalone: true, +}) +class Override extends BaseComponent { +} +``` + + + diff --git a/docs/lint/ts/rules/themed-component-selectors.md b/docs/lint/ts/rules/themed-component-selectors.md new file mode 100644 index 0000000000..f4d0ea177c --- /dev/null +++ b/docs/lint/ts/rules/themed-component-selectors.md @@ -0,0 +1,156 @@ +[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-selectors` +_______ + +Themeable component selectors should follow the DSpace convention + +Each themeable component is comprised of a base component, a wrapper component and any number of themed components +- Base components should have a selector starting with `ds-base-` +- Themed components should have a selector starting with `ds-themed-` +- Wrapper components should have a selector starting with `ds-`, but not `ds-base-` or `ds-themed-` + - This is the regular DSpace selector prefix + - **When making a regular component themeable, its selector prefix should be changed to `ds-base-`, and the new wrapper's component should reuse the previous selector** + +Unit tests are exempt from this rule, because they may redefine components using the same class name as other themeable components elsewhere in the source. + + +_______ + +[Source code](../../../../lint/src/rules/ts/themed-component-selectors.ts) + +### Examples + + +#### Valid code + +##### Regular non-themeable component selector + +```typescript +@Component({ + selector: 'ds-something', +}) +class Something { +} +``` + +##### Themeable component selector should replace the original version, unthemed version should be changed to ds-base- + +```typescript +@Component({ + selector: 'ds-base-something', +}) +class Something { +} + +@Component({ + selector: 'ds-something', +}) +class ThemedSomething extends ThemedComponent { +} + +@Component({ + selector: 'ds-themed-something', +}) +class OverrideSomething extends Something { +} +``` + +##### Other themed component wrappers should not interfere + +```typescript +@Component({ + selector: 'ds-something', +}) +class Something { +} + +@Component({ + selector: 'ds-something-else', +}) +class ThemedSomethingElse extends ThemedComponent { +} +``` + + + + +#### Invalid code & automatic fixes + +##### Wrong selector for base component + +Filename: `lint/test/fixture/src/app/test/test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-something', +}) +class TestThemeableComponent { +} +``` +Will produce the following error(s): +``` +Unthemed version of themeable component should have a selector starting with 'ds-base-' +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-base-something', +}) +class TestThemeableComponent { +} +``` + + +##### Wrong selector for wrapper component + +Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-themed-something', +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` +Will produce the following error(s): +``` +Themed component wrapper of themeable component shouldn't have a selector starting with 'ds-themed-' +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-something', +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} +``` + + +##### Wrong selector for theme override + +Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts` + +```typescript +@Component({ + selector: 'ds-something', +}) +class TestThememeableComponent extends BaseComponent { +} +``` +Will produce the following error(s): +``` +Theme override of themeable component should have a selector starting with 'ds-themed-' +``` + +Result of `yarn lint --fix`: +```typescript +@Component({ + selector: 'ds-themed-something', +}) +class TestThememeableComponent extends BaseComponent { +} +``` + + + diff --git a/docs/lint/ts/rules/themed-component-usages.md b/docs/lint/ts/rules/themed-component-usages.md new file mode 100644 index 0000000000..16ccb701c2 --- /dev/null +++ b/docs/lint/ts/rules/themed-component-usages.md @@ -0,0 +1,332 @@ +[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-usages` +_______ + +Themeable components should be used via their `ThemedComponent` wrapper class + +This ensures that custom themes can correctly override _all_ instances of this component. +There are a few exceptions where the base class can still be used: +- Class declaration expressions (otherwise we can't declare, extend or override the class in the first place) +- Angular modules (except for routing modules) +- Angular `@ViewChild` decorators +- Type annotations + + +_______ + +[Source code](../../../../lint/src/rules/ts/themed-component-usages.ts) + +### Examples + + +#### Valid code + +##### allow wrapper class usages + +```typescript +import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; + +const config = { + a: ThemedTestThemeableComponent, + b: ChipsComponent, +} +``` + +##### allow base class in class declaration + +```typescript +export class TestThemeableComponent { +} +``` + +##### allow inheriting from base class + +```typescript +import { TestThemeableComponent } from './app/test/test-themeable.component'; + +export class ThemedAdminSidebarComponent extends ThemedComponent { +} +``` + +##### allow base class in ViewChild + +```typescript +import { TestThemeableComponent } from './app/test/test-themeable.component'; + +export class Something { + @ViewChild(TestThemeableComponent) test: TestThemeableComponent; +} +``` + +##### allow wrapper selectors in test queries + +Filename: `lint/test/fixture/src/app/test/test.component.spec.ts` + +```typescript +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); +``` + +##### allow wrapper selectors in cypress queries + +Filename: `lint/test/fixture/src/app/test/test.component.cy.ts` + +```typescript +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); +``` + + + + +#### Invalid code & automatic fixes + +##### disallow direct usages of base class + +```typescript +import { TestThemeableComponent } from './app/test/test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: TestThemeableComponent, + b: TestComponent, +} +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: ThemedTestThemeableComponent, + b: TestComponent, +} +``` + + +##### disallow direct usages of base class, keep other imports + +```typescript +import { Something, TestThemeableComponent } from './app/test/test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: TestThemeableComponent, + b: TestComponent, + c: Something, +} +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +import { Something } from './app/test/test-themeable.component'; +import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: ThemedTestThemeableComponent, + b: TestComponent, + c: Something, +} +``` + + +##### handle array replacements correctly + +```typescript +const DECLARATIONS = [ + Something, + TestThemeableComponent, + Something, + ThemedTestThemeableComponent, +]; +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +const DECLARATIONS = [ + Something, + Something, + ThemedTestThemeableComponent, +]; +``` + + +##### disallow override selector in test queries + +Filename: `lint/test/fixture/src/app/test/test.component.spec.ts` + +```typescript +By.css('ds-themed-themeable'); +By.css('#test > ds-themed-themeable > #nest'); +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); +``` + + +##### disallow base selector in test queries + +Filename: `lint/test/fixture/src/app/test/test.component.spec.ts` + +```typescript +By.css('ds-base-themeable'); +By.css('#test > ds-base-themeable > #nest'); +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); +``` + + +##### disallow override selector in cypress queries + +Filename: `lint/test/fixture/src/app/test/test.component.cy.ts` + +```typescript +cy.get('ds-themed-themeable'); +cy.get('#test > ds-themed-themeable > #nest'); +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +cy.get('ds-themeable'); +cy.get('#test > ds-themeable > #nest'); +``` + + +##### disallow base selector in cypress queries + +Filename: `lint/test/fixture/src/app/test/test.component.cy.ts` + +```typescript +cy.get('ds-base-themeable'); +cy.get('#test > ds-base-themeable > #nest'); +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +cy.get('ds-themeable'); +cy.get('#test > ds-themeable > #nest'); +``` + + +##### edge case: unable to find usage node through usage token, but import is still flagged and fixed + +Filename: `lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts` + +```typescript +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { TestThemeableComponent } from '../../../../app/test/test-themeable.component'; + +@Component({ + standalone: true, + imports: [TestThemeableComponent], +}) +export class UsageComponent { +} +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component'; + +@Component({ + standalone: true, + imports: [ThemedTestThemeableComponent], +}) +export class UsageComponent { +} +``` + + +##### edge case edge case: both are imported, only wrapper is retained + +Filename: `lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts` + +```typescript +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { TestThemeableComponent } from '../../../../app/test/test-themeable.component'; +import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component'; + +@Component({ + standalone: true, + imports: [TestThemeableComponent, ThemedTestThemeableComponent], +}) +export class UsageComponent { +} +``` +Will produce the following error(s): +``` +Themeable components should be used via their ThemedComponent wrapper +Themeable components should be used via their ThemedComponent wrapper +``` + +Result of `yarn lint --fix`: +```typescript +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component'; + +@Component({ + standalone: true, + imports: [ThemedTestThemeableComponent], +}) +export class UsageComponent { +} +``` + + + diff --git a/lint/.gitignore b/lint/.gitignore new file mode 100644 index 0000000000..0d22081b3b --- /dev/null +++ b/lint/.gitignore @@ -0,0 +1,3 @@ +/dist/ +/coverage/ +/node-modules/ diff --git a/lint/README.md b/lint/README.md new file mode 100644 index 0000000000..7251a35c06 --- /dev/null +++ b/lint/README.md @@ -0,0 +1,50 @@ +# DSpace ESLint plugins + +Custom ESLint rules for DSpace Angular peculiarities. + +## Usage + +These plugins are included with the rest of our ESLint configuration in [.eslintc.json](../.eslintrc.json). Individual rules can be configured or disabled there, like usual. +- In order for the new rules to be picked up by your IDE, you should first run `yarn build:lint` to build the plugins. +- This will also happen automatically each time `yarn lint` is run. + +## Documentation + +The rules are split up into plugins by language: +- [TypeScript rules](../docs/lint/ts/index.md) +- [HTML rules](../docs/lint/html/index.md) + +> Run `yarn docs:lint` to generate this documentation! + +## Developing + +### Overview + +- All rules are written in TypeScript and compiled into [`dist`](./dist) + - The plugins are linked into the main project dependencies from here + - These directories already contain the necessary `package.json` files to mark them as ESLint plugins +- Rule source files are structured, so they can be imported all in one go + - Each rule must export the following: + - `Messages`: an Enum of error message IDs + - `info`: metadata about this rule (name, description, messages, options, ...) + - `rule`: the implementation of the rule + - `tests`: the tests for this rule, as a set of valid/invalid code snippets. These snippets are used as example in the documentation. + - New rules should be added to their plugin's `index.ts` +- Some useful links + - [Developing ESLint plugins](https://eslint.org/docs/latest/extend/plugins) + - [Custom rules in typescript-eslint](https://typescript-eslint.io/developers/custom-rules) + - [Angular ESLint](https://github.com/angular-eslint/angular-eslint) + +### Parsing project metadata in advance ~ TypeScript AST + +While it is possible to retain persistent state between files during the linting process, it becomes quite complicated if the content of one file determines how we want to lint another file. +Because the two files may be linted out of order, we may not know whether the first file is wrong before we pass by the second. This means that we cannot report or fix the issue, because the first file is already detached from the linting context. + +For example, we cannot consistently determine which components are themeable (i.e. have a `ThemedComponent` wrapper) while linting. +To work around this issue, we construct a registry of themeable components _before_ linting anything. +- We don't have a good way to hook into the ESLint parser at this time +- Instead, we leverage the actual TypeScript AST parser + - Retrieve all `ThemedComponent` wrapper files by the pattern of their path (`themed-*.component.ts`) + - Determine the themed component they're linked to (by the actual type annotation/import path, since filenames are prone to errors) + - Store metadata describing these component pairs in a global registry that can be shared between rules +- This only needs to happen once, and only takes a fraction of a second (for ~100 themeable components) \ No newline at end of file diff --git a/lint/dist/src/rules/html/package.json b/lint/dist/src/rules/html/package.json new file mode 100644 index 0000000000..d3f310d23b --- /dev/null +++ b/lint/dist/src/rules/html/package.json @@ -0,0 +1,6 @@ +{ + "name": "eslint-plugin-dspace-angular-html", + "version": "0.0.0", + "main": "./index.js", + "private": true +} diff --git a/lint/dist/src/rules/ts/package.json b/lint/dist/src/rules/ts/package.json new file mode 100644 index 0000000000..f19e18756a --- /dev/null +++ b/lint/dist/src/rules/ts/package.json @@ -0,0 +1,6 @@ +{ + "name": "eslint-plugin-dspace-angular-ts", + "version": "0.0.0", + "main": "./index.js", + "private": true +} diff --git a/lint/generate-docs.ts b/lint/generate-docs.ts new file mode 100644 index 0000000000..fb2bf53fb5 --- /dev/null +++ b/lint/generate-docs.ts @@ -0,0 +1,85 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { + existsSync, + mkdirSync, + readFileSync, + rmSync, + writeFileSync, +} from 'fs'; +import { join } from 'path'; + +import { default as htmlPlugin } from './src/rules/html'; +import { default as tsPlugin } from './src/rules/ts'; + +const templates = new Map(); + +function lazyEJS(path: string, data: object): string { + if (!templates.has(path)) { + templates.set(path, require('ejs').compile(readFileSync(path).toString())); + } + + return templates.get(path)(data).replace(/\r\n/g, '\n'); +} + +const docsDir = join('docs', 'lint'); +const tsDir = join(docsDir, 'ts'); +const htmlDir = join(docsDir, 'html'); + +if (existsSync(docsDir)) { + rmSync(docsDir, { recursive: true }); +} + +mkdirSync(join(tsDir, 'rules'), { recursive: true }); +mkdirSync(join(htmlDir, 'rules'), { recursive: true }); + +function template(name: string): string { + return join('lint', 'src', 'util', 'templates', name); +} + +// TypeScript docs +writeFileSync( + join(tsDir, 'index.md'), + lazyEJS(template('index.ejs'), { + plugin: tsPlugin, + rules: tsPlugin.index.map(rule => rule.info), + }), +); + +for (const rule of tsPlugin.index) { + writeFileSync( + join(tsDir, 'rules', rule.info.name + '.md'), + lazyEJS(template('rule.ejs'), { + plugin: tsPlugin, + rule: rule.info, + tests: rule.tests, + }), + ); +} + +// HTML docs +writeFileSync( + join(htmlDir, 'index.md'), + lazyEJS(template('index.ejs'), { + plugin: htmlPlugin, + rules: htmlPlugin.index.map(rule => rule.info), + }), +); + +for (const rule of htmlPlugin.index) { + writeFileSync( + join(htmlDir, 'rules', rule.info.name + '.md'), + lazyEJS(template('rule.ejs'), { + plugin: htmlPlugin, + rule: rule.info, + tests: rule.tests, + }), + ); +} + diff --git a/lint/jasmine.json b/lint/jasmine.json new file mode 100644 index 0000000000..dfacd41a96 --- /dev/null +++ b/lint/jasmine.json @@ -0,0 +1,7 @@ +{ + "spec_files": ["**/*.spec.js"], + "spec_dir": "lint/dist/test", + "helpers": [ + "./test/helpers.js" + ] +} diff --git a/lint/src/rules/html/index.ts b/lint/src/rules/html/index.ts new file mode 100644 index 0000000000..7c1370ae2d --- /dev/null +++ b/lint/src/rules/html/index.ts @@ -0,0 +1,22 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +/* eslint-disable import/no-namespace */ +import { + bundle, + RuleExports, +} from '../../util/structure'; +import * as themedComponentUsages from './themed-component-usages'; + +const index = [ + themedComponentUsages, +] as unknown as RuleExports[]; + +export = { + parser: require('@angular-eslint/template-parser'), + ...bundle('dspace-angular-html', 'HTML', index), +}; diff --git a/lint/src/rules/html/themed-component-usages.ts b/lint/src/rules/html/themed-component-usages.ts new file mode 100644 index 0000000000..0b9a13456a --- /dev/null +++ b/lint/src/rules/html/themed-component-usages.ts @@ -0,0 +1,191 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { TmplAstElement } from '@angular-eslint/bundled-angular-compiler'; +import { TemplateParserServices } from '@angular-eslint/utils'; +import { + ESLintUtils, + TSESLint, +} from '@typescript-eslint/utils'; + +import { fixture } from '../../../test/fixture'; +import { + DSpaceESLintRuleInfo, + NamedTests, +} from '../../util/structure'; +import { + DISALLOWED_THEME_SELECTORS, + fixSelectors, +} from '../../util/theme-support'; +import { + getFilename, + getSourceCode, +} from '../../util/typescript'; + +export enum Message { + WRONG_SELECTOR = 'mustUseThemedWrapperSelector', +} + +export const info = { + name: 'themed-component-usages', + meta: { + docs: { + description: `Themeable components should be used via the selector of their \`ThemedComponent\` wrapper class + +This ensures that custom themes can correctly override _all_ instances of this component. +The only exception to this rule are unit tests, where we may want to use the base component in order to keep the test setup simple. + `, + }, + type: 'problem', + fixable: 'code', + schema: [], + messages: { + [Message.WRONG_SELECTOR]: 'Themeable components should be used via their ThemedComponent wrapper\'s selector', + }, + }, + defaultOptions: [], +} as DSpaceESLintRuleInfo; + +export const rule = ESLintUtils.RuleCreator.withoutDocs({ + ...info, + create(context: TSESLint.RuleContext) { + if (getFilename(context).includes('.spec.ts')) { + // skip inline templates in unit tests + return {}; + } + + const parserServices = getSourceCode(context).parserServices as TemplateParserServices; + + return { + [`Element$1[name = /^${DISALLOWED_THEME_SELECTORS}/]`](node: TmplAstElement) { + const { startSourceSpan, endSourceSpan } = node; + const openStart = startSourceSpan.start.offset as number; + + context.report({ + messageId: Message.WRONG_SELECTOR, + loc: parserServices.convertNodeSourceSpanToLoc(startSourceSpan), + fix(fixer) { + const oldSelector = node.name; + const newSelector = fixSelectors(oldSelector); + + const ops = [ + fixer.replaceTextRange([openStart + 1, openStart + 1 + oldSelector.length], newSelector), + ]; + + // make sure we don't mangle self-closing tags + if (endSourceSpan !== null && startSourceSpan.end.offset !== endSourceSpan.end.offset) { + const closeStart = endSourceSpan.start.offset as number; + const closeEnd = endSourceSpan.end.offset as number; + + ops.push(fixer.replaceTextRange([closeStart + 2, closeEnd - 1], newSelector)); + } + + return ops; + }, + }); + }, + }; + }, +}); + +export const tests = { + plugin: info.name, + valid: [ + { + name: 'use no-prefix selectors in HTML templates', + code: ` + + + + `, + }, + { + name: 'use no-prefix selectors in TypeScript templates', + code: ` +@Component({ + template: '' +}) +class Test { +} + `, + }, + { + name: 'use no-prefix selectors in TypeScript test templates', + filename: fixture('src/test.spec.ts'), + code: ` +@Component({ + template: '' +}) +class Test { +} + `, + }, + { + name: 'base selectors are also allowed in TypeScript test templates', + filename: fixture('src/test.spec.ts'), + code: ` +@Component({ + template: '' +}) +class Test { +} + `, + }, + ], + invalid: [ + { + name: 'themed override selectors are not allowed in HTML templates', + code: ` + + + + `, + errors: [ + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + ], + output: ` + + + + `, + }, + { + name: 'base selectors are not allowed in HTML templates', + code: ` + + + + `, + errors: [ + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + ], + output: ` + + + + `, + }, + ], +} as NamedTests; + +export default rule; diff --git a/lint/src/rules/ts/index.ts b/lint/src/rules/ts/index.ts new file mode 100644 index 0000000000..a7fdfe41ef --- /dev/null +++ b/lint/src/rules/ts/index.ts @@ -0,0 +1,25 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { + bundle, + RuleExports, +} from '../../util/structure'; +/* eslint-disable import/no-namespace */ +import * as themedComponentClasses from './themed-component-classes'; +import * as themedComponentSelectors from './themed-component-selectors'; +import * as themedComponentUsages from './themed-component-usages'; + +const index = [ + themedComponentClasses, + themedComponentSelectors, + themedComponentUsages, +] as unknown as RuleExports[]; + +export = { + ...bundle('dspace-angular-ts', 'TypeScript', index), +}; diff --git a/lint/src/rules/ts/themed-component-classes.ts b/lint/src/rules/ts/themed-component-classes.ts new file mode 100644 index 0000000000..66c37395b4 --- /dev/null +++ b/lint/src/rules/ts/themed-component-classes.ts @@ -0,0 +1,382 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { + ESLintUtils, + TSESLint, + TSESTree, +} from '@typescript-eslint/utils'; + +import { fixture } from '../../../test/fixture'; +import { + getComponentImportNode, + getComponentInitializer, + getComponentStandaloneNode, +} from '../../util/angular'; +import { appendObjectProperties } from '../../util/fix'; +import { DSpaceESLintRuleInfo } from '../../util/structure'; +import { + getBaseComponentClassName, + inThemedComponentOverrideFile, + isThemeableComponent, + isThemedComponentWrapper, +} from '../../util/theme-support'; +import { getFilename } from '../../util/typescript'; + +export enum Message { + NOT_STANDALONE = 'mustBeStandalone', + NOT_STANDALONE_IMPORTS_BASE = 'mustBeStandaloneAndImportBase', + WRAPPER_IMPORTS_BASE = 'wrapperShouldImportBase', +} + +export const info = { + name: 'themed-component-classes', + meta: { + docs: { + description: `Formatting rules for themeable component classes + +- All themeable components must be standalone. +- The base component must always be imported in the \`ThemedComponent\` wrapper. This ensures that it is always sufficient to import just the wrapper whenever we use the component. + `, + }, + type: 'problem', + fixable: 'code', + schema: [], + messages: { + [Message.NOT_STANDALONE]: 'Themeable components must be standalone', + [Message.NOT_STANDALONE_IMPORTS_BASE]: 'Themeable component wrapper classes must be standalone and import the base class', + [Message.WRAPPER_IMPORTS_BASE]: 'Themed component wrapper classes must only import the base class', + }, + }, + defaultOptions: [], +} as DSpaceESLintRuleInfo; + +export const rule = ESLintUtils.RuleCreator.withoutDocs({ + ...info, + create(context: TSESLint.RuleContext) { + const filename = getFilename(context); + + if (filename.endsWith('.spec.ts')) { + return {}; + } + + function enforceStandalone(decoratorNode: TSESTree.Decorator, withBaseImport = false) { + const standaloneNode = getComponentStandaloneNode(decoratorNode); + + if (standaloneNode === undefined) { + // We may need to add these properties in one go + if (!withBaseImport) { + context.report({ + messageId: Message.NOT_STANDALONE, + node: decoratorNode, + fix(fixer) { + const initializer = getComponentInitializer(decoratorNode); + return appendObjectProperties(context, fixer, initializer, ['standalone: true']); + }, + }); + } + } else if (!standaloneNode.value) { + context.report({ + messageId: Message.NOT_STANDALONE, + node: standaloneNode, + fix(fixer) { + return fixer.replaceText(standaloneNode, 'true'); + }, + }); + } + + if (withBaseImport) { + const baseClass = getBaseComponentClassName(decoratorNode); + + if (baseClass === undefined) { + return; + } + + const importsNode = getComponentImportNode(decoratorNode); + + if (importsNode === undefined) { + if (standaloneNode === undefined) { + context.report({ + messageId: Message.NOT_STANDALONE_IMPORTS_BASE, + node: decoratorNode, + fix(fixer) { + const initializer = getComponentInitializer(decoratorNode); + return appendObjectProperties(context, fixer, initializer, ['standalone: true', `imports: [${baseClass}]`]); + }, + }); + } else { + context.report({ + messageId: Message.WRAPPER_IMPORTS_BASE, + node: decoratorNode, + fix(fixer) { + const initializer = getComponentInitializer(decoratorNode); + return appendObjectProperties(context, fixer, initializer, [`imports: [${baseClass}]`]); + }, + }); + } + } else { + // If we have an imports node, standalone: true will be enforced by another rule + + const imports = importsNode.elements.map(e => (e as TSESTree.Identifier).name); + + if (!imports.includes(baseClass) || imports.length > 1) { + // The wrapper should _only_ import the base component + context.report({ + messageId: Message.WRAPPER_IMPORTS_BASE, + node: importsNode, + fix(fixer) { + // todo: this may leave unused imports, but that's better than mangling things + return fixer.replaceText(importsNode, `[${baseClass}]`); + }, + }); + } + } + } + } + + return { + 'ClassDeclaration > Decorator[expression.callee.name = "Component"]'(node: TSESTree.Decorator) { + const classNode = node.parent as TSESTree.ClassDeclaration; + const className = classNode.id?.name; + + if (className === undefined) { + return; + } + + if (isThemedComponentWrapper(node)) { + enforceStandalone(node, true); + } else if (inThemedComponentOverrideFile(filename)) { + enforceStandalone(node); + } else if (isThemeableComponent(className)) { + enforceStandalone(node); + } + }, + }; + }, +}); + +export const tests = { + plugin: info.name, + valid: [ + { + name: 'Regular non-themeable component', + code: ` +@Component({ + selector: 'ds-something', + standalone: true, +}) +class Something { +} + `, + }, + { + name: 'Base component', + code: ` +@Component({ + selector: 'ds-base-test-themable', + standalone: true, +}) +class TestThemeableTomponent { +} + `, + }, + { + name: 'Wrapper component', + filename: fixture('src/app/test/themed-test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [ + TestThemeableComponent, + ], +}) +class ThemedTestThemeableTomponent extends ThemedComponent { +} + `, + }, + { + name: 'Override component', + filename: fixture('src/themes/test/app/test/test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-themed-test-themable', + standalone: true, +}) +class Override extends BaseComponent { +} + `, + }, + ], + invalid: [ + { + name: 'Base component must be standalone', + code: ` +@Component({ + selector: 'ds-base-test-themable', +}) +class TestThemeableComponent { +} + `, + errors:[ + { + messageId: Message.NOT_STANDALONE, + }, + ], + output: ` +@Component({ + selector: 'ds-base-test-themable', + standalone: true, +}) +class TestThemeableComponent { +} + `, + }, + { + name: 'Wrapper component must be standalone and import base component', + filename: fixture('src/app/test/themed-test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-test-themable', +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + errors:[ + { + messageId: Message.NOT_STANDALONE_IMPORTS_BASE, + }, + ], + output: ` +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + }, + + { + name: 'Wrapper component must import base component (array present but empty)', + filename: fixture('src/app/test/themed-test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + errors:[ + { + messageId: Message.WRAPPER_IMPORTS_BASE, + }, + ], + output: ` +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + }, + { + name: 'Wrapper component must import base component (array is wrong)', + filename: fixture('src/app/test/themed-test-themeable.component.ts'), + code: ` +import { SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [ + SomethingElse, + ], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + errors:[ + { + messageId: Message.WRAPPER_IMPORTS_BASE, + }, + ], + output: ` +import { SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + }, { + name: 'Wrapper component must import base component (array is wrong)', + filename: fixture('src/app/test/themed-test-themeable.component.ts'), + code: ` +import { Something, SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [ + SomethingElse, + ], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + errors:[ + { + messageId: Message.WRAPPER_IMPORTS_BASE, + }, + ], + output: ` +import { Something, SomethingElse } from './somewhere-else'; + +@Component({ + selector: 'ds-test-themable', + standalone: true, + imports: [TestThemeableComponent], +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + }, + { + name: 'Override component must be standalone', + filename: fixture('src/themes/test/app/test/test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-themed-test-themable', +}) +class Override extends BaseComponent { +} + `, + errors:[ + { + messageId: Message.NOT_STANDALONE, + }, + ], + output: ` +@Component({ + selector: 'ds-themed-test-themable', + standalone: true, +}) +class Override extends BaseComponent { +} + `, + }, + ], +}; diff --git a/lint/src/rules/ts/themed-component-selectors.ts b/lint/src/rules/ts/themed-component-selectors.ts new file mode 100644 index 0000000000..e06f5ababf --- /dev/null +++ b/lint/src/rules/ts/themed-component-selectors.ts @@ -0,0 +1,257 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { + ESLintUtils, + TSESLint, + TSESTree, +} from '@typescript-eslint/utils'; + +import { fixture } from '../../../test/fixture'; +import { getComponentSelectorNode } from '../../util/angular'; +import { stringLiteral } from '../../util/misc'; +import { DSpaceESLintRuleInfo } from '../../util/structure'; +import { + inThemedComponentOverrideFile, + isThemeableComponent, + isThemedComponentWrapper, +} from '../../util/theme-support'; +import { getFilename } from '../../util/typescript'; + +export enum Message { + BASE = 'wrongSelectorUnthemedComponent', + WRAPPER = 'wrongSelectorThemedComponentWrapper', + THEMED = 'wrongSelectorThemedComponentOverride', +} + +export const info = { + name: 'themed-component-selectors', + meta: { + docs: { + description: `Themeable component selectors should follow the DSpace convention + +Each themeable component is comprised of a base component, a wrapper component and any number of themed components +- Base components should have a selector starting with \`ds-base-\` +- Themed components should have a selector starting with \`ds-themed-\` +- Wrapper components should have a selector starting with \`ds-\`, but not \`ds-base-\` or \`ds-themed-\` + - This is the regular DSpace selector prefix + - **When making a regular component themeable, its selector prefix should be changed to \`ds-base-\`, and the new wrapper's component should reuse the previous selector** + +Unit tests are exempt from this rule, because they may redefine components using the same class name as other themeable components elsewhere in the source. + `, + }, + type: 'problem', + schema: [], + fixable: 'code', + messages: { + [Message.BASE]: 'Unthemed version of themeable component should have a selector starting with \'ds-base-\'', + [Message.WRAPPER]: 'Themed component wrapper of themeable component shouldn\'t have a selector starting with \'ds-themed-\'', + [Message.THEMED]: 'Theme override of themeable component should have a selector starting with \'ds-themed-\'', + }, + }, + defaultOptions: [], +} as DSpaceESLintRuleInfo; + +export const rule = ESLintUtils.RuleCreator.withoutDocs({ + ...info, + create(context: TSESLint.RuleContext) { + const filename = getFilename(context); + + if (filename.endsWith('.spec.ts')) { + return {}; + } + + function enforceWrapperSelector(selectorNode: TSESTree.StringLiteral) { + if (selectorNode?.value.startsWith('ds-themed-')) { + context.report({ + messageId: Message.WRAPPER, + node: selectorNode, + fix(fixer) { + return fixer.replaceText(selectorNode, stringLiteral(selectorNode.value.replace('ds-themed-', 'ds-'))); + }, + }); + } + } + + function enforceBaseSelector(selectorNode: TSESTree.StringLiteral) { + if (!selectorNode?.value.startsWith('ds-base-')) { + context.report({ + messageId: Message.BASE, + node: selectorNode, + fix(fixer) { + return fixer.replaceText(selectorNode, stringLiteral(selectorNode.value.replace('ds-', 'ds-base-'))); + }, + }); + } + } + + function enforceThemedSelector(selectorNode: TSESTree.StringLiteral) { + if (!selectorNode?.value.startsWith('ds-themed-')) { + context.report({ + messageId: Message.THEMED, + node: selectorNode, + fix(fixer) { + return fixer.replaceText(selectorNode, stringLiteral(selectorNode.value.replace('ds-', 'ds-themed-'))); + }, + }); + } + } + + return { + 'ClassDeclaration > Decorator[expression.callee.name = "Component"]'(node: TSESTree.Decorator) { + const selectorNode = getComponentSelectorNode(node); + + if (selectorNode === undefined) { + return; + } + + const selector = selectorNode?.value; + const classNode = node.parent as TSESTree.ClassDeclaration; + const className = classNode.id?.name; + + if (selector === undefined || className === undefined) { + return; + } + + if (isThemedComponentWrapper(node)) { + enforceWrapperSelector(selectorNode); + } else if (inThemedComponentOverrideFile(filename)) { + enforceThemedSelector(selectorNode); + } else if (isThemeableComponent(className)) { + enforceBaseSelector(selectorNode); + } + }, + }; + }, +}); + +export const tests = { + plugin: info.name, + valid: [ + { + name: 'Regular non-themeable component selector', + code: ` +@Component({ + selector: 'ds-something', +}) +class Something { +} + `, + }, + { + name: 'Themeable component selector should replace the original version, unthemed version should be changed to ds-base-', + code: ` +@Component({ + selector: 'ds-base-something', +}) +class Something { +} + +@Component({ + selector: 'ds-something', +}) +class ThemedSomething extends ThemedComponent { +} + +@Component({ + selector: 'ds-themed-something', +}) +class OverrideSomething extends Something { +} + `, + }, + { + name: 'Other themed component wrappers should not interfere', + code: ` +@Component({ + selector: 'ds-something', +}) +class Something { +} + +@Component({ + selector: 'ds-something-else', +}) +class ThemedSomethingElse extends ThemedComponent { +} + `, + }, + ], + invalid: [ + { + name: 'Wrong selector for base component', + filename: fixture('src/app/test/test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-something', +}) +class TestThemeableComponent { +} + `, + errors: [ + { + messageId: Message.BASE, + }, + ], + output: ` +@Component({ + selector: 'ds-base-something', +}) +class TestThemeableComponent { +} + `, + }, + { + name: 'Wrong selector for wrapper component', + filename: fixture('src/app/test/themed-test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-themed-something', +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + errors: [ + { + messageId: Message.WRAPPER, + }, + ], + output: ` +@Component({ + selector: 'ds-something', +}) +class ThemedTestThemeableComponent extends ThemedComponent { +} + `, + }, + { + name: 'Wrong selector for theme override', + filename: fixture('src/themes/test/app/test/test-themeable.component.ts'), + code: ` +@Component({ + selector: 'ds-something', +}) +class TestThememeableComponent extends BaseComponent { +} + `, + errors: [ + { + messageId: Message.THEMED, + }, + ], + output: ` +@Component({ + selector: 'ds-themed-something', +}) +class TestThememeableComponent extends BaseComponent { +} + `, + }, + ], +}; + +export default rule; diff --git a/lint/src/rules/ts/themed-component-usages.ts b/lint/src/rules/ts/themed-component-usages.ts new file mode 100644 index 0000000000..96e9962ccf --- /dev/null +++ b/lint/src/rules/ts/themed-component-usages.ts @@ -0,0 +1,502 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { + ESLintUtils, + TSESLint, + TSESTree, +} from '@typescript-eslint/utils'; + +import { fixture } from '../../../test/fixture'; +import { + removeWithCommas, + replaceOrRemoveArrayIdentifier, +} from '../../util/fix'; +import { DSpaceESLintRuleInfo } from '../../util/structure'; +import { + allThemeableComponents, + DISALLOWED_THEME_SELECTORS, + fixSelectors, + getThemeableComponentByBaseClass, + isAllowedUnthemedUsage, +} from '../../util/theme-support'; +import { + findImportSpecifier, + findUsages, + findUsagesByName, + getFilename, + relativePath, +} from '../../util/typescript'; + +export enum Message { + WRONG_CLASS = 'mustUseThemedWrapperClass', + WRONG_IMPORT = 'mustImportThemedWrapper', + WRONG_SELECTOR = 'mustUseThemedWrapperSelector', + BASE_IN_MODULE = 'baseComponentNotNeededInModule', +} + +export const info = { + name: 'themed-component-usages', + meta: { + docs: { + description: `Themeable components should be used via their \`ThemedComponent\` wrapper class + +This ensures that custom themes can correctly override _all_ instances of this component. +There are a few exceptions where the base class can still be used: +- Class declaration expressions (otherwise we can't declare, extend or override the class in the first place) +- Angular modules (except for routing modules) +- Angular \`@ViewChild\` decorators +- Type annotations + `, + }, + type: 'problem', + schema: [], + fixable: 'code', + messages: { + [Message.WRONG_CLASS]: 'Themeable components should be used via their ThemedComponent wrapper', + [Message.WRONG_IMPORT]: 'Themeable components should be used via their ThemedComponent wrapper', + [Message.WRONG_SELECTOR]: 'Themeable components should be used via their ThemedComponent wrapper', + [Message.BASE_IN_MODULE]: 'Base themeable components shouldn\'t be declared in modules', + }, + }, + defaultOptions: [], +} as DSpaceESLintRuleInfo; + +export const rule = ESLintUtils.RuleCreator.withoutDocs({ + ...info, + create(context: TSESLint.RuleContext) { + const filename = getFilename(context); + + function handleUnthemedUsagesInTypescript(node: TSESTree.Identifier) { + if (isAllowedUnthemedUsage(node)) { + return; + } + + const entry = getThemeableComponentByBaseClass(node.name); + + if (entry === undefined) { + // this should never happen + throw new Error(`No such themeable component in registry: '${node.name}'`); + } + + context.report({ + messageId: Message.WRONG_CLASS, + node: node, + fix(fixer) { + if (node.parent.type === TSESTree.AST_NODE_TYPES.ArrayExpression) { + return replaceOrRemoveArrayIdentifier(context, fixer, node, entry.wrapperClass); + } else { + return fixer.replaceText(node, entry.wrapperClass); + } + }, + }); + } + + function handleThemedSelectorQueriesInTests(node: TSESTree.Literal) { + context.report({ + node, + messageId: Message.WRONG_SELECTOR, + fix(fixer){ + const newSelector = fixSelectors(node.raw); + return fixer.replaceText(node, newSelector); + }, + }); + } + + function handleUnthemedImportsInTypescript(specifierNode: TSESTree.ImportSpecifier) { + const allUsages = findUsages(context, specifierNode.local); + const badUsages = allUsages.filter(usage => !isAllowedUnthemedUsage(usage)); + + if (badUsages.length === 0) { + return; + } + + const importedNode = specifierNode.imported; + const declarationNode = specifierNode.parent as TSESTree.ImportDeclaration; + + const entry = getThemeableComponentByBaseClass(importedNode.name); + if (entry === undefined) { + // this should never happen + throw new Error(`No such themeable component in registry: '${importedNode.name}'`); + } + + context.report({ + messageId: Message.WRONG_IMPORT, + node: importedNode, + fix(fixer) { + const ops = []; + + const wrapperImport = findImportSpecifier(context, entry.wrapperClass); + + if (findUsagesByName(context, entry.wrapperClass).length === 0) { + // Wrapper is not present in this file, safe to add import + + const newImportLine = `import { ${entry.wrapperClass} } from '${relativePath(filename, entry.wrapperPath)}';`; + + if (declarationNode.specifiers.length === 1) { + if (allUsages.length === badUsages.length) { + ops.push(fixer.replaceText(declarationNode, newImportLine)); + } else if (wrapperImport === undefined) { + ops.push(fixer.insertTextAfter(declarationNode, '\n' + newImportLine)); + } + } else { + ops.push(...removeWithCommas(context, fixer, specifierNode)); + if (wrapperImport === undefined) { + ops.push(fixer.insertTextAfter(declarationNode, '\n' + newImportLine)); + } + } + } else { + // Wrapper already present in the file, remove import instead + + if (allUsages.length === badUsages.length) { + if (declarationNode.specifiers.length === 1) { + // Make sure we remove the newline as well + ops.push(fixer.removeRange([declarationNode.range[0], declarationNode.range[1] + 1])); + } else { + ops.push(...removeWithCommas(context, fixer, specifierNode)); + } + } + } + + return ops; + }, + }); + } + + // ignore tests and non-routing modules + if (filename.endsWith('.spec.ts')) { + return { + [`CallExpression[callee.object.name = "By"][callee.property.name = "css"] > Literal:first-child[value = /.*${DISALLOWED_THEME_SELECTORS}.*/]`]: handleThemedSelectorQueriesInTests, + }; + } else if (filename.endsWith('.cy.ts')) { + return { + [`CallExpression[callee.object.name = "cy"][callee.property.name = "get"] > Literal:first-child[value = /.*${DISALLOWED_THEME_SELECTORS}.*/]`]: handleThemedSelectorQueriesInTests, + }; + } else if ( + filename.match(/(?!src\/themes\/).*(?!routing).module.ts$/) + || filename.match(/themed-.+\.component\.ts$/) + ) { + // do nothing + return {}; + } else { + return allThemeableComponents().reduce( + (rules, entry) => { + return { + ...rules, + [`:not(:matches(ClassDeclaration, ImportSpecifier)) > Identifier[name = "${entry.baseClass}"]`]: handleUnthemedUsagesInTypescript, + [`ImportSpecifier[imported.name = "${entry.baseClass}"]`]: handleUnthemedImportsInTypescript, + }; + }, {}, + ); + } + + }, +}); + +export const tests = { + plugin: info.name, + valid: [ + { + name: 'allow wrapper class usages', + code: ` +import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; + +const config = { + a: ThemedTestThemeableComponent, + b: ChipsComponent, +} + `, + }, + { + name: 'allow base class in class declaration', + code: ` +export class TestThemeableComponent { +} + `, + }, + { + name: 'allow inheriting from base class', + code: ` +import { TestThemeableComponent } from './app/test/test-themeable.component'; + +export class ThemedAdminSidebarComponent extends ThemedComponent { +} + `, + }, + { + name: 'allow base class in ViewChild', + code: ` +import { TestThemeableComponent } from './app/test/test-themeable.component'; + +export class Something { + @ViewChild(TestThemeableComponent) test: TestThemeableComponent; +} + `, + }, + { + name: 'allow wrapper selectors in test queries', + filename: fixture('src/app/test/test.component.spec.ts'), + code: ` +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); + `, + }, + { + name: 'allow wrapper selectors in cypress queries', + filename: fixture('src/app/test/test.component.cy.ts'), + code: ` +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); + `, + }, + ], + invalid: [ + { + name: 'disallow direct usages of base class', + code: ` +import { TestThemeableComponent } from './app/test/test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: TestThemeableComponent, + b: TestComponent, +} + `, + errors: [ + { + messageId: Message.WRONG_IMPORT, + }, + { + messageId: Message.WRONG_CLASS, + }, + ], + output: ` +import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: ThemedTestThemeableComponent, + b: TestComponent, +} + `, + }, + { + name: 'disallow direct usages of base class, keep other imports', + code: ` +import { Something, TestThemeableComponent } from './app/test/test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: TestThemeableComponent, + b: TestComponent, + c: Something, +} + `, + errors: [ + { + messageId: Message.WRONG_IMPORT, + }, + { + messageId: Message.WRONG_CLASS, + }, + ], + output: ` +import { Something } from './app/test/test-themeable.component'; +import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; +import { TestComponent } from './app/test/test.component'; + +const config = { + a: ThemedTestThemeableComponent, + b: TestComponent, + c: Something, +} + `, + }, + { + name: 'handle array replacements correctly', + code: ` +const DECLARATIONS = [ + Something, + TestThemeableComponent, + Something, + ThemedTestThemeableComponent, +]; + `, + errors: [ + { + messageId: Message.WRONG_CLASS, + }, + ], + output: ` +const DECLARATIONS = [ + Something, + Something, + ThemedTestThemeableComponent, +]; + `, + }, + { + name: 'disallow override selector in test queries', + filename: fixture('src/app/test/test.component.spec.ts'), + code: ` +By.css('ds-themed-themeable'); +By.css('#test > ds-themed-themeable > #nest'); + `, + errors: [ + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + ], + output: ` +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); + `, + }, + { + name: 'disallow base selector in test queries', + filename: fixture('src/app/test/test.component.spec.ts'), + code: ` +By.css('ds-base-themeable'); +By.css('#test > ds-base-themeable > #nest'); + `, + errors: [ + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + ], + output: ` +By.css('ds-themeable'); +By.css('#test > ds-themeable > #nest'); + `, + }, + { + name: 'disallow override selector in cypress queries', + filename: fixture('src/app/test/test.component.cy.ts'), + code: ` +cy.get('ds-themed-themeable'); +cy.get('#test > ds-themed-themeable > #nest'); + `, + errors: [ + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + ], + output: ` +cy.get('ds-themeable'); +cy.get('#test > ds-themeable > #nest'); + `, + }, + { + name: 'disallow base selector in cypress queries', + filename: fixture('src/app/test/test.component.cy.ts'), + code: ` +cy.get('ds-base-themeable'); +cy.get('#test > ds-base-themeable > #nest'); + `, + errors: [ + { + messageId: Message.WRONG_SELECTOR, + }, + { + messageId: Message.WRONG_SELECTOR, + }, + ], + output: ` +cy.get('ds-themeable'); +cy.get('#test > ds-themeable > #nest'); + `, + }, + { + name: 'edge case: unable to find usage node through usage token, but import is still flagged and fixed', + filename: fixture('src/themes/test/app/test/other-themeable.component.ts'), + code: ` +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { TestThemeableComponent } from '../../../../app/test/test-themeable.component'; + +@Component({ + standalone: true, + imports: [TestThemeableComponent], +}) +export class UsageComponent { +} + `, + errors: [ + { + messageId: Message.WRONG_IMPORT, + }, + { + messageId: Message.WRONG_CLASS, + }, + ], + output: ` +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component'; + +@Component({ + standalone: true, + imports: [ThemedTestThemeableComponent], +}) +export class UsageComponent { +} + `, + }, + { + name: 'edge case edge case: both are imported, only wrapper is retained', + filename: fixture('src/themes/test/app/test/other-themeable.component.ts'), + code: ` +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { TestThemeableComponent } from '../../../../app/test/test-themeable.component'; +import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component'; + +@Component({ + standalone: true, + imports: [TestThemeableComponent, ThemedTestThemeableComponent], +}) +export class UsageComponent { +} + `, + errors: [ + { + messageId: Message.WRONG_IMPORT, + }, + { + messageId: Message.WRONG_CLASS, + }, + ], + output: ` +import { Component } from '@angular/core'; + +import { Context } from './app/core/shared/context.model'; +import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component'; + +@Component({ + standalone: true, + imports: [ThemedTestThemeableComponent], +}) +export class UsageComponent { +} + `, + }, + ], +}; + +export default rule; diff --git a/lint/src/util/angular.ts b/lint/src/util/angular.ts new file mode 100644 index 0000000000..70ee903fb8 --- /dev/null +++ b/lint/src/util/angular.ts @@ -0,0 +1,83 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { TSESTree } from '@typescript-eslint/utils'; + +import { getObjectPropertyNodeByName } from './typescript'; + +export function getComponentSelectorNode(componentDecoratorNode: TSESTree.Decorator): TSESTree.StringLiteral | undefined { + const property = getComponentInitializerNodeByName(componentDecoratorNode, 'selector'); + + if (property !== undefined) { + // todo: support template literals as well + if (property.type === TSESTree.AST_NODE_TYPES.Literal && typeof property.value === 'string') { + return property as TSESTree.StringLiteral; + } + } + + return undefined; +} + +export function getComponentStandaloneNode(componentDecoratorNode: TSESTree.Decorator): TSESTree.BooleanLiteral | undefined { + const property = getComponentInitializerNodeByName(componentDecoratorNode, 'standalone'); + + if (property !== undefined) { + if (property.type === TSESTree.AST_NODE_TYPES.Literal && typeof property.value === 'boolean') { + return property as TSESTree.BooleanLiteral; + } + } + + return undefined; +} +export function getComponentImportNode(componentDecoratorNode: TSESTree.Decorator): TSESTree.ArrayExpression | undefined { + const property = getComponentInitializerNodeByName(componentDecoratorNode, 'imports'); + + if (property !== undefined) { + if (property.type === TSESTree.AST_NODE_TYPES.ArrayExpression) { + return property as TSESTree.ArrayExpression; + } + } + + return undefined; +} + +export function getComponentClassName(decoratorNode: TSESTree.Decorator): string | undefined { + if (decoratorNode.parent.type !== TSESTree.AST_NODE_TYPES.ClassDeclaration) { + return undefined; + } + + if (decoratorNode.parent.id?.type !== TSESTree.AST_NODE_TYPES.Identifier) { + return undefined; + } + + return decoratorNode.parent.id.name; +} + +export function getComponentSuperClassName(decoratorNode: TSESTree.Decorator): string | undefined { + if (decoratorNode.parent.type !== TSESTree.AST_NODE_TYPES.ClassDeclaration) { + return undefined; + } + + if (decoratorNode.parent.superClass?.type !== TSESTree.AST_NODE_TYPES.Identifier) { + return undefined; + } + + return decoratorNode.parent.superClass.name; +} + +export function getComponentInitializer(componentDecoratorNode: TSESTree.Decorator): TSESTree.ObjectExpression { + return (componentDecoratorNode.expression as TSESTree.CallExpression).arguments[0] as TSESTree.ObjectExpression; +} + +export function getComponentInitializerNodeByName(componentDecoratorNode: TSESTree.Decorator, name: string): TSESTree.Node | undefined { + const initializer = getComponentInitializer(componentDecoratorNode); + return getObjectPropertyNodeByName(initializer, name); +} + +export function isPartOfViewChild(node: TSESTree.Identifier): boolean { + return (node.parent as any)?.callee?.name === 'ViewChild'; +} diff --git a/lint/src/util/fix.ts b/lint/src/util/fix.ts new file mode 100644 index 0000000000..10408cc316 --- /dev/null +++ b/lint/src/util/fix.ts @@ -0,0 +1,125 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { TSESTree } from '@typescript-eslint/utils'; +import { + RuleContext, + RuleFix, + RuleFixer, +} from '@typescript-eslint/utils/ts-eslint'; + +import { getSourceCode } from './typescript'; + + + +export function appendObjectProperties(context: RuleContext, fixer: RuleFixer, objectNode: TSESTree.ObjectExpression, properties: string[]): RuleFix { + // todo: may not handle empty objects too well + const lastProperty = objectNode.properties[objectNode.properties.length - 1]; + const source = getSourceCode(context); + const nextToken = source.getTokenAfter(lastProperty); + + // todo: newline & indentation are hardcoded for @Component({}) + // todo: we're assuming that we need trailing commas, what if we don't? + const newPart = '\n' + properties.map(p => ` ${p},`).join('\n'); + + if (nextToken !== null && nextToken.value === ',') { + return fixer.insertTextAfter(nextToken, newPart); + } else { + return fixer.insertTextAfter(lastProperty, ',' + newPart); + } +} + +export function appendArrayElement(context: RuleContext, fixer: RuleFixer, arrayNode: TSESTree.ArrayExpression, value: string): RuleFix { + const source = getSourceCode(context); + + if (arrayNode.elements.length === 0) { + // This is the first element + const openArray = source.getTokenByRangeStart(arrayNode.range[0]); + + if (openArray == null) { + throw new Error('Unexpected null token for opening square bracket'); + } + + // safe to assume the list is single-line + return fixer.insertTextAfter(openArray, `${value}`); + } else { + const lastElement = arrayNode.elements[arrayNode.elements.length - 1]; + + if (lastElement == null) { + throw new Error('Unexpected null node in array'); + } + + const nextToken = source.getTokenAfter(lastElement); + + // todo: we don't know if the list is chopped or not, so we can't make any assumptions -- may produce output that will be flagged by other rules on the next run! + // todo: we're assuming that we need trailing commas, what if we don't? + if (nextToken !== null && nextToken.value === ',') { + return fixer.insertTextAfter(nextToken, ` ${value},`); + } else { + return fixer.insertTextAfter(lastElement, `, ${value},`); + } + } + +} + +export function isLast(elementNode: TSESTree.Node): boolean { + if (!elementNode.parent) { + return false; + } + + let siblingNodes: (TSESTree.Node | null)[] = [null]; + if (elementNode.parent.type === TSESTree.AST_NODE_TYPES.ArrayExpression) { + siblingNodes = elementNode.parent.elements; + } else if (elementNode.parent.type === TSESTree.AST_NODE_TYPES.ImportDeclaration) { + siblingNodes = elementNode.parent.specifiers; + } + + return elementNode === siblingNodes[siblingNodes.length - 1]; +} + +export function removeWithCommas(context: RuleContext, fixer: RuleFixer, elementNode: TSESTree.Node): RuleFix[] { + const ops = []; + + const source = getSourceCode(context); + let nextToken = source.getTokenAfter(elementNode); + let prevToken = source.getTokenBefore(elementNode); + + if (nextToken !== null && prevToken !== null) { + if (nextToken.value === ',') { + nextToken = source.getTokenAfter(nextToken); + if (nextToken !== null) { + ops.push(fixer.removeRange([elementNode.range[0], nextToken.range[0]])); + } + } + if (isLast(elementNode) && prevToken.value === ',') { + prevToken = source.getTokenBefore(prevToken); + if (prevToken !== null) { + ops.push(fixer.removeRange([prevToken.range[1], elementNode.range[1]])); + } + } + } else if (nextToken !== null) { + ops.push(fixer.removeRange([elementNode.range[0], nextToken.range[0]])); + } + + return ops; +} + +export function replaceOrRemoveArrayIdentifier(context: RuleContext, fixer: RuleFixer, identifierNode: TSESTree.Identifier, newValue: string): RuleFix[] { + if (identifierNode.parent.type !== TSESTree.AST_NODE_TYPES.ArrayExpression) { + throw new Error('Parent node is not an array expression!'); + } + + const array = identifierNode.parent as TSESTree.ArrayExpression; + + for (const element of array.elements) { + if (element !== null && element.type === TSESTree.AST_NODE_TYPES.Identifier && element.name === newValue) { + return removeWithCommas(context, fixer, identifierNode); + } + } + + return [fixer.replaceText(identifierNode, newValue)]; +} diff --git a/lint/src/util/misc.ts b/lint/src/util/misc.ts new file mode 100644 index 0000000000..49cb60124e --- /dev/null +++ b/lint/src/util/misc.ts @@ -0,0 +1,28 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +export function match(rangeA: number[], rangeB: number[]) { + return rangeA[0] === rangeB[0] && rangeA[1] === rangeB[1]; +} + + +export function stringLiteral(value: string): string { + return `'${value}'`; +} + +/** + * Transform Windows-style paths into Unix-style paths + */ +export function toUnixStylePath(path: string): string { + // note: we're assuming that none of the directory/file names contain '\' or '/' characters. + // using these characters in paths is very bad practice in general, so this should be a safe assumption. + if (path.includes('\\')) { + return path.replace(/^[A-Z]:\\/, '/').replaceAll('\\', '/'); + } + return path; +} diff --git a/lint/src/util/structure.ts b/lint/src/util/structure.ts new file mode 100644 index 0000000000..bfbf7ec7f2 --- /dev/null +++ b/lint/src/util/structure.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { TSESLint } from '@typescript-eslint/utils'; +import { RuleTester } from 'eslint'; +import { EnumType } from 'typescript'; + +export type Meta = TSESLint.RuleMetaData; +export type Valid = TSESLint.ValidTestCase | RuleTester.ValidTestCase; +export type Invalid = TSESLint.InvalidTestCase | RuleTester.InvalidTestCase; + +export interface DSpaceESLintRuleInfo { + name: string; + meta: Meta, + defaultOptions: unknown[], +} + +export interface NamedTests { + plugin: string; + valid: Valid[]; + invalid: Invalid[]; +} + +export interface RuleExports { + Message: EnumType, + info: DSpaceESLintRuleInfo, + rule: TSESLint.RuleModule, + tests: NamedTests, + default: unknown, +} + +export interface PluginExports { + name: string, + language: string, + rules: Record, + index: RuleExports[], +} + +export function bundle( + name: string, + language: string, + index: RuleExports[], +): PluginExports { + return index.reduce((o: PluginExports, i: RuleExports) => { + o.rules[i.info.name] = i.rule; + return o; + }, { + name, + language, + rules: {}, + index, + }); +} diff --git a/lint/src/util/templates/index.ejs b/lint/src/util/templates/index.ejs new file mode 100644 index 0000000000..d959f29291 --- /dev/null +++ b/lint/src/util/templates/index.ejs @@ -0,0 +1,5 @@ +[DSpace ESLint plugins](../../../lint/README.md) > <%= plugin.language %> rules +_______ +<% rules.forEach(rule => { %> +- [`<%= plugin.name %>/<%= rule.name %>`](./rules/<%= rule.name %>.md)<% if (rule.meta?.docs?.description) {%>: <%= rule.meta.docs.description.split('\n')[0].trim() -%><% }-%> +<% }) %> diff --git a/lint/src/util/templates/rule.ejs b/lint/src/util/templates/rule.ejs new file mode 100644 index 0000000000..b39d193cc1 --- /dev/null +++ b/lint/src/util/templates/rule.ejs @@ -0,0 +1,48 @@ +[DSpace ESLint plugins](../../../../lint/README.md) > [<%= plugin.language %> rules](../index.md) > `<%= plugin.name %>/<%= rule.name %>` +_______ + +<%- rule.meta.docs?.description %> + +_______ + +[Source code](../../../../lint/src/rules/<%- plugin.name.replace('dspace-angular-', '') %>/<%- rule.name %>.ts) + +### Examples + +<% if (tests.valid) {%> +#### Valid code + <% tests.valid.forEach(test => { %> +##### <%= test.name !== undefined ? test.name : 'UNNAMED' %> + <% if (test.filename) { %> +Filename: `<%- test.filename %>` + <% } %> +```<%- plugin.language.toLowerCase() %> +<%- test.code.trim() %> +``` + <% }) %> +<% } %> + +<% if (tests.invalid) {%> +#### Invalid code <%= rule.meta.fixable ? ' & automatic fixes' : '' %> + <% tests.invalid.forEach(test => { %> +##### <%= test.name !== undefined ? test.name : 'UNNAMED' %> + <% if (test.filename) { %> +Filename: `<%- test.filename %>` + <% } %> +```<%- plugin.language.toLowerCase() %> +<%- test.code.trim() %> +``` +Will produce the following error(s): +``` +<% for (const error of test.errors) { -%> +<%- rule.meta.messages[error.messageId] %> +<% } -%> +``` + <% if (test.output) { %> +Result of `yarn lint --fix`: +```<%- plugin.language.toLowerCase() %> +<%- test.output.trim() %> +``` + <% } %> + <% }) %> +<% } %> diff --git a/lint/src/util/theme-support.ts b/lint/src/util/theme-support.ts new file mode 100644 index 0000000000..64644145fa --- /dev/null +++ b/lint/src/util/theme-support.ts @@ -0,0 +1,265 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TSESTree } from '@typescript-eslint/utils'; +import { readFileSync } from 'fs'; +import { basename } from 'path'; +import ts, { Identifier } from 'typescript'; + +import { + getComponentClassName, + isPartOfViewChild, +} from './angular'; +import { + isPartOfClassDeclaration, + isPartOfTypeExpression, +} from './typescript'; + +/** + * Couples a themeable Component to its ThemedComponent wrapper + */ +export interface ThemeableComponentRegistryEntry { + basePath: string; + baseFileName: string, + baseClass: string; + + wrapperPath: string; + wrapperFileName: string, + wrapperClass: string; +} + +function isAngularComponentDecorator(node: ts.Node) { + if (node.kind === ts.SyntaxKind.Decorator && node.parent.kind === ts.SyntaxKind.ClassDeclaration) { + const decorator = node as ts.Decorator; + + if (decorator.expression.kind === ts.SyntaxKind.CallExpression) { + const method = decorator.expression as ts.CallExpression; + + if (method.expression.kind === ts.SyntaxKind.Identifier) { + return (method.expression as Identifier).text === 'Component'; + } + } + } + + return false; +} + +function findImportDeclaration(source: ts.SourceFile, identifierName: string): ts.ImportDeclaration | undefined { + return ts.forEachChild(source, (topNode: ts.Node) => { + if (topNode.kind === ts.SyntaxKind.ImportDeclaration) { + const importDeclaration = topNode as ts.ImportDeclaration; + + if (importDeclaration.importClause?.namedBindings?.kind === ts.SyntaxKind.NamedImports) { + const namedImports = importDeclaration.importClause?.namedBindings as ts.NamedImports; + + for (const element of namedImports.elements) { + if (element.name.text === identifierName) { + return importDeclaration; + } + } + } + } + + return undefined; + }); +} + +/** + * Listing of all themeable Components + */ +class ThemeableComponentRegistry { + public readonly entries: Set; + public readonly byBaseClass: Map; + public readonly byWrapperClass: Map; + public readonly byBasePath: Map; + public readonly byWrapperPath: Map; + + constructor() { + this.entries = new Set(); + this.byBaseClass = new Map(); + this.byWrapperClass = new Map(); + this.byBasePath = new Map(); + this.byWrapperPath = new Map(); + } + + public initialize(prefix = '') { + if (this.entries.size > 0) { + return; + } + + function registerWrapper(path: string) { + const source = getSource(path); + + function traverse(node: ts.Node) { + if (node.parent !== undefined && isAngularComponentDecorator(node)) { + const classNode = node.parent as ts.ClassDeclaration; + + if (classNode.name === undefined || classNode.heritageClauses === undefined) { + return; + } + + const wrapperClass = classNode.name?.escapedText as string; + + for (const heritageClause of classNode.heritageClauses) { + for (const type of heritageClause.types) { + if ((type as any).expression.escapedText === 'ThemedComponent') { + if (type.kind !== ts.SyntaxKind.ExpressionWithTypeArguments || type.typeArguments === undefined) { + continue; + } + + const firstTypeArg = type.typeArguments[0] as ts.TypeReferenceNode; + const baseClass = (firstTypeArg.typeName as ts.Identifier)?.escapedText; + + if (baseClass === undefined) { + continue; + } + + const importDeclaration = findImportDeclaration(source, baseClass); + + if (importDeclaration === undefined) { + continue; + } + + const basePath = resolveLocalPath((importDeclaration.moduleSpecifier as ts.StringLiteral).text, path); + + themeableComponents.add({ + baseClass, + basePath: basePath.replace(new RegExp(`^${prefix}`), ''), + baseFileName: basename(basePath).replace(/\.ts$/, ''), + wrapperClass, + wrapperPath: path.replace(new RegExp(`^${prefix}`), ''), + wrapperFileName: basename(path).replace(/\.ts$/, ''), + }); + } + } + } + + return; + } else { + ts.forEachChild(node, traverse); + } + } + + traverse(source); + } + + const glob = require('glob'); + + // note: this outputs Unix-style paths on Windows + const wrappers: string[] = glob.GlobSync(prefix + 'src/app/**/themed-*.component.ts', { ignore: 'node_modules/**' }).found; + + for (const wrapper of wrappers) { + registerWrapper(wrapper); + } + } + + private add(entry: ThemeableComponentRegistryEntry) { + this.entries.add(entry); + this.byBaseClass.set(entry.baseClass, entry); + this.byWrapperClass.set(entry.wrapperClass, entry); + this.byBasePath.set(entry.basePath, entry); + this.byWrapperPath.set(entry.wrapperPath, entry); + } +} + +export const themeableComponents = new ThemeableComponentRegistry(); + +/** + * Construct the AST of a TypeScript source file + * @param file + */ +function getSource(file: string): ts.SourceFile { + return ts.createSourceFile( + file, + readFileSync(file).toString(), + ts.ScriptTarget.ES2020, // todo: actually use tsconfig.json? + /*setParentNodes */ true, + ); +} + +/** + * Resolve a possibly relative local path into an absolute path starting from the root directory of the project + */ +function resolveLocalPath(path: string, relativeTo: string) { + if (path.startsWith('src/')) { + return path; + } else if (path.startsWith('./')) { + const parts = relativeTo.split('/'); + return [ + ...parts.slice(0, parts.length - 1), + path.replace(/^.\//, ''), + ].join('/') + '.ts'; + } else { + throw new Error(`Unsupported local path: ${path}`); + } +} + +export function isThemedComponentWrapper(decoratorNode: TSESTree.Decorator): boolean { + if (decoratorNode.parent.type !== TSESTree.AST_NODE_TYPES.ClassDeclaration) { + return false; + } + + if (decoratorNode.parent.superClass?.type !== TSESTree.AST_NODE_TYPES.Identifier) { + return false; + } + + return (decoratorNode.parent.superClass as any)?.name === 'ThemedComponent'; +} + +export function getBaseComponentClassName(decoratorNode: TSESTree.Decorator): string | undefined { + const wrapperClass = getComponentClassName(decoratorNode); + + if (wrapperClass === undefined) { + return; + } + + themeableComponents.initialize(); + const entry = themeableComponents.byWrapperClass.get(wrapperClass); + + if (entry === undefined) { + return undefined; + } + + return entry.baseClass; +} + +export function isThemeableComponent(className: string): boolean { + themeableComponents.initialize(); + return themeableComponents.byBaseClass.has(className); +} + +export function inThemedComponentOverrideFile(filename: string): boolean { + const match = filename.match(/src\/themes\/[^\/]+\/(app\/.*)/); + + if (!match) { + return false; + } + themeableComponents.initialize(); + // todo: this is fragile! + return themeableComponents.byBasePath.has(`src/${match[1]}`); +} + +export function allThemeableComponents(): ThemeableComponentRegistryEntry[] { + themeableComponents.initialize(); + return [...themeableComponents.entries]; +} + +export function getThemeableComponentByBaseClass(baseClass: string): ThemeableComponentRegistryEntry | undefined { + themeableComponents.initialize(); + return themeableComponents.byBaseClass.get(baseClass); +} + +export function isAllowedUnthemedUsage(usageNode: TSESTree.Identifier) { + return isPartOfClassDeclaration(usageNode) || isPartOfTypeExpression(usageNode) || isPartOfViewChild(usageNode); +} + +export const DISALLOWED_THEME_SELECTORS = 'ds-(base|themed)-'; + +export function fixSelectors(text: string): string { + return text.replaceAll(/ds-(base|themed)-/g, 'ds-'); +} diff --git a/lint/src/util/typescript.ts b/lint/src/util/typescript.ts new file mode 100644 index 0000000000..3fecad270e --- /dev/null +++ b/lint/src/util/typescript.ts @@ -0,0 +1,154 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { + TSESLint, + TSESTree, +} from '@typescript-eslint/utils'; + +import { + match, + toUnixStylePath, +} from './misc'; + +export type AnyRuleContext = TSESLint.RuleContext; + +/** + * Return the current filename based on the ESLint rule context as a Unix-style path. + * This is easier for regex and comparisons to glob paths. + */ +export function getFilename(context: AnyRuleContext): string { + // TSESLint claims this is deprecated, but the suggested alternative is undefined (could be a version mismatch between ESLint and TSESlint?) + // eslint-disable-next-line deprecation/deprecation + return toUnixStylePath(context.getFilename()); +} + +export function getSourceCode(context: AnyRuleContext): TSESLint.SourceCode { + // TSESLint claims this is deprecated, but the suggested alternative is undefined (could be a version mismatch between ESLint and TSESlint?) + // eslint-disable-next-line deprecation/deprecation + return context.getSourceCode(); +} + +export function getObjectPropertyNodeByName(objectNode: TSESTree.ObjectExpression, propertyName: string): TSESTree.Node | undefined { + for (const propertyNode of objectNode.properties) { + if ( + propertyNode.type === TSESTree.AST_NODE_TYPES.Property + && ( + ( + propertyNode.key?.type === TSESTree.AST_NODE_TYPES.Identifier + && propertyNode.key?.name === propertyName + ) || ( + propertyNode.key?.type === TSESTree.AST_NODE_TYPES.Literal + && propertyNode.key?.value === propertyName + ) + ) + ) { + return propertyNode.value; + } + } + return undefined; +} + +export function findUsages(context: AnyRuleContext, localNode: TSESTree.Identifier): TSESTree.Identifier[] { + const source = getSourceCode(context); + + const usages: TSESTree.Identifier[] = []; + + for (const token of source.ast.tokens) { + if (token.type === TSESTree.AST_TOKEN_TYPES.Identifier && token.value === localNode.name && !match(token.range, localNode.range)) { + const node = source.getNodeByRangeIndex(token.range[0]); + // todo: in some cases, the resulting node can actually be the whole program (!) + if (node !== null) { + usages.push(node as TSESTree.Identifier); + } + } + } + + return usages; +} + +export function findUsagesByName(context: AnyRuleContext, identifier: string): TSESTree.Identifier[] { + const source = getSourceCode(context); + + const usages: TSESTree.Identifier[] = []; + + for (const token of source.ast.tokens) { + if (token.type === TSESTree.AST_TOKEN_TYPES.Identifier && token.value === identifier) { + const node = source.getNodeByRangeIndex(token.range[0]); + // todo: in some cases, the resulting node can actually be the whole program (!) + if (node !== null) { + usages.push(node as TSESTree.Identifier); + } + } + } + + return usages; +} + +export function isPartOfTypeExpression(node: TSESTree.Identifier): boolean { + return node.parent?.type?.valueOf().startsWith('TSType'); +} + +export function isPartOfClassDeclaration(node: TSESTree.Identifier): boolean { + return node.parent?.type === TSESTree.AST_NODE_TYPES.ClassDeclaration; +} + +function fromSrc(path: string): string { + const m = path.match(/^.*(src\/.+)(\.(ts|json|js)?)$/); + + if (m) { + return m[1]; + } else { + throw new Error(`Can't infer project-absolute TS/resource path from: ${path}`); + } +} + + +export function relativePath(thisFile: string, importFile: string): string { + const fromParts = fromSrc(thisFile).split('/'); + const toParts = fromSrc(importFile).split('/'); + + let lastCommon = 0; + for (let i = 0; i < fromParts.length - 1; i++) { + if (fromParts[i] === toParts[i]) { + lastCommon++; + } else { + break; + } + } + + const path = toParts.slice(lastCommon, toParts.length).join('/'); + const backtrack = fromParts.length - lastCommon - 1; + + let prefix: string; + if (backtrack > 0) { + prefix = '../'.repeat(backtrack); + } else { + prefix = './'; + } + + return prefix + path; +} + + +export function findImportSpecifier(context: AnyRuleContext, identifier: string): TSESTree.ImportSpecifier | undefined { + const source = getSourceCode(context); + + const usages: TSESTree.Identifier[] = []; + + for (const token of source.ast.tokens) { + if (token.type === TSESTree.AST_TOKEN_TYPES.Identifier && token.value === identifier) { + const node = source.getNodeByRangeIndex(token.range[0]); + // todo: in some cases, the resulting node can actually be the whole program (!) + if (node && node.parent && node.parent.type === TSESTree.AST_NODE_TYPES.ImportSpecifier) { + return node.parent; + } + } + } + + return undefined; +} diff --git a/lint/test/fixture/README.md b/lint/test/fixture/README.md new file mode 100644 index 0000000000..b19ae11b55 --- /dev/null +++ b/lint/test/fixture/README.md @@ -0,0 +1,9 @@ +# ESLint testing fixtures + +The files in this directory are used for the ESLint testing environment +- Some rules rely on registries that must be built up _before_ the rule is run + - In order to test these registries, the fixture sources contain a few dummy components +- The TypeScript ESLint test runner requires at least one dummy file to exist to run any tests + - By default, [`test.ts`](./src/test.ts) is used. Note that this file is empty; it's only there for the TypeScript configuration, the actual content is injected from the `code` property in the tests. + - To test rules that make assertions based on the path of the file, you'll need to include the `filename` property in the test configuration. Note that it must point to an existing file too! + - The `filename` must be provided as `fixture('src/something.ts')` \ No newline at end of file diff --git a/lint/test/fixture/index.ts b/lint/test/fixture/index.ts new file mode 100644 index 0000000000..1d4f33f7e2 --- /dev/null +++ b/lint/test/fixture/index.ts @@ -0,0 +1,13 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +export const FIXTURE = 'lint/test/fixture/'; + +export function fixture(path: string): string { + return FIXTURE + path; +} diff --git a/lint/test/fixture/src/app/test/test-routing.module.ts b/lint/test/fixture/src/app/test/test-routing.module.ts new file mode 100644 index 0000000000..1ccbccc599 --- /dev/null +++ b/lint/test/fixture/src/app/test/test-routing.module.ts @@ -0,0 +1,14 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { ThemedTestThemeableComponent } from './themed-test-themeable.component'; + +export const ROUTES = [ + { + component: ThemedTestThemeableComponent, + }, +]; diff --git a/lint/test/fixture/src/app/test/test-themeable.component.ts b/lint/test/fixture/src/app/test/test-themeable.component.ts new file mode 100644 index 0000000000..b445040539 --- /dev/null +++ b/lint/test/fixture/src/app/test/test-themeable.component.ts @@ -0,0 +1,16 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-base-test-themeable', + template: '', + standalone: true, +}) +export class TestThemeableComponent { +} diff --git a/lint/test/fixture/src/app/test/test.component.cy.ts b/lint/test/fixture/src/app/test/test.component.cy.ts new file mode 100644 index 0000000000..2300ac4a56 --- /dev/null +++ b/lint/test/fixture/src/app/test/test.component.cy.ts @@ -0,0 +1,8 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + diff --git a/lint/test/fixture/src/app/test/test.component.spec.ts b/lint/test/fixture/src/app/test/test.component.spec.ts new file mode 100644 index 0000000000..2300ac4a56 --- /dev/null +++ b/lint/test/fixture/src/app/test/test.component.spec.ts @@ -0,0 +1,8 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + diff --git a/lint/test/fixture/src/app/test/test.component.ts b/lint/test/fixture/src/app/test/test.component.ts new file mode 100644 index 0000000000..c01f104c98 --- /dev/null +++ b/lint/test/fixture/src/app/test/test.component.ts @@ -0,0 +1,15 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-test', + template: '', +}) +export class TestComponent { +} diff --git a/lint/test/fixture/src/app/test/test.module.ts b/lint/test/fixture/src/app/test/test.module.ts new file mode 100644 index 0000000000..a37396ef45 --- /dev/null +++ b/lint/test/fixture/src/app/test/test.module.ts @@ -0,0 +1,24 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +// @ts-ignore +import { NgModule } from '@angular/core'; + +import { TestComponent } from './test.component'; +import { TestThemeableComponent } from './test-themeable.component'; +import { ThemedTestThemeableComponent } from './themed-test-themeable.component'; + +@NgModule({ + declarations: [ + TestComponent, + TestThemeableComponent, + ThemedTestThemeableComponent, + ], +}) +export class TestModule { + +} diff --git a/lint/test/fixture/src/app/test/themed-test-themeable.component.ts b/lint/test/fixture/src/app/test/themed-test-themeable.component.ts new file mode 100644 index 0000000000..2697a8c598 --- /dev/null +++ b/lint/test/fixture/src/app/test/themed-test-themeable.component.ts @@ -0,0 +1,31 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { Component } from '@angular/core'; + +import { ThemedComponent } from '../../../../../../src/app/shared/theme-support/themed.component'; +import { TestThemeableComponent } from './test-themeable.component'; + +@Component({ + selector: 'ds-test-themeable', + template: '', + standalone: true, + imports: [TestThemeableComponent], +}) +export class ThemedTestThemeableComponent extends ThemedComponent { + protected getComponentName(): string { + return ''; + } + + protected importThemedComponent(themeName: string): Promise { + return Promise.resolve(undefined); + } + + protected importUnthemedComponent(): Promise { + return Promise.resolve(undefined); + } +} diff --git a/lint/test/fixture/src/test.ts b/lint/test/fixture/src/test.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts b/lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts new file mode 100644 index 0000000000..f72161b2bf --- /dev/null +++ b/lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts @@ -0,0 +1,16 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-themed-test-themeable', + template: '', +}) +export class OtherThemeableComponent { + +} diff --git a/lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts b/lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts new file mode 100644 index 0000000000..d2b02ca9f1 --- /dev/null +++ b/lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts @@ -0,0 +1,18 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { Component } from '@angular/core'; + +import { TestThemeableComponent as BaseComponent } from '../../../../app/test/test-themeable.component'; + +@Component({ + selector: 'ds-themed-test-themeable', + template: '', +}) +export class TestThemeableComponent extends BaseComponent { + +} diff --git a/lint/test/fixture/src/themes/test/test.module.ts b/lint/test/fixture/src/themes/test/test.module.ts new file mode 100644 index 0000000000..ff6ec3b2c0 --- /dev/null +++ b/lint/test/fixture/src/themes/test/test.module.ts @@ -0,0 +1,22 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +// @ts-ignore +import { NgModule } from '@angular/core'; + +import { OtherThemeableComponent } from './app/test/other-themeable.component'; +import { TestThemeableComponent } from './app/test/test-themeable.component'; + +@NgModule({ + declarations: [ + TestThemeableComponent, + OtherThemeableComponent, + ], +}) +export class TestModule { + +} diff --git a/lint/test/fixture/tsconfig.json b/lint/test/fixture/tsconfig.json new file mode 100644 index 0000000000..0fd1141ae0 --- /dev/null +++ b/lint/test/fixture/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": [ + "src/**/*.ts" + ], + "exclude": [] +} diff --git a/lint/test/helpers.js b/lint/test/helpers.js new file mode 100644 index 0000000000..bd648d007f --- /dev/null +++ b/lint/test/helpers.js @@ -0,0 +1,13 @@ +const SpecReporter = require('jasmine-spec-reporter').SpecReporter; +const StacktraceOption = require('jasmine-spec-reporter').StacktraceOption; + +jasmine.getEnv().clearReporters(); // Clear default console reporter for those instead +jasmine.getEnv().addReporter(new SpecReporter({ + spec: { + displayErrorMessages: false, + }, + summary: { + displayFailed: true, + displayStacktrace: StacktraceOption.PRETTY, + }, +})); diff --git a/lint/test/rules.spec.ts b/lint/test/rules.spec.ts new file mode 100644 index 0000000000..11c9bec46c --- /dev/null +++ b/lint/test/rules.spec.ts @@ -0,0 +1,26 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { default as htmlPlugin } from '../src/rules/html'; +import { default as tsPlugin } from '../src/rules/ts'; +import { + htmlRuleTester, + tsRuleTester, +} from './testing'; + +describe('TypeScript rules', () => { + for (const { info, rule, tests } of tsPlugin.index) { + tsRuleTester.run(info.name, rule, tests as any); + } +}); + +describe('HTML rules', () => { + for (const { info, rule, tests } of htmlPlugin.index) { + htmlRuleTester.run(info.name, rule, tests); + } +}); diff --git a/lint/test/structure.spec.ts b/lint/test/structure.spec.ts new file mode 100644 index 0000000000..24e69e42d9 --- /dev/null +++ b/lint/test/structure.spec.ts @@ -0,0 +1,76 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { default as html } from '../src/rules/html'; +import { default as ts } from '../src/rules/ts'; + +describe('plugin structure', () => { + for (const pluginExports of [ts, html]) { + const pluginName = pluginExports.name ?? 'UNNAMED PLUGIN'; + + describe(pluginName, () => { + it('should have a name', () => { + expect(pluginExports.name).toBeTruthy(); + }); + + it('should have rules', () => { + expect(pluginExports.index).toBeTruthy(); + expect(pluginExports.rules).toBeTruthy(); + expect(pluginExports.index.length).toBeGreaterThan(0); + }); + + for (const ruleExports of pluginExports.index) { + const ruleName = ruleExports.info.name ?? 'UNNAMED RULE'; + + describe(ruleName, () => { + it('should have a name', () => { + expect(ruleExports.info.name).toBeTruthy(); + }); + + it('should be included under the right name in the plugin', () => { + expect(pluginExports.rules[ruleExports.info.name]).toBe(ruleExports.rule); + }); + + it('should contain metadata', () => { + expect(ruleExports.info).toBeTruthy(); + expect(ruleExports.info.name).toBeTruthy(); + expect(ruleExports.info.meta).toBeTruthy(); + expect(ruleExports.info.defaultOptions).toBeTruthy(); + }); + + it('should contain messages', () => { + expect(ruleExports.Message).toBeTruthy(); + expect(ruleExports.info.meta.messages).toBeTruthy(); + }); + + describe('messages', () => { + for (const member of Object.keys(ruleExports.Message)) { + describe(member, () => { + const id = (ruleExports.Message as any)[member]; + + it('should have a valid ID', () => { + expect(id).toBeTruthy(); + }); + + it('should have valid metadata', () => { + expect(ruleExports.info.meta.messages[id]).toBeTruthy(); + }); + }); + } + }); + + it('should contain tests', () => { + expect(ruleExports.tests).toBeTruthy(); + expect(ruleExports.tests.valid.length).toBeGreaterThan(0); + expect(ruleExports.tests.invalid.length).toBeGreaterThan(0); + }); + }); + } + }); + } +}); diff --git a/lint/test/testing.ts b/lint/test/testing.ts new file mode 100644 index 0000000000..cfa54c5b85 --- /dev/null +++ b/lint/test/testing.ts @@ -0,0 +1,53 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { RuleTester as TypeScriptRuleTester } from '@typescript-eslint/rule-tester'; +import { RuleTester } from 'eslint'; + +import { themeableComponents } from '../src/util/theme-support'; +import { + FIXTURE, + fixture, +} from './fixture'; + + +// Register themed components from test fixture +themeableComponents.initialize(FIXTURE); + +TypeScriptRuleTester.itOnly = fit; +TypeScriptRuleTester.itSkip = xit; + +export const tsRuleTester = new TypeScriptRuleTester({ + parser: '@typescript-eslint/parser', + defaultFilenames: { + ts: fixture('src/test.ts'), + tsx: 'n/a', + }, + parserOptions: { + project: fixture('tsconfig.json'), + }, +}); + +class HtmlRuleTester extends RuleTester { + run(name: string, rule: any, tests: { valid: any[], invalid: any[] }) { + super.run(name, rule, { + valid: tests.valid.map((test) => ({ + filename: fixture('test.html'), + ...test, + })), + invalid: tests.invalid.map((test) => ({ + filename: fixture('test.html'), + ...test, + })), + }); + } +} + +export const htmlRuleTester = new HtmlRuleTester({ + parser: require.resolve('@angular-eslint/template-parser'), +}); diff --git a/lint/test/theme-support.spec.ts b/lint/test/theme-support.spec.ts new file mode 100644 index 0000000000..2edf9594b6 --- /dev/null +++ b/lint/test/theme-support.spec.ts @@ -0,0 +1,24 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { themeableComponents } from '../src/util/theme-support'; + +describe('theme-support', () => { + describe('themeable component registry', () => { + it('should contain all themeable components from the fixture', () => { + expect(themeableComponents.entries.size).toBe(1); + expect(themeableComponents.byBasePath.size).toBe(1); + expect(themeableComponents.byWrapperPath.size).toBe(1); + expect(themeableComponents.byBaseClass.size).toBe(1); + + expect(themeableComponents.byBaseClass.get('TestThemeableComponent')).toBeTruthy(); + expect(themeableComponents.byBasePath.get('src/app/test/test-themeable.component.ts')).toBeTruthy(); + expect(themeableComponents.byWrapperPath.get('src/app/test/themed-test-themeable.component.ts')).toBeTruthy(); + }); + }); +}); diff --git a/lint/tsconfig.json b/lint/tsconfig.json new file mode 100644 index 0000000000..d3537a7376 --- /dev/null +++ b/lint/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2021", + "lib": [ + "es2021" + ], + "module": "nodenext", + "moduleResolution": "nodenext", + "noImplicitReturns": true, + "skipLibCheck": true, + "strict": true, + "outDir": "./dist", + "sourceMap": true, + "allowSyntheticDefaultImports": true, + "types": [ + "jasmine", + "node" + ] + }, + "include": [ + "**/*.ts", + ], + "exclude": [ + "dist", + "test/fixture" + ] +} diff --git a/package.json b/package.json index 0571d166bc..72b11eec8b 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,16 @@ "build:stats": "ng build --stats-json", "build:prod": "cross-env NODE_ENV=production yarn run build:ssr", "build:ssr": "ng build --configuration production && ng run dspace-angular:server:production", + "build:lint": "rimraf 'lint/dist/**/*.js' 'lint/dist/**/*.js.map' && tsc -b lint/tsconfig.json", "test": "ng test --source-map=true --watch=false --configuration test", "test:watch": "nodemon --exec \"ng test --source-map=true --watch=true --configuration test\"", "test:headless": "ng test --source-map=true --watch=false --configuration test --browsers=ChromeHeadless --code-coverage", - "lint": "ng lint", - "lint-fix": "ng lint --fix=true", + "test:lint": "yarn build:lint && yarn test:lint:nobuild", + "test:lint:nobuild": "jasmine --config=lint/jasmine.json", + "lint": "yarn build:lint && yarn lint:nobuild", + "lint:nobuild": "ng lint", + "lint-fix": "yarn build:lint && ng lint --fix=true", + "docs:lint": "ts-node --project ./lint/tsconfig.json ./lint/generate-docs.ts", "e2e": "cross-env NODE_ENV=production ng e2e", "clean:dev:config": "rimraf src/assets/config.json", "clean:coverage": "rimraf coverage", @@ -40,7 +45,8 @@ "cypress:run": "cypress run", "env:yaml": "ts-node --project ./tsconfig.ts-node.json scripts/env-to-yaml.ts", "base-href": "ts-node --project ./tsconfig.ts-node.json scripts/base-href.ts", - "check-circ-deps": "npx madge --exclude '(bitstream|bundle|collection|config-submission-form|eperson|item|version)\\.model\\.ts$' --circular --extensions ts ./" + "check-circ-deps": "npx madge --exclude '(bitstream|bundle|collection|config-submission-form|eperson|item|version)\\.model\\.ts$' --circular --extensions ts ./", + "postinstall": "yarn build:lint || echo 'Skipped DSpace ESLint plugins.'" }, "browser": { "fs": false, @@ -136,6 +142,7 @@ "@angular-builders/custom-webpack": "~17.0.1", "@angular-devkit/build-angular": "^17.3.0", "@angular-eslint/builder": "17.2.1", + "@angular-eslint/bundled-angular-compiler": "17.2.1", "@angular-eslint/eslint-plugin": "17.2.1", "@angular-eslint/eslint-plugin-template": "17.2.1", "@angular-eslint/schematics": "17.2.1", @@ -155,8 +162,10 @@ "@types/lodash": "^4.14.194", "@types/node": "^14.14.9", "@types/sanitize-html": "^2.9.0", - "@typescript-eslint/eslint-plugin": "^5.59.1", - "@typescript-eslint/parser": "^5.59.1", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "@typescript-eslint/rule-tester": "^7.2.0", + "@typescript-eslint/utils": "^7.2.0", "axe-core": "^4.7.2", "browser-sync": "^3.0.0", "compression-webpack-plugin": "^9.2.0", @@ -167,6 +176,8 @@ "deep-freeze": "0.0.1", "eslint": "^8.39.0", "eslint-plugin-deprecation": "^1.4.1", + "eslint-plugin-dspace-angular-html": "link:./lint/dist/src/rules/html", + "eslint-plugin-dspace-angular-ts": "link:./lint/dist/src/rules/ts", "eslint-plugin-import": "^2.27.5", "eslint-plugin-import-newlines": "^1.3.1", "eslint-plugin-jsdoc": "^45.0.0", @@ -176,6 +187,7 @@ "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-unused-imports": "^2.0.0", "express-static-gzip": "^2.1.7", + "jasmine": "^3.8.0", "jasmine-core": "^3.8.0", "jasmine-marbles": "0.9.2", "karma": "^6.4.2", @@ -206,4 +218,4 @@ "webpack-cli": "^4.2.0", "webpack-dev-server": "^4.13.3" } -} \ No newline at end of file +} diff --git a/src/app/access-control/bulk-access/browse/bulk-access-browse.component.html b/src/app/access-control/bulk-access/browse/bulk-access-browse.component.html index 6e967b53b5..f96ddf4a23 100644 --- a/src/app/access-control/bulk-access/browse/bulk-access-browse.component.html +++ b/src/app/access-control/bulk-access/browse/bulk-access-browse.component.html @@ -23,10 +23,10 @@ {{'admin.access-control.bulk-access-browse.search.header' | translate}}
- + [showThumbnails]="false">
@@ -37,7 +37,6 @@ - + diff --git a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.html b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.html index 9168bbaf8e..b4c0781ac7 100644 --- a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.html +++ b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.html @@ -42,17 +42,16 @@ - +

{{messagePrefix + '.groupsEPersonIsMemberOf' | translate}}

- + @@ -86,7 +85,6 @@ diff --git a/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts b/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts index 92f764fe98..4a707ef159 100644 --- a/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts +++ b/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts @@ -114,21 +114,21 @@ export interface EPersonListActionConfig { export class MembersListComponent implements OnInit, OnDestroy { @Input() - messagePrefix: string; + messagePrefix: string; @Input() - actionConfig: EPersonListActionConfig = { - add: { - css: 'btn-outline-primary', - disabled: false, - icon: 'fas fa-plus fa-fw', - }, - remove: { - css: 'btn-outline-danger', - disabled: false, - icon: 'fas fa-trash-alt fa-fw', - }, - }; + actionConfig: EPersonListActionConfig = { + add: { + css: 'btn-outline-primary', + disabled: false, + icon: 'fas fa-plus fa-fw', + }, + remove: { + css: 'btn-outline-danger', + disabled: false, + icon: 'fas fa-trash-alt fa-fw', + }, + }; /** * EPeople being displayed in search result, initially all members, after search result of search diff --git a/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.html b/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.html index ab7bd84f6b..66404bde0d 100644 --- a/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.html +++ b/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.html @@ -5,7 +5,6 @@ @@ -84,7 +83,6 @@ diff --git a/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.ts b/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.ts index fc25dd4fc9..95c1b7f249 100644 --- a/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.ts +++ b/src/app/access-control/group-registry/group-form/subgroup-list/subgroups-list.component.ts @@ -80,7 +80,7 @@ enum SubKey { export class SubgroupsListComponent implements OnInit, OnDestroy { @Input() - messagePrefix: string; + messagePrefix: string; /** * Result of search groups, initially all groups diff --git a/src/app/access-control/group-registry/groups-registry.component.html b/src/app/access-control/group-registry/groups-registry.component.html index 2ef67ddf54..c2d998d954 100644 --- a/src/app/access-control/group-registry/groups-registry.component.html +++ b/src/app/access-control/group-registry/groups-registry.component.html @@ -33,11 +33,10 @@
- + diff --git a/src/app/admin/admin-ldn-services/ldn-services-directory/ldn-services-directory.component.html b/src/app/admin/admin-ldn-services/ldn-services-directory/ldn-services-directory.component.html index 0aaa39bda2..3dcce659c2 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-directory/ldn-services-directory.component.html +++ b/src/app/admin/admin-ldn-services/ldn-services-directory/ldn-services-directory.component.html @@ -10,7 +10,6 @@ [collectionSize]="(ldnServicesRD$ | async)?.payload?.totalElements" [hideGear]="true" [hidePagerWhenSinglePage]="true" - [pageInfoState]="(ldnServicesRD$ | async)?.payload" [paginationOptions]="pageConfig">
diff --git a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters.ts b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters.ts index 73af060413..25fb9e70dd 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters.ts @@ -18,13 +18,13 @@ export class Itemfilter extends CacheableObject { @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserialize - id: string; + id: string; @deserialize - _links: { + _links: { self: { href: string; }; diff --git a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-patterns.model.ts b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-patterns.model.ts index 650511005c..fac5a1d704 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-patterns.model.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-service-patterns.model.ts @@ -5,9 +5,9 @@ import { autoserialize } from 'cerialize'; */ export class NotifyServicePattern { @autoserialize - pattern: string; + pattern: string; @autoserialize - constraint: string; + constraint: string; @autoserialize - automatic: string; + automatic: string; } diff --git a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-services.model.ts b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-services.model.ts index 69b84427d1..1497b618f0 100644 --- a/src/app/admin/admin-ldn-services/ldn-services-model/ldn-services.model.ts +++ b/src/app/admin/admin-ldn-services/ldn-services-model/ldn-services.model.ts @@ -29,43 +29,43 @@ export class LdnService extends CacheableObject { @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserialize - id: number; + id: number; @deserializeAs('id') - uuid: string; + uuid: string; @autoserialize - name: string; + name: string; @autoserialize - description: string; + description: string; @autoserialize - url: string; + url: string; @autoserialize - score: number; + score: number; @autoserialize - enabled: boolean; + enabled: boolean; @autoserialize - ldnUrl: string; + ldnUrl: string; @autoserialize - lowerIp: string; + lowerIp: string; @autoserialize - upperIp: string; + upperIp: string; @autoserialize - notifyServiceInboundPatterns?: NotifyServicePattern[]; + notifyServiceInboundPatterns?: NotifyServicePattern[]; @deserialize - _links: { + _links: { self: { href: string; }; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts index a2013356ab..717d24a9fc 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.ts @@ -43,7 +43,7 @@ export class AdminNotifyDetailModalComponent { * An event fired when the modal is closed */ @Output() - response = new EventEmitter(); + response = new EventEmitter(); public isCoarMessageVisible = false; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.html b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.html index f7c4f77a70..57ce83934c 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.html +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.html @@ -15,11 +15,11 @@
- + >
diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.ts index 4cb6696fe2..33ac2b4cb1 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component.ts @@ -51,7 +51,7 @@ import { ThemedSearchComponent } from '../../../../shared/search/themed-search.c export class AdminNotifyLogsResultComponent implements OnInit { @Input() - defaultConfiguration: string; + defaultConfiguration: string; public selectedSearchConfig$: Observable; diff --git a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts index 727b081d89..af5345f512 100644 --- a/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts +++ b/src/app/admin/admin-notify-dashboard/admin-notify-metrics/admin-notify-metrics.component.ts @@ -27,7 +27,7 @@ import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; export class AdminNotifyMetricsComponent { @Input() - boxesConfig: AdminNotifyMetricsRow[]; + boxesConfig: AdminNotifyMetricsRow[]; private incomingConfiguration = 'NOTIFY.incoming'; private involvedItemsSuffix = 'involvedItems'; diff --git a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts index f32451eaff..2524ffed9b 100644 --- a/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts +++ b/src/app/admin/admin-notify-dashboard/models/admin-notify-message.model.ts @@ -24,138 +24,138 @@ export class AdminNotifyMessage extends DSpaceObject { * The type of the resource */ @excludeFromEquals - type = ADMIN_NOTIFY_MESSAGE; + type = ADMIN_NOTIFY_MESSAGE; /** * The id of the message */ @autoserialize - id: string; + id: string; /** * The id of the notification */ @autoserialize - notificationId: string; + notificationId: string; /** * The type of the notification */ @autoserialize - notificationType: string; + notificationType: string; /** * The type of the notification */ @autoserialize - coarNotifyType: string; + coarNotifyType: string; /** * The type of the activity */ @autoserialize - activityStreamType: string; + activityStreamType: string; /** * The object the message reply to */ @autoserialize - inReplyTo: string; + inReplyTo: string; /** * The object the message relates to */ @autoserialize - object: string; + object: string; /** * The name of the related item */ @autoserialize - relatedItem: string; + relatedItem: string; /** * The name of the related ldn service */ @autoserialize - ldnService: string; + ldnService: string; /** * The context of the message */ @autoserialize - context: string; + context: string; /** * The related COAR message */ @autoserialize - message: string; + message: string; /** * The attempts of the queue */ @autoserialize - queueAttempts: number; + queueAttempts: number; /** * Timestamp of the last queue attempt */ @autoserialize - queueLastStartTime: string; + queueLastStartTime: string; /** * The type of the activity stream */ @autoserialize - origin: number | string; + origin: number | string; /** * The type of the activity stream */ @autoserialize - target: number | string; + target: number | string; /** * The label for the status of the queue */ @autoserialize - queueStatusLabel: string; + queueStatusLabel: string; /** * The timeout of the queue */ @autoserialize - queueTimeout: string; + queueTimeout: string; /** * The status of the queue */ @autoserialize - queueStatus: number; + queueStatus: number; /** * Thumbnail link used when browsing items with showThumbs config enabled. */ @autoserialize - thumbnail: string; + thumbnail: string; /** * The observable pointing to the item itself */ @autoserialize - item: Observable; + item: Observable; /** * The observable pointing to the access status of the item */ @autoserialize - accessStatus: Observable; + accessStatus: Observable; @deserialize - _links: { + _links: { self: { href: string; }; diff --git a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.html b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.html index abb0a2fd53..912e931f40 100644 --- a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.html +++ b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.html @@ -11,7 +11,6 @@ diff --git a/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.html b/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.html index 97123d29a5..f748279a1d 100644 --- a/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.html +++ b/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.html @@ -16,7 +16,6 @@ diff --git a/src/app/admin/admin-search-page/admin-search-page.component.html b/src/app/admin/admin-search-page/admin-search-page.component.html index 516799ddf9..69ff132fe3 100644 --- a/src/app/admin/admin-search-page/admin-search-page.component.html +++ b/src/app/admin/admin-search-page/admin-search-page.component.html @@ -1 +1 @@ - + diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.scss b/src/app/admin/admin-sidebar/admin-sidebar.component.scss index d3607ca625..a679155c32 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.scss +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.scss @@ -138,3 +138,9 @@ } } } + +::ng-deep { + .browser-firefox-windows { + --ds-dark-scrollbar-width: 20px; + } +} diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.ts b/src/app/admin/admin-sidebar/admin-sidebar.component.ts index cd26a11995..00514d2afc 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.ts @@ -41,7 +41,7 @@ import { ThemeService } from '../../shared/theme-support/theme.service'; * Component representing the admin sidebar */ @Component({ - selector: 'ds-admin-sidebar', + selector: 'ds-base-admin-sidebar', templateUrl: './admin-sidebar.component.html', styleUrls: ['./admin-sidebar.component.scss'], animations: [slideSidebar], diff --git a/src/app/admin/admin-sidebar/themed-admin-sidebar.component.ts b/src/app/admin/admin-sidebar/themed-admin-sidebar.component.ts index 165f48384a..6127fd42a9 100644 --- a/src/app/admin/admin-sidebar/themed-admin-sidebar.component.ts +++ b/src/app/admin/admin-sidebar/themed-admin-sidebar.component.ts @@ -11,10 +11,11 @@ import { AdminSidebarComponent } from './admin-sidebar.component'; * Themed wrapper for AdminSidebarComponent */ @Component({ - selector: 'ds-themed-admin-sidebar', + selector: 'ds-admin-sidebar', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [AdminSidebarComponent], }) export class ThemedAdminSidebarComponent extends ThemedComponent { diff --git a/src/app/admin/admin-workflow-page/admin-workflow-page.component.html b/src/app/admin/admin-workflow-page/admin-workflow-page.component.html index c16ed31168..d12cefb331 100644 --- a/src/app/admin/admin-workflow-page/admin-workflow-page.component.html +++ b/src/app/admin/admin-workflow-page/admin-workflow-page.component.html @@ -1 +1 @@ - + diff --git a/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/supervision-order-group-selector/supervision-order-group-selector.component.ts b/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/supervision-order-group-selector/supervision-order-group-selector.component.ts index 597940ca10..67dcd09b8e 100644 --- a/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/supervision-order-group-selector/supervision-order-group-selector.component.ts +++ b/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/supervision-order-group-selector/supervision-order-group-selector.component.ts @@ -15,6 +15,7 @@ import { NotificationsService } from 'src/app/shared/notifications/notifications import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; import { RemoteData } from '../../../../../../core/data/remote-data'; +import { RequestEntryState } from '../../../../../../core/data/request-entry-state.model'; import { Group } from '../../../../../../core/eperson/models/group.model'; import { SupervisionOrder } from '../../../../../../core/supervision-order/models/supervision-order.model'; import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; @@ -95,7 +96,7 @@ export class SupervisionOrderGroupSelectorComponent { this.supervisionOrderDataService.create(supervisionDataObject, this.itemUUID, this.selectedGroup.uuid, this.selectedOrderType).pipe( getFirstCompletedRemoteData(), ).subscribe((rd: RemoteData) => { - if (rd.state === 'Success') { + if (rd.state === RequestEntryState.Success) { this.notificationsService.success(this.translateService.get('supervision-group-selector.notification.create.success.title', { name: this.dsoNameService.getName(this.selectedGroup) })); this.create.emit(rd.payload); this.close(); diff --git a/src/app/app.component.html b/src/app/app.component.html index fb9983a6ef..9016f42dc1 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,3 +1,3 @@ - + [shouldShowRouteLoader]="isRouteLoading$ | async"> diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html index b306eb2721..f7d2c60832 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html @@ -2,7 +2,7 @@
- +
@@ -27,7 +27,7 @@
- +
diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index f4d285ac74..36b0816ade 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -80,7 +80,7 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { ThemedThumbnailComponent } from '../../thumbnail/themed-thumbnail.component'; @Component({ - selector: 'ds-edit-bitstream-page', + selector: 'ds-base-edit-bitstream-page', styleUrls: ['./edit-bitstream-page.component.scss'], templateUrl: './edit-bitstream-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/bitstream-page/edit-bitstream-page/themed-edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/themed-edit-bitstream-page.component.ts index 4d8a9946f5..7e922485cb 100644 --- a/src/app/bitstream-page/edit-bitstream-page/themed-edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/themed-edit-bitstream-page.component.ts @@ -4,10 +4,11 @@ import { ThemedComponent } from '../../shared/theme-support/themed.component'; import { EditBitstreamPageComponent } from './edit-bitstream-page.component'; @Component({ - selector: 'ds-themed-edit-bitstream-page', + selector: 'ds-edit-bitstream-page', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [EditBitstreamPageComponent], }) export class ThemedEditBitstreamPageComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/breadcrumbs/breadcrumbs.component.ts b/src/app/breadcrumbs/breadcrumbs.component.ts index 2483335245..9820d672c9 100644 --- a/src/app/breadcrumbs/breadcrumbs.component.ts +++ b/src/app/breadcrumbs/breadcrumbs.component.ts @@ -18,7 +18,7 @@ import { BreadcrumbsService } from './breadcrumbs.service'; * Component representing the breadcrumbs of a page */ @Component({ - selector: 'ds-breadcrumbs', + selector: 'ds-base-breadcrumbs', templateUrl: './breadcrumbs.component.html', styleUrls: ['./breadcrumbs.component.scss'], standalone: true, diff --git a/src/app/breadcrumbs/themed-breadcrumbs.component.ts b/src/app/breadcrumbs/themed-breadcrumbs.component.ts index 2e471fd92d..255af605dc 100644 --- a/src/app/breadcrumbs/themed-breadcrumbs.component.ts +++ b/src/app/breadcrumbs/themed-breadcrumbs.component.ts @@ -7,10 +7,11 @@ import { BreadcrumbsComponent } from './breadcrumbs.component'; * Themed wrapper for BreadcrumbsComponent */ @Component({ - selector: 'ds-themed-breadcrumbs', + selector: 'ds-breadcrumbs', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [BreadcrumbsComponent], }) export class ThemedBreadcrumbsComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts b/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts index 7cdb083c10..edd7cd951a 100644 --- a/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts +++ b/src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts @@ -28,7 +28,6 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv import { PaginationService } from '../../core/pagination/pagination.service'; import { Community } from '../../core/shared/community.model'; import { Item } from '../../core/shared/item.model'; -import { BrowseByComponent } from '../../shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -135,7 +134,6 @@ describe('BrowseByDateComponent', () => { ThemedComcolPageHandleComponent, ComcolPageContentComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, ThemedLoadingComponent, ThemedBrowseByComponent, ], diff --git a/src/app/browse-by/browse-by-date/browse-by-date.component.ts b/src/app/browse-by/browse-by-date/browse-by-date.component.ts index 3382a46f58..c84fc4cb77 100644 --- a/src/app/browse-by/browse-by-date/browse-by-date.component.ts +++ b/src/app/browse-by/browse-by-date/browse-by-date.component.ts @@ -35,7 +35,6 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv import { RemoteData } from '../../core/data/remote-data'; import { PaginationService } from '../../core/pagination/pagination.service'; import { Item } from '../../core/shared/item.model'; -import { BrowseByComponent } from '../../shared/browse-by/browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component'; import { ThemedComcolPageHandleComponent } from '../../shared/comcol/comcol-page-handle/themed-comcol-page-handle.component'; @@ -72,7 +71,6 @@ import { ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.html b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.html index 69c3c31c46..22e564ac27 100644 --- a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.html +++ b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.html @@ -1,6 +1,6 @@
diff --git a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts index c3bad2a923..3c893f5259 100644 --- a/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts +++ b/src/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts @@ -45,7 +45,6 @@ import { BrowseEntry } from '../../core/shared/browse-entry.model'; import { Context } from '../../core/shared/context.model'; import { Item } from '../../core/shared/item.model'; import { getFirstSucceededRemoteData } from '../../core/shared/operators'; -import { BrowseByComponent } from '../../shared/browse-by/browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component'; import { ThemedComcolPageHandleComponent } from '../../shared/comcol/comcol-page-handle/themed-comcol-page-handle.component'; @@ -78,7 +77,6 @@ export const BBM_PAGINATION_ID = 'bbm'; ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts b/src/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts index 39a90de83e..94956f257d 100644 --- a/src/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts +++ b/src/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts @@ -27,7 +27,6 @@ import { Context } from '../../core/shared/context.model'; import { HierarchicalBrowseDefinition } from '../../core/shared/hierarchical-browse-definition.model'; import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; -import { BrowseByComponent } from '../../shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -55,7 +54,6 @@ import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type'; ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts b/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts index a184a44953..e2e022391a 100644 --- a/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts +++ b/src/app/browse-by/browse-by-title/browse-by-title.component.spec.ts @@ -25,7 +25,6 @@ import { ItemDataService } from '../../core/data/item-data.service'; import { PaginationService } from '../../core/pagination/pagination.service'; import { Community } from '../../core/shared/community.model'; import { Item } from '../../core/shared/item.model'; -import { BrowseByComponent } from '../../shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -108,7 +107,6 @@ describe('BrowseByTitleComponent', () => { ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, ThemedLoadingComponent, ThemedBrowseByComponent, ] }, diff --git a/src/app/browse-by/browse-by-title/browse-by-title.component.ts b/src/app/browse-by/browse-by-title/browse-by-title.component.ts index 38c4c1333c..d99332baf1 100644 --- a/src/app/browse-by/browse-by-title/browse-by-title.component.ts +++ b/src/app/browse-by/browse-by-title/browse-by-title.component.ts @@ -15,7 +15,6 @@ import { SortDirection, SortOptions, } from '../../core/cache/models/sort-options.model'; -import { BrowseByComponent } from '../../shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -47,7 +46,6 @@ import { ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.html b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.html index 77f85d5f78..3ca9665b1c 100644 --- a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.html +++ b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.html @@ -28,14 +28,14 @@
- - +
diff --git a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts index 7f8a6076a1..71ba467084 100644 --- a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts +++ b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts @@ -23,7 +23,6 @@ import { SortDirection, SortOptions, } from '../../core/cache/models/sort-options.model'; -import { CollectionDataService } from '../../core/data/collection-data.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { ItemDataService } from '../../core/data/item-data.service'; @@ -39,6 +38,7 @@ import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-configurat import { ErrorComponent } from '../../shared/error/error.component'; import { HostWindowService } from '../../shared/host-window.service'; import { LoadingComponent } from '../../shared/loading/loading.component'; +import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { ItemSelectComponent } from '../../shared/object-select/item-select/item-select.component'; import { ObjectSelectService } from '../../shared/object-select/object-select.service'; @@ -58,6 +58,7 @@ import { RouterStub } from '../../shared/testing/router.stub'; import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; import { SearchServiceStub } from '../../shared/testing/search-service.stub'; import { createPaginatedList } from '../../shared/testing/utils.test'; +import { ThemeService } from '../../shared/theme-support/theme.service'; import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe'; import { VarDirective } from '../../shared/utils/var.directive'; import { CollectionItemMapperComponent } from './collection-item-mapper.component'; @@ -190,7 +191,6 @@ describe('CollectionItemMapperComponent', () => { { provide: SearchService, useValue: searchServiceStub }, { provide: NotificationsService, useValue: new NotificationsServiceStub() }, { provide: ItemDataService, useValue: itemDataServiceStub }, - { provide: CollectionDataService, useValue: collectionDataServiceStub }, { provide: TranslateService, useValue: translateServiceStub }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub() }, @@ -199,6 +199,7 @@ describe('CollectionItemMapperComponent', () => { { provide: GroupDataService, useValue: groupDataService }, { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: ThemeService, useValue: getMockThemeService() }, ], }).overrideComponent(CollectionItemMapperComponent, { set: { diff --git a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.ts b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.ts index 709efcdd00..c60e23e81e 100644 --- a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.ts +++ b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.ts @@ -35,7 +35,6 @@ import { SortDirection, SortOptions, } from '../../core/cache/models/sort-options.model'; -import { CollectionDataService } from '../../core/data/collection-data.service'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; import { ItemDataService } from '../../core/data/item-data.service'; import { PaginatedList } from '../../core/data/paginated-list.model'; @@ -150,7 +149,6 @@ export class CollectionItemMapperComponent implements OnInit { private searchService: SearchService, private notificationsService: NotificationsService, private itemDataService: ItemDataService, - private collectionDataService: CollectionDataService, private translateService: TranslateService, private dsoNameService: DSONameService) { } @@ -187,6 +185,8 @@ export class CollectionItemMapperComponent implements OnInit { this.shouldUpdate$.next(false); } return this.itemDataService.findListByHref(collectionRD.payload._links.mappedItems.href, Object.assign(options, { + currentPage: options.pagination.currentPage, + elementsPerPage: options.pagination.pageSize, sort: this.defaultSortOptions, }),!shouldUpdate, false, followLink('owningCollection')).pipe( getAllSucceededRemoteData(), diff --git a/src/app/collection-page/collection-page-routes.ts b/src/app/collection-page/collection-page-routes.ts index 91e9d59992..889b910d6a 100644 --- a/src/app/collection-page/collection-page-routes.ts +++ b/src/app/collection-page/collection-page-routes.ts @@ -7,6 +7,7 @@ import { browseByGuard } from '../browse-by/browse-by-guard'; import { browseByI18nBreadcrumbResolver } from '../browse-by/browse-by-i18n-breadcrumb.resolver'; import { authenticatedGuard } from '../core/auth/authenticated.guard'; import { collectionBreadcrumbResolver } from '../core/breadcrumbs/collection-breadcrumb.resolver'; +import { communityBreadcrumbResolver } from '../core/breadcrumbs/community-breadcrumb.resolver'; import { i18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; import { ComcolBrowseByComponent } from '../shared/comcol/sections/comcol-browse-by/comcol-browse-by.component'; import { ComcolSearchSectionComponent } from '../shared/comcol/sections/comcol-search-section/comcol-search-section.component'; @@ -27,12 +28,29 @@ import { itemTemplatePageResolver } from './edit-item-template-page/item-templat import { ThemedEditItemTemplatePageComponent } from './edit-item-template-page/themed-edit-item-template-page.component'; import { ThemedCollectionPageComponent } from './themed-collection-page.component'; - export const ROUTES: Route[] = [ { path: COLLECTION_CREATE_PATH, - component: CreateCollectionPageComponent, canActivate: [authenticatedGuard, createCollectionPageGuard], + children: [ + { + path: '', + component: CreateCollectionPageComponent, + resolve: { + breadcrumb: i18nBreadcrumbResolver, + }, + data: { + breadcrumbKey: 'collection.create', + }, + }, + ], + data: { + breadcrumbQueryParam: 'parent', + }, + resolve: { + breadcrumb: communityBreadcrumbResolver, + }, + runGuardsAndResolvers: 'always', }, { path: ':id', diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index d5da37c12f..f9739a4aa9 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -17,10 +17,10 @@ - - +
- - +
@@ -55,7 +55,7 @@
- + \ No newline at end of file diff --git a/src/app/collection-page/collection-page.component.ts b/src/app/collection-page/collection-page.component.ts index c015213ee1..5b5d0a84d7 100644 --- a/src/app/collection-page/collection-page.component.ts +++ b/src/app/collection-page/collection-page.component.ts @@ -54,7 +54,7 @@ import { ViewTrackerComponent } from '../statistics/angulartics/dspace/view-trac import { getCollectionPageRoute } from './collection-page-routing-paths'; @Component({ - selector: 'ds-collection-page', + selector: 'ds-base-collection-page', styleUrls: ['./collection-page.component.scss'], templateUrl: './collection-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html index 7b4ac97421..2294085096 100644 --- a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html +++ b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html @@ -25,7 +25,7 @@ - +

{{ 'collection.edit.tabs.source.form.head' | translate }}

diff --git a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html index 8d095dd229..7f0b2efba2 100644 --- a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html +++ b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html @@ -3,10 +3,10 @@

{{ 'collection.edit.template.head' | translate:{ collection: dsoNameService.getName(collection) } }}

- +
- +
diff --git a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.spec.ts b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.spec.ts index 7fa29919f8..4d33e7d008 100644 --- a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.spec.ts +++ b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.spec.ts @@ -12,7 +12,6 @@ import { of as observableOf } from 'rxjs'; import { ItemTemplateDataService } from '../../core/data/item-template-data.service'; import { Collection } from '../../core/shared/collection.model'; -import { DsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/dso-edit-metadata.component'; import { ThemedDsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -51,7 +50,7 @@ describe('EditItemTemplatePageComponent', () => { schemas: [NO_ERRORS_SCHEMA], }).overrideComponent(EditItemTemplatePageComponent, { remove: { - imports: [ThemedDsoEditMetadataComponent, DsoEditMetadataComponent], + imports: [ThemedDsoEditMetadataComponent], }, }).compileComponents(); })); diff --git a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts index eb44ffdc9b..f7c5dc4b14 100644 --- a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts +++ b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts @@ -24,7 +24,6 @@ import { RemoteData } from '../../core/data/remote-data'; import { Collection } from '../../core/shared/collection.model'; import { Item } from '../../core/shared/item.model'; import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; -import { DsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/dso-edit-metadata.component'; import { ThemedDsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component'; import { AlertComponent } from '../../shared/alert/alert.component'; import { AlertType } from '../../shared/alert/alert-type'; @@ -33,11 +32,10 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { getCollectionEditRoute } from '../collection-page-routing-paths'; @Component({ - selector: 'ds-edit-item-template-page', + selector: 'ds-base-edit-item-template-page', templateUrl: './edit-item-template-page.component.html', imports: [ ThemedDsoEditMetadataComponent, - DsoEditMetadataComponent, RouterLink, AsyncPipe, VarDirective, diff --git a/src/app/collection-page/edit-item-template-page/themed-edit-item-template-page.component.ts b/src/app/collection-page/edit-item-template-page/themed-edit-item-template-page.component.ts index 2dff557835..421049990a 100644 --- a/src/app/collection-page/edit-item-template-page/themed-edit-item-template-page.component.ts +++ b/src/app/collection-page/edit-item-template-page/themed-edit-item-template-page.component.ts @@ -4,10 +4,11 @@ import { ThemedComponent } from '../../shared/theme-support/themed.component'; import { EditItemTemplatePageComponent } from './edit-item-template-page.component'; @Component({ - selector: 'ds-themed-edit-item-template-page', + selector: 'ds-edit-item-template-page', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [EditItemTemplatePageComponent], }) /** * Component for editing the item template of a collection diff --git a/src/app/collection-page/themed-collection-page.component.ts b/src/app/collection-page/themed-collection-page.component.ts index e095e6eb68..c84d7c5fb4 100644 --- a/src/app/collection-page/themed-collection-page.component.ts +++ b/src/app/collection-page/themed-collection-page.component.ts @@ -7,10 +7,11 @@ import { CollectionPageComponent } from './collection-page.component'; * Themed wrapper for CollectionPageComponent */ @Component({ - selector: 'ds-themed-collection-page', + selector: 'ds-collection-page', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [CollectionPageComponent], }) export class ThemedCollectionPageComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/community-list-page/community-list-page.component.html b/src/app/community-list-page/community-list-page.component.html index 4392fb87d0..ca05201478 100644 --- a/src/app/community-list-page/community-list-page.component.html +++ b/src/app/community-list-page/community-list-page.component.html @@ -1,4 +1,4 @@

{{ 'communityList.title' | translate }}

- +
diff --git a/src/app/community-list-page/community-list-page.component.ts b/src/app/community-list-page/community-list-page.component.ts index aaf7bc2000..ca0db89f53 100644 --- a/src/app/community-list-page/community-list-page.component.ts +++ b/src/app/community-list-page/community-list-page.component.ts @@ -8,7 +8,7 @@ import { ThemedCommunityListComponent } from './community-list/themed-community- * navigated to with community-list.page.routing.module */ @Component({ - selector: 'ds-community-list-page', + selector: 'ds-base-community-list-page', templateUrl: './community-list-page.component.html', standalone: true, imports: [ThemedCommunityListComponent, TranslateModule], diff --git a/src/app/community-list-page/community-list/community-list.component.html b/src/app/community-list-page/community-list/community-list.component.html index 0d678299e1..82238ddd0d 100644 --- a/src/app/community-list-page/community-list/community-list.component.html +++ b/src/app/community-list-page/community-list/community-list.component.html @@ -1,4 +1,4 @@ - + {{ 'communityList.showMore' | translate }} - +
@@ -61,7 +61,7 @@ - +
diff --git a/src/app/community-list-page/community-list/community-list.component.ts b/src/app/community-list-page/community-list/community-list.component.ts index e0456ca700..5819471d7e 100644 --- a/src/app/community-list-page/community-list/community-list.component.ts +++ b/src/app/community-list-page/community-list/community-list.component.ts @@ -38,7 +38,7 @@ import { FlatNode } from '../flat-node.model'; * Which nodes were expanded is kept in the store, so this persists across pages. */ @Component({ - selector: 'ds-community-list', + selector: 'ds-base-community-list', templateUrl: './community-list.component.html', styleUrls: ['./community-list.component.scss'], standalone: true, diff --git a/src/app/community-list-page/community-list/themed-community-list.component.ts b/src/app/community-list-page/community-list/themed-community-list.component.ts index dc6c0aa345..5340384ed5 100644 --- a/src/app/community-list-page/community-list/themed-community-list.component.ts +++ b/src/app/community-list-page/community-list/themed-community-list.component.ts @@ -5,10 +5,11 @@ import { CommunityListComponent } from './community-list.component'; @Component({ - selector: 'ds-themed-community-list', + selector: 'ds-community-list', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [CommunityListComponent], }) export class ThemedCommunityListComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/community-list-page/themed-community-list-page.component.ts b/src/app/community-list-page/themed-community-list-page.component.ts index 4f0575c7db..d427b1bec1 100644 --- a/src/app/community-list-page/themed-community-list-page.component.ts +++ b/src/app/community-list-page/themed-community-list-page.component.ts @@ -7,10 +7,11 @@ import { CommunityListPageComponent } from './community-list-page.component'; * Themed wrapper for CommunityListPageComponent */ @Component({ - selector: 'ds-themed-community-list-page', + selector: 'ds-community-list-page', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [CommunityListPageComponent], }) export class ThemedCommunityListPageComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/community-page/community-page-routes.ts b/src/app/community-page/community-page-routes.ts index 995af8274f..656b96c311 100644 --- a/src/app/community-page/community-page-routes.ts +++ b/src/app/community-page/community-page-routes.ts @@ -28,8 +28,26 @@ import { ThemedCommunityPageComponent } from './themed-community-page.component' export const ROUTES: Route[] = [ { path: COMMUNITY_CREATE_PATH, - component: CreateCommunityPageComponent, + children: [ + { + path: '', + component: CreateCommunityPageComponent, + resolve: { + breadcrumb: i18nBreadcrumbResolver, + }, + data: { + breadcrumbKey: 'community.create', + }, + }, + ], canActivate: [authenticatedGuard, createCommunityPageGuard], + data: { + breadcrumbQueryParam: 'parent', + }, + resolve: { + breadcrumb: communityBreadcrumbResolver, + }, + runGuardsAndResolvers: 'always', }, { path: ':id', diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index b3e577af7d..a695e2019a 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -10,8 +10,8 @@ - - + + @@ -25,8 +25,8 @@
- - + +
@@ -39,5 +39,5 @@ - + diff --git a/src/app/community-page/community-page.component.ts b/src/app/community-page/community-page.component.ts index ce3d05aef9..bdb3a50c6b 100644 --- a/src/app/community-page/community-page.component.ts +++ b/src/app/community-page/community-page.component.ts @@ -47,7 +47,7 @@ import { ThemedCollectionPageSubCollectionListComponent } from './sections/sub-c import { ThemedCommunityPageSubCommunityListComponent } from './sections/sub-com-col-section/sub-community-list/themed-community-page-sub-community-list.component'; @Component({ - selector: 'ds-community-page', + selector: 'ds-base-community-page', styleUrls: ['./community-page.component.scss'], templateUrl: './community-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.html b/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.html index b5fbf1a01d..59d7b3bb5e 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.html +++ b/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.html @@ -9,5 +9,5 @@ - + diff --git a/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts b/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts index 2935f25595..1e8ff1d46c 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts +++ b/src/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts @@ -36,7 +36,7 @@ import { PaginationComponentOptions } from '../../../../shared/pagination/pagina import { VarDirective } from '../../../../shared/utils/var.directive'; @Component({ - selector: 'ds-community-page-sub-collection-list', + selector: 'ds-base-community-page-sub-collection-list', styleUrls: ['./community-page-sub-collection-list.component.scss'], templateUrl: './community-page-sub-collection-list.component.html', animations: [fadeIn], diff --git a/src/app/community-page/sections/sub-com-col-section/sub-collection-list/themed-community-page-sub-collection-list.component.ts b/src/app/community-page/sections/sub-com-col-section/sub-collection-list/themed-community-page-sub-collection-list.component.ts index ff5d057b31..4a965bc926 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-collection-list/themed-community-page-sub-collection-list.component.ts +++ b/src/app/community-page/sections/sub-com-col-section/sub-collection-list/themed-community-page-sub-collection-list.component.ts @@ -8,10 +8,11 @@ import { ThemedComponent } from '../../../../shared/theme-support/themed.compone import { CommunityPageSubCollectionListComponent } from './community-page-sub-collection-list.component'; @Component({ - selector: 'ds-themed-community-page-sub-collection-list', + selector: 'ds-community-page-sub-collection-list', styleUrls: [], templateUrl: '../../../../shared/theme-support/themed.component.html', standalone: true, + imports: [CommunityPageSubCollectionListComponent], }) export class ThemedCollectionPageSubCollectionListComponent extends ThemedComponent { @Input() community: Community; diff --git a/src/app/community-page/sections/sub-com-col-section/sub-com-col-section.component.html b/src/app/community-page/sections/sub-com-col-section/sub-com-col-section.component.html index 515e08ffdf..a811014bcc 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-com-col-section.component.html +++ b/src/app/community-page/sections/sub-com-col-section/sub-com-col-section.component.html @@ -1,8 +1,8 @@ - - - + - + diff --git a/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.html b/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.html index 0834d08ba5..7f9840f6b7 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.html +++ b/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.html @@ -9,5 +9,5 @@ - + diff --git a/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts b/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts index 4f74eff601..36bd9919bb 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts +++ b/src/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts @@ -35,7 +35,7 @@ import { PaginationComponentOptions } from '../../../../shared/pagination/pagina import { VarDirective } from '../../../../shared/utils/var.directive'; @Component({ - selector: 'ds-community-page-sub-community-list', + selector: 'ds-base-community-page-sub-community-list', styleUrls: ['./community-page-sub-community-list.component.scss'], templateUrl: './community-page-sub-community-list.component.html', animations: [fadeIn], diff --git a/src/app/community-page/sections/sub-com-col-section/sub-community-list/themed-community-page-sub-community-list.component.ts b/src/app/community-page/sections/sub-com-col-section/sub-community-list/themed-community-page-sub-community-list.component.ts index 11b62d68e4..5988ad0f5e 100644 --- a/src/app/community-page/sections/sub-com-col-section/sub-community-list/themed-community-page-sub-community-list.component.ts +++ b/src/app/community-page/sections/sub-com-col-section/sub-community-list/themed-community-page-sub-community-list.component.ts @@ -8,10 +8,11 @@ import { ThemedComponent } from '../../../../shared/theme-support/themed.compone import { CommunityPageSubCommunityListComponent } from './community-page-sub-community-list.component'; @Component({ - selector: 'ds-themed-community-page-sub-community-list', + selector: 'ds-community-page-sub-community-list', styleUrls: [], templateUrl: '../../../../shared/theme-support/themed.component.html', standalone: true, + imports: [CommunityPageSubCommunityListComponent], }) export class ThemedCommunityPageSubCommunityListComponent extends ThemedComponent { diff --git a/src/app/community-page/themed-community-page.component.ts b/src/app/community-page/themed-community-page.component.ts index 41a2960719..b655452041 100644 --- a/src/app/community-page/themed-community-page.component.ts +++ b/src/app/community-page/themed-community-page.component.ts @@ -7,10 +7,11 @@ import { CommunityPageComponent } from './community-page.component'; * Themed wrapper for CommunityPageComponent */ @Component({ - selector: 'ds-themed-community-page', + selector: 'ds-community-page', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [CommunityPageComponent], }) export class ThemedCommunityPageComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/core/auth/models/auth-status.model.ts b/src/app/core/auth/models/auth-status.model.ts index 1a6938887d..f25e5a4892 100644 --- a/src/app/core/auth/models/auth-status.model.ts +++ b/src/app/core/auth/models/auth-status.model.ts @@ -36,14 +36,14 @@ export class AuthStatus implements CacheableObject { * The unique identifier of this auth status */ @autoserialize - id: string; + id: string; /** * The type for this AuthStatus */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The UUID of this auth status @@ -57,19 +57,19 @@ export class AuthStatus implements CacheableObject { * True if REST API is up and running, should never return false */ @autoserialize - okay: boolean; + okay: boolean; /** * If the auth status represents an authenticated state */ @autoserialize - authenticated: boolean; + authenticated: boolean; /** * The {@link HALLink}s for this AuthStatus */ @deserialize - _links: { + _links: { self: HALLink; eperson: HALLink; specialGroups: HALLink; @@ -80,32 +80,32 @@ export class AuthStatus implements CacheableObject { * Will be undefined unless the eperson {@link HALLink} has been resolved. */ @link(EPERSON) - eperson?: Observable>; + eperson?: Observable>; /** * The SpecialGroup of this auth status * Will be undefined unless the SpecialGroup {@link HALLink} has been resolved. */ @link(GROUP, true) - specialGroups?: Observable>>; + specialGroups?: Observable>>; /** * True if the token is valid, false if there was no token or the token wasn't valid */ @autoserialize - token?: AuthTokenInfo; + token?: AuthTokenInfo; /** * Authentication error if there was one for this status */ // TODO should be refactored to use the RemoteData error @autoserialize - error?: AuthError; + error?: AuthError; /** * All authentication methods enabled at the backend */ @autoserialize - authMethods: AuthMethod[]; + authMethods: AuthMethod[]; } diff --git a/src/app/core/auth/models/short-lived-token.model.ts b/src/app/core/auth/models/short-lived-token.model.ts index d91a26e990..5e8587d02d 100644 --- a/src/app/core/auth/models/short-lived-token.model.ts +++ b/src/app/core/auth/models/short-lived-token.model.ts @@ -22,19 +22,19 @@ export class ShortLivedToken implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The value for this ShortLivedToken */ @autoserializeAs('token') - value: string; + value: string; /** * The {@link HALLink}s for this ShortLivedToken */ @deserialize - _links: { + _links: { self: HALLink; }; } diff --git a/src/app/core/breadcrumbs/community-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/community-breadcrumb.resolver.ts index 1064a1cc19..0c37b5ca4f 100644 --- a/src/app/core/breadcrumbs/community-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/community-breadcrumb.resolver.ts @@ -8,11 +8,15 @@ import { Observable } from 'rxjs'; import { BreadcrumbConfig } from '../../breadcrumbs/breadcrumb/breadcrumb-config.model'; import { COMMUNITY_PAGE_LINKS_TO_FOLLOW } from '../../community-page/community-page.resolver'; +import { hasValue } from '../../shared/empty.util'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { CommunityDataService } from '../data/community-data.service'; import { Community } from '../shared/community.model'; import { DSpaceObject } from '../shared/dspace-object.model'; -import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; +import { + DSOBreadcrumbResolver, + DSOBreadcrumbResolverByUuid, +} from './dso-breadcrumb.resolver'; import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; /** @@ -25,11 +29,22 @@ export const communityBreadcrumbResolver: ResolveFn> dataService: CommunityDataService = inject(CommunityDataService), ): Observable> => { const linksToFollow: FollowLinkConfig[] = COMMUNITY_PAGE_LINKS_TO_FOLLOW as FollowLinkConfig[]; - return DSOBreadcrumbResolver( - route, - state, - breadcrumbService, - dataService, - ...linksToFollow, - ) as Observable>; + if (hasValue(route.data.breadcrumbQueryParam) && hasValue(route.queryParams[route.data.breadcrumbQueryParam])) { + return DSOBreadcrumbResolverByUuid( + route, + state, + route.queryParams[route.data.breadcrumbQueryParam], + breadcrumbService, + dataService, + ...linksToFollow, + ) as Observable>; + } else { + return DSOBreadcrumbResolver( + route, + state, + breadcrumbService, + dataService, + ...linksToFollow, + ) as Observable>; + } }; diff --git a/src/app/core/breadcrumbs/dso-breadcrumb.resolver.spec.ts b/src/app/core/breadcrumbs/dso-breadcrumb.resolver.spec.ts index ae19128d4e..c40a14a323 100644 --- a/src/app/core/breadcrumbs/dso-breadcrumb.resolver.spec.ts +++ b/src/app/core/breadcrumbs/dso-breadcrumb.resolver.spec.ts @@ -18,7 +18,10 @@ describe('DSOBreadcrumbResolver', () => { uuid = '1234-65487-12354-1235'; breadcrumbUrl = `/collections/${uuid}`; currentUrl = `${breadcrumbUrl}/edit`; - testCollection = Object.assign(new Collection(), { uuid }); + testCollection = Object.assign(new Collection(), { + uuid: uuid, + type: 'collection', + }); dsoBreadcrumbService = {}; collectionService = { findById: () => createSuccessfulRemoteDataObject$(testCollection), diff --git a/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts index cb1f96b103..992627ddfa 100644 --- a/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts @@ -5,6 +5,7 @@ import { import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { getDSORoute } from '../../app-routing-paths'; import { BreadcrumbConfig } from '../../breadcrumbs/breadcrumb/breadcrumb-config.model'; import { hasValue } from '../../shared/empty.util'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; @@ -32,15 +33,34 @@ export const DSOBreadcrumbResolver: (route: ActivatedRouteSnapshot, state: Route dataService: IdentifiableDataService, ...linksToFollow: FollowLinkConfig[] ): Observable> => { - const uuid = route.params.id; + return DSOBreadcrumbResolverByUuid(route, state, route.params.id, breadcrumbService, dataService, ...linksToFollow); +}; + +/** + * Method for resolving a breadcrumb config object with the given UUID + * + * @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot + * @param {RouterStateSnapshot} state The current RouterStateSnapshot + * @param {String} uuid The uuid of the DSO object + * @param {DSOBreadcrumbsService} breadcrumbService + * @param {IdentifiableDataService} dataService + * @param linksToFollow + * @returns BreadcrumbConfig object + */ +export const DSOBreadcrumbResolverByUuid: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot, uuid: string, breadcrumbService: DSOBreadcrumbsService, dataService: IdentifiableDataService, ...linksToFollow: FollowLinkConfig[]) => Observable> = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot, + uuid: string, + breadcrumbService: DSOBreadcrumbsService, + dataService: IdentifiableDataService, + ...linksToFollow: FollowLinkConfig[] +): Observable> => { return dataService.findById(uuid, true, false, ...linksToFollow).pipe( getFirstCompletedRemoteData(), getRemoteDataPayload(), map((object: DSpaceObject) => { if (hasValue(object)) { - const fullPath = state.url; - const url = (fullPath.substring(0, fullPath.indexOf(uuid))).concat(uuid); - return { provider: breadcrumbService, key: object, url: url }; + return { provider: breadcrumbService, key: object, url: getDSORoute(object) }; } else { return undefined; } diff --git a/src/app/core/cache/models/self-link.model.ts b/src/app/core/cache/models/self-link.model.ts index 903a779495..a87acdd506 100644 --- a/src/app/core/cache/models/self-link.model.ts +++ b/src/app/core/cache/models/self-link.model.ts @@ -3,9 +3,9 @@ import { autoserialize } from 'cerialize'; export class SelfLink { @autoserialize - self: string; + self: string; @autoserialize - uuid: string; + uuid: string; } diff --git a/src/app/core/config/models/bulk-access-condition-options.model.ts b/src/app/core/config/models/bulk-access-condition-options.model.ts index c491343852..514c682b4e 100644 --- a/src/app/core/config/models/bulk-access-condition-options.model.ts +++ b/src/app/core/config/models/bulk-access-condition-options.model.ts @@ -25,19 +25,19 @@ export class BulkAccessConditionOptions extends ConfigObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserializeAs(String, 'name') - uuid: string; + uuid: string; @autoserialize - id: string; + id: string; @autoserialize - itemAccessConditionOptions: AccessesConditionOption[]; + itemAccessConditionOptions: AccessesConditionOption[]; @autoserialize - bitstreamAccessConditionOptions: AccessesConditionOption[]; + bitstreamAccessConditionOptions: AccessesConditionOption[]; _links: { self: HALLink }; } diff --git a/src/app/core/config/models/config-submission-access.model.ts b/src/app/core/config/models/config-submission-access.model.ts index 4617dc4719..2e9a929183 100644 --- a/src/app/core/config/models/config-submission-access.model.ts +++ b/src/app/core/config/models/config-submission-access.model.ts @@ -22,25 +22,25 @@ export class SubmissionAccessModel extends ConfigObject { * A list of available item access conditions */ @autoserialize - accessConditionOptions: AccessesConditionOption[]; + accessConditionOptions: AccessesConditionOption[]; /** * Boolean that indicates whether the current item must be findable via search or browse. */ @autoserialize - discoverable: boolean; + discoverable: boolean; /** * Boolean that indicates whether or not the user can change the discoverable flag. */ @autoserialize - canChangeDiscoverable: boolean; + canChangeDiscoverable: boolean; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink }; diff --git a/src/app/core/config/models/config-submission-definition.model.ts b/src/app/core/config/models/config-submission-definition.model.ts index 2d6b1ad604..eda4f54340 100644 --- a/src/app/core/config/models/config-submission-definition.model.ts +++ b/src/app/core/config/models/config-submission-definition.model.ts @@ -23,20 +23,20 @@ export class SubmissionDefinitionModel extends ConfigObject { * A boolean representing if this submission definition is the default or not */ @autoserialize - isDefault: boolean; + isDefault: boolean; /** * A list of SubmissionSectionModel that are present in this submission definition */ // TODO refactor using remotedata @deserialize - sections: PaginatedList; + sections: PaginatedList; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, collections: HALLink, sections: HALLink diff --git a/src/app/core/config/models/config-submission-form.model.ts b/src/app/core/config/models/config-submission-form.model.ts index f6011adc76..c524a83916 100644 --- a/src/app/core/config/models/config-submission-form.model.ts +++ b/src/app/core/config/models/config-submission-form.model.ts @@ -27,5 +27,5 @@ export class SubmissionFormModel extends ConfigObject { * An array of [FormRowModel] that are present in this form */ @autoserialize - rows: FormRowModel[]; + rows: FormRowModel[]; } diff --git a/src/app/core/config/models/config-submission-section.model.ts b/src/app/core/config/models/config-submission-section.model.ts index 0d4ae9aa10..feb4fc9cb0 100644 --- a/src/app/core/config/models/config-submission-section.model.ts +++ b/src/app/core/config/models/config-submission-section.model.ts @@ -27,31 +27,31 @@ export class SubmissionSectionModel extends ConfigObject { * The header for this section */ @autoserialize - header: string; + header: string; /** * A boolean representing if this submission section is the mandatory or not */ @autoserialize - mandatory: boolean; + mandatory: boolean; /** * A string representing the kind of section object */ @autoserialize - sectionType: SectionsType; + sectionType: SectionsType; /** * The [SubmissionSectionVisibility] object for this section */ @autoserialize - visibility: SubmissionSectionVisibility; + visibility: SubmissionSectionVisibility; /** * The {@link HALLink}s for this SubmissionSectionModel */ @deserialize - _links: { + _links: { self: HALLink; config: HALLink; }; diff --git a/src/app/core/config/models/config-submission-upload.model.ts b/src/app/core/config/models/config-submission-upload.model.ts index edc4626f83..cabc84d0f5 100644 --- a/src/app/core/config/models/config-submission-upload.model.ts +++ b/src/app/core/config/models/config-submission-upload.model.ts @@ -27,22 +27,22 @@ export class SubmissionUploadModel extends ConfigObject { * A list of available bitstream access conditions */ @autoserialize - accessConditionOptions: AccessConditionOption[]; + accessConditionOptions: AccessConditionOption[]; /** * An object representing the configuration describing the bitstream metadata form */ @link(SUBMISSION_FORMS_TYPE) - metadata?: Observable>; + metadata?: Observable>; @autoserialize - required: boolean; + required: boolean; @autoserialize - maxSize: number; + maxSize: number; @deserialize - _links: { + _links: { metadata: HALLink self: HALLink }; diff --git a/src/app/core/config/models/config.model.ts b/src/app/core/config/models/config.model.ts index c1db44e891..74d090b89d 100644 --- a/src/app/core/config/models/config.model.ts +++ b/src/app/core/config/models/config.model.ts @@ -27,13 +27,13 @@ export abstract class ConfigObject implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, [name: string]: HALLink }; diff --git a/src/app/core/data/feature-authorization/authorization-utils.ts b/src/app/core/data/feature-authorization/authorization-utils.ts index f763b1a38d..cd4bc452a5 100644 --- a/src/app/core/data/feature-authorization/authorization-utils.ts +++ b/src/app/core/data/feature-authorization/authorization-utils.ts @@ -91,5 +91,5 @@ export const oneAuthorizationMatchesFeature = (featureID: FeatureID) => return observableOf([]); } }), - map((features: Feature[]) => features.filter((feature: Feature) => feature.id === featureID).length > 0), + map((features: Feature[]) => features.filter((feature: Feature) => feature.id === featureID.valueOf()).length > 0), ); diff --git a/src/app/core/data/paginated-list.model.ts b/src/app/core/data/paginated-list.model.ts index e412af4986..ef2819afd8 100644 --- a/src/app/core/data/paginated-list.model.ts +++ b/src/app/core/data/paginated-list.model.ts @@ -73,13 +73,13 @@ export class PaginatedList extends CacheableObject { * The type of the list */ @excludeFromEquals - type = PAGINATED_LIST; + type = PAGINATED_LIST; /** * The type of objects in the list */ @autoserialize - objectType?: ResourceType; + objectType?: ResourceType; /** * The list of objects that represents the current page @@ -90,13 +90,13 @@ export class PaginatedList extends CacheableObject { * the {@link PageInfo} object */ @autoserialize - pageInfo?: PageInfo; + pageInfo?: PageInfo; /** * The {@link HALLink}s for this PaginatedList */ @deserialize - _links: { + _links: { self: HALLink; page: HALLink[]; first?: HALLink; diff --git a/src/app/core/data/root.model.ts b/src/app/core/data/root.model.ts index 46a276fa1f..ced115b055 100644 --- a/src/app/core/data/root.model.ts +++ b/src/app/core/data/root.model.ts @@ -22,37 +22,37 @@ export class Root implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The url for the dspace UI */ @autoserialize - dspaceUI: string; + dspaceUI: string; /** * The repository Name */ @autoserialize - dspaceName: string; + dspaceName: string; /** * The url for the rest api */ @autoserialize - dspaceServer: string; + dspaceServer: string; /** * The current DSpace version */ @autoserialize - dspaceVersion: string; + dspaceVersion: string; /** * The {@link HALLink}s for the root object */ @deserialize - _links: { + _links: { self: HALLink; [k: string]: HALLink | HALLink[]; }; diff --git a/src/app/core/dspace-rest/dspace-rest.service.ts b/src/app/core/dspace-rest/dspace-rest.service.ts index 67d74e9570..a75cef53bf 100644 --- a/src/app/core/dspace-rest/dspace-rest.service.ts +++ b/src/app/core/dspace-rest/dspace-rest.service.ts @@ -151,7 +151,7 @@ export class DspaceRestService { return form; } - protected handleHttpError(err: unknown): RequestError | unknown { + protected handleHttpError(err: unknown): unknown { if (err instanceof HttpErrorResponse) { const error = new RequestError( (isNotEmpty(err?.error?.message)) ? err.error.message : err.message, diff --git a/src/app/core/dspace-rest/dspace.serializer.spec.ts b/src/app/core/dspace-rest/dspace.serializer.spec.ts index 9a6635bc98..169dd97a57 100644 --- a/src/app/core/dspace-rest/dspace.serializer.spec.ts +++ b/src/app/core/dspace-rest/dspace.serializer.spec.ts @@ -9,13 +9,13 @@ import { DSpaceSerializer } from './dspace.serializer'; class TestModel implements HALResource { @autoserialize - id: string; + id: string; @autoserialize - name: string; + name: string; @deserialize - _links: { + _links: { self: HALLink; parents: HALLink; }; diff --git a/src/app/core/eperson/models/group.model.ts b/src/app/core/eperson/models/group.model.ts index bed55af0a2..71923d6c55 100644 --- a/src/app/core/eperson/models/group.model.ts +++ b/src/app/core/eperson/models/group.model.ts @@ -48,7 +48,7 @@ export class Group extends DSpaceObject { * The {@link HALLink}s for this Group */ @deserialize - _links: { + _links: { self: HALLink; subgroups: HALLink; epersons: HALLink; diff --git a/src/app/core/metadata/metadata-field.model.ts b/src/app/core/metadata/metadata-field.model.ts index 1084b4009f..11b6e1c74e 100644 --- a/src/app/core/metadata/metadata-field.model.ts +++ b/src/app/core/metadata/metadata-field.model.ts @@ -32,37 +32,37 @@ export class MetadataField extends ListableObject implements HALResource { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The identifier of this metadata field */ @autoserialize - id: number; + id: number; /** * The element of this metadata field */ @autoserialize - element: string; + element: string; /** * The qualifier of this metadata field */ @autoserialize - qualifier: string; + qualifier: string; /** * The scope note of this metadata field */ @autoserialize - scopeNote: string; + scopeNote: string; /** * The {@link HALLink}s for this MetadataField */ @deserialize - _links: { + _links: { self: HALLink, schema: HALLink }; @@ -72,7 +72,7 @@ export class MetadataField extends ListableObject implements HALResource { * Will be undefined unless the schema {@link HALLink} has been resolved. */ @link(METADATA_SCHEMA) - schema?: Observable>; + schema?: Observable>; /** * Method to print this metadata field as a string without the schema diff --git a/src/app/core/metadata/metadata-schema.model.ts b/src/app/core/metadata/metadata-schema.model.ts index 85faf5d2ce..656638b4c6 100644 --- a/src/app/core/metadata/metadata-schema.model.ts +++ b/src/app/core/metadata/metadata-schema.model.ts @@ -23,29 +23,29 @@ export class MetadataSchema extends ListableObject implements HALResource { * The unique identifier for this metadata schema */ @autoserialize - id: number; + id: number; /** * The object type */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * A unique prefix that defines this schema */ @autoserialize - prefix: string; + prefix: string; /** * The namespace of this metadata schema */ @autoserialize - namespace: string; + namespace: string; @deserialize - _links: { + _links: { self: HALLink, }; diff --git a/src/app/core/notifications/models/suggestion-source.model.ts b/src/app/core/notifications/models/suggestion-source.model.ts index f8e7c70cf5..1a757a5aa0 100644 --- a/src/app/core/notifications/models/suggestion-source.model.ts +++ b/src/app/core/notifications/models/suggestion-source.model.ts @@ -24,26 +24,26 @@ export class SuggestionSource implements CacheableObject { * The Suggestion Target id */ @autoserialize - id: string; + id: string; /** * The total number of suggestions provided by Suggestion Target for */ @autoserialize - total: number; + total: number; /** * The type of this ConfigObject */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, suggestiontargets: HALLink }; diff --git a/src/app/core/notifications/models/suggestion-target.model.ts b/src/app/core/notifications/models/suggestion-target.model.ts index 1cbd78ae6b..cdc78eb466 100644 --- a/src/app/core/notifications/models/suggestion-target.model.ts +++ b/src/app/core/notifications/models/suggestion-target.model.ts @@ -24,38 +24,38 @@ export class SuggestionTarget implements CacheableObject { * The Suggestion Target id */ @autoserialize - id: string; + id: string; /** * The Suggestion Target name to display */ @autoserialize - display: string; + display: string; /** * The Suggestion Target source to display */ @autoserialize - source: string; + source: string; /** * The total number of suggestions provided by Suggestion Target for */ @autoserialize - total: number; + total: number; /** * The type of this ConfigObject */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, suggestions: HALLink, target: HALLink diff --git a/src/app/core/notifications/models/suggestion.model.ts b/src/app/core/notifications/models/suggestion.model.ts index a84fe9ffe2..bd4015b499 100644 --- a/src/app/core/notifications/models/suggestion.model.ts +++ b/src/app/core/notifications/models/suggestion.model.ts @@ -38,57 +38,57 @@ export class Suggestion implements CacheableObject { * The Suggestion id */ @autoserialize - id: string; + id: string; /** * The Suggestion name to display */ @autoserialize - display: string; + display: string; /** * The Suggestion source to display */ @autoserialize - source: string; + source: string; /** * The Suggestion external source uri */ @autoserialize - externalSourceUri: string; + externalSourceUri: string; /** * The Total Score of the suggestion */ @autoserialize - score: string; + score: string; /** * The total number of suggestions provided by Suggestion Target for */ @autoserialize - evidences: SuggestionEvidences; + evidences: SuggestionEvidences; /** * All metadata of this suggestion object */ @excludeFromEquals @autoserializeAs(MetadataMapSerializer) - metadata: MetadataMap; + metadata: MetadataMap; /** * The type of this ConfigObject */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, target: HALLink }; diff --git a/src/app/core/notifications/qa/models/quality-assurance-event.model.ts b/src/app/core/notifications/qa/models/quality-assurance-event.model.ts index 9210d8f6f9..e015dd01d9 100644 --- a/src/app/core/notifications/qa/models/quality-assurance-event.model.ts +++ b/src/app/core/notifications/qa/models/quality-assurance-event.model.ts @@ -104,62 +104,62 @@ export class QualityAssuranceEventObject implements CacheableObject { * The Quality Assurance event uuid inside DSpace */ @autoserialize - id: string; + id: string; /** * The universally unique identifier of this Quality Assurance event */ @autoserializeAs(String, 'id') - uuid: string; + uuid: string; /** * The Quality Assurance event original id (ex.: the source archive OAI-PMH identifier) */ @autoserialize - originalId: string; + originalId: string; /** * The title of the article to which the suggestion refers */ @autoserialize - title: string; + title: string; /** * Reliability of the suggestion (of the data inside 'message') */ @autoserialize - trust: number; + trust: number; /** * The timestamp Quality Assurance event was saved in DSpace */ @autoserialize - eventDate: string; + eventDate: string; /** * The Quality Assurance event status (ACCEPTED, REJECTED, DISCARDED, PENDING) */ @autoserialize - status: string; + status: string; /** * The suggestion data. Data may vary depending on the source */ @autoserialize - message: SourceQualityAssuranceEventMessageObject; + message: SourceQualityAssuranceEventMessageObject; /** * The type of this ConfigObject */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, target: HALLink, related: HALLink @@ -170,12 +170,12 @@ export class QualityAssuranceEventObject implements CacheableObject { * Will be undefined unless the {@item HALLink} has been resolved. */ @link(ITEM) - target?: Observable>; + target?: Observable>; /** * The related project for this Event * Will be undefined unless the {@related HALLink} has been resolved. */ @link(ITEM) - related?: Observable>; + related?: Observable>; } diff --git a/src/app/core/notifications/qa/models/quality-assurance-source.model.ts b/src/app/core/notifications/qa/models/quality-assurance-source.model.ts index cc5f874119..56c674b031 100644 --- a/src/app/core/notifications/qa/models/quality-assurance-source.model.ts +++ b/src/app/core/notifications/qa/models/quality-assurance-source.model.ts @@ -24,32 +24,32 @@ export class QualityAssuranceSourceObject implements CacheableObject { * The Quality Assurance source id */ @autoserialize - id: string; + id: string; /** * The date of the last udate from Notifications */ @autoserialize - lastEvent: string; + lastEvent: string; /** * The total number of suggestions provided by Notifications for this source */ @autoserialize - totalEvents: number; + totalEvents: number; /** * The type of this ConfigObject */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, }; } diff --git a/src/app/core/notifications/qa/models/quality-assurance-topic.model.ts b/src/app/core/notifications/qa/models/quality-assurance-topic.model.ts index ddc027d194..0d4235a531 100644 --- a/src/app/core/notifications/qa/models/quality-assurance-topic.model.ts +++ b/src/app/core/notifications/qa/models/quality-assurance-topic.model.ts @@ -24,38 +24,38 @@ export class QualityAssuranceTopicObject implements CacheableObject { * The Quality Assurance topic id */ @autoserialize - id: string; + id: string; /** * The Quality Assurance topic name to display */ @autoserialize - name: string; + name: string; /** * The date of the last udate from Notifications */ @autoserialize - lastEvent: string; + lastEvent: string; /** * The total number of suggestions provided by Notifications for this topic */ @autoserialize - totalEvents: number; + totalEvents: number; /** * The type of this ConfigObject */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The links to all related resources returned by the rest api. */ @deserialize - _links: { + _links: { self: HALLink, }; } diff --git a/src/app/core/orcid/model/orcid-history.model.ts b/src/app/core/orcid/model/orcid-history.model.ts index 62f5353ed2..aa8c4b41ba 100644 --- a/src/app/core/orcid/model/orcid-history.model.ts +++ b/src/app/core/orcid/model/orcid-history.model.ts @@ -23,49 +23,49 @@ export class OrcidHistory extends CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The identifier of this Orcid History record */ @autoserialize - id: number; + id: number; /** * The name of the related entity */ @autoserialize - entityName: string; + entityName: string; /** * The identifier of the profileItem of this Orcid History record. */ @autoserialize - profileItemId: string; + profileItemId: string; /** * The identifier of the entity related to this Orcid History record. */ @autoserialize - entityId: string; + entityId: string; /** * The type of the entity related to this Orcid History record. */ @autoserialize - entityType: string; + entityType: string; /** * The response status coming from ORCID api. */ @autoserialize - status: number; + status: number; /** * The putCode assigned by ORCID to the entity. */ @autoserialize - putCode: string; + putCode: string; /** * The last send attempt timestamp. @@ -86,7 +86,7 @@ export class OrcidHistory extends CacheableObject { * The {@link HALLink}s for this Orcid History record */ @deserialize - _links: { + _links: { self: HALLink, }; diff --git a/src/app/core/orcid/model/orcid-queue.model.ts b/src/app/core/orcid/model/orcid-queue.model.ts index fedb078cc5..2735114f22 100644 --- a/src/app/core/orcid/model/orcid-queue.model.ts +++ b/src/app/core/orcid/model/orcid-queue.model.ts @@ -23,49 +23,49 @@ export class OrcidQueue extends CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The identifier of this Orcid Queue record */ @autoserialize - id: number; + id: number; /** * The record description. */ @autoserialize - description: string; + description: string; /** * The identifier of the profileItem of this Orcid Queue record. */ @autoserialize - profileItemId: string; + profileItemId: string; /** * The identifier of the entity related to this Orcid Queue record. */ @autoserialize - entityId: string; + entityId: string; /** * The type of this Orcid Queue record. */ @autoserialize - recordType: string; + recordType: string; /** * The operation related to this Orcid Queue record. */ @autoserialize - operation: string; + operation: string; /** * The {@link HALLink}s for this Orcid Queue record */ @deserialize - _links: { + _links: { self: HALLink, }; diff --git a/src/app/core/profile/model/researcher-profile.model.ts b/src/app/core/profile/model/researcher-profile.model.ts index d26156123c..28ffd09a7b 100644 --- a/src/app/core/profile/model/researcher-profile.model.ts +++ b/src/app/core/profile/model/researcher-profile.model.ts @@ -31,28 +31,28 @@ export class ResearcherProfile extends CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The identifier of this Researcher Profile */ @autoserialize - id: string; + id: string; @deserializeAs('id') - uuid: string; + uuid: string; /** * The visibility of this Researcher Profile */ @autoserialize - visible: boolean; + visible: boolean; /** * The {@link HALLink}s for this Researcher Profile */ @deserialize - _links: { + _links: { self: HALLink, item: HALLink, eperson: HALLink @@ -63,6 +63,6 @@ export class ResearcherProfile extends CacheableObject { * Will be undefined unless the item {@link HALLink} has been resolved. */ @link(ITEM) - item?: Observable>; + item?: Observable>; } diff --git a/src/app/core/resource-policy/models/resource-policy.model.ts b/src/app/core/resource-policy/models/resource-policy.model.ts index d4558cfe3a..669844690b 100644 --- a/src/app/core/resource-policy/models/resource-policy.model.ts +++ b/src/app/core/resource-policy/models/resource-policy.model.ts @@ -34,50 +34,50 @@ export class ResourcePolicy implements CacheableObject { * The identifier for this Resource Policy */ @autoserialize - id: string; + id: string; /** * The name for this Resource Policy */ @autoserialize - name: string; + name: string; /** * The description for this Resource Policy */ @autoserialize - description: string; + description: string; /** * The classification or this Resource Policy */ @autoserialize - policyType: PolicyType; + policyType: PolicyType; /** * The action that is allowed by this Resource Policy */ @autoserialize - action: ActionType; + action: ActionType; /** * The first day of validity of the policy (format YYYY-MM-DD) */ @autoserialize - startDate: string; + startDate: string; /** * The last day of validity of the policy (format YYYY-MM-DD) */ @autoserialize - endDate: string; + endDate: string; /** * The object type */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The universally unique identifier for this Resource Policy @@ -91,7 +91,7 @@ export class ResourcePolicy implements CacheableObject { * The {@link HALLink}s for this ResourcePolicy */ @deserialize - _links: { + _links: { eperson: HALLink, group: HALLink, self: HALLink, @@ -102,12 +102,12 @@ export class ResourcePolicy implements CacheableObject { * Will be undefined unless the version {@link HALLink} has been resolved. */ @link(EPERSON) - eperson?: Observable>; + eperson?: Observable>; /** * The group linked by this resource policy * Will be undefined unless the version {@link HALLink} has been resolved. */ @link(GROUP) - group?: Observable>; + group?: Observable>; } diff --git a/src/app/core/shared/authorization.model.ts b/src/app/core/shared/authorization.model.ts index 0031b054f6..1712db9a07 100644 --- a/src/app/core/shared/authorization.model.ts +++ b/src/app/core/shared/authorization.model.ts @@ -31,10 +31,10 @@ export class Authorization extends DSpaceObject { * Unique identifier for this authorization */ @autoserialize - id: string; + id: string; @deserialize - _links: { + _links: { self: HALLink; eperson: HALLink; feature: HALLink; @@ -46,17 +46,17 @@ export class Authorization extends DSpaceObject { * Null if the authorization grants access to anonymous users */ @link(EPERSON) - eperson?: Observable>; + eperson?: Observable>; /** * The Feature enabled by this Authorization */ @link(FEATURE) - feature?: Observable>; + feature?: Observable>; /** * The Object this authorization applies to */ @link(ITEM) - object?: Observable>; + object?: Observable>; } diff --git a/src/app/core/shared/bitstream-format.model.ts b/src/app/core/shared/bitstream-format.model.ts index 354edb4cbd..44ba85c974 100644 --- a/src/app/core/shared/bitstream-format.model.ts +++ b/src/app/core/shared/bitstream-format.model.ts @@ -25,43 +25,43 @@ export class BitstreamFormat implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * Short description of this Bitstream Format */ @autoserialize - shortDescription: string; + shortDescription: string; /** * Description of this Bitstream Format */ @autoserialize - description: string; + description: string; /** * String representing the MIME type of this Bitstream Format */ @autoserialize - mimetype: string; + mimetype: string; /** * The level of support the system offers for this Bitstream Format */ @autoserialize - supportLevel: BitstreamFormatSupportLevel; + supportLevel: BitstreamFormatSupportLevel; /** * True if the Bitstream Format is used to store system information, rather than the content of items in the system */ @autoserialize - internal: boolean; + internal: boolean; /** * String representing this Bitstream Format's file extension */ @autoserialize - extensions: string[]; + extensions: string[]; /** * Universally unique identifier for this Bitstream Format @@ -77,13 +77,13 @@ export class BitstreamFormat implements CacheableObject { * but might not be unique across different object types */ @autoserialize - id: string; + id: string; /** * The {@link HALLink}s for this BitstreamFormat */ @deserialize - _links: { + _links: { self: HALLink; }; } diff --git a/src/app/core/shared/bitstream.model.ts b/src/app/core/shared/bitstream.model.ts index d1b821e8cd..73e5e04b36 100644 --- a/src/app/core/shared/bitstream.model.ts +++ b/src/app/core/shared/bitstream.model.ts @@ -28,25 +28,25 @@ export class Bitstream extends DSpaceObject implements ChildHALResource { * The size of this bitstream in bytes */ @autoserialize - sizeBytes: number; + sizeBytes: number; /** * The description of this Bitstream */ @autoserialize - description: string; + description: string; /** * The name of the Bundle this Bitstream is part of */ @autoserialize - bundleName: string; + bundleName: string; /** * The {@link HALLink}s for this Bitstream */ @deserialize - _links: { + _links: { self: HALLink; bundle: HALLink; format: HALLink; @@ -59,21 +59,21 @@ export class Bitstream extends DSpaceObject implements ChildHALResource { * Will be undefined unless the thumbnail {@link HALLink} has been resolved. */ @link(BITSTREAM, false, 'thumbnail') - thumbnail?: Observable>; + thumbnail?: Observable>; /** * The BitstreamFormat of this Bitstream * Will be undefined unless the format {@link HALLink} has been resolved. */ @link(BITSTREAM_FORMAT, false, 'format') - format?: Observable>; + format?: Observable>; /** * The owning bundle for this Bitstream * Will be undefined unless the bundle{@link HALLink} has been resolved. */ @link(BUNDLE) - bundle?: Observable>; + bundle?: Observable>; getParentLinkKey(): keyof this['_links'] { return 'format'; diff --git a/src/app/core/shared/browse-definition.model.ts b/src/app/core/shared/browse-definition.model.ts index 8e50a57bb5..6de81727fa 100644 --- a/src/app/core/shared/browse-definition.model.ts +++ b/src/app/core/shared/browse-definition.model.ts @@ -9,7 +9,7 @@ import { CacheableObject } from '../cache/cacheable-object.model'; export abstract class BrowseDefinition extends CacheableObject { @autoserialize - id: string; + id: string; /** * Get the render type of the BrowseDefinition model diff --git a/src/app/core/shared/browse-entry.model.ts b/src/app/core/shared/browse-entry.model.ts index 03e3ab3f5b..746333872e 100644 --- a/src/app/core/shared/browse-entry.model.ts +++ b/src/app/core/shared/browse-entry.model.ts @@ -25,41 +25,41 @@ export class BrowseEntry extends ListableObject implements TypedObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The authority string of this browse entry */ @autoserialize - authority: string; + authority: string; /** * The value of this browse entry */ @autoserialize - value: string; + value: string; /** * The language of the value of this browse entry */ @autoserializeAs('valueLang') - language: string; + language: string; /** * Thumbnail link used when browsing items with showThumbs config enabled. */ @autoserializeAs('thumbnail') - thumbnail: string; + thumbnail: string; /** * The count of this browse entry */ @excludeFromEquals @autoserialize - count: number; + count: number; @deserialize - _links: { + _links: { self: HALLink; entries: HALLink; thumbnail: HALLink; diff --git a/src/app/core/shared/bundle.model.ts b/src/app/core/shared/bundle.model.ts index e5b92799d4..d9ea6d83dc 100644 --- a/src/app/core/shared/bundle.model.ts +++ b/src/app/core/shared/bundle.model.ts @@ -27,7 +27,7 @@ export class Bundle extends DSpaceObject { * The {@link HALLink}s for this Bundle */ @deserialize - _links: { + _links: { self: HALLink; primaryBitstream: HALLink; bitstreams: HALLink; @@ -39,19 +39,19 @@ export class Bundle extends DSpaceObject { * Will be undefined unless the primaryBitstream {@link HALLink} has been resolved. */ @link(BITSTREAM) - primaryBitstream?: Observable>; + primaryBitstream?: Observable>; /** * The list of Bitstreams that are direct children of this Bundle * Will be undefined unless the bitstreams {@link HALLink} has been resolved. */ @link(BITSTREAM, true) - bitstreams?: Observable>>; + bitstreams?: Observable>>; /** * The owning item for this Bundle * Will be undefined unless the Item{@link HALLink} has been resolved. */ @link(ITEM) - item?: Observable>; + item?: Observable>; } diff --git a/src/app/core/shared/collection.model.ts b/src/app/core/shared/collection.model.ts index 468b0ccc64..b929e54ccb 100644 --- a/src/app/core/shared/collection.model.ts +++ b/src/app/core/shared/collection.model.ts @@ -33,13 +33,13 @@ export class Collection extends DSpaceObject implements ChildHALResource, Handle @excludeFromEquals @autoserialize - archivedItemsCount: number; + archivedItemsCount: number; /** * The {@link HALLink}s for this Collection */ @deserialize - _links: { + _links: { license: HALLink; harvester: HALLink; mappedItems: HALLink; @@ -60,28 +60,28 @@ export class Collection extends DSpaceObject implements ChildHALResource, Handle * Will be undefined unless the license {@link HALLink} has been resolved. */ @link(LICENSE) - license?: Observable>; + license?: Observable>; /** * The logo for this Collection * Will be undefined unless the logo {@link HALLink} has been resolved. */ @link(BITSTREAM) - logo?: Observable>; + logo?: Observable>; /** * The default access conditions for this Collection * Will be undefined unless the defaultAccessConditions {@link HALLink} has been resolved. */ @link(RESOURCE_POLICY, true) - defaultAccessConditions?: Observable>>; + defaultAccessConditions?: Observable>>; /** * The Community that is a direct parent of this Collection * Will be undefined unless the parent community HALLink has been resolved. */ @link(COMMUNITY, false) - parentCommunity?: Observable>; + parentCommunity?: Observable>; /** * A string representing the unique handle of this Collection diff --git a/src/app/core/shared/community.model.ts b/src/app/core/shared/community.model.ts index 764b15e2ed..31b00398ff 100644 --- a/src/app/core/shared/community.model.ts +++ b/src/app/core/shared/community.model.ts @@ -29,13 +29,13 @@ export class Community extends DSpaceObject implements ChildHALResource, HandleO @excludeFromEquals @autoserialize - archivedItemsCount: number; + archivedItemsCount: number; /** * The {@link HALLink}s for this Community */ @deserialize - _links: { + _links: { collections: HALLink; logo: HALLink; subcommunities: HALLink; @@ -49,28 +49,28 @@ export class Community extends DSpaceObject implements ChildHALResource, HandleO * Will be undefined unless the logo {@link HALLink} has been resolved. */ @link(BITSTREAM) - logo?: Observable>; + logo?: Observable>; /** * The list of Collections that are direct children of this Community * Will be undefined unless the collections {@link HALLink} has been resolved. */ @link(COLLECTION, true) - collections?: Observable>>; + collections?: Observable>>; /** * The list of Communities that are direct children of this Community * Will be undefined unless the subcommunities {@link HALLink} has been resolved. */ @link(COMMUNITY, true) - subcommunities?: Observable>>; + subcommunities?: Observable>>; /** * The Community that is a direct parent of this Community * Will be undefined unless the parent community HALLink has been resolved. */ @link(COMMUNITY, false) - parentCommunity?: Observable>; + parentCommunity?: Observable>; /** * A string representing the unique handle of this Community diff --git a/src/app/core/shared/configuration-property.model.ts b/src/app/core/shared/configuration-property.model.ts index 2b6ab606c9..e15f8a5b85 100644 --- a/src/app/core/shared/configuration-property.model.ts +++ b/src/app/core/shared/configuration-property.model.ts @@ -23,31 +23,31 @@ export class ConfigurationProperty implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The uuid of the configuration property * The name is used as id for configuration properties */ @autoserializeAs(String, 'name') - uuid: string; + uuid: string; /** * The name of the configuration property */ @autoserialize - name: string; + name: string; /** * The values of the configuration property */ @autoserialize - values: string[]; + values: string[]; /** * The links of the configuration property */ @deserialize - _links: { self: HALLink }; + _links: { self: HALLink }; } diff --git a/src/app/core/shared/content-source.model.ts b/src/app/core/shared/content-source.model.ts index ee535191d0..cfc78f223f 100644 --- a/src/app/core/shared/content-source.model.ts +++ b/src/app/core/shared/content-source.model.ts @@ -38,20 +38,20 @@ export class ContentSource extends CacheableObject { * and we need a custom responseparser for ContentSource responses */ @excludeFromEquals - type: ResourceType = CONTENT_SOURCE; + type: ResourceType = CONTENT_SOURCE; /** * Unique identifier, this is necessary to store the ContentSource in FieldUpdates * Because the ContentSource coming from the REST API doesn't have a UUID, we're using the selflink */ @deserializeAs('self') - uuid: string; + uuid: string; /** * OAI Provider / Source */ @autoserializeAs('oai_source') - oaiSource: string; + oaiSource: string; /** * OAI Specific set ID @@ -64,14 +64,14 @@ export class ContentSource extends CacheableObject { * The ID of the metadata format used */ @autoserializeAs('metadata_config_id') - metadataConfigId: string; + metadataConfigId: string; /** * Type of content being harvested * Defaults to 'NONE', meaning the collection doesn't harvest its content from an external source */ @autoserializeAs('harvest_type') - harvestType = ContentSourceHarvestType.None; + harvestType = ContentSourceHarvestType.None; /** * The available metadata configurations @@ -82,31 +82,31 @@ export class ContentSource extends CacheableObject { * The current harvest status */ @autoserializeAs('harvest_status') - harvestStatus: string; + harvestStatus: string; /** * The last's harvest start time */ @autoserializeAs('harvest_start_time') - harvestStartTime: string; + harvestStartTime: string; /** * When the collection was last harvested */ @autoserializeAs('last_harvested') - lastHarvested: string; + lastHarvested: string; /** * The current harvest message */ @autoserializeAs('harvest_message') - message: string; + message: string; /** * The {@link HALLink}s for this ContentSource */ @deserialize - _links: { + _links: { self: HALLink }; } diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index dc9b7f5fca..7bc05b1d3a 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -46,20 +46,20 @@ export class DSpaceObject extends ListableObject implements CacheableObject { */ @excludeFromEquals @autoserializeAs(String, 'uuid') - id: string; + id: string; /** * The universally unique ide ntifier of this DSpaceObject */ @autoserializeAs(String) - uuid: string; + uuid: string; /** * A string representing the kind of DSpaceObject, e.g. community, item, … */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * A shorthand to get this DSpaceObject's self link @@ -100,10 +100,10 @@ export class DSpaceObject extends ListableObject implements CacheableObject { */ @excludeFromEquals @autoserializeAs(MetadataMapSerializer) - metadata: MetadataMap; + metadata: MetadataMap; @deserialize - _links: { + _links: { self: HALLink; }; diff --git a/src/app/core/shared/external-source-entry.model.ts b/src/app/core/shared/external-source-entry.model.ts index d743a92310..01e52d30d5 100644 --- a/src/app/core/shared/external-source-entry.model.ts +++ b/src/app/core/shared/external-source-entry.model.ts @@ -27,44 +27,44 @@ export class ExternalSourceEntry extends ListableObject { * Unique identifier */ @autoserialize - id: string; + id: string; /** * The object type */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The value to display */ @autoserialize - display: string; + display: string; /** * The value to store the entry with */ @autoserialize - value: string; + value: string; /** * The ID of the external source this entry originates from */ @autoserialize - externalSource: string; + externalSource: string; /** * Metadata of the entry */ @autoserializeAs(MetadataMapSerializer) - metadata: MetadataMap; + metadata: MetadataMap; /** * The {@link HALLink}s for this ExternalSourceEntry */ @deserialize - _links: { + _links: { self: HALLink; }; diff --git a/src/app/core/shared/external-source.model.ts b/src/app/core/shared/external-source.model.ts index 70766e0494..40661917e2 100644 --- a/src/app/core/shared/external-source.model.ts +++ b/src/app/core/shared/external-source.model.ts @@ -30,38 +30,38 @@ export class ExternalSource extends CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * Unique identifier */ @autoserialize - id: string; + id: string; /** * The name of this external source */ @autoserialize - name: string; + name: string; /** * Is the source hierarchical? */ @autoserialize - hierarchical: boolean; + hierarchical: boolean; /** * The list of entity types that are compatible with this external source * Will be undefined unless the entityTypes {@link HALLink} has been resolved. */ @link(ITEM_TYPE, true) - entityTypes?: Observable>>; + entityTypes?: Observable>>; /** * The {@link HALLink}s for this ExternalSource */ @deserialize - _links: { + _links: { self: HALLink; entries: HALLink; entityTypes: HALLink; diff --git a/src/app/core/shared/feature.model.ts b/src/app/core/shared/feature.model.ts index 270eb2de9d..1c18d1478f 100644 --- a/src/app/core/shared/feature.model.ts +++ b/src/app/core/shared/feature.model.ts @@ -21,22 +21,22 @@ export class Feature extends DSpaceObject { * Unique identifier for this feature */ @autoserialize - id: string; + id: string; /** * A human readable description of the feature's purpose */ @autoserialize - description: string; + description: string; /** * A list of resource types this feature applies to */ @autoserialize - resourcetypes: string[]; + resourcetypes: string[]; @deserialize - _links: { + _links: { self: HALLink; }; } diff --git a/src/app/core/shared/flat-browse-definition.model.ts b/src/app/core/shared/flat-browse-definition.model.ts index d9d59d1114..74166f937c 100644 --- a/src/app/core/shared/flat-browse-definition.model.ts +++ b/src/app/core/shared/flat-browse-definition.model.ts @@ -23,14 +23,14 @@ export class FlatBrowseDefinition extends NonHierarchicalBrowseDefinition { * The object type */ @excludeFromEquals - type: ResourceType = FLAT_BROWSE_DEFINITION; + type: ResourceType = FLAT_BROWSE_DEFINITION; get self(): string { return this._links.self.href; } @deserialize - _links: { + _links: { self: HALLink; items: HALLink; }; diff --git a/src/app/core/shared/hal-resource.model.ts b/src/app/core/shared/hal-resource.model.ts index 5f9d107a54..a27d448bd6 100644 --- a/src/app/core/shared/hal-resource.model.ts +++ b/src/app/core/shared/hal-resource.model.ts @@ -13,7 +13,7 @@ export class HALResource { * The {@link HALLink}s for this {@link HALResource} */ @deserialize - _links: { + _links: { /** * The {@link HALLink} that refers to this {@link HALResource} diff --git a/src/app/core/shared/hierarchical-browse-definition.model.ts b/src/app/core/shared/hierarchical-browse-definition.model.ts index 97d50c3ca6..e7c06a5372 100644 --- a/src/app/core/shared/hierarchical-browse-definition.model.ts +++ b/src/app/core/shared/hierarchical-browse-definition.model.ts @@ -25,23 +25,23 @@ export class HierarchicalBrowseDefinition extends BrowseDefinition { * The object type */ @excludeFromEquals - type: ResourceType = HIERARCHICAL_BROWSE_DEFINITION; + type: ResourceType = HIERARCHICAL_BROWSE_DEFINITION; @autoserialize - facetType: string; + facetType: string; @autoserialize - vocabulary: string; + vocabulary: string; @autoserializeAs('metadata') - metadataKeys: string[]; + metadataKeys: string[]; get self(): string { return this._links.self.href; } @deserialize - _links: { + _links: { self: HALLink; vocabulary: HALLink; }; diff --git a/src/app/core/shared/item-relationships/item-type.model.ts b/src/app/core/shared/item-relationships/item-type.model.ts index 1d8ca6df98..bbf1cb3be0 100644 --- a/src/app/core/shared/item-relationships/item-type.model.ts +++ b/src/app/core/shared/item-relationships/item-type.model.ts @@ -24,16 +24,16 @@ export class ItemType implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The identifier of this ItemType */ @autoserialize - id: string; + id: string; @autoserialize - label: string; + label: string; /** * The universally unique identifier of this ItemType @@ -47,7 +47,7 @@ export class ItemType implements CacheableObject { * The {@link HALLink}s for this ItemType */ @deserialize - _links: { + _links: { self: HALLink, }; } diff --git a/src/app/core/shared/item-relationships/relationship-type.model.ts b/src/app/core/shared/item-relationships/relationship-type.model.ts index 75d5d70af6..3a86ee34f8 100644 --- a/src/app/core/shared/item-relationships/relationship-type.model.ts +++ b/src/app/core/shared/item-relationships/relationship-type.model.ts @@ -31,19 +31,19 @@ export class RelationshipType implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The label that describes this RelationshipType */ @autoserialize - label: string; + label: string; /** * The identifier of this RelationshipType */ @autoserialize - id: string; + id: string; /** * The universally unique identifier of this RelationshipType @@ -57,43 +57,43 @@ export class RelationshipType implements CacheableObject { * The label that describes the Relation to the left of this RelationshipType */ @autoserialize - leftwardType: string; + leftwardType: string; /** * The maximum amount of Relationships allowed to the left of this RelationshipType */ @autoserialize - leftMaxCardinality: number; + leftMaxCardinality: number; /** * The minimum amount of Relationships allowed to the left of this RelationshipType */ @autoserialize - leftMinCardinality: number; + leftMinCardinality: number; /** * The label that describes the Relation to the right of this RelationshipType */ @autoserialize - rightwardType: string; + rightwardType: string; /** * The maximum amount of Relationships allowed to the right of this RelationshipType */ @autoserialize - rightMaxCardinality: number; + rightMaxCardinality: number; /** * The minimum amount of Relationships allowed to the right of this RelationshipType */ @autoserialize - rightMinCardinality: number; + rightMinCardinality: number; /** * The {@link HALLink}s for this RelationshipType */ @deserialize - _links: { + _links: { self: HALLink; leftType: HALLink; rightType: HALLink; @@ -104,12 +104,12 @@ export class RelationshipType implements CacheableObject { * Will be undefined unless the leftType {@link HALLink} has been resolved. */ @link(ITEM_TYPE) - leftType?: Observable>; + leftType?: Observable>; /** * The type of Item found on the right side of this RelationshipType * Will be undefined unless the rightType {@link HALLink} has been resolved. */ @link(ITEM_TYPE) - rightType?: Observable>; + rightType?: Observable>; } diff --git a/src/app/core/shared/item-relationships/relationship.model.ts b/src/app/core/shared/item-relationships/relationship.model.ts index 4f6fe2796d..77fdff8651 100644 --- a/src/app/core/shared/item-relationships/relationship.model.ts +++ b/src/app/core/shared/item-relationships/relationship.model.ts @@ -33,7 +33,7 @@ export class Relationship implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The universally unique identifier of this Relationship @@ -47,37 +47,37 @@ export class Relationship implements CacheableObject { * The identifier of this Relationship */ @autoserialize - id: string; + id: string; /** * The place of the Item to the left side of this Relationship */ @autoserialize - leftPlace: number; + leftPlace: number; /** * The place of the Item to the right side of this Relationship */ @autoserialize - rightPlace: number; + rightPlace: number; /** * The name variant of the Item to the left side of this Relationship */ @autoserialize - leftwardValue: string; + leftwardValue: string; /** * The name variant of the Item to the right side of this Relationship */ @autoserialize - rightwardValue: string; + rightwardValue: string; /** * The {@link HALLink}s for this Relationship */ @deserialize - _links: { + _links: { self: HALLink; leftItem: HALLink; rightItem: HALLink; @@ -89,20 +89,20 @@ export class Relationship implements CacheableObject { * Will be undefined unless the leftItem {@link HALLink} has been resolved. */ @link(ITEM) - leftItem?: Observable>; + leftItem?: Observable>; /** * The item on the right side of this relationship * Will be undefined unless the rightItem {@link HALLink} has been resolved. */ @link(ITEM) - rightItem?: Observable>; + rightItem?: Observable>; /** * The RelationshipType for this Relationship * Will be undefined unless the relationshipType {@link HALLink} has been resolved. */ @link(RELATIONSHIP_TYPE) - relationshipType?: Observable>; + relationshipType?: Observable>; } diff --git a/src/app/core/shared/item-request.model.ts b/src/app/core/shared/item-request.model.ts index 8b1ef94512..5a4f912363 100644 --- a/src/app/core/shared/item-request.model.ts +++ b/src/app/core/shared/item-request.model.ts @@ -22,70 +22,70 @@ export class ItemRequest implements CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * opaque string which uniquely identifies this request */ @autoserialize - token: string; + token: string; /** * true if the request is for all bitstreams of the item. */ @autoserialize - allfiles: boolean; + allfiles: boolean; /** * email address of the person requesting the files. */ @autoserialize - requestEmail: string; + requestEmail: string; /** * Human-readable name of the person requesting the files. */ @autoserialize - requestName: string; + requestName: string; /** * arbitrary message provided by the person requesting the files. */ @autoserialize - requestMessage: string; + requestMessage: string; /** * date that the request was recorded. */ @autoserialize - requestDate: string; + requestDate: string; /** * true if the request has been granted. */ @autoserialize - acceptRequest: boolean; + acceptRequest: boolean; /** * date that the request was granted or denied. */ @autoserialize - decisionDate: string; + decisionDate: string; /** * date on which the request is considered expired. */ @autoserialize - expires: string; + expires: string; /** * UUID of the requested Item. */ @autoserialize - itemId: string; + itemId: string; /** * UUID of the requested bitstream. */ @autoserialize - bitstreamId: string; + bitstreamId: string; /** * The {@link HALLink}s for this ItemRequest */ @deserialize - _links: { + _links: { self: HALLink; item: HALLink; bitstream: HALLink; diff --git a/src/app/core/shared/item.model.ts b/src/app/core/shared/item.model.ts index 33a9f3bb38..b13cf25f03 100644 --- a/src/app/core/shared/item.model.ts +++ b/src/app/core/shared/item.model.ts @@ -48,37 +48,37 @@ export class Item extends DSpaceObject implements ChildHALResource, HandleObject * A string representing the unique handle of this Item */ @autoserialize - handle: string; + handle: string; /** * The Date of the last modification of this Item */ @deserializeAs(Date) - lastModified: Date; + lastModified: Date; /** * A boolean representing if this Item is currently archived or not */ @autoserializeAs(Boolean, 'inArchive') - isArchived: boolean; + isArchived: boolean; /** * A boolean representing if this Item is currently discoverable or not */ @autoserializeAs(Boolean, 'discoverable') - isDiscoverable: boolean; + isDiscoverable: boolean; /** * A boolean representing if this Item is currently withdrawn or not */ @autoserializeAs(Boolean, 'withdrawn') - isWithdrawn: boolean; + isWithdrawn: boolean; /** * The {@link HALLink}s for this Item */ @deserialize - _links: { + _links: { mappedCollections: HALLink; relationships: HALLink; bundles: HALLink; @@ -96,35 +96,35 @@ export class Item extends DSpaceObject implements ChildHALResource, HandleObject * Will be undefined unless the owningCollection {@link HALLink} has been resolved. */ @link(COLLECTION) - owningCollection?: Observable>; + owningCollection?: Observable>; /** * The version this item represents in its history * Will be undefined unless the version {@link HALLink} has been resolved. */ @link(VERSION) - version?: Observable>; + version?: Observable>; /** * The list of Bundles inside this Item * Will be undefined unless the bundles {@link HALLink} has been resolved. */ @link(BUNDLE, true) - bundles?: Observable>>; + bundles?: Observable>>; /** * The list of Relationships this Item has with others * Will be undefined unless the relationships {@link HALLink} has been resolved. */ @link(RELATIONSHIP, true) - relationships?: Observable>>; + relationships?: Observable>>; /** * The thumbnail for this Item * Will be undefined unless the thumbnail {@link HALLink} has been resolved. */ @link(BITSTREAM, false, 'thumbnail') - thumbnail?: Observable>; + thumbnail?: Observable>; /** * The access status for this Item @@ -138,7 +138,7 @@ export class Item extends DSpaceObject implements ChildHALResource, HandleObject * Will be undefined unless the identifiers {@link HALLink} has been resolved. */ @link(IDENTIFIERS, false, 'identifiers') - identifiers?: Observable>; + identifiers?: Observable>; /** * Method that returns as which type of object this object should be rendered diff --git a/src/app/core/shared/license.model.ts b/src/app/core/shared/license.model.ts index af85c31eea..0cb1e70b6b 100644 --- a/src/app/core/shared/license.model.ts +++ b/src/app/core/shared/license.model.ts @@ -16,11 +16,11 @@ export class License extends DSpaceObject { * Is the license custom? */ @autoserialize - custom: boolean; + custom: boolean; /** * The text of the license */ @autoserialize - text: string; + text: string; } diff --git a/src/app/core/shared/metadata.models.ts b/src/app/core/shared/metadata.models.ts index 4ba78e39f7..0f26d7ff59 100644 --- a/src/app/core/shared/metadata.models.ts +++ b/src/app/core/shared/metadata.models.ts @@ -37,26 +37,26 @@ export class MetadataValue implements MetadataValueInterface { /** The language. */ @autoserialize - language: string; + language: string; /** The string value. */ @autoserialize - value: string; + value: string; /** * The place of this MetadataValue within its list of metadata * This is used to render metadata in a specific custom order */ @autoserialize - place: number; + place: number; /** The authority key used for authority-controlled metadata */ @autoserialize - authority: string; + authority: string; /** The authority confidence value */ @autoserialize - confidence: number; + confidence: number; /** * Returns true if this Metadatum's authority key starts with 'virtual::' diff --git a/src/app/core/shared/non-hierarchical-browse-definition.ts b/src/app/core/shared/non-hierarchical-browse-definition.ts index 769d70629d..7f8c6d0e5f 100644 --- a/src/app/core/shared/non-hierarchical-browse-definition.ts +++ b/src/app/core/shared/non-hierarchical-browse-definition.ts @@ -16,14 +16,14 @@ import { SortOption } from './sort-option.model'; export abstract class NonHierarchicalBrowseDefinition extends BrowseDefinition { @autoserialize - sortOptions: SortOption[]; + sortOptions: SortOption[]; @autoserializeAs('order') - defaultSortOrder: string; + defaultSortOrder: string; @autoserializeAs('metadata') - metadataKeys: string[]; + metadataKeys: string[]; @autoserialize - dataType: BrowseByDataType; + dataType: BrowseByDataType; } diff --git a/src/app/core/shared/page-info.model.ts b/src/app/core/shared/page-info.model.ts index 5594e58309..c9557abcb6 100644 --- a/src/app/core/shared/page-info.model.ts +++ b/src/app/core/shared/page-info.model.ts @@ -17,31 +17,31 @@ export class PageInfo implements HALResource { * The number of elements on a page */ @autoserializeAs(Number, 'size') - elementsPerPage: number; + elementsPerPage: number; /** * The total number of elements in the entire set */ @autoserialize - totalElements: number; + totalElements: number; /** * The total number of pages */ @autoserialize - totalPages: number; + totalPages: number; /** * The number of the current page, zero-based */ @autoserializeAs(Number, 'number') - currentPage: number; + currentPage: number; /** * The {@link HALLink}s for this PageInfo */ @deserialize - _links: { + _links: { first: HALLink; prev: HALLink; next: HALLink; diff --git a/src/app/core/shared/search/search-filters/search-config.model.ts b/src/app/core/shared/search/search-filters/search-config.model.ts index ccc9827e59..1595eba49d 100644 --- a/src/app/core/shared/search/search-filters/search-config.model.ts +++ b/src/app/core/shared/search/search-filters/search-config.model.ts @@ -20,31 +20,31 @@ export class SearchConfig implements CacheableObject { * The id of this search configuration. */ @autoserialize - id: string; + id: string; /** * The configured filters. */ @autoserialize - filters: FilterConfig[]; + filters: FilterConfig[]; /** * The configured sort options. */ @autoserialize - sortOptions: SortConfig[]; + sortOptions: SortConfig[]; /** * The object type. */ @autoserialize - type: ResourceType; + type: ResourceType; /** * The {@link HALLink}s for this Item */ @deserialize - _links: { + _links: { facets: HALLink; objects: HALLink; self: HALLink; diff --git a/src/app/core/shared/sort-option.model.ts b/src/app/core/shared/sort-option.model.ts index b179d159b6..c735e87b9a 100644 --- a/src/app/core/shared/sort-option.model.ts +++ b/src/app/core/shared/sort-option.model.ts @@ -2,8 +2,8 @@ import { autoserialize } from 'cerialize'; export class SortOption { @autoserialize - name: string; + name: string; @autoserialize - metadata: string; + metadata: string; } diff --git a/src/app/core/shared/template-item.model.ts b/src/app/core/shared/template-item.model.ts index 4c33a2bd92..a536dea49e 100644 --- a/src/app/core/shared/template-item.model.ts +++ b/src/app/core/shared/template-item.model.ts @@ -23,6 +23,6 @@ export class TemplateItem extends Item { * The Collection that this item is a template for */ @link(COLLECTION) - templateItemOf: Observable>; + templateItemOf: Observable>; } diff --git a/src/app/core/shared/value-list-browse-definition.model.ts b/src/app/core/shared/value-list-browse-definition.model.ts index 80ad73e761..ad9fc60d1c 100644 --- a/src/app/core/shared/value-list-browse-definition.model.ts +++ b/src/app/core/shared/value-list-browse-definition.model.ts @@ -23,14 +23,14 @@ export class ValueListBrowseDefinition extends NonHierarchicalBrowseDefinition { * The object type */ @excludeFromEquals - type: ResourceType = VALUE_LIST_BROWSE_DEFINITION; + type: ResourceType = VALUE_LIST_BROWSE_DEFINITION; get self(): string { return this._links.self.href; } @deserialize - _links: { + _links: { self: HALLink; entries: HALLink; }; diff --git a/src/app/core/shared/version-history.model.ts b/src/app/core/shared/version-history.model.ts index 9792a20ff3..58d9259a04 100644 --- a/src/app/core/shared/version-history.model.ts +++ b/src/app/core/shared/version-history.model.ts @@ -27,7 +27,7 @@ export class VersionHistory extends DSpaceObject { static type = VERSION_HISTORY; @deserialize - _links: { + _links: { self: HALLink; versions: HALLink; draftVersion: HALLink; @@ -37,30 +37,30 @@ export class VersionHistory extends DSpaceObject { * The identifier of this Version History */ @autoserialize - id: string; + id: string; /** * The summary of this Version History */ @autoserialize - summary: string; + summary: string; /** * The name of the submitter of this Version History */ @autoserialize - submitterName: string; + submitterName: string; /** * Whether exist a workspace item */ @autoserialize - draftVersion: boolean; + draftVersion: boolean; /** * The list of versions within this history */ @excludeFromEquals @link(VERSION, true) - versions: Observable>>; + versions: Observable>>; } diff --git a/src/app/core/shared/version.model.ts b/src/app/core/shared/version.model.ts index f66bc8938b..105ba74416 100644 --- a/src/app/core/shared/version.model.ts +++ b/src/app/core/shared/version.model.ts @@ -30,7 +30,7 @@ export class Version extends DSpaceObject { static type = VERSION; @deserialize - _links: { + _links: { self: HALLink; item: HALLink; versionhistory: HALLink; @@ -41,50 +41,50 @@ export class Version extends DSpaceObject { * The identifier of this Version */ @autoserialize - id: string; + id: string; /** * The version number of the version's history this version represents */ @autoserialize - version: number; + version: number; /** * The summary for the changes made in this version */ @autoserialize - summary: string; + summary: string; /** * The name of the submitter of this version */ @autoserialize - submitterName: string; + submitterName: string; /** * The Date this version was created */ @deserialize - created: Date; + created: Date; /** * The full version history this version is apart of */ @excludeFromEquals @link(VERSION_HISTORY) - versionhistory: Observable>; + versionhistory: Observable>; /** * The item this version represents */ @excludeFromEquals @link(ITEM) - item: Observable>; + item: Observable>; /** * The e-person who created this version */ @excludeFromEquals @link(EPERSON) - eperson: Observable>; + eperson: Observable>; } diff --git a/src/app/core/statistics/models/usage-report.model.ts b/src/app/core/statistics/models/usage-report.model.ts index b8a415667d..a4924f3a3d 100644 --- a/src/app/core/statistics/models/usage-report.model.ts +++ b/src/app/core/statistics/models/usage-report.model.ts @@ -26,19 +26,19 @@ export class UsageReport extends HALResource { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserialize - id: string; + id: string; @autoserializeAs('report-type') reportType: string; @autoserialize - points: Point[]; + points: Point[]; @deserialize - _links: { + _links: { self: HALLink; }; } diff --git a/src/app/core/submission/models/correctiontype.model.ts b/src/app/core/submission/models/correctiontype.model.ts index 0b9dd75545..4b5bd1ddd6 100644 --- a/src/app/core/submission/models/correctiontype.model.ts +++ b/src/app/core/submission/models/correctiontype.model.ts @@ -22,7 +22,7 @@ export class CorrectionType extends CacheableObject { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserialize /** * The unique identifier for the correction type mode. diff --git a/src/app/core/submission/models/submission-cc-license-url.model.ts b/src/app/core/submission/models/submission-cc-license-url.model.ts index 85fa1d0896..b1e53aa206 100644 --- a/src/app/core/submission/models/submission-cc-license-url.model.ts +++ b/src/app/core/submission/models/submission-cc-license-url.model.ts @@ -20,8 +20,8 @@ export class SubmissionCcLicenceUrl extends HALResource { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserialize - url: string; + url: string; } diff --git a/src/app/core/submission/models/submission-cc-license.model.ts b/src/app/core/submission/models/submission-cc-license.model.ts index c730aa44fc..8ab235941f 100644 --- a/src/app/core/submission/models/submission-cc-license.model.ts +++ b/src/app/core/submission/models/submission-cc-license.model.ts @@ -20,16 +20,16 @@ export class SubmissionCcLicence extends HALResource { */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; @autoserialize - id: string; + id: string; @autoserialize - name: string; + name: string; @autoserialize - fields: Field[]; + fields: Field[]; } export interface Field { diff --git a/src/app/core/submission/models/submission-object.model.ts b/src/app/core/submission/models/submission-object.model.ts index 882fafb467..d4836f6dcf 100644 --- a/src/app/core/submission/models/submission-object.model.ts +++ b/src/app/core/submission/models/submission-object.model.ts @@ -35,38 +35,38 @@ export abstract class SubmissionObject extends DSpaceObject implements Cacheable @excludeFromEquals @autoserialize - id: string; + id: string; /** * The SubmissionObject last modified date */ @autoserialize - lastModified: Date; + lastModified: Date; /** * The collection this submission applies to * Will be undefined unless the collection {@link HALLink} has been resolved. */ @link(COLLECTION) - collection?: Observable> | Collection; + collection?: Observable> | Collection; /** * The SubmissionObject's last section's data */ @autoserialize - sections: WorkspaceitemSectionsObject; + sections: WorkspaceitemSectionsObject; /** * The SubmissionObject's last section's errors */ @autoserialize - errors: SubmissionObjectError[]; + errors: SubmissionObjectError[]; /** * The {@link HALLink}s for this SubmissionObject */ @deserialize - _links: { + _links: { self: HALLink; collection: HALLink; item: HALLink; @@ -92,14 +92,14 @@ export abstract class SubmissionObject extends DSpaceObject implements Cacheable * Will be undefined unless the submissionDefinition {@link HALLink} has been resolved. */ @link(SubmissionDefinitionsModel.type) - submissionDefinition?: Observable> | SubmissionDefinitionsModel; + submissionDefinition?: Observable> | SubmissionDefinitionsModel; /** * The submitter for this SubmissionObject * Will be undefined unless the submitter {@link HALLink} has been resolved. */ @link(EPERSON) - submitter?: Observable> | EPerson; + submitter?: Observable> | EPerson; /** * The submission supervision order diff --git a/src/app/core/submission/resolver/submission-links-to-follow.ts b/src/app/core/submission/resolver/submission-links-to-follow.ts new file mode 100644 index 0000000000..1ddda024c5 --- /dev/null +++ b/src/app/core/submission/resolver/submission-links-to-follow.ts @@ -0,0 +1,17 @@ +import { + followLink, + FollowLinkConfig, +} from '../../../shared/utils/follow-link-config.model'; +import { WorkflowItem } from '../models/workflowitem.model'; +import { WorkspaceItem } from '../models/workspaceitem.model'; + +/** + * The self links defined in this list are expected to be requested somewhere in the near future + * Requesting them as embeds will limit the number of requests + * + * Needs to be in a separate file to prevent circular dependencies in webpack. + */ +export const SUBMISSION_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ + followLink('item'), + followLink('collection'), +]; diff --git a/src/app/core/submission/resolver/submission-object.resolver.ts b/src/app/core/submission/resolver/submission-object.resolver.ts index 4ddd9dea93..3ead988c9b 100644 --- a/src/app/core/submission/resolver/submission-object.resolver.ts +++ b/src/app/core/submission/resolver/submission-object.resolver.ts @@ -5,12 +5,12 @@ import { import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { followLink } from '../../../shared/utils/follow-link-config.model'; import { IdentifiableDataService } from '../../data/base/identifiable-data.service'; import { RemoteData } from '../../data/remote-data'; import { Item } from '../../shared/item.model'; import { getFirstCompletedRemoteData } from '../../shared/operators'; import { SubmissionObject } from '../models/submission-object.model'; +import { SUBMISSION_LINKS_TO_FOLLOW } from './submission-links-to-follow'; /** * Method for resolving an item based on the parameters in the current route @@ -28,7 +28,7 @@ export const SubmissionObjectResolver: (route: ActivatedRouteSnapshot, state: Ro return dataService.findById(route.params.id, true, false, - followLink('item'), + ...SUBMISSION_LINKS_TO_FOLLOW, ).pipe( getFirstCompletedRemoteData(), switchMap((wfiRD: RemoteData) => wfiRD.payload.item as Observable>), diff --git a/src/app/core/submission/resolver/submission-parent-breadcrumb.resolver.ts b/src/app/core/submission/resolver/submission-parent-breadcrumb.resolver.ts new file mode 100644 index 0000000000..92412be869 --- /dev/null +++ b/src/app/core/submission/resolver/submission-parent-breadcrumb.resolver.ts @@ -0,0 +1,51 @@ +import { + ActivatedRouteSnapshot, + Resolve, + RouterStateSnapshot, +} from '@angular/router'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { BreadcrumbConfig } from '../../../breadcrumbs/breadcrumb/breadcrumb-config.model'; +import { IdentifiableDataService } from '../../data/base/identifiable-data.service'; +import { + getFirstCompletedRemoteData, + getRemoteDataPayload, +} from '../../shared/operators'; +import { SubmissionObject } from '../models/submission-object.model'; +import { SubmissionParentBreadcrumbsService } from '../submission-parent-breadcrumb.service'; +import { SUBMISSION_LINKS_TO_FOLLOW } from './submission-links-to-follow'; + +/** + * This class represents a resolver that requests a specific item before the route is activated + */ +export abstract class SubmissionParentBreadcrumbResolver implements Resolve> { + + protected constructor( + protected dataService: IdentifiableDataService, + protected breadcrumbService: SubmissionParentBreadcrumbsService, + ) { + } + + /** + * Method for resolving an item based on the parameters in the current route + * @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot + * @param {RouterStateSnapshot} state The current RouterStateSnapshot + * @returns Observable<> Emits the found item based on the parameters in the current route, + * or an error if something went wrong + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable> { + return this.dataService.findById(route.params.id, + true, + false, + ...SUBMISSION_LINKS_TO_FOLLOW, + ).pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + map((submissionObject: SubmissionObject) => ({ + provider: this.breadcrumbService, + key: submissionObject, + } as BreadcrumbConfig)), + ); + } +} diff --git a/src/app/core/submission/submission-json-patch-operations.service.spec.ts b/src/app/core/submission/submission-json-patch-operations.service.spec.ts index 76e487400b..dd98b5de57 100644 --- a/src/app/core/submission/submission-json-patch-operations.service.spec.ts +++ b/src/app/core/submission/submission-json-patch-operations.service.spec.ts @@ -17,6 +17,9 @@ describe('SubmissionJsonPatchOperationsService', () => { const rdbService = {} as RemoteDataBuildService; const halEndpointService = {} as HALEndpointService; + const uuid = '91ecbeda-99fe-42ac-9430-b9b75af56f78'; + const href = 'https://rest.api/some/self/link?with=maybe&a=few&other=parameters'; + function initTestService() { return new SubmissionJsonPatchOperationsService( requestService, @@ -36,4 +39,16 @@ describe('SubmissionJsonPatchOperationsService', () => { expect((service as any).patchRequestConstructor).toEqual(SubmissionPatchRequest); }); + describe(`getRequestInstance`, () => { + it(`should add a parameter to embed the item to the request URL`, () => { + const result = (service as any).getRequestInstance(uuid, href); + const resultURL = new URL(result.href); + expect(resultURL.searchParams.get('embed')).toEqual('item'); + + // if we delete the embed item param, it should be identical to the original url + resultURL.searchParams.delete('embed', 'item'); + expect(href).toEqual(resultURL.toString()); + }); + }); + }); diff --git a/src/app/core/submission/submission-json-patch-operations.service.ts b/src/app/core/submission/submission-json-patch-operations.service.ts index 16d74b2bf8..8d454ae211 100644 --- a/src/app/core/submission/submission-json-patch-operations.service.ts +++ b/src/app/core/submission/submission-json-patch-operations.service.ts @@ -8,6 +8,7 @@ import { RequestService } from '../data/request.service'; import { JsonPatchOperationsService } from '../json-patch/json-patch-operations.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { SubmitDataResponseDefinitionObject } from '../shared/submit-data-response-definition.model'; +import { URLCombiner } from '../url-combiner/url-combiner'; /** * A service that provides methods to make JSON Patch requests. @@ -26,4 +27,20 @@ export class SubmissionJsonPatchOperationsService extends JsonPatchOperationsSer super(); } + /** + * Return an instance for RestRequest class + * + * @param uuid + * The request uuid + * @param href + * The request href + * @param body + * The request body + * @return Object + * instance of PatchRequestDefinition + */ + protected getRequestInstance(uuid: string, href: string, body?: any): SubmissionPatchRequest { + return new this.patchRequestConstructor(uuid, new URLCombiner(href, '?embed=item').toString(), body); + } + } diff --git a/src/app/core/submission/submission-parent-breadcrumb.service.ts b/src/app/core/submission/submission-parent-breadcrumb.service.ts new file mode 100644 index 0000000000..4241d00192 --- /dev/null +++ b/src/app/core/submission/submission-parent-breadcrumb.service.ts @@ -0,0 +1,70 @@ +import { Injectable } from '@angular/core'; +import { + combineLatest, + Observable, + of as observableOf, + switchMap, +} from 'rxjs'; + +import { getDSORoute } from '../../app-routing-paths'; +import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model'; +import { hasValue } from '../../shared/empty.util'; +import { SubmissionService } from '../../submission/submission.service'; +import { BreadcrumbsProviderService } from '../breadcrumbs/breadcrumbsProviderService'; +import { DSOBreadcrumbsService } from '../breadcrumbs/dso-breadcrumbs.service'; +import { DSONameService } from '../breadcrumbs/dso-name.service'; +import { CollectionDataService } from '../data/collection-data.service'; +import { RemoteData } from '../data/remote-data'; +import { Collection } from '../shared/collection.model'; +import { + getFirstCompletedRemoteData, + getRemoteDataPayload, +} from '../shared/operators'; +import { SubmissionObject } from './models/submission-object.model'; + +/** + * Service to calculate the parent {@link DSpaceObject} breadcrumbs for a {@link SubmissionObject} + */ +@Injectable({ + providedIn: 'root', +}) +export class SubmissionParentBreadcrumbsService implements BreadcrumbsProviderService { + + constructor( + protected dsoNameService: DSONameService, + protected dsoBreadcrumbsService: DSOBreadcrumbsService, + protected submissionService: SubmissionService, + protected collectionService: CollectionDataService, + ) { + } + + /** + * Creates the parent breadcrumb structure for {@link SubmissionObject}s. It also automatically recreates the + * parent breadcrumb structure when you change a {@link SubmissionObject}'s by dispatching a + * {@link ChangeSubmissionCollectionAction}. + * + * @param submissionObject The {@link SubmissionObject} for which the parent breadcrumb structure needs to be created + */ + getBreadcrumbs(submissionObject: SubmissionObject): Observable { + return combineLatest([ + (submissionObject.collection as Observable>).pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + ), + this.submissionService.getSubmissionCollectionId(submissionObject.id), + ]).pipe( + switchMap(([collection, latestCollectionId]: [Collection, string]) => { + if (hasValue(latestCollectionId)) { + return this.collectionService.findById(latestCollectionId).pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + ); + } else { + return observableOf(collection); + } + }), + switchMap((collection: Collection) => this.dsoBreadcrumbsService.getBreadcrumbs(collection, getDSORoute(collection))), + ); + } + +} diff --git a/src/app/core/submission/vocabularies/models/vocabulary-entry-detail.model.ts b/src/app/core/submission/vocabularies/models/vocabulary-entry-detail.model.ts index 3dcb0d374a..f7dff16a40 100644 --- a/src/app/core/submission/vocabularies/models/vocabulary-entry-detail.model.ts +++ b/src/app/core/submission/vocabularies/models/vocabulary-entry-detail.model.ts @@ -21,19 +21,19 @@ export class VocabularyEntryDetail extends VocabularyEntry { * The unique id of the entry */ @autoserialize - id: string; + id: string; /** * In an hierarchical vocabulary representing if entry is selectable as value */ @autoserialize - selectable: boolean; + selectable: boolean; /** * The {@link HALLink}s for this ExternalSourceEntry */ @deserialize - _links: { + _links: { self: HALLink; vocabulary: HALLink; parent: HALLink; diff --git a/src/app/core/submission/vocabularies/models/vocabulary-entry.model.ts b/src/app/core/submission/vocabularies/models/vocabulary-entry.model.ts index 323db57de1..85b310bad8 100644 --- a/src/app/core/submission/vocabularies/models/vocabulary-entry.model.ts +++ b/src/app/core/submission/vocabularies/models/vocabulary-entry.model.ts @@ -24,25 +24,25 @@ export class VocabularyEntry extends ListableObject { * The identifier of this vocabulary entry */ @autoserialize - authority: string; + authority: string; /** * The display value of this vocabulary entry */ @autoserialize - display: string; + display: string; /** * The value of this vocabulary entry */ @autoserialize - value: string; + value: string; /** * An object containing additional information related to this vocabulary entry */ @autoserialize - otherInformation: OtherInformation; + otherInformation: OtherInformation; /** * A string representing the kind of vocabulary entry @@ -55,7 +55,7 @@ export class VocabularyEntry extends ListableObject { * The {@link HALLink}s for this ExternalSourceEntry */ @deserialize - _links: { + _links: { self: HALLink; vocabularyEntryDetail?: HALLink; }; diff --git a/src/app/core/submission/vocabularies/models/vocabulary.model.ts b/src/app/core/submission/vocabularies/models/vocabulary.model.ts index 9026ce677a..9da5ade326 100644 --- a/src/app/core/submission/vocabularies/models/vocabulary.model.ts +++ b/src/app/core/submission/vocabularies/models/vocabulary.model.ts @@ -29,32 +29,32 @@ export class Vocabulary implements CacheableObject { * The identifier of this Vocabulary */ @autoserialize - id: string; + id: string; /** * The name of this Vocabulary */ @autoserialize - name: string; + name: string; /** * True if it is possible to scroll all the entries in the vocabulary without providing a filter parameter */ @autoserialize - scrollable: boolean; + scrollable: boolean; /** * True if the vocabulary exposes a tree structure where some entries are parent of others */ @autoserialize - hierarchical: boolean; + hierarchical: boolean; /** * For hierarchical vocabularies express the preference to preload the tree at a specific * level of depth (0 only the top nodes are shown, 1 also their children are preloaded and so on) */ @autoserialize - preloadLevel: any; + preloadLevel: any; /** * A string representing the kind of Vocabulary model @@ -64,13 +64,13 @@ export class Vocabulary implements CacheableObject { public type: any; @link(VOCABULARY_ENTRY, true) - entries?: Observable>>; + entries?: Observable>>; /** * The {@link HALLink}s for this Vocabulary */ @deserialize - _links: { + _links: { self: HALLink, entries: HALLink }; diff --git a/src/app/core/supervision-order/models/supervision-order.model.ts b/src/app/core/supervision-order/models/supervision-order.model.ts index 64087c8a21..6426f62aec 100644 --- a/src/app/core/supervision-order/models/supervision-order.model.ts +++ b/src/app/core/supervision-order/models/supervision-order.model.ts @@ -32,21 +32,21 @@ export class SupervisionOrder implements CacheableObject { * The identifier for this Supervision Order */ @autoserialize - id: string; + id: string; /** * The object type */ @excludeFromEquals @autoserialize - type: ResourceType; + type: ResourceType; /** * The object type */ @excludeFromEquals @autoserialize - ordertype: string; + ordertype: string; /** * The universally unique identifier for this Supervision Order @@ -60,7 +60,7 @@ export class SupervisionOrder implements CacheableObject { * The {@link HALLink}s for this SupervisionOrder */ @deserialize - _links: { + _links: { item: HALLink, group: HALLink, self: HALLink, @@ -71,12 +71,12 @@ export class SupervisionOrder implements CacheableObject { * Will be undefined unless the item {@link HALLink} has been resolved. */ @link(ITEM) - item?: Observable>; + item?: Observable>; /** * The group linked by this supervision order * Will be undefined unless the version {@link HALLink} has been resolved. */ @link(GROUP) - group?: Observable>; + group?: Observable>; } diff --git a/src/app/core/tasks/models/advanced-workflow-info.model.ts b/src/app/core/tasks/models/advanced-workflow-info.model.ts index 6e5feec357..87991a375c 100644 --- a/src/app/core/tasks/models/advanced-workflow-info.model.ts +++ b/src/app/core/tasks/models/advanced-workflow-info.model.ts @@ -6,6 +6,6 @@ import { autoserialize } from 'cerialize'; export abstract class AdvancedWorkflowInfo { @autoserialize - id: string; + id: string; } diff --git a/src/app/core/tasks/models/rating-advanced-workflow-info.model.ts b/src/app/core/tasks/models/rating-advanced-workflow-info.model.ts index 892806f7d1..6ecb0e6dbf 100644 --- a/src/app/core/tasks/models/rating-advanced-workflow-info.model.ts +++ b/src/app/core/tasks/models/rating-advanced-workflow-info.model.ts @@ -21,12 +21,12 @@ export class RatingAdvancedWorkflowInfo extends AdvancedWorkflowInfo { * Whether the description is required. */ @autoserialize - descriptionRequired: boolean; + descriptionRequired: boolean; /** * The maximum value. */ @autoserialize - maxValue: number; + maxValue: number; } diff --git a/src/app/core/tasks/models/select-reviewer-advanced-workflow-info.model.ts b/src/app/core/tasks/models/select-reviewer-advanced-workflow-info.model.ts index d202593efb..307caeaa1f 100644 --- a/src/app/core/tasks/models/select-reviewer-advanced-workflow-info.model.ts +++ b/src/app/core/tasks/models/select-reviewer-advanced-workflow-info.model.ts @@ -18,6 +18,6 @@ export class SelectReviewerAdvancedWorkflowInfo extends AdvancedWorkflowInfo { static type: ResourceType = SELECT_REVIEWER_ADVANCED_WORKFLOW_INFO; @autoserialize - group: string; + group: string; } diff --git a/src/app/core/tasks/models/task-object.model.ts b/src/app/core/tasks/models/task-object.model.ts index cea886a1c6..0e5022d579 100644 --- a/src/app/core/tasks/models/task-object.model.ts +++ b/src/app/core/tasks/models/task-object.model.ts @@ -34,19 +34,19 @@ export class TaskObject extends DSpaceObject implements CacheableObject { * The task identifier */ @autoserialize - id: string; + id: string; /** * The workflow step */ @autoserialize - step: string; + step: string; /** * The {@link HALLink}s for this TaskObject */ @deserialize - _links: { + _links: { self: HALLink; owner: HALLink; group: HALLink; @@ -59,14 +59,14 @@ export class TaskObject extends DSpaceObject implements CacheableObject { * Will be undefined unless the eperson {@link HALLink} has been resolved. */ @link(EPERSON, false, 'owner') - eperson?: Observable>; + eperson?: Observable>; /** * The Group for this task * Will be undefined unless the group {@link HALLink} has been resolved. */ @link(GROUP) - group?: Observable>; + group?: Observable>; /** * The WorkflowItem for this task @@ -81,6 +81,6 @@ export class TaskObject extends DSpaceObject implements CacheableObject { * Will be undefined unless the group {@link HALLink} has been resolved. */ @link(WORKFLOW_ACTION, false, 'action') - action: Observable>; + action: Observable>; } diff --git a/src/app/core/tasks/models/workflow-action-object.model.ts b/src/app/core/tasks/models/workflow-action-object.model.ts index 53ae4249c8..a101000885 100644 --- a/src/app/core/tasks/models/workflow-action-object.model.ts +++ b/src/app/core/tasks/models/workflow-action-object.model.ts @@ -20,30 +20,30 @@ export class WorkflowAction extends DSpaceObject { * The workflow action's identifier */ @autoserialize - id: string; + id: string; /** * The options available for this workflow action */ @autoserialize - options: string[]; + options: string[]; /** * Whether this action has advanced options */ @autoserialize - advanced: boolean; + advanced: boolean; /** * The advanced options that the user can select at this action */ @autoserialize - advancedOptions: string[]; + advancedOptions: string[]; /** * The advanced info required by the advanced options */ @autoserialize - advancedInfo: AdvancedWorkflowInfo[]; + advancedInfo: AdvancedWorkflowInfo[]; } diff --git a/src/app/core/utilities/equatable.spec.ts b/src/app/core/utilities/equatable.spec.ts index 808c21b39f..cea3c35b3d 100644 --- a/src/app/core/utilities/equatable.spec.ts +++ b/src/app/core/utilities/equatable.spec.ts @@ -21,7 +21,7 @@ class Dog extends EquatableObject { class Owner extends EquatableObject { @excludeFromEquals - favouriteFood: string; + favouriteFood: string; constructor( public name: string, diff --git a/src/app/curation-form/curation-form.component.ts b/src/app/curation-form/curation-form.component.ts index 0580193418..8e1c1b26c8 100644 --- a/src/app/curation-form/curation-form.component.ts +++ b/src/app/curation-form/curation-form.component.ts @@ -62,7 +62,7 @@ export class CurationFormComponent implements OnDestroy, OnInit { form: UntypedFormGroup; @Input() - dsoHandle: string; + dsoHandle: string; subs: Subscription[] = []; diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html index b79b185b40..0c1088e3fd 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html @@ -55,7 +55,7 @@
diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts index ccfcfca93c..fbbfe982aa 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts @@ -221,7 +221,7 @@ describe('DsoEditMetadataValueComponent', () => { it('should not show a badge', () => { expect( - fixture.debugElement.query(By.css('ds-themed-type-badge')), + fixture.debugElement.query(By.css('ds-type-badge')), ).toBeNull(); }); @@ -289,7 +289,7 @@ describe('DsoEditMetadataValueComponent', () => { it('should show a badge', () => { expect( - fixture.debugElement.query(By.css('ds-themed-type-badge')), + fixture.debugElement.query(By.css('ds-type-badge')), ).toBeTruthy(); }); diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts index 32822f1832..32e57e003d 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts @@ -22,7 +22,7 @@ import { Item } from '../../core/shared/item.model'; import { ITEM } from '../../core/shared/item.resource-type'; import { MetadataValue } from '../../core/shared/metadata.models'; import { AlertComponent } from '../../shared/alert/alert.component'; -import { LoadingComponent } from '../../shared/loading/loading.component'; +import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { TestDataService } from '../../shared/testing/test-data-service.mock'; import { VarDirective } from '../../shared/utils/var.directive'; @@ -112,7 +112,7 @@ describe('DsoEditMetadataComponent', () => { DsoEditMetadataValueHeadersComponent, DsoEditMetadataFieldValuesComponent, AlertComponent, - LoadingComponent, + ThemedLoadingComponent, ], }, }) diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts index cded29230e..677a601b9d 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts @@ -24,8 +24,8 @@ import { import { BehaviorSubject, combineLatest as observableCombineLatest, - EMPTY, Observable, + of, Subscription, } from 'rxjs'; import { @@ -52,7 +52,7 @@ import { hasValue, isNotEmpty, } from '../../shared/empty.util'; -import { LoadingComponent } from '../../shared/loading/loading.component'; +import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { DsoEditMetadataFieldValuesComponent } from './dso-edit-metadata-field-values/dso-edit-metadata-field-values.component'; import { DsoEditMetadataForm } from './dso-edit-metadata-form'; @@ -62,11 +62,11 @@ import { DsoEditMetadataValueHeadersComponent } from './dso-edit-metadata-value- import { MetadataFieldSelectorComponent } from './metadata-field-selector/metadata-field-selector.component'; @Component({ - selector: 'ds-dso-edit-metadata', + selector: 'ds-base-dso-edit-metadata', styleUrls: ['./dso-edit-metadata.component.scss'], templateUrl: './dso-edit-metadata.component.html', standalone: true, - imports: [NgIf, DsoEditMetadataHeadersComponent, MetadataFieldSelectorComponent, DsoEditMetadataValueHeadersComponent, DsoEditMetadataValueComponent, NgFor, DsoEditMetadataFieldValuesComponent, AlertComponent, LoadingComponent, AsyncPipe, TranslateModule], + imports: [NgIf, DsoEditMetadataHeadersComponent, MetadataFieldSelectorComponent, DsoEditMetadataValueHeadersComponent, DsoEditMetadataValueComponent, NgFor, DsoEditMetadataFieldValuesComponent, AlertComponent, ThemedLoadingComponent, AsyncPipe, TranslateModule], }) /** * Component showing a table of all metadata on a DSpaceObject and options to modify them @@ -188,7 +188,7 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy { const lazyProvider$: Observable> = lazyDataService(this.dataServiceMap, this.dsoType, this.parentInjector); return lazyProvider$; } else { - return EMPTY; + return of(this.updateDataService); } } diff --git a/src/app/dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component.ts b/src/app/dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component.ts index 9de9c539a2..063263b670 100644 --- a/src/app/dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component.ts +++ b/src/app/dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component.ts @@ -9,10 +9,11 @@ import { ThemedComponent } from '../../shared/theme-support/themed.component'; import { DsoEditMetadataComponent } from './dso-edit-metadata.component'; @Component({ - selector: 'ds-themed-dso-edit-metadata', + selector: 'ds-dso-edit-metadata', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [DsoEditMetadataComponent], }) export class ThemedDsoEditMetadataComponent extends ThemedComponent { diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html index 33ce615305..bca1a1b3b3 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html @@ -8,18 +8,18 @@ [attr.rel]="(linkType === linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]" class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
- - + +
- - + +
- +

diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html index de80448e8d..3b14a1d8b0 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html @@ -8,18 +8,18 @@ [attr.rel]="(linkType === linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]" class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
- - + +
- - + +
- +

diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html index b537fb60d9..20084f21ba 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html @@ -8,18 +8,18 @@ [attr.rel]="(linkType === linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]" class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
- - + +
- - + +
- +

diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.html b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.html index 545e8c67a6..59d2ea4dc9 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.html +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.html @@ -12,7 +12,7 @@
- + { }).overrideComponent(JournalIssueSearchResultListElementComponent, { add: { changeDetection: ChangeDetectionStrategy.Default } , remove: { - imports: [ThumbnailComponent, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent], + imports: [ThemedThumbnailComponent, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent], } }, ).compileComponents(); })); diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.ts index ca12acaa10..f3f8d79809 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.ts @@ -13,7 +13,7 @@ import { listableObjectComponent } from '../../../../../shared/object-collection import { ItemSearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; import { TruncatableComponent } from '../../../../../shared/truncatable/truncatable.component'; import { TruncatablePartComponent } from '../../../../../shared/truncatable/truncatable-part/truncatable-part.component'; -import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../thumbnail/themed-thumbnail.component'; @listableObjectComponent('JournalIssueSearchResult', ViewMode.ListElement) @Component({ @@ -21,7 +21,7 @@ import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component styleUrls: ['./journal-issue-search-result-list-element.component.scss'], templateUrl: './journal-issue-search-result-list-element.component.html', standalone: true, - imports: [NgIf, RouterLink, ThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], + imports: [NgIf, RouterLink, ThemedThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], }) /** * The component for displaying a list element for an item search result of the type Journal Issue diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.html b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.html index 2ccbbe1095..4a6ffb412d 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.html +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.html @@ -12,7 +12,7 @@
- + { add: { changeDetection: ChangeDetectionStrategy.Default }, remove: { imports: [ - ThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, + ThemedThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, ], }, }).compileComponents(); @@ -196,7 +196,7 @@ describe('JournalVolumeSearchResultListElementComponent', () => { add: { changeDetection: ChangeDetectionStrategy.Default }, remove: { imports: [ - ThumbnailComponent, + ThemedThumbnailComponent, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.ts index b44a4896b7..4aee64c4f5 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.ts @@ -13,7 +13,7 @@ import { listableObjectComponent } from '../../../../../shared/object-collection import { ItemSearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; import { TruncatableComponent } from '../../../../../shared/truncatable/truncatable.component'; import { TruncatablePartComponent } from '../../../../../shared/truncatable/truncatable-part/truncatable-part.component'; -import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../thumbnail/themed-thumbnail.component'; @listableObjectComponent('JournalVolumeSearchResult', ViewMode.ListElement) @Component({ @@ -21,7 +21,7 @@ import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component styleUrls: ['./journal-volume-search-result-list-element.component.scss'], templateUrl: './journal-volume-search-result-list-element.component.html', standalone: true, - imports: [NgIf, RouterLink, ThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], + imports: [NgIf, RouterLink, ThemedThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], }) /** * The component for displaying a list element for an item search result of the type Journal Volume diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.html b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.html index 3074d53df6..bd119493d3 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.html +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.html @@ -11,7 +11,7 @@
- + { add: { changeDetection: ChangeDetectionStrategy.Default }, remove: { imports: [ - ThumbnailComponent, + ThemedThumbnailComponent, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.ts index d931feece7..8ef14120e0 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.ts @@ -13,7 +13,7 @@ import { listableObjectComponent } from '../../../../../shared/object-collection import { ItemSearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; import { TruncatableComponent } from '../../../../../shared/truncatable/truncatable.component'; import { TruncatablePartComponent } from '../../../../../shared/truncatable/truncatable-part/truncatable-part.component'; -import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../thumbnail/themed-thumbnail.component'; @listableObjectComponent('JournalSearchResult', ViewMode.ListElement) @Component({ @@ -21,7 +21,7 @@ import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component styleUrls: ['./journal-search-result-list-element.component.scss'], templateUrl: './journal-search-result-list-element.component.html', standalone: true, - imports: [NgIf, RouterLink, ThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], + imports: [NgIf, RouterLink, ThemedThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], }) /** * The component for displaying a list element for an item search result of the type Journal diff --git a/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html b/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html index 3648b53b51..e3dec92c52 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html @@ -1,13 +1,13 @@ - +
- - + +
- + +
- - + +
- + +
- - + +
- +
- - + +
- - + +
- +

diff --git a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html index 976d2c55e5..7b444d261c 100644 --- a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html +++ b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html @@ -8,18 +8,18 @@ [attr.rel]="(linkType === linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]" class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
- - + +
- - + +
- +

diff --git a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html index 1025b4c35d..2181a4eb07 100644 --- a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html +++ b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html @@ -8,18 +8,18 @@ [attr.rel]="(linkType === linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]" class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
- - + +
- - + +
- +

diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html index 60251c15b8..ed1181a407 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html @@ -18,7 +18,7 @@
- +
- +
- + { schemas: [NO_ERRORS_SCHEMA], }).overrideComponent(ProjectSearchResultListElementComponent, { add: { changeDetection: ChangeDetectionStrategy.Default }, - remove: { imports: [ThumbnailComponent, TruncatableComponent, ThemedBadgesComponent] }, + remove: { imports: [ThemedThumbnailComponent, TruncatableComponent, ThemedBadgesComponent] }, }).compileComponents(); })); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.ts index fc6e031f40..825f7be387 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.ts @@ -11,7 +11,7 @@ import { ThemedBadgesComponent } from '../../../../../shared/object-collection/s import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; import { ItemSearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; import { TruncatableComponent } from '../../../../../shared/truncatable/truncatable.component'; -import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../thumbnail/themed-thumbnail.component'; @listableObjectComponent('ProjectSearchResult', ViewMode.ListElement) @Component({ @@ -19,7 +19,7 @@ import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component styleUrls: ['./project-search-result-list-element.component.scss'], templateUrl: './project-search-result-list-element.component.html', standalone: true, - imports: [NgIf, RouterLink, ThumbnailComponent, NgClass, TruncatableComponent, ThemedBadgesComponent, AsyncPipe], + imports: [NgIf, RouterLink, ThemedThumbnailComponent, NgClass, TruncatableComponent, ThemedBadgesComponent, AsyncPipe], }) /** * The component for displaying a list element for an item search result of the type Project diff --git a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html index f28550a4e0..126845e36f 100644 --- a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html +++ b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html @@ -1,18 +1,18 @@ - +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + - - + diff --git a/src/app/entity-groups/research-entities/submission/item-list-elements/person/person-search-result-list-submission-element.component.ts b/src/app/entity-groups/research-entities/submission/item-list-elements/person/person-search-result-list-submission-element.component.ts index 49d6ecb59c..1145fb78e3 100644 --- a/src/app/entity-groups/research-entities/submission/item-list-elements/person/person-search-result-list-submission-element.component.ts +++ b/src/app/entity-groups/research-entities/submission/item-list-elements/person/person-search-result-list-submission-element.component.ts @@ -29,7 +29,7 @@ import { listableObjectComponent } from '../../../../../shared/object-collection import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component'; import { SelectableListService } from '../../../../../shared/object-list/selectable-list/selectable-list.service'; import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; -import { ThumbnailComponent } from '../../../../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../thumbnail/themed-thumbnail.component'; import { NameVariantModalComponent } from '../../name-variant-modal/name-variant-modal.component'; import { PersonInputSuggestionsComponent } from './person-suggestions/person-input-suggestions.component'; @@ -39,7 +39,7 @@ import { PersonInputSuggestionsComponent } from './person-suggestions/person-inp styleUrls: ['./person-search-result-list-submission-element.component.scss'], templateUrl: './person-search-result-list-submission-element.component.html', standalone: true, - imports: [NgIf, ThumbnailComponent, NgClass, PersonInputSuggestionsComponent, FormsModule, NgFor, AsyncPipe], + imports: [NgIf, ThemedThumbnailComponent, NgClass, PersonInputSuggestionsComponent, FormsModule, NgFor, AsyncPipe], }) /** diff --git a/src/app/footer/footer.component.ts b/src/app/footer/footer.component.ts index f9fdde7834..99e74ed4aa 100644 --- a/src/app/footer/footer.component.ts +++ b/src/app/footer/footer.component.ts @@ -27,7 +27,7 @@ import { KlaroService } from '../shared/cookies/klaro.service'; import { hasValue } from '../shared/empty.util'; @Component({ - selector: 'ds-footer', + selector: 'ds-base-footer', styleUrls: ['footer.component.scss'], templateUrl: 'footer.component.html', standalone: true, diff --git a/src/app/footer/themed-footer.component.ts b/src/app/footer/themed-footer.component.ts index 1c3ae83026..a09484ebca 100644 --- a/src/app/footer/themed-footer.component.ts +++ b/src/app/footer/themed-footer.component.ts @@ -7,10 +7,11 @@ import { FooterComponent } from './footer.component'; * Themed wrapper for FooterComponent */ @Component({ - selector: 'ds-themed-footer', + selector: 'ds-footer', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [FooterComponent], }) export class ThemedFooterComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/forbidden/forbidden.component.ts b/src/app/forbidden/forbidden.component.ts index 03441f1bff..74cfdf31ce 100644 --- a/src/app/forbidden/forbidden.component.ts +++ b/src/app/forbidden/forbidden.component.ts @@ -12,7 +12,7 @@ import { ServerResponseService } from '../core/services/server-response.service' * This component representing the `Forbidden` DSpace page. */ @Component({ - selector: 'ds-forbidden', + selector: 'ds-base-forbidden', templateUrl: './forbidden.component.html', styleUrls: ['./forbidden.component.scss'], standalone: true, diff --git a/src/app/forbidden/themed-forbidden.component.ts b/src/app/forbidden/themed-forbidden.component.ts index 85efec18ee..4d1b6d6fb7 100644 --- a/src/app/forbidden/themed-forbidden.component.ts +++ b/src/app/forbidden/themed-forbidden.component.ts @@ -7,10 +7,11 @@ import { ForbiddenComponent } from './forbidden.component'; * Themed wrapper for ForbiddenComponent */ @Component({ - selector: 'ds-themed-forbidden', + selector: 'ds-forbidden', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [ForbiddenComponent], }) export class ThemedForbiddenComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/forgot-password/forgot-password-email/forgot-email.component.html b/src/app/forgot-password/forgot-password-email/forgot-email.component.html index aaa0c27b46..995108cdbc 100644 --- a/src/app/forgot-password/forgot-password-email/forgot-email.component.html +++ b/src/app/forgot-password/forgot-password-email/forgot-email.component.html @@ -1,3 +1,3 @@ - - + diff --git a/src/app/forgot-password/forgot-password-email/forgot-email.component.spec.ts b/src/app/forgot-password/forgot-password-email/forgot-email.component.spec.ts index 5ddeae8051..b9e625caac 100644 --- a/src/app/forgot-password/forgot-password-email/forgot-email.component.spec.ts +++ b/src/app/forgot-password/forgot-password-email/forgot-email.component.spec.ts @@ -8,7 +8,6 @@ import { import { ReactiveFormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; -import { RegisterEmailFormComponent } from '../../register-email-form/register-email-form.component'; import { ThemedRegisterEmailFormComponent } from '../../register-email-form/themed-registry-email-form.component'; import { ForgotEmailComponent } from './forgot-email.component'; @@ -23,7 +22,7 @@ describe('ForgotEmailComponent', () => { }) .overrideComponent(ForgotEmailComponent, { remove: { - imports: [RegisterEmailFormComponent, ThemedRegisterEmailFormComponent], + imports: [ThemedRegisterEmailFormComponent], }, }) .compileComponents(); diff --git a/src/app/forgot-password/forgot-password-email/forgot-email.component.ts b/src/app/forgot-password/forgot-password-email/forgot-email.component.ts index a7455c4ca9..2ab05e6518 100644 --- a/src/app/forgot-password/forgot-password-email/forgot-email.component.ts +++ b/src/app/forgot-password/forgot-password-email/forgot-email.component.ts @@ -1,17 +1,14 @@ import { Component } from '@angular/core'; import { ThemedRegisterEmailFormComponent } from 'src/app/register-email-form/themed-registry-email-form.component'; -import { - RegisterEmailFormComponent, - TYPE_REQUEST_FORGOT, -} from '../../register-email-form/register-email-form.component'; +import { TYPE_REQUEST_FORGOT } from '../../register-email-form/register-email-form.component'; @Component({ - selector: 'ds-forgot-email', + selector: 'ds-base-forgot-email', styleUrls: ['./forgot-email.component.scss'], templateUrl: './forgot-email.component.html', imports: [ - RegisterEmailFormComponent, ThemedRegisterEmailFormComponent, + ThemedRegisterEmailFormComponent, ], standalone: true, }) diff --git a/src/app/forgot-password/forgot-password-email/themed-forgot-email.component.ts b/src/app/forgot-password/forgot-password-email/themed-forgot-email.component.ts index 936815a49c..af9f557fbb 100644 --- a/src/app/forgot-password/forgot-password-email/themed-forgot-email.component.ts +++ b/src/app/forgot-password/forgot-password-email/themed-forgot-email.component.ts @@ -7,10 +7,11 @@ import { ForgotEmailComponent } from './forgot-email.component'; * Themed wrapper for ForgotEmailComponent */ @Component({ - selector: 'ds-themed-forgot-email', + selector: 'ds-forgot-email', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [ForgotEmailComponent], }) export class ThemedForgotEmailComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts index 3d8d6e3cd7..442e4bf9fa 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts @@ -30,7 +30,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { BrowserOnlyPipe } from '../../shared/utils/browser-only.pipe'; @Component({ - selector: 'ds-forgot-password-form', + selector: 'ds-base-forgot-password-form', styleUrls: ['./forgot-password-form.component.scss'], templateUrl: './forgot-password-form.component.html', imports: [ diff --git a/src/app/forgot-password/forgot-password-form/themed-forgot-password-form.component.ts b/src/app/forgot-password/forgot-password-form/themed-forgot-password-form.component.ts index e74fed2f36..956568e2bf 100644 --- a/src/app/forgot-password/forgot-password-form/themed-forgot-password-form.component.ts +++ b/src/app/forgot-password/forgot-password-form/themed-forgot-password-form.component.ts @@ -7,10 +7,11 @@ import { ForgotPasswordFormComponent } from './forgot-password-form.component'; * Themed wrapper for ForgotPasswordFormComponent */ @Component({ - selector: 'ds-themed-forgot-password-form', + selector: 'ds-forgot-password-form', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [ForgotPasswordFormComponent], }) export class ThemedForgotPasswordFormComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/header-nav-wrapper/header-navbar-wrapper.component.html b/src/app/header-nav-wrapper/header-navbar-wrapper.component.html index ba3060ff69..60b38dcabf 100644 --- a/src/app/header-nav-wrapper/header-navbar-wrapper.component.html +++ b/src/app/header-nav-wrapper/header-navbar-wrapper.component.html @@ -1,4 +1,4 @@
- - + +
diff --git a/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts b/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts index 862173b9bb..53f1057531 100644 --- a/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts +++ b/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts @@ -21,7 +21,7 @@ import { MenuID } from '../shared/menu/menu-id.model'; * This component represents a wrapper for the horizontal navbar and the header */ @Component({ - selector: 'ds-header-navbar-wrapper', + selector: 'ds-base-header-navbar-wrapper', styleUrls: ['header-navbar-wrapper.component.scss'], templateUrl: 'header-navbar-wrapper.component.html', standalone: true, diff --git a/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts b/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts index 5895530e8a..64d36edae3 100644 --- a/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts +++ b/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts @@ -7,10 +7,11 @@ import { HeaderNavbarWrapperComponent } from './header-navbar-wrapper.component' * Themed wrapper for {@link HeaderNavbarWrapperComponent} */ @Component({ - selector: 'ds-themed-header-navbar-wrapper', + selector: 'ds-header-navbar-wrapper', styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', standalone: true, + imports: [HeaderNavbarWrapperComponent], }) export class ThemedHeaderNavbarWrapperComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index e98959d162..e59086134a 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -6,10 +6,10 @@
- + diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.ts b/src/app/home-page/top-level-community-list/top-level-community-list.component.ts index d49f9f264f..c562d38ff2 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.ts +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.ts @@ -42,7 +42,7 @@ import { VarDirective } from '../../shared/utils/var.directive'; * this component renders the Top-Level Community list */ @Component({ - selector: 'ds-top-level-community-list', + selector: 'ds-base-top-level-community-list', styleUrls: ['./top-level-community-list.component.scss'], templateUrl: './top-level-community-list.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/import-external-page/import-external-page.component.html b/src/app/import-external-page/import-external-page.component.html index 5b0c7e3ed6..5edccd55cb 100644 --- a/src/app/import-external-page/import-external-page.component.html +++ b/src/app/import-external-page/import-external-page.component.html @@ -1 +1 @@ - + diff --git a/src/app/info/end-user-agreement/end-user-agreement.component.ts b/src/app/info/end-user-agreement/end-user-agreement.component.ts index ae3c67573e..5c10c02432 100644 --- a/src/app/info/end-user-agreement/end-user-agreement.component.ts +++ b/src/app/info/end-user-agreement/end-user-agreement.component.ts @@ -28,7 +28,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { EndUserAgreementContentComponent } from './end-user-agreement-content/end-user-agreement-content.component'; @Component({ - selector: 'ds-end-user-agreement', + selector: 'ds-base-end-user-agreement', templateUrl: './end-user-agreement.component.html', styleUrls: ['./end-user-agreement.component.scss'], standalone: true, diff --git a/src/app/info/end-user-agreement/themed-end-user-agreement.component.ts b/src/app/info/end-user-agreement/themed-end-user-agreement.component.ts index 941b08c2eb..05e6474c3d 100644 --- a/src/app/info/end-user-agreement/themed-end-user-agreement.component.ts +++ b/src/app/info/end-user-agreement/themed-end-user-agreement.component.ts @@ -7,10 +7,11 @@ import { EndUserAgreementComponent } from './end-user-agreement.component'; * Themed wrapper for EndUserAgreementComponent */ @Component({ - selector: 'ds-themed-end-user-agreement', + selector: 'ds-end-user-agreement', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [EndUserAgreementComponent], }) export class ThemedEndUserAgreementComponent extends ThemedComponent { diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.ts b/src/app/info/feedback/feedback-form/feedback-form.component.ts index d32eefb333..59be526f17 100644 --- a/src/app/info/feedback/feedback-form/feedback-form.component.ts +++ b/src/app/info/feedback/feedback-form/feedback-form.component.ts @@ -34,7 +34,7 @@ import { ErrorComponent } from '../../../shared/error/error.component'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @Component({ - selector: 'ds-feedback-form', + selector: 'ds-base-feedback-form', templateUrl: './feedback-form.component.html', styleUrls: ['./feedback-form.component.scss'], standalone: true, diff --git a/src/app/info/feedback/feedback-form/themed-feedback-form.component.ts b/src/app/info/feedback/feedback-form/themed-feedback-form.component.ts index c45565928c..0a72323f08 100644 --- a/src/app/info/feedback/feedback-form/themed-feedback-form.component.ts +++ b/src/app/info/feedback/feedback-form/themed-feedback-form.component.ts @@ -7,10 +7,11 @@ import { FeedbackFormComponent } from './feedback-form.component'; * Themed wrapper for {@link FeedbackFormComponent} */ @Component({ - selector: 'ds-themed-feedback-form', + selector: 'ds-feedback-form', styleUrls: [], templateUrl: '../../../shared/theme-support/themed.component.html', standalone: true, + imports: [FeedbackFormComponent], }) export class ThemedFeedbackFormComponent extends ThemedComponent { diff --git a/src/app/info/feedback/feedback.component.html b/src/app/info/feedback/feedback.component.html index ad42f0f90e..266deec270 100644 --- a/src/app/info/feedback/feedback.component.html +++ b/src/app/info/feedback/feedback.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/info/feedback/feedback.component.ts b/src/app/info/feedback/feedback.component.ts index 1087009810..1fdf8740c3 100644 --- a/src/app/info/feedback/feedback.component.ts +++ b/src/app/info/feedback/feedback.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { ThemedFeedbackFormComponent } from './feedback-form/themed-feedback-form.component'; @Component({ - selector: 'ds-feedback', + selector: 'ds-base-feedback', templateUrl: './feedback.component.html', styleUrls: ['./feedback.component.scss'], standalone: true, diff --git a/src/app/info/feedback/themed-feedback.component.ts b/src/app/info/feedback/themed-feedback.component.ts index 4f6080081d..a5713b839f 100644 --- a/src/app/info/feedback/themed-feedback.component.ts +++ b/src/app/info/feedback/themed-feedback.component.ts @@ -7,10 +7,11 @@ import { FeedbackComponent } from './feedback.component'; * Themed wrapper for FeedbackComponent */ @Component({ - selector: 'ds-themed-feedback', + selector: 'ds-feedback', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [FeedbackComponent], }) export class ThemedFeedbackComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/info/privacy/privacy.component.ts b/src/app/info/privacy/privacy.component.ts index db38fffe03..7b75f85a60 100644 --- a/src/app/info/privacy/privacy.component.ts +++ b/src/app/info/privacy/privacy.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { PrivacyContentComponent } from './privacy-content/privacy-content.component'; @Component({ - selector: 'ds-privacy', + selector: 'ds-base-privacy', templateUrl: './privacy.component.html', styleUrls: ['./privacy.component.scss'], standalone: true, diff --git a/src/app/info/privacy/themed-privacy.component.ts b/src/app/info/privacy/themed-privacy.component.ts index 77bf277a43..117727da08 100644 --- a/src/app/info/privacy/themed-privacy.component.ts +++ b/src/app/info/privacy/themed-privacy.component.ts @@ -7,10 +7,11 @@ import { PrivacyComponent } from './privacy.component'; * Themed wrapper for PrivacyComponent */ @Component({ - selector: 'ds-themed-privacy', + selector: 'ds-privacy', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [PrivacyComponent], }) export class ThemedPrivacyComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/item-page/alerts/item-alerts.component.ts b/src/app/item-page/alerts/item-alerts.component.ts index 6196eaf9ec..1984de0324 100644 --- a/src/app/item-page/alerts/item-alerts.component.ts +++ b/src/app/item-page/alerts/item-alerts.component.ts @@ -30,7 +30,7 @@ import { } from '../../shared/dso-page/dso-withdrawn-reinstate-service/dso-withdrawn-reinstate-modal.service'; @Component({ - selector: 'ds-item-alerts', + selector: 'ds-base-item-alerts', templateUrl: './item-alerts.component.html', styleUrls: ['./item-alerts.component.scss'], imports: [ diff --git a/src/app/item-page/alerts/themed-item-alerts.component.ts b/src/app/item-page/alerts/themed-item-alerts.component.ts index 9a686d9a36..94197f3fb4 100644 --- a/src/app/item-page/alerts/themed-item-alerts.component.ts +++ b/src/app/item-page/alerts/themed-item-alerts.component.ts @@ -11,10 +11,11 @@ import { ItemAlertsComponent } from './item-alerts.component'; * Themed wrapper for {@link ItemAlertsComponent} */ @Component({ - selector: 'ds-themed-item-alerts', + selector: 'ds-item-alerts', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [ItemAlertsComponent], }) export class ThemedItemAlertsComponent extends ThemedComponent { protected inAndOutputNames: (keyof ItemAlertsComponent & keyof this)[] = ['item']; diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 48635a50f6..bb0c3e3760 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -48,7 +48,7 @@ class="alert alert-info w-100 d-inline-block mt-4" role="alert"> {{'item.edit.bitstreams.empty' | translate}}
- +
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html index e43c504858..c3d6ebc823 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html @@ -3,7 +3,6 @@ [hidePagerWhenSinglePage]="true" [hidePaginationDetail]="true" [paginationOptions]="options" - [pageInfoState]="(objectsRD$ | async)?.payload" [collectionSize]="(objectsRD$ | async)?.payload?.totalElements">
- + diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts index 5706805661..81950d3321 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts @@ -145,7 +145,7 @@ export class ItemEditBitstreamComponent implements OnChanges, OnDestroy, OnInit * Check if a user should be allowed to cancel the update to this field */ canUndo(): boolean { - return this.fieldUpdate.changeType >= 0; + return this.fieldUpdate.changeType?.valueOf() >= 0; } } diff --git a/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html b/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html index 57287fdfe2..9e298edcc6 100644 --- a/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html +++ b/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html @@ -27,13 +27,13 @@
- - +
diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html index a03b3ce85b..0a99a5820f 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html @@ -10,7 +10,6 @@ @@ -31,5 +30,5 @@
{{"item.edit.relationships.no-relationships" | translate}}
- + diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts index 8341070537..5f213327e3 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts @@ -199,6 +199,6 @@ export class EditRelationshipComponent implements OnChanges { * Check if a user should be allowed to cancel the update to this field */ canUndo(): boolean { - return this.fieldUpdate.changeType >= 0; + return this.fieldUpdate.changeType?.valueOf() >= 0; } } diff --git a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html index 3a0a33d1a0..c3556962d4 100644 --- a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html +++ b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html @@ -32,7 +32,7 @@ >
- +
diff --git a/src/app/item-page/edit-item-page/item-status/item-status.component.ts b/src/app/item-page/edit-item-page/item-status/item-status.component.ts index f330c2e457..bbd7b99a97 100644 --- a/src/app/item-page/edit-item-page/item-status/item-status.component.ts +++ b/src/app/item-page/edit-item-page/item-status/item-status.component.ts @@ -58,7 +58,7 @@ import { ItemOperationComponent } from '../item-operation/item-operation.compone import { ItemOperation } from '../item-operation/itemOperation.model'; @Component({ - selector: 'ds-item-status', + selector: 'ds-base-item-status', templateUrl: './item-status.component.html', changeDetection: ChangeDetectionStrategy.Default, animations: [ diff --git a/src/app/item-page/edit-item-page/item-status/themed-item-status.component.ts b/src/app/item-page/edit-item-page/item-status/themed-item-status.component.ts index 705ef6d8ad..c3ba17a4b5 100644 --- a/src/app/item-page/edit-item-page/item-status/themed-item-status.component.ts +++ b/src/app/item-page/edit-item-page/item-status/themed-item-status.component.ts @@ -4,10 +4,11 @@ import { ThemedComponent } from '../../../shared/theme-support/themed.component' import { ItemStatusComponent } from './item-status.component'; @Component({ - selector: 'ds-themed-item-status', + selector: 'ds-item-status', styleUrls: [], templateUrl: '../../../shared/theme-support/themed.component.html', standalone: true, + imports: [ItemStatusComponent], }) export class ThemedItemStatusComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/item-page/field-components/metadata-values/metadata-values.component.ts b/src/app/item-page/field-components/metadata-values/metadata-values.component.ts index abc26c0d82..1a73d692eb 100644 --- a/src/app/item-page/field-components/metadata-values/metadata-values.component.ts +++ b/src/app/item-page/field-components/metadata-values/metadata-values.component.ts @@ -117,6 +117,8 @@ export class MetadataValuesComponent implements OnChanges { */ getQueryParams(value) { const queryParams = { startsWith: value }; + // todo: should compare with type instead? + // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison if (this.browseDefinition.getRenderType() === VALUE_LIST_BROWSE_DEFINITION.value) { return { value: value }; } diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.html b/src/app/item-page/full/field-components/file-section/full-file-section.component.html index 7774754079..8c534e6630 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.html +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.html @@ -6,14 +6,13 @@ [hideGear]="true" [hidePagerWhenSinglePage]="true" [paginationOptions]="originalOptions" - [pageInfoState]="originals" [collectionSize]="originals?.totalElements" [retainScrollPosition]="true">
- +
@@ -34,9 +33,9 @@
- + {{"item.page.filesection.download" | translate}} - +
@@ -49,14 +48,13 @@ [hideGear]="true" [hidePagerWhenSinglePage]="true" [paginationOptions]="licenseOptions" - [pageInfoState]="licenses" [collectionSize]="licenses?.totalElements" [retainScrollPosition]="true">
- +
@@ -75,9 +73,9 @@
- + {{"item.page.filesection.download" | translate}} - +
diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.ts b/src/app/item-page/full/field-components/file-section/full-file-section.component.ts index 8f8b01eb26..f038b18bfc 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.ts +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.ts @@ -52,7 +52,7 @@ import { FileSectionComponent } from '../../../simple/field-components/file-sect */ @Component({ - selector: 'ds-item-page-full-file-section', + selector: 'ds-base-item-page-full-file-section', styleUrls: ['./full-file-section.component.scss'], templateUrl: './full-file-section.component.html', imports: [ diff --git a/src/app/item-page/full/field-components/file-section/themed-full-file-section.component.ts b/src/app/item-page/full/field-components/file-section/themed-full-file-section.component.ts index 38a4879715..425b0cffd8 100644 --- a/src/app/item-page/full/field-components/file-section/themed-full-file-section.component.ts +++ b/src/app/item-page/full/field-components/file-section/themed-full-file-section.component.ts @@ -11,10 +11,11 @@ import { FullFileSectionComponent } from './full-file-section.component'; * Themed wrapper for {@link FullFileSectionComponent} */ @Component({ - selector: 'ds-themed-item-page-full-file-section', + selector: 'ds-item-page-full-file-section', styleUrls: [], templateUrl: './../../../../shared/theme-support/themed.component.html', standalone: true, + imports: [FullFileSectionComponent], }) export class ThemedFullFileSectionComponent extends ThemedComponent { diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html index 1d83181395..b6e1d1e6ed 100644 --- a/src/app/item-page/full/full-item-page.component.html +++ b/src/app/item-page/full/full-item-page.component.html @@ -1,12 +1,12 @@
- +
- +
- +
@@ -40,5 +40,5 @@
- + diff --git a/src/app/item-page/full/full-item-page.component.ts b/src/app/item-page/full/full-item-page.component.ts index fba1d00e9b..c041d80d1c 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -60,7 +60,7 @@ import { ThemedFullFileSectionComponent } from './field-components/file-section/ */ @Component({ - selector: 'ds-full-item-page', + selector: 'ds-base-full-item-page', styleUrls: ['./full-item-page.component.scss'], templateUrl: './full-item-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/item-page/full/themed-full-item-page.component.ts b/src/app/item-page/full/themed-full-item-page.component.ts index f29947b075..f5034d3042 100644 --- a/src/app/item-page/full/themed-full-item-page.component.ts +++ b/src/app/item-page/full/themed-full-item-page.component.ts @@ -7,10 +7,11 @@ import { FullItemPageComponent } from './full-item-page.component'; * Themed wrapper for FullItemPageComponent */ @Component({ - selector: 'ds-themed-full-item-page', + selector: 'ds-full-item-page', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [FullItemPageComponent], }) export class ThemedFullItemPageComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts b/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts index 4523068118..f2191f074d 100644 --- a/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts +++ b/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts @@ -20,7 +20,7 @@ import { MediaViewerItem } from '../../../core/shared/media-viewer-item.model'; * This componenet render an image gallery for the image viewer */ @Component({ - selector: 'ds-media-viewer-image', + selector: 'ds-base-media-viewer-image', templateUrl: './media-viewer-image.component.html', styleUrls: ['./media-viewer-image.component.scss'], imports: [ diff --git a/src/app/item-page/media-viewer/media-viewer-image/themed-media-viewer-image.component.ts b/src/app/item-page/media-viewer/media-viewer-image/themed-media-viewer-image.component.ts index 84ffeaca5c..d7df6da629 100644 --- a/src/app/item-page/media-viewer/media-viewer-image/themed-media-viewer-image.component.ts +++ b/src/app/item-page/media-viewer/media-viewer-image/themed-media-viewer-image.component.ts @@ -11,10 +11,11 @@ import { MediaViewerImageComponent } from './media-viewer-image.component'; * Themed wrapper for {@link MediaViewerImageComponent}. */ @Component({ - selector: 'ds-themed-media-viewer-image', + selector: 'ds-media-viewer-image', styleUrls: [], templateUrl: '../../../shared/theme-support/themed.component.html', standalone: true, + imports: [MediaViewerImageComponent], }) export class ThemedMediaViewerImageComponent extends ThemedComponent { diff --git a/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts b/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts index 7523e0109f..700431ff3f 100644 --- a/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts +++ b/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts @@ -19,7 +19,7 @@ import { languageHelper } from './language-helper'; * This component renders a video viewer and playlist for the media viewer */ @Component({ - selector: 'ds-media-viewer-video', + selector: 'ds-base-media-viewer-video', templateUrl: './media-viewer-video.component.html', styleUrls: ['./media-viewer-video.component.scss'], imports: [ diff --git a/src/app/item-page/media-viewer/media-viewer-video/themed-media-viewer-video.component.ts b/src/app/item-page/media-viewer/media-viewer-video/themed-media-viewer-video.component.ts index 797780d3b8..800034835c 100644 --- a/src/app/item-page/media-viewer/media-viewer-video/themed-media-viewer-video.component.ts +++ b/src/app/item-page/media-viewer/media-viewer-video/themed-media-viewer-video.component.ts @@ -12,10 +12,11 @@ import { MediaViewerVideoComponent } from './media-viewer-video.component'; * Themed wrapper for {@link MediaViewerVideoComponent}. */ @Component({ - selector: 'ds-themed-media-viewer-video', + selector: 'ds-media-viewer-video', styleUrls: [], templateUrl: '../../../shared/theme-support/themed.component.html', standalone: true, + imports: [MediaViewerVideoComponent], }) export class ThemedMediaViewerVideoComponent extends ThemedComponent { diff --git a/src/app/item-page/media-viewer/media-viewer.component.html b/src/app/item-page/media-viewer/media-viewer.component.html index c8a02e039c..a76ee73963 100644 --- a/src/app/item-page/media-viewer/media-viewer.component.html +++ b/src/app/item-page/media-viewer/media-viewer.component.html @@ -1,25 +1,25 @@ - + >
- - + +
- + > diff --git a/src/app/item-page/media-viewer/media-viewer.component.spec.ts b/src/app/item-page/media-viewer/media-viewer.component.spec.ts index 4d02307452..7649e17b71 100644 --- a/src/app/item-page/media-viewer/media-viewer.component.spec.ts +++ b/src/app/item-page/media-viewer/media-viewer.component.spec.ts @@ -124,7 +124,7 @@ describe('MediaViewerComponent', () => { }); it('should display a loading component', () => { - const loading = fixture.debugElement.query(By.css('ds-themed-loading')); + const loading = fixture.debugElement.query(By.css('ds-loading')); expect(loading.nativeElement).toBeDefined(); }); }); @@ -152,7 +152,7 @@ describe('MediaViewerComponent', () => { it('should display a default, thumbnail', () => { const defaultThumbnail = fixture.debugElement.query( - By.css('ds-themed-media-viewer-image'), + By.css('ds-media-viewer-image'), ); expect(defaultThumbnail.nativeElement).toBeDefined(); }); diff --git a/src/app/item-page/media-viewer/media-viewer.component.ts b/src/app/item-page/media-viewer/media-viewer.component.ts index fbeadee905..7513f5dada 100644 --- a/src/app/item-page/media-viewer/media-viewer.component.ts +++ b/src/app/item-page/media-viewer/media-viewer.component.ts @@ -34,7 +34,7 @@ import { hasValue } from '../../shared/empty.util'; import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component'; import { followLink } from '../../shared/utils/follow-link-config.model'; import { VarDirective } from '../../shared/utils/var.directive'; -import { ThumbnailComponent } from '../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../thumbnail/themed-thumbnail.component'; import { ThemedMediaViewerImageComponent } from './media-viewer-image/themed-media-viewer-image.component'; import { ThemedMediaViewerVideoComponent } from './media-viewer-video/themed-media-viewer-video.component'; @@ -42,12 +42,12 @@ import { ThemedMediaViewerVideoComponent } from './media-viewer-video/themed-med * This component renders the media viewers */ @Component({ - selector: 'ds-media-viewer', + selector: 'ds-base-media-viewer', templateUrl: './media-viewer.component.html', styleUrls: ['./media-viewer.component.scss'], imports: [ ThemedMediaViewerImageComponent, - ThumbnailComponent, + ThemedThumbnailComponent, AsyncPipe, NgIf, ThemedMediaViewerVideoComponent, diff --git a/src/app/item-page/media-viewer/themed-media-viewer.component.ts b/src/app/item-page/media-viewer/themed-media-viewer.component.ts index da790fbd4a..0fa5657094 100644 --- a/src/app/item-page/media-viewer/themed-media-viewer.component.ts +++ b/src/app/item-page/media-viewer/themed-media-viewer.component.ts @@ -12,10 +12,11 @@ import { MediaViewerComponent } from './media-viewer.component'; * Themed wrapper for {@link MediaViewerComponent}. */ @Component({ - selector: 'ds-themed-media-viewer', + selector: 'ds-media-viewer', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [MediaViewerComponent], }) export class ThemedMediaViewerComponent extends ThemedComponent { diff --git a/src/app/item-page/orcid-page/orcid-page.component.ts b/src/app/item-page/orcid-page/orcid-page.component.ts index 1277d0d341..a3c31e791d 100644 --- a/src/app/item-page/orcid-page/orcid-page.component.ts +++ b/src/app/item-page/orcid-page/orcid-page.component.ts @@ -38,7 +38,7 @@ import { import { AlertComponent } from '../../shared/alert/alert.component'; import { AlertType } from '../../shared/alert/alert-type'; import { isNotEmpty } from '../../shared/empty.util'; -import { LoadingComponent } from '../../shared/loading/loading.component'; +import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component'; import { getItemPageRoute } from '../item-page-routing-paths'; import { OrcidAuthComponent } from './orcid-auth/orcid-auth.component'; import { OrcidQueueComponent } from './orcid-queue/orcid-queue.component'; @@ -53,7 +53,7 @@ import { OrcidSyncSettingsComponent } from './orcid-sync-settings/orcid-sync-set styleUrls: ['./orcid-page.component.scss'], imports: [ CommonModule, - LoadingComponent, + ThemedLoadingComponent, AlertComponent, OrcidAuthComponent, OrcidSyncSettingsComponent, diff --git a/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts b/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts index c783e592c6..0f02d7083c 100644 --- a/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts +++ b/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts @@ -37,7 +37,7 @@ import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { AlertComponent } from '../../../shared/alert/alert.component'; import { AlertType } from '../../../shared/alert/alert-type'; import { hasValue } from '../../../shared/empty.util'; -import { LoadingComponent } from '../../../shared/loading/loading.component'; +import { ThemedLoadingComponent } from '../../../shared/loading/themed-loading.component'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { PaginationComponent } from '../../../shared/pagination/pagination.component'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; @@ -50,7 +50,7 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio CommonModule, NgbTooltipModule, TranslateModule, - LoadingComponent, + ThemedLoadingComponent, AlertComponent, PaginationComponent, ], diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.html b/src/app/item-page/simple/field-components/file-section/file-section.component.html index e1748e8bcf..44c83b8626 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.html +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.html @@ -1,15 +1,15 @@
- + {{ 'item.page.bitstreams.primary' | translate }} {{ dsoNameService.getName(file) }} ({{(file?.sizeBytes) | dsFileSize }}) - - + +
diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts b/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts index b2fb2bf29f..9ead81c337 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts @@ -132,7 +132,7 @@ describe('FileSectionComponent', () => { }); it('should display a loading component', () => { - const loading = fixture.debugElement.query(By.css('ds-themed-loading')); + const loading = fixture.debugElement.query(By.css('ds-loading')); expect(loading.nativeElement).toBeDefined(); }); }); @@ -155,7 +155,7 @@ describe('FileSectionComponent', () => { it('one bitstream should be on the page', () => { const viewMore = fixture.debugElement.query(By.css('.bitstream-view-more')); viewMore.triggerEventHandler('click', null); - const fileDownloadLink = fixture.debugElement.queryAll(By.css('ds-themed-file-download-link')); + const fileDownloadLink = fixture.debugElement.queryAll(By.css('ds-file-download-link')); expect(fileDownloadLink.length).toEqual(1); }); @@ -168,7 +168,7 @@ describe('FileSectionComponent', () => { }); it('should contain another bitstream', () => { - const fileDownloadLink = fixture.debugElement.queryAll(By.css('ds-themed-file-download-link')); + const fileDownloadLink = fixture.debugElement.queryAll(By.css('ds-file-download-link')); expect(fileDownloadLink.length).toEqual(2); }); }); diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.ts b/src/app/item-page/simple/field-components/file-section/file-section.component.ts index 8a88989a05..9df34e0d13 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.ts +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.ts @@ -35,7 +35,7 @@ import { VarDirective } from '../../../../shared/utils/var.directive'; * inside a 'ds-metadata-field-wrapper' component. */ @Component({ - selector: 'ds-item-page-file-section', + selector: 'ds-base-item-page-file-section', templateUrl: './file-section.component.html', imports: [ CommonModule, diff --git a/src/app/item-page/simple/field-components/file-section/themed-file-section.component.ts b/src/app/item-page/simple/field-components/file-section/themed-file-section.component.ts index 7a7229715d..2dd8a1df73 100644 --- a/src/app/item-page/simple/field-components/file-section/themed-file-section.component.ts +++ b/src/app/item-page/simple/field-components/file-section/themed-file-section.component.ts @@ -8,9 +8,10 @@ import { ThemedComponent } from '../../../../shared/theme-support/themed.compone import { FileSectionComponent } from './file-section.component'; @Component({ - selector: 'ds-themed-item-page-file-section', + selector: 'ds-item-page-file-section', templateUrl: '../../../../shared/theme-support/themed.component.html', standalone: true, + imports: [FileSectionComponent], }) export class ThemedFileSectionComponent extends ThemedComponent { diff --git a/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts index 7923805462..27d7fc585e 100644 --- a/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts @@ -9,7 +9,7 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service import { Item } from '../../../../../core/shared/item.model'; @Component({ - selector: 'ds-item-page-title-field', + selector: 'ds-base-item-page-title-field', templateUrl: './item-page-title-field.component.html', standalone: true, imports: [NgIf, TranslateModule], diff --git a/src/app/item-page/simple/field-components/specific-field/title/themed-item-page-field.component.ts b/src/app/item-page/simple/field-components/specific-field/title/themed-item-page-field.component.ts index 8e4eb532fc..385a98d47f 100644 --- a/src/app/item-page/simple/field-components/specific-field/title/themed-item-page-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/title/themed-item-page-field.component.ts @@ -11,10 +11,11 @@ import { ItemPageTitleFieldComponent } from './item-page-title-field.component'; * Themed wrapper for {@link ItemPageTitleFieldComponent} */ @Component({ - selector: 'ds-themed-item-page-title-field', + selector: 'ds-item-page-title-field', styleUrls: [], templateUrl: '../../../../../shared/theme-support/themed.component.html', standalone: true, + imports: [ItemPageTitleFieldComponent], }) export class ThemedItemPageTitleFieldComponent extends ThemedComponent { diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index dc8ed87a86..912115c961 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -1,7 +1,7 @@
- + @@ -11,5 +11,5 @@
- +
diff --git a/src/app/item-page/simple/item-page.component.spec.ts b/src/app/item-page/simple/item-page.component.spec.ts index 2766bee3a5..827af05b65 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -182,7 +182,7 @@ describe('ItemPageComponent', () => { }); it('should display a loading component', () => { - const loading = fixture.debugElement.query(By.css('ds-themed-loading')); + const loading = fixture.debugElement.query(By.css('ds-loading')); expect(loading.nativeElement).toBeDefined(); }); }); diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index cb6da792a1..f1155fd10f 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -64,7 +64,7 @@ import { QaEventNotificationComponent } from './qa-event-notification/qa-event-n * All fields of the item that should be displayed, are defined in its template. */ @Component({ - selector: 'ds-item-page', + selector: 'ds-base-item-page', styleUrls: ['./item-page.component.scss'], templateUrl: './item-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index d09b560042..5f96682be2 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -1,4 +1,4 @@ - +
- - + +
- +
- +
- + - - + diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 35a00dc7b7..5ab42556e2 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -1,4 +1,4 @@ - +
- - + +
- +
- +
- + - - + diff --git a/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html b/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html index efbe9206d1..424c2324fa 100644 --- a/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html +++ b/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html @@ -4,7 +4,7 @@ - +
- +
- +
- + diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts index 74b490a2e7..40f51fe70b 100644 --- a/src/app/shared/pagination/pagination.component.ts +++ b/src/app/shared/pagination/pagination.component.ts @@ -39,13 +39,11 @@ import { PaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationRouteParams } from '../../core/pagination/pagination-route-params.interface'; -import { PageInfo } from '../../core/shared/page-info.model'; import { ViewMode } from '../../core/shared/view-mode.model'; import { hasValue } from '../empty.util'; import { HostWindowService } from '../host-window.service'; import { ListableObject } from '../object-collection/shared/listable-object.model'; import { RSSComponent } from '../rss-feed/rss.component'; -import { HostWindowState } from '../search/host-window.reducer'; import { EnumKeysPipe } from '../utils/enum-keys-pipe'; import { PaginationComponentOptions } from './pagination-component-options.model'; @@ -73,11 +71,6 @@ export class PaginationComponent implements OnDestroy, OnInit { */ @Input() collectionSize: number; - /** - * Page state of a Remote paginated objects. - */ - @Input() pageInfoState: Observable = undefined; - /** * Configuration for the NgbPagination component. */ @@ -167,18 +160,13 @@ export class PaginationComponent implements OnDestroy, OnInit { /** * Current page. */ - public currentPage$; + public currentPage$: Observable; /** * Current page in the state of a Remote paginated objects. */ public currentPageState: number = undefined; - /** - * An observable of HostWindowState type - */ - public hostWindow: Observable; - /** * ID for the pagination instance. This ID is used in the routing to retrieve the pagination options. * This ID needs to be unique between different pagination components when more than one will be displayed on the same page. @@ -268,7 +256,7 @@ export class PaginationComponent implements OnDestroy, OnInit { map((currentPagination) => currentPagination.pageSize), ); - let sortOptions; + let sortOptions: SortOptions; if (this.sortOptions) { sortOptions = this.sortOptions; } else { @@ -282,16 +270,6 @@ export class PaginationComponent implements OnDestroy, OnInit { ); } - /** - * @param cdRef - * ChangeDetectorRef is a singleton service provided by Angular. - * @param route - * Route is a singleton service provided by Angular. - * @param router - * Router is a singleton service provided by Angular. - * @param hostWindowService - * the HostWindowService singleton. - */ constructor(private cdRef: ChangeDetectorRef, private paginationService: PaginationService, public hostWindowService: HostWindowService) { @@ -330,17 +308,6 @@ export class PaginationComponent implements OnDestroy, OnInit { this.emitPaginationChange(); } - /** - * Method to change the route to the given sort field - * - * @param sortField - * The sort field being navigated to. - */ - public doSortFieldChange(field: string) { - this.updateParams({ page: 1, sortField: field }); - this.emitPaginationChange(); - } - /** * Method to emit a general pagination change event */ @@ -364,10 +331,10 @@ export class PaginationComponent implements OnDestroy, OnInit { if (collectionSize) { showingDetails = this.paginationService.getCurrentPagination(this.id, this.paginationOptions).pipe( map((currentPaginationOptions) => { - let lastItem; + let lastItem: number; const pageMax = currentPaginationOptions.pageSize * currentPaginationOptions.currentPage; - const firstItem = currentPaginationOptions.pageSize * (currentPaginationOptions.currentPage - 1) + 1; + const firstItem: number = currentPaginationOptions.pageSize * (currentPaginationOptions.currentPage - 1) + 1; if (collectionSize > pageMax) { lastItem = pageMax; } else { diff --git a/src/app/shared/resource-policies/entry/resource-policy-entry.component.ts b/src/app/shared/resource-policies/entry/resource-policy-entry.component.ts index 82a2dcb2d9..491ebffb86 100644 --- a/src/app/shared/resource-policies/entry/resource-policy-entry.component.ts +++ b/src/app/shared/resource-policies/entry/resource-policy-entry.component.ts @@ -67,7 +67,7 @@ export interface ResourcePolicyCheckboxEntry { }) export class ResourcePolicyEntryComponent implements OnInit { @Input() - entry: ResourcePolicyCheckboxEntry; + entry: ResourcePolicyCheckboxEntry; @Output() public toggleCheckbox: EventEmitter = new EventEmitter(); diff --git a/src/app/shared/results-back-button/results-back-button.component.ts b/src/app/shared/results-back-button/results-back-button.component.ts index ebae3911ad..3d237733a1 100644 --- a/src/app/shared/results-back-button/results-back-button.component.ts +++ b/src/app/shared/results-back-button/results-back-button.component.ts @@ -9,7 +9,7 @@ import { TranslateService } from '@ngx-translate/core'; import { Observable } from 'rxjs'; @Component({ - selector: 'ds-results-back-button', + selector: 'ds-base-results-back-button', styleUrls: ['./results-back-button.component.scss'], templateUrl: './results-back-button.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/shared/results-back-button/themed-results-back-button.component.ts b/src/app/shared/results-back-button/themed-results-back-button.component.ts index d096c2af81..d280e9b849 100644 --- a/src/app/shared/results-back-button/themed-results-back-button.component.ts +++ b/src/app/shared/results-back-button/themed-results-back-button.component.ts @@ -8,10 +8,11 @@ import { ThemedComponent } from '../theme-support/themed.component'; import { ResultsBackButtonComponent } from './results-back-button.component'; @Component({ - selector: 'ds-themed-results-back-button', + selector: 'ds-results-back-button', styleUrls: [], templateUrl: '../theme-support/themed.component.html', standalone: true, + imports: [ResultsBackButtonComponent], }) export class ThemedResultsBackButtonComponent extends ThemedComponent { diff --git a/src/app/shared/search-form/search-form.component.ts b/src/app/shared/search-form/search-form.component.ts index 325f8a074e..1fabb9c8e2 100644 --- a/src/app/shared/search-form/search-form.component.ts +++ b/src/app/shared/search-form/search-form.component.ts @@ -35,7 +35,7 @@ import { currentPath } from '../utils/route.utils'; import { ScopeSelectorModalComponent } from './scope-selector-modal/scope-selector-modal.component'; @Component({ - selector: 'ds-search-form', + selector: 'ds-base-search-form', styleUrls: ['./search-form.component.scss'], templateUrl: './search-form.component.html', standalone: true, @@ -59,7 +59,7 @@ export class SearchFormComponent implements OnChanges { * The currently selected scope object's UUID */ @Input() - scope = ''; + scope = ''; /** * Hides the scope in the url, this can be useful when you hardcode the scope in another way diff --git a/src/app/shared/search-form/themed-search-form.component.ts b/src/app/shared/search-form/themed-search-form.component.ts index 301ee86acf..52c4f80755 100644 --- a/src/app/shared/search-form/themed-search-form.component.ts +++ b/src/app/shared/search-form/themed-search-form.component.ts @@ -12,10 +12,11 @@ import { SearchFormComponent } from './search-form.component'; * Themed wrapper for {@link SearchFormComponent} */ @Component({ - selector: 'ds-themed-search-form', + selector: 'ds-search-form', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', standalone: true, + imports: [SearchFormComponent], }) export class ThemedSearchFormComponent extends ThemedComponent { diff --git a/src/app/shared/search/models/facet-config-response.model.ts b/src/app/shared/search/models/facet-config-response.model.ts index 6b1cc37997..821d4cdaeb 100644 --- a/src/app/shared/search/models/facet-config-response.model.ts +++ b/src/app/shared/search/models/facet-config-response.model.ts @@ -19,7 +19,7 @@ export class FacetConfigResponse implements CacheableObject { * hardcoded because rest doesn't a unique one. */ @excludeFromEquals - type = FACET_CONFIG_RESPONSE; + type = FACET_CONFIG_RESPONSE; /** * the filters in this response @@ -30,7 +30,7 @@ export class FacetConfigResponse implements CacheableObject { * The {@link HALLink}s for this SearchFilterConfig */ @deserialize - _links: { + _links: { self: HALLink; }; } diff --git a/src/app/shared/search/models/facet-value.model.ts b/src/app/shared/search/models/facet-value.model.ts index a343e007c9..6861b452e0 100644 --- a/src/app/shared/search/models/facet-value.model.ts +++ b/src/app/shared/search/models/facet-value.model.ts @@ -15,31 +15,31 @@ export class FacetValue implements HALResource { * The display label of the facet value */ @autoserialize - label: string; + label: string; /** * The value of the facet value */ @autoserializeAs(String, 'label') - value: string; + value: string; /** * The number of results this facet value would have if selected */ @autoserialize - count: number; + count: number; /** * The Authority Value for this facet */ @autoserialize - authorityKey?: string; + authorityKey?: string; /** * The {@link HALLink}s for this FacetValue */ @deserialize - _links: { + _links: { self: HALLink search: HALLink }; diff --git a/src/app/shared/search/models/facet-values.model.ts b/src/app/shared/search/models/facet-values.model.ts index 4c14c7d90c..a0cdffb9a5 100644 --- a/src/app/shared/search/models/facet-values.model.ts +++ b/src/app/shared/search/models/facet-values.model.ts @@ -29,23 +29,23 @@ export class FacetValues extends SearchQueryResponse { * The name of the facet the values are for */ @autoserialize - name: string; + name: string; /** * The type of facet the values are for */ @autoserializeAs(String, 'facetType') - filterType: FilterType; + filterType: FilterType; /** * The max number of returned facetValues */ @autoserialize - facetLimit: number; + facetLimit: number; /** * The results for this query */ @autoserializeAs(FacetValue, 'values') - page: FacetValue[]; + page: FacetValue[]; } diff --git a/src/app/shared/search/models/search-objects.model.ts b/src/app/shared/search/models/search-objects.model.ts index fa483017ee..5c70e3b0a1 100644 --- a/src/app/shared/search/models/search-objects.model.ts +++ b/src/app/shared/search/models/search-objects.model.ts @@ -31,5 +31,5 @@ export class SearchObjects extends SearchQueryResponse[]; + page: SearchResult[]; } diff --git a/src/app/shared/search/models/search-query-response.model.ts b/src/app/shared/search/models/search-query-response.model.ts index 961095e5f3..9152321410 100644 --- a/src/app/shared/search/models/search-query-response.model.ts +++ b/src/app/shared/search/models/search-query-response.model.ts @@ -11,44 +11,44 @@ export abstract class SearchQueryResponse extends PaginatedList { * The scope used in the search request represented by the UUID of a DSpaceObject */ @autoserialize - scope: string; + scope: string; /** * The search query used in the search request */ @autoserialize - query: string; + query: string; /** * The currently active filters used in the search request */ @autoserialize - appliedFilters: any[]; // TODO + appliedFilters: any[]; // TODO /** * The sort parameters used in the search request */ @autoserialize - sort: any; // TODO + sort: any; // TODO /** * The sort parameters used in the search request */ @autoserialize - configuration: string; + configuration: string; /** * Pagination configuration for this response */ @autoserialize - pageInfo: PageInfo; + pageInfo: PageInfo; /** * The results for this query */ @autoserialize - page: T[]; + page: T[]; @autoserialize - facets: any; // TODO + facets: any; // TODO } diff --git a/src/app/shared/search/models/search-result.model.ts b/src/app/shared/search/models/search-result.model.ts index b2bc167c81..e3bc927941 100644 --- a/src/app/shared/search/models/search-result.model.ts +++ b/src/app/shared/search/models/search-result.model.ts @@ -33,13 +33,13 @@ export class SearchResult extends ListableObject impleme */ @excludeFromEquals @autoserialize - hitHighlights: MetadataMap; + hitHighlights: MetadataMap; /** * The {@link HALLink}s for this SearchResult */ @deserialize - _links: { + _links: { self: HALLink; indexableObject: HALLink; }; @@ -48,7 +48,7 @@ export class SearchResult extends ListableObject impleme * The DSpaceObject that was found */ @fieldsForEquals('uuid') - indexableObject: T; + indexableObject: T; /** * Method that returns as which type of object this object should be rendered diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index f94e4282bf..9ac49f6af8 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -38,7 +38,7 @@ import { SearchFilterConfig } from '../models/search-filter-config.model'; import { SearchFilterComponent } from './search-filter/search-filter.component'; @Component({ - selector: 'ds-search-filters', + selector: 'ds-base-search-filters', styleUrls: ['./search-filters.component.scss'], templateUrl: './search-filters.component.html', standalone: true, diff --git a/src/app/shared/search/search-filters/themed-search-filters.component.ts b/src/app/shared/search/search-filters/themed-search-filters.component.ts index 22cc098662..3e30aed1d9 100644 --- a/src/app/shared/search/search-filters/themed-search-filters.component.ts +++ b/src/app/shared/search/search-filters/themed-search-filters.component.ts @@ -13,10 +13,11 @@ import { SearchFiltersComponent } from './search-filters.component'; * Themed wrapper for SearchFiltersComponent */ @Component({ - selector: 'ds-themed-search-filters', + selector: 'ds-search-filters', styleUrls: [], templateUrl: '../../theme-support/themed.component.html', standalone: true, + imports: [SearchFiltersComponent], }) export class ThemedSearchFiltersComponent extends ThemedComponent { diff --git a/src/app/shared/search/search-labels/search-label/search-label.component.html b/src/app/shared/search/search-labels/search-label/search-label.component.html index 2269771de1..d35494b591 100644 --- a/src/app/shared/search/search-labels/search-label/search-label.component.html +++ b/src/app/shared/search/search-labels/search-label/search-label.component.html @@ -1,7 +1,9 @@ - - {{('search.filters.applied.' + key) | translate}}: {{'search.filters.' + filterName + '.' + value | translate: {default: normalizeFilterValue(value)} }} - + + {{('search.filters.applied.' + key) | translate}}: {{'search.filters.' + filterName + '.' + value | translate: {default: normalizeFilterValue(value)} }} + + diff --git a/src/app/shared/search/search-labels/search-label/search-label.component.scss b/src/app/shared/search/search-labels/search-label/search-label.component.scss new file mode 100644 index 0000000000..601f57d407 --- /dev/null +++ b/src/app/shared/search/search-labels/search-label/search-label.component.scss @@ -0,0 +1,3 @@ +.badge { + white-space: inherit; +} diff --git a/src/app/shared/search/search-labels/search-label/search-label.component.ts b/src/app/shared/search/search-labels/search-label/search-label.component.ts index b24ff13826..0be52d38c6 100644 --- a/src/app/shared/search/search-labels/search-label/search-label.component.ts +++ b/src/app/shared/search/search-labels/search-label/search-label.component.ts @@ -26,6 +26,7 @@ import { stripOperatorFromFilterValue } from '../../search.utils'; @Component({ selector: 'ds-search-label', templateUrl: './search-label.component.html', + styleUrls: ['./search-label.component.scss'], standalone: true, imports: [RouterLink, AsyncPipe, TranslateModule], }) diff --git a/src/app/shared/search/search-labels/search-labels.component.scss b/src/app/shared/search/search-labels/search-labels.component.scss index c48cd57304..348c46571d 100644 --- a/src/app/shared/search/search-labels/search-labels.component.scss +++ b/src/app/shared/search/search-labels/search-labels.component.scss @@ -1,3 +1,10 @@ :host { line-height: 1; -} \ No newline at end of file + .labels { + margin: 0 calc(-1 * var(--bs-spacer)/8); + ds-search-label { + display: inline-block; + padding: 0 calc(var(--bs-spacer)/8); + } + } +} diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html index e3f4d0d883..0c7e560238 100644 --- a/src/app/shared/search/search-results/search-results.component.html +++ b/src/app/shared/search/search-results/search-results.component.html @@ -19,7 +19,7 @@ (selectObject)="selectObject.emit($event)">
- +
diff --git a/src/app/shared/search/search-results/search-results.component.ts b/src/app/shared/search/search-results/search-results.component.ts index 16c9575b86..09186e8c6c 100644 --- a/src/app/shared/search/search-results/search-results.component.ts +++ b/src/app/shared/search/search-results/search-results.component.ts @@ -37,7 +37,7 @@ export interface SelectionConfig { } @Component({ - selector: 'ds-search-results', + selector: 'ds-base-search-results', templateUrl: './search-results.component.html', animations: [ fadeIn, diff --git a/src/app/shared/search/search-results/themed-search-results.component.ts b/src/app/shared/search/search-results/themed-search-results.component.ts index c473a4ec72..5f9f1975af 100644 --- a/src/app/shared/search/search-results/themed-search-results.component.ts +++ b/src/app/shared/search/search-results/themed-search-results.component.ts @@ -25,10 +25,11 @@ import { * Themed wrapper for SearchResultsComponent */ @Component({ - selector: 'ds-themed-search-results', + selector: 'ds-search-results', styleUrls: [], templateUrl: '../../theme-support/themed.component.html', standalone: true, + imports: [SearchResultsComponent], }) export class ThemedSearchResultsComponent extends ThemedComponent { diff --git a/src/app/shared/search/search-settings/search-settings.component.ts b/src/app/shared/search/search-settings/search-settings.component.ts index 6f8ace0df1..68f118bd1c 100644 --- a/src/app/shared/search/search-settings/search-settings.component.ts +++ b/src/app/shared/search/search-settings/search-settings.component.ts @@ -21,7 +21,7 @@ import { PageSizeSelectorComponent } from '../../page-size-selector/page-size-se import { SidebarDropdownComponent } from '../../sidebar/sidebar-dropdown.component'; @Component({ - selector: 'ds-search-settings', + selector: 'ds-base-search-settings', styleUrls: ['./search-settings.component.scss'], templateUrl: './search-settings.component.html', standalone: true, diff --git a/src/app/shared/search/search-settings/themed-search-settings.component.ts b/src/app/shared/search/search-settings/themed-search-settings.component.ts index af3a15ca51..22cd638b1a 100644 --- a/src/app/shared/search/search-settings/themed-search-settings.component.ts +++ b/src/app/shared/search/search-settings/themed-search-settings.component.ts @@ -11,10 +11,11 @@ import { SearchSettingsComponent } from './search-settings.component'; * Themed wrapper for SearchSettingsComponent */ @Component({ - selector: 'ds-themed-search-settings', + selector: 'ds-search-settings', styleUrls: [], templateUrl: '../../theme-support/themed.component.html', standalone: true, + imports: [SearchSettingsComponent], }) export class ThemedSearchSettingsComponent extends ThemedComponent { @Input() currentSortOption: SortOptions; diff --git a/src/app/shared/search/search-sidebar/search-sidebar.component.html b/src/app/shared/search/search-sidebar/search-sidebar.component.html index f14854593e..28bafe96db 100644 --- a/src/app/shared/search/search-sidebar/search-sidebar.component.html +++ b/src/app/shared/search/search-sidebar/search-sidebar.component.html @@ -18,13 +18,13 @@ [defaultConfiguration]="configuration" [inPlaceSearch]="inPlaceSearch" (changeConfiguration)="changeConfiguration.emit($event)"> - - + [inPlaceSearch]="inPlaceSearch"> +
diff --git a/src/app/shared/search/search-sidebar/search-sidebar.component.ts b/src/app/shared/search/search-sidebar/search-sidebar.component.ts index 1aabe12737..f7968ab95d 100644 --- a/src/app/shared/search/search-sidebar/search-sidebar.component.ts +++ b/src/app/shared/search/search-sidebar/search-sidebar.component.ts @@ -29,7 +29,7 @@ import { SearchSwitchConfigurationComponent } from '../search-switch-configurati */ @Component({ - selector: 'ds-search-sidebar', + selector: 'ds-base-search-sidebar', styleUrls: ['./search-sidebar.component.scss'], templateUrl: './search-sidebar.component.html', standalone: true, diff --git a/src/app/shared/search/search-sidebar/themed-search-sidebar.component.ts b/src/app/shared/search/search-sidebar/themed-search-sidebar.component.ts index d44698cfc2..a7c6af7a7b 100644 --- a/src/app/shared/search/search-sidebar/themed-search-sidebar.component.ts +++ b/src/app/shared/search/search-sidebar/themed-search-sidebar.component.ts @@ -22,10 +22,11 @@ import { SearchSidebarComponent } from './search-sidebar.component'; * Themed wrapper for SearchSidebarComponent */ @Component({ - selector: 'ds-themed-search-sidebar', + selector: 'ds-search-sidebar', styleUrls: [], templateUrl: '../../theme-support/themed.component.html', standalone: true, + imports: [SearchSidebarComponent], }) export class ThemedSearchSidebarComponent extends ThemedComponent { diff --git a/src/app/shared/search/search.component.html b/src/app/shared/search/search.component.html index a8a4bc1a6a..adb164e799 100644 --- a/src/app/shared/search/search.component.html +++ b/src/app/shared/search/search.component.html @@ -33,7 +33,8 @@ | translate}}
- + + (selectObject)="selectObject.emit($event)">
- - + - + - - -
-
+ +
+
diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index 35e7f130cc..68880119a4 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -82,7 +82,7 @@ import { ThemedSearchSidebarComponent } from './search-sidebar/themed-search-sid import { SearchConfigurationOption } from './search-switch-configuration/search-configuration-option.model'; @Component({ - selector: 'ds-search', + selector: 'ds-base-search', styleUrls: ['./search.component.scss'], templateUrl: './search.component.html', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/shared/search/themed-search.component.ts b/src/app/shared/search/themed-search.component.ts index c6bf3927b4..733248e21e 100644 --- a/src/app/shared/search/themed-search.component.ts +++ b/src/app/shared/search/themed-search.component.ts @@ -20,9 +20,10 @@ import { SearchConfigurationOption } from './search-switch-configuration/search- * Themed wrapper for {@link SearchComponent} */ @Component({ - selector: 'ds-themed-search', + selector: 'ds-search', templateUrl: '../theme-support/themed.component.html', standalone: true, + imports: [SearchComponent], }) export class ThemedSearchComponent extends ThemedComponent { diff --git a/src/app/shared/sidebar/page-with-sidebar.component.ts b/src/app/shared/sidebar/page-with-sidebar.component.ts index d806c37f61..aa7ae23a8b 100644 --- a/src/app/shared/sidebar/page-with-sidebar.component.ts +++ b/src/app/shared/sidebar/page-with-sidebar.component.ts @@ -47,7 +47,7 @@ export class PageWithSidebarComponent implements OnInit { * The width of the sidebar (bootstrap columns) */ @Input() - sideBarWidth = 3; + sideBarWidth = 3; /** * Observable for whether or not the sidebar is currently collapsed diff --git a/src/app/shared/subscriptions/models/subscription.model.ts b/src/app/shared/subscriptions/models/subscription.model.ts index cf3ea645dd..513b239259 100644 --- a/src/app/shared/subscriptions/models/subscription.model.ts +++ b/src/app/shared/subscriptions/models/subscription.model.ts @@ -44,7 +44,7 @@ export class Subscription extends DSpaceObject { * The {@link HALLink}s for this Subscription */ @deserialize - _links: { + _links: { self: HALLink; eperson: HALLink; resource: HALLink; @@ -55,14 +55,14 @@ export class Subscription extends DSpaceObject { * Will be undefined unless the logo {@link HALLink} has been resolved. */ @link(EPERSON) - eperson?: Observable>; + eperson?: Observable>; /** * The logo for this Community * Will be undefined unless the logo {@link HALLink} has been resolved. */ @link(DSPACE_OBJECT) - resource?: Observable>; + resource?: Observable>; /** * The embedded ePerson & dSpaceObject for this Subscription */ diff --git a/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html b/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html index 4894d66de3..e0bbc1a609 100644 --- a/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html +++ b/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html @@ -7,7 +7,7 @@
diff --git a/src/app/submission/form/collection/submission-form-collection.component.ts b/src/app/submission/form/collection/submission-form-collection.component.ts index ec978ba3b3..dcbcfd9cb3 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.ts +++ b/src/app/submission/form/collection/submission-form-collection.component.ts @@ -166,7 +166,7 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit { */ ngOnInit() { this.pathCombiner = new JsonPatchOperationPathCombiner('sections', 'collection'); - this.available$ = this.sectionsService.isSectionTypeAvailable(this.submissionId, SectionsType.collection); + this.available$ = this.sectionsService.isSectionTypeAvailable(this.submissionId, SectionsType.Collection); } /** diff --git a/src/app/submission/form/submission-form.component.html b/src/app/submission/form/submission-form.component.html index 461c91db7a..17e863d435 100644 --- a/src/app/submission/form/submission-form.component.html +++ b/src/app/submission/form/submission-form.component.html @@ -27,7 +27,7 @@
- +
diff --git a/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts b/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts index e205a6ef8b..989726e7e4 100644 --- a/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts +++ b/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts @@ -145,7 +145,7 @@ describe('SubmissionImportExternalCollectionComponent test suite', () => { fixture.detectChanges(); fixture.whenStable().then(() => { - const dropdownMenu = fixture.debugElement.query(By.css('ds-themed-collection-dropdown')).nativeElement; + const dropdownMenu = fixture.debugElement.query(By.css('ds-collection-dropdown')).nativeElement; expect(dropdownMenu.classList).toContain('d-none'); }); })); diff --git a/src/app/submission/import-external/submission-import-external.component.html b/src/app/submission/import-external/submission-import-external.component.html index 55acb591d4..21783f9a2e 100644 --- a/src/app/submission/import-external/submission-import-external.component.html +++ b/src/app/submission/import-external/submission-import-external.component.html @@ -22,8 +22,8 @@ [importConfig]="importConfig" (importObject)="import($event)"> - +
{{ 'search.results.empty' | translate }}
diff --git a/src/app/submission/import-external/submission-import-external.component.ts b/src/app/submission/import-external/submission-import-external.component.ts index ee7e2c82ce..47b5c09d66 100644 --- a/src/app/submission/import-external/submission-import-external.component.ts +++ b/src/app/submission/import-external/submission-import-external.component.ts @@ -64,7 +64,7 @@ import { * This component allows to submit a new workspaceitem importing the data from an external source. */ @Component({ - selector: 'ds-submission-import-external', + selector: 'ds-base-submission-import-external', styleUrls: ['./submission-import-external.component.scss'], templateUrl: './submission-import-external.component.html', animations: [fadeIn], diff --git a/src/app/submission/import-external/themed-submission-import-external.component.ts b/src/app/submission/import-external/themed-submission-import-external.component.ts index b130325c8f..bd7242293d 100644 --- a/src/app/submission/import-external/themed-submission-import-external.component.ts +++ b/src/app/submission/import-external/themed-submission-import-external.component.ts @@ -7,10 +7,11 @@ import { SubmissionImportExternalComponent } from './submission-import-external. * Themed wrapper for SubmissionImportExternalComponent */ @Component({ - selector: 'ds-themed-submission-import-external', + selector: 'ds-submission-import-external', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [SubmissionImportExternalComponent], }) export class ThemedSubmissionImportExternalComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/submission/objects/submission-objects.effects.ts b/src/app/submission/objects/submission-objects.effects.ts index 53dcd9a19e..232ff214da 100644 --- a/src/app/submission/objects/submission-objects.effects.ts +++ b/src/app/submission/objects/submission-objects.effects.ts @@ -501,7 +501,7 @@ function getForm(forms, currentState, sectionId) { * Whether notifications are enabled */ function filterErrors(sectionForm: FormState, sectionErrors: SubmissionSectionError[], sectionType: string, notify: boolean): SubmissionSectionError[] { - if (notify || sectionType !== SectionsType.SubmissionForm) { + if (notify || sectionType !== SectionsType.SubmissionForm.valueOf()) { return sectionErrors; } if (!sectionForm || !sectionForm.touched) { diff --git a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html index 7c6145a65e..0c8c1abeeb 100644 --- a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html +++ b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html @@ -4,7 +4,7 @@ - + {{ getSelectedCcLicense().name }} @@ -121,7 +121,7 @@
- +
diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index 808591bdb3..25c2ae303d 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -92,7 +92,7 @@ export class SectionFormOperationsService { * @return number * the array index is part of array, zero otherwise */ - public getArrayIndexFromEvent(event: DynamicFormControlEvent | any): number { + public getArrayIndexFromEvent(event: any): number { let fieldIndex: number; if (isNotEmpty(event)) { @@ -110,7 +110,7 @@ export class SectionFormOperationsService { } else { // This is the case of a custom event which contains indexes information - fieldIndex = event.index as any; + fieldIndex = event?.index as any; } } diff --git a/src/app/submission/sections/form/section-form.component.html b/src/app/submission/sections/form/section-form.component.html index 675b550b57..cd7b45bb00 100644 --- a/src/app/submission/sections/form/section-form.component.html +++ b/src/app/submission/sections/form/section-form.component.html @@ -1,4 +1,4 @@ - +
- - +
- + [submissionId]="submissionId">

diff --git a/src/app/submission/submission.service.ts b/src/app/submission/submission.service.ts index 312d74bc8a..19c8893a7e 100644 --- a/src/app/submission/submission.service.ts +++ b/src/app/submission/submission.service.ts @@ -1,7 +1,12 @@ import { HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; -import { Store } from '@ngrx/store'; +import { + createSelector, + MemoizedSelector, + select, + Store, +} from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; import { Observable, @@ -71,6 +76,20 @@ import { SubmissionState, } from './submission.reducers'; +function getSubmissionSelector(submissionId: string): MemoizedSelector { + return createSelector( + submissionSelector, + (state: SubmissionState) => state.objects[submissionId], + ); +} + +function getSubmissionCollectionIdSelector(submissionId: string): MemoizedSelector { + return createSelector( + getSubmissionSelector(submissionId), + (submission: SubmissionObjectEntry) => submission?.collection, + ); +} + /** * A service that provides methods used in submission process. */ @@ -120,10 +139,19 @@ export class SubmissionService { * @param collectionId * The collection id */ - changeSubmissionCollection(submissionId, collectionId) { + changeSubmissionCollection(submissionId: string, collectionId: string): void { this.store.dispatch(new ChangeSubmissionCollectionAction(submissionId, collectionId)); } + /** + * Listen to collection changes for a certain {@link SubmissionObject} + * + * @param submissionId The submission id + */ + getSubmissionCollectionId(submissionId: string): Observable { + return this.store.pipe(select(getSubmissionCollectionIdSelector(submissionId))); + } + /** * Perform a REST call to create a new workspaceitem and return response * diff --git a/src/app/submission/submit/submission-submit.component.ts b/src/app/submission/submit/submission-submit.component.ts index 84e1232147..c9e087f7d8 100644 --- a/src/app/submission/submit/submission-submit.component.ts +++ b/src/app/submission/submit/submission-submit.component.ts @@ -39,7 +39,7 @@ import { SubmissionService } from '../submission.service'; * This component allows to submit a new workspaceitem. */ @Component({ - selector: 'ds-submission-submit', + selector: 'ds-base-submission-submit', styleUrls: ['./submission-submit.component.scss'], templateUrl: './submission-submit.component.html', standalone: true, diff --git a/src/app/submission/submit/themed-submission-submit.component.ts b/src/app/submission/submit/themed-submission-submit.component.ts index 15faf2c420..ee5ee74746 100644 --- a/src/app/submission/submit/themed-submission-submit.component.ts +++ b/src/app/submission/submit/themed-submission-submit.component.ts @@ -7,10 +7,11 @@ import { SubmissionSubmitComponent } from './submission-submit.component'; * Themed wrapper for SubmissionSubmitComponent */ @Component({ - selector: 'ds-themed-submission-submit', + selector: 'ds-submission-submit', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [SubmissionSubmitComponent], }) export class ThemedSubmissionSubmitComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/subscriptions-page/subscriptions-page.component.html b/src/app/subscriptions-page/subscriptions-page.component.html index fcdaaaeace..e8dfc8fc6a 100644 --- a/src/app/subscriptions-page/subscriptions-page.component.html +++ b/src/app/subscriptions-page/subscriptions-page.component.html @@ -4,7 +4,7 @@

{{'subscriptions.title' | translate}}

- + { diff --git a/src/app/thumbnail/thumbnail.component.html b/src/app/thumbnail/thumbnail.component.html index 6a0516b0d4..c32a44da3f 100644 --- a/src/app/thumbnail/thumbnail.component.html +++ b/src/app/thumbnail/thumbnail.component.html @@ -2,7 +2,7 @@
- +
diff --git a/src/app/thumbnail/thumbnail.component.spec.ts b/src/app/thumbnail/thumbnail.component.spec.ts index 78afc42051..b5bf5474f7 100644 --- a/src/app/thumbnail/thumbnail.component.spec.ts +++ b/src/app/thumbnail/thumbnail.component.spec.ts @@ -111,11 +111,11 @@ describe('ThumbnailComponent', () => { }); it('should show a loading animation while isLoading$ is true', () => { - expect(de.query(By.css('ds-themed-loading'))).toBeTruthy(); + expect(de.query(By.css('ds-loading'))).toBeTruthy(); comp.isLoading$.next(false); fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('ds-themed-loading'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('ds-loading'))).toBeFalsy(); }); describe('with a thumbnail image', () => { diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts index 96d3965a4e..efcbfb1a81 100644 --- a/src/app/thumbnail/thumbnail.component.ts +++ b/src/app/thumbnail/thumbnail.component.ts @@ -32,7 +32,7 @@ import { VarDirective } from '../shared/utils/var.directive'; * If no Bitstream is provided, an HTML placeholder will be rendered instead. */ @Component({ - selector: 'ds-thumbnail', + selector: 'ds-base-thumbnail', styleUrls: ['./thumbnail.component.scss'], templateUrl: './thumbnail.component.html', standalone: true, diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts index 60ab557432..830e520655 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts @@ -75,16 +75,16 @@ enum SubKey { export class ReviewersListComponent extends MembersListComponent implements OnInit, OnChanges, OnDestroy { @Input() - groupId: string | null; + groupId: string | null; @Input() - actionConfig: EPersonListActionConfig; + actionConfig: EPersonListActionConfig; @Input() - multipleReviewers: boolean; + multipleReviewers: boolean; @Output() - selectedReviewersUpdated: EventEmitter = new EventEmitter(); + selectedReviewersUpdated: EventEmitter = new EventEmitter(); selectedReviewers: EPerson[] = []; diff --git a/src/app/workflowitems-edit-page/item-from-workflow-breadcrumb.resolver.ts b/src/app/workflowitems-edit-page/item-from-workflow-breadcrumb.resolver.ts new file mode 100644 index 0000000000..1c29d6b861 --- /dev/null +++ b/src/app/workflowitems-edit-page/item-from-workflow-breadcrumb.resolver.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Resolve } from '@angular/router'; + +import { BreadcrumbConfig } from '../breadcrumbs/breadcrumb/breadcrumb-config.model'; +import { SubmissionObject } from '../core/submission/models/submission-object.model'; +import { SubmissionParentBreadcrumbResolver } from '../core/submission/resolver/submission-parent-breadcrumb.resolver'; +import { SubmissionParentBreadcrumbsService } from '../core/submission/submission-parent-breadcrumb.service'; +import { WorkflowItemDataService } from '../core/submission/workflowitem-data.service'; + +/** + * This class represents a resolver that retrieves the breadcrumbs of the workflow item + */ +@Injectable({ + providedIn: 'root', +}) +export class ItemFromWorkflowBreadcrumbResolver extends SubmissionParentBreadcrumbResolver implements Resolve> { + + constructor( + protected dataService: WorkflowItemDataService, + protected breadcrumbService: SubmissionParentBreadcrumbsService, + ) { + super(dataService, breadcrumbService); + } + +} diff --git a/src/app/workflowitems-edit-page/workflow-item-delete/themed-workflow-item-delete.component.ts b/src/app/workflowitems-edit-page/workflow-item-delete/themed-workflow-item-delete.component.ts index 4be1b65741..39180d1c7b 100644 --- a/src/app/workflowitems-edit-page/workflow-item-delete/themed-workflow-item-delete.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-delete/themed-workflow-item-delete.component.ts @@ -8,10 +8,11 @@ import { WorkflowItemDeleteComponent } from './workflow-item-delete.component'; */ @Component({ - selector: 'ds-themed-workflow-item-delete', + selector: 'ds-workflow-item-delete', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [WorkflowItemDeleteComponent], }) export class ThemedWorkflowItemDeleteComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts b/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts index 3d5fae9fe6..0352eba098 100644 --- a/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts @@ -26,7 +26,7 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { WorkflowItemActionPageDirective } from '../workflow-item-action-page.component'; @Component({ - selector: 'ds-workflow-item-delete', + selector: 'ds-base-workflow-item-delete', templateUrl: '../workflow-item-action-page.component.html', standalone: true, imports: [VarDirective, TranslateModule, CommonModule, ModifyItemOverviewComponent], diff --git a/src/app/workflowitems-edit-page/workflow-item-send-back/themed-workflow-item-send-back.component.ts b/src/app/workflowitems-edit-page/workflow-item-send-back/themed-workflow-item-send-back.component.ts index ecf7c965b6..72edd8147e 100644 --- a/src/app/workflowitems-edit-page/workflow-item-send-back/themed-workflow-item-send-back.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-send-back/themed-workflow-item-send-back.component.ts @@ -8,10 +8,11 @@ import { WorkflowItemSendBackComponent } from './workflow-item-send-back.compone */ @Component({ - selector: 'ds-themed-workflow-item-send-back', + selector: 'ds-workflow-item-send-back', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, + imports: [WorkflowItemSendBackComponent], }) export class ThemedWorkflowItemSendBackComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts b/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts index 797146e1f2..ad0b1d91a8 100644 --- a/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts @@ -22,7 +22,7 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { WorkflowItemActionPageDirective } from '../workflow-item-action-page.component'; @Component({ - selector: 'ds-workflow-item-send-back', + selector: 'ds-base-workflow-item-send-back', templateUrl: '../workflow-item-action-page.component.html', standalone: true, imports: [VarDirective, TranslateModule, CommonModule, ModifyItemOverviewComponent], diff --git a/src/app/workflowitems-edit-page/workflowitems-edit-page-routes.ts b/src/app/workflowitems-edit-page/workflowitems-edit-page-routes.ts index 95e1c69de8..4bc074c425 100644 --- a/src/app/workflowitems-edit-page/workflowitems-edit-page-routes.ts +++ b/src/app/workflowitems-edit-page/workflowitems-edit-page-routes.ts @@ -6,6 +6,7 @@ import { ThemedFullItemPageComponent } from '../item-page/full/themed-full-item- import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submission-edit.component'; import { AdvancedWorkflowActionPageComponent } from './advanced-workflow-action/advanced-workflow-action-page/advanced-workflow-action-page.component'; import { itemFromWorkflowResolver } from './item-from-workflow.resolver'; +import { ItemFromWorkflowBreadcrumbResolver } from './item-from-workflow-breadcrumb.resolver'; import { ThemedWorkflowItemDeleteComponent } from './workflow-item-delete/themed-workflow-item-delete.component'; import { workflowItemPageResolver } from './workflow-item-page.resolver'; import { ThemedWorkflowItemSendBackComponent } from './workflow-item-send-back/themed-workflow-item-send-back.component'; @@ -20,7 +21,10 @@ import { export const ROUTES: Routes = [ { path: ':id', - resolve: { wfi: workflowItemPageResolver }, + resolve: { + breadcrumb: ItemFromWorkflowBreadcrumbResolver, + wfi: workflowItemPageResolver, + }, children: [ { canActivate: [authenticatedGuard], diff --git a/src/app/workspaceitems-edit-page/item-from-workspace-breadcrumb.resolver.ts b/src/app/workspaceitems-edit-page/item-from-workspace-breadcrumb.resolver.ts new file mode 100644 index 0000000000..912d578b45 --- /dev/null +++ b/src/app/workspaceitems-edit-page/item-from-workspace-breadcrumb.resolver.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Resolve } from '@angular/router'; + +import { BreadcrumbConfig } from '../breadcrumbs/breadcrumb/breadcrumb-config.model'; +import { SubmissionObject } from '../core/submission/models/submission-object.model'; +import { SubmissionParentBreadcrumbResolver } from '../core/submission/resolver/submission-parent-breadcrumb.resolver'; +import { SubmissionParentBreadcrumbsService } from '../core/submission/submission-parent-breadcrumb.service'; +import { WorkspaceitemDataService } from '../core/submission/workspaceitem-data.service'; + +/** + * This class represents a resolver that retrieves the breadcrumbs of the workspace item + */ +@Injectable({ + providedIn: 'root', +}) +export class ItemFromWorkspaceBreadcrumbResolver extends SubmissionParentBreadcrumbResolver implements Resolve> { + + constructor( + protected dataService: WorkspaceitemDataService, + protected breadcrumbService: SubmissionParentBreadcrumbsService, + ) { + super(dataService, breadcrumbService); + } + +} diff --git a/src/app/workspaceitems-edit-page/workspaceitems-delete-page/themed-workspaceitems-delete-page.component.ts b/src/app/workspaceitems-edit-page/workspaceitems-delete-page/themed-workspaceitems-delete-page.component.ts index b335c1dbd0..6907f15af8 100644 --- a/src/app/workspaceitems-edit-page/workspaceitems-delete-page/themed-workspaceitems-delete-page.component.ts +++ b/src/app/workspaceitems-edit-page/workspaceitems-delete-page/themed-workspaceitems-delete-page.component.ts @@ -1,8 +1,5 @@ -import { CommonModule } from '@angular/common'; import { Component } from '@angular/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { ModifyItemOverviewComponent } from '../../item-page/edit-item-page/modify-item-overview/modify-item-overview.component'; import { ThemedComponent } from '../../shared/theme-support/themed.component'; import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page.component'; @@ -11,15 +8,11 @@ import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page. */ @Component({ - selector: 'ds-themed-workspace-items-delete', + selector: 'ds-workspace-items-delete', styleUrls: [], templateUrl: './../../shared/theme-support/themed.component.html', standalone: true, - imports: [ - ModifyItemOverviewComponent, - TranslateModule, - CommonModule, - ], + imports: [WorkspaceItemsDeletePageComponent], }) export class ThemedWorkspaceItemsDeletePageComponent extends ThemedComponent { protected getComponentName(): string { diff --git a/src/app/workspaceitems-edit-page/workspaceitems-delete-page/workspaceitems-delete-page.component.ts b/src/app/workspaceitems-edit-page/workspaceitems-delete-page/workspaceitems-delete-page.component.ts index ea3ee4ae42..00ab6e969c 100644 --- a/src/app/workspaceitems-edit-page/workspaceitems-delete-page/workspaceitems-delete-page.component.ts +++ b/src/app/workspaceitems-edit-page/workspaceitems-delete-page/workspaceitems-delete-page.component.ts @@ -38,7 +38,7 @@ import { ModifyItemOverviewComponent } from '../../item-page/edit-item-page/modi import { NotificationsService } from '../../shared/notifications/notifications.service'; @Component({ - selector: 'ds-workspaceitems-delete-page', + selector: 'ds-base-workspaceitems-delete-page', templateUrl: './workspaceitems-delete-page.component.html', styleUrls: ['./workspaceitems-delete-page.component.scss'], imports: [ diff --git a/src/app/workspaceitems-edit-page/workspaceitems-edit-page-routes.ts b/src/app/workspaceitems-edit-page/workspaceitems-edit-page-routes.ts index f648be0209..8f07c24edc 100644 --- a/src/app/workspaceitems-edit-page/workspaceitems-edit-page-routes.ts +++ b/src/app/workspaceitems-edit-page/workspaceitems-edit-page-routes.ts @@ -5,9 +5,9 @@ import { i18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso import { ThemedFullItemPageComponent } from '../item-page/full/themed-full-item-page.component'; import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submission-edit.component'; import { itemFromWorkspaceResolver } from './item-from-workspace.resolver'; +import { ItemFromWorkspaceBreadcrumbResolver } from './item-from-workspace-breadcrumb.resolver'; import { workspaceItemPageResolver } from './workspace-item-page.resolver'; import { ThemedWorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page/themed-workspaceitems-delete-page.component'; -import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page/workspaceitems-delete-page.component'; export const ROUTES: Route[] = [ { @@ -16,7 +16,10 @@ export const ROUTES: Route[] = [ }, { path: ':id', - resolve: { wsi: workspaceItemPageResolver }, + resolve: { + breadcrumb: ItemFromWorkspaceBreadcrumbResolver, + wsi: workspaceItemPageResolver, + }, children: [ { canActivate: [authenticatedGuard], @@ -40,7 +43,7 @@ export const ROUTES: Route[] = [ { canActivate: [authenticatedGuard], path: 'delete', - component: WorkspaceItemsDeletePageComponent, + component: ThemedWorkspaceItemsDeletePageComponent, resolve: { dso: itemFromWorkspaceResolver, breadcrumb: i18nBreadcrumbResolver, diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index d4731f9bb9..9cb33aca9a 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1108,6 +1108,8 @@ "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", + "collection.create.breadcrumbs": "Create collection", + "collection.browse.logo": "Browse for a collection logo", "collection.create.head": "Create a Collection", @@ -1398,6 +1400,8 @@ "community.subcoms-cols.breadcrumbs": "Subcommunities and Collections", + "community.create.breadcrumbs": "Create Community", + "community.create.head": "Create a Community", "community.create.notifications.success": "Successfully created the Community", diff --git a/src/robots.txt.ejs b/src/robots.txt.ejs index cd5e228b3a..f6dc7fa5cb 100644 --- a/src/robots.txt.ejs +++ b/src/robots.txt.ejs @@ -16,6 +16,8 @@ Disallow: /submit Disallow: /workspaceitems Disallow: /profile Disallow: /workflowitems +# Crawlers should be able to access entity pages, but not the facet search links present on entity pages +Disallow: /entities/*?f # Optionally uncomment the following line ONLY if sitemaps are working # and you have verified that your site is being indexed correctly. diff --git a/src/themes/custom/app/admin/admin-sidebar/admin-sidebar.component.ts b/src/themes/custom/app/admin/admin-sidebar/admin-sidebar.component.ts index dfaf4cad5b..2d61561611 100644 --- a/src/themes/custom/app/admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/themes/custom/app/admin/admin-sidebar/admin-sidebar.component.ts @@ -15,7 +15,7 @@ import { AdminSidebarComponent as BaseComponent } from '../../../../../app/admin * Component representing the admin sidebar */ @Component({ - selector: 'ds-admin-sidebar', + selector: 'ds-themed-admin-sidebar', // templateUrl: './admin-sidebar.component.html', templateUrl: '../../../../../app/admin/admin-sidebar/admin-sidebar.component.html', // styleUrls: ['./admin-sidebar.component.scss'] diff --git a/src/themes/custom/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/themes/custom/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index 00c02fb728..1fc23a1bd0 100644 --- a/src/themes/custom/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/themes/custom/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -18,7 +18,7 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; import { ThemedThumbnailComponent } from '../../../../../app/thumbnail/themed-thumbnail.component'; @Component({ - selector: 'ds-edit-bitstream-page', + selector: 'ds-themed-edit-bitstream-page', // styleUrls: ['./edit-bitstream-page.component.scss'], styleUrls: ['../../../../../app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.scss'], // templateUrl: './edit-bitstream-page.component.html', diff --git a/src/themes/custom/app/breadcrumbs/breadcrumbs.component.ts b/src/themes/custom/app/breadcrumbs/breadcrumbs.component.ts index 93fcfa36c8..c71caf9f02 100644 --- a/src/themes/custom/app/breadcrumbs/breadcrumbs.component.ts +++ b/src/themes/custom/app/breadcrumbs/breadcrumbs.component.ts @@ -16,7 +16,7 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive'; * Component representing the breadcrumbs of a page */ @Component({ - selector: 'ds-breadcrumbs', + selector: 'ds-themed-breadcrumbs', // templateUrl: './breadcrumbs.component.html', templateUrl: '../../../../app/breadcrumbs/breadcrumbs.component.html', // styleUrls: ['./breadcrumbs.component.scss'] diff --git a/src/themes/custom/app/browse-by/browse-by-date/browse-by-date.component.ts b/src/themes/custom/app/browse-by/browse-by-date/browse-by-date.component.ts index 128e059fd3..3621a04a07 100644 --- a/src/themes/custom/app/browse-by/browse-by-date/browse-by-date.component.ts +++ b/src/themes/custom/app/browse-by/browse-by-date/browse-by-date.component.ts @@ -6,7 +6,6 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { BrowseByDateComponent as BaseComponent } from '../../../../../app/browse-by/browse-by-date/browse-by-date.component'; -import { BrowseByComponent } from '../../../../../app/shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../../../../app/shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../../../../app/shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -34,7 +33,6 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/themes/custom/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts b/src/themes/custom/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts index c1d5e66583..a5d611e452 100644 --- a/src/themes/custom/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts +++ b/src/themes/custom/app/browse-by/browse-by-metadata/browse-by-metadata.component.ts @@ -6,7 +6,6 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { BrowseByMetadataComponent as BaseComponent } from '../../../../../app/browse-by/browse-by-metadata/browse-by-metadata.component'; -import { BrowseByComponent } from '../../../../../app/shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../../../../app/shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../../../../app/shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -34,7 +33,6 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/themes/custom/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts b/src/themes/custom/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts index 80190b92cf..2d97ef0602 100644 --- a/src/themes/custom/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts +++ b/src/themes/custom/app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component.ts @@ -3,11 +3,10 @@ import { NgIf, } from '@angular/common'; import { Component } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { RouterLink } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { BrowseByTaxonomyComponent as BaseComponent } from '../../../../../app/browse-by/browse-by-taxonomy/browse-by-taxonomy.component'; -import { BrowseByComponent } from '../../../../../app/shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../../../../app/shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../../../../app/shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -32,16 +31,15 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; ComcolPageHeaderComponent, ComcolPageLogoComponent, NgIf, - RouterModule, ThemedComcolPageHandleComponent, ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - VocabularyTreeviewComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, + VocabularyTreeviewComponent, + RouterLink, ], }) export class BrowseByTaxonomyComponent extends BaseComponent { diff --git a/src/themes/custom/app/browse-by/browse-by-title/browse-by-title.component.ts b/src/themes/custom/app/browse-by/browse-by-title/browse-by-title.component.ts index 84b8d4bc36..16e5234c38 100644 --- a/src/themes/custom/app/browse-by/browse-by-title/browse-by-title.component.ts +++ b/src/themes/custom/app/browse-by/browse-by-title/browse-by-title.component.ts @@ -6,7 +6,6 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { BrowseByTitleComponent as BaseComponent } from '../../../../../app/browse-by/browse-by-title/browse-by-title.component'; -import { BrowseByComponent } from '../../../../../app/shared/browse-by/browse-by.component'; import { ThemedBrowseByComponent } from '../../../../../app/shared/browse-by/themed-browse-by.component'; import { ThemedComcolPageBrowseByComponent } from '../../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ComcolPageContentComponent } from '../../../../../app/shared/comcol/comcol-page-content/comcol-page-content.component'; @@ -34,7 +33,6 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; ComcolPageContentComponent, DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, - BrowseByComponent, TranslateModule, ThemedLoadingComponent, ThemedBrowseByComponent, diff --git a/src/themes/custom/app/collection-page/collection-page.component.ts b/src/themes/custom/app/collection-page/collection-page.component.ts index 40360833e9..4023e8479e 100644 --- a/src/themes/custom/app/collection-page/collection-page.component.ts +++ b/src/themes/custom/app/collection-page/collection-page.component.ts @@ -28,7 +28,7 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp @Component({ - selector: 'ds-collection-page', + selector: 'ds-themed-collection-page', // templateUrl: './collection-page.component.html', templateUrl: '../../../../app/collection-page/collection-page.component.html', // styleUrls: ['./collection-page.component.scss'] @@ -43,7 +43,6 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp ComcolPageContentComponent, ErrorComponent, NgIf, - RouterOutlet, ThemedLoadingComponent, TranslateModule, ViewTrackerComponent, @@ -55,6 +54,7 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp DsoEditMenuComponent, ThemedComcolPageBrowseByComponent, ObjectCollectionComponent, + RouterOutlet, ], }) /** diff --git a/src/themes/custom/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts b/src/themes/custom/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts index 9ca52219e5..f69fcc868c 100644 --- a/src/themes/custom/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts +++ b/src/themes/custom/app/collection-page/edit-item-template-page/edit-item-template-page.component.ts @@ -13,7 +13,7 @@ import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed import { VarDirective } from '../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-edit-item-template-page', + selector: 'ds-themed-edit-item-template-page', styleUrls: ['./edit-item-template-page.component.scss'], // templateUrl: './edit-item-template-page.component.html', templateUrl: '../../../../../app/collection-page/edit-item-template-page/edit-item-template-page.component.html', diff --git a/src/themes/custom/app/community-list-page/community-list-page.component.ts b/src/themes/custom/app/community-list-page/community-list-page.component.ts index 621a58d698..571964d5de 100644 --- a/src/themes/custom/app/community-list-page/community-list-page.component.ts +++ b/src/themes/custom/app/community-list-page/community-list-page.component.ts @@ -5,7 +5,7 @@ import { ThemedCommunityListComponent } from '../../../../app/community-list-pag import { CommunityListPageComponent as BaseComponent } from '../../../../app/community-list-page/community-list-page.component'; @Component({ - selector: 'ds-community-list-page', + selector: 'ds-themed-community-list-page', // styleUrls: ['./community-list-page.component.scss'], // templateUrl: './community-list-page.component.html' templateUrl: '../../../../app/community-list-page/community-list-page.component.html', diff --git a/src/themes/custom/app/community-list-page/community-list/community-list.component.ts b/src/themes/custom/app/community-list-page/community-list/community-list.component.ts index 334c8bc4ed..8a48901634 100644 --- a/src/themes/custom/app/community-list-page/community-list/community-list.component.ts +++ b/src/themes/custom/app/community-list-page/community-list/community-list.component.ts @@ -21,7 +21,7 @@ import { TruncatablePartComponent } from '../../../../../app/shared/truncatable/ * Which nodes were expanded is kept in the store, so this persists across pages. */ @Component({ - selector: 'ds-community-list', + selector: 'ds-themed-community-list', // styleUrls: ['./community-list.component.scss'], // templateUrl: './community-list.component.html' templateUrl: '../../../../../app/community-list-page/community-list/community-list.component.html', diff --git a/src/themes/custom/app/community-page/community-page.component.ts b/src/themes/custom/app/community-page/community-page.component.ts index fb421c605f..56cd54c5c3 100644 --- a/src/themes/custom/app/community-page/community-page.component.ts +++ b/src/themes/custom/app/community-page/community-page.component.ts @@ -6,7 +6,10 @@ import { ChangeDetectionStrategy, Component, } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { + RouterModule, + RouterOutlet, +} from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { CommunityPageComponent as BaseComponent } from '../../../../app/community-page/community-page.component'; @@ -26,7 +29,7 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp @Component({ - selector: 'ds-community-page', + selector: 'ds-themed-community-page', // templateUrl: './community-page.component.html', templateUrl: '../../../../app/community-page/community-page.component.html', // styleUrls: ['./community-page.component.scss'] @@ -50,6 +53,7 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp AsyncPipe, ViewTrackerComponent, VarDirective, + RouterOutlet, RouterModule, ], }) diff --git a/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts b/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts index 8ebe26fd44..6160a2d451 100644 --- a/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts +++ b/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.ts @@ -1,13 +1,31 @@ +import { + AsyncPipe, + NgIf, +} from '@angular/common'; import { Component } from '@angular/core'; +import { TranslateModule } from '@ngx-translate/core'; import { CommunityPageSubCollectionListComponent as BaseComponent } from '../../../../../../../app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component'; +import { ErrorComponent } from '../../../../../../../app/shared/error/error.component'; +import { ThemedLoadingComponent } from '../../../../../../../app/shared/loading/themed-loading.component'; +import { ObjectCollectionComponent } from '../../../../../../../app/shared/object-collection/object-collection.component'; +import { VarDirective } from '../../../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-community-page-sub-collection-list', + selector: 'ds-themed-community-page-sub-collection-list', // styleUrls: ['./community-page-sub-collection-list.component.scss'], styleUrls: ['../../../../../app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.scss'], // templateUrl: './community-page-sub-collection-list.component.html', templateUrl: '../../../../../app/community-page/sections/sub-com-col-section/sub-collection-list/community-page-sub-collection-list.component.html', + imports: [ + ObjectCollectionComponent, + ErrorComponent, + ThemedLoadingComponent, + NgIf, + TranslateModule, + AsyncPipe, + VarDirective, + ], standalone: true, }) export class CommunityPageSubCollectionListComponent extends BaseComponent { diff --git a/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts b/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts index dda061deab..3b48efcb0e 100644 --- a/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts +++ b/src/themes/custom/app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.ts @@ -12,7 +12,7 @@ import { ObjectCollectionComponent } from '../../../../../../../app/shared/objec import { VarDirective } from '../../../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-community-page-sub-community-list', + selector: 'ds-themed-community-page-sub-community-list', // styleUrls: ['./community-page-sub-community-list.component.scss'], styleUrls: ['../../../../../../../app/community-page/sections/sub-com-col-section/sub-community-list/community-page-sub-community-list.component.scss'], // templateUrl: './community-page-sub-community-list.component.html', diff --git a/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts b/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts index 3dcec71730..a7437c0408 100644 --- a/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts +++ b/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts @@ -13,16 +13,16 @@ import { DsoEditMetadataValueComponent } from '../../../../../app/dso-shared/dso import { DsoEditMetadataValueHeadersComponent } from '../../../../../app/dso-shared/dso-edit-metadata/dso-edit-metadata-value-headers/dso-edit-metadata-value-headers.component'; import { MetadataFieldSelectorComponent } from '../../../../../app/dso-shared/dso-edit-metadata/metadata-field-selector/metadata-field-selector.component'; import { AlertComponent } from '../../../../../app/shared/alert/alert.component'; -import { LoadingComponent } from '../../../../../app/shared/loading/loading.component'; +import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component'; @Component({ - selector: 'ds-dso-edit-metadata', + selector: 'ds-themed-dso-edit-metadata', // styleUrls: ['./dso-edit-metadata.component.scss'], styleUrls: ['../../../../../app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.scss'], // templateUrl: './dso-edit-metadata.component.html', templateUrl: '../../../../../app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html', standalone: true, - imports: [NgIf, DsoEditMetadataHeadersComponent, MetadataFieldSelectorComponent, DsoEditMetadataValueHeadersComponent, DsoEditMetadataValueComponent, NgFor, DsoEditMetadataFieldValuesComponent, AlertComponent, LoadingComponent, AsyncPipe, TranslateModule], + imports: [NgIf, DsoEditMetadataHeadersComponent, MetadataFieldSelectorComponent, DsoEditMetadataValueHeadersComponent, DsoEditMetadataValueComponent, NgFor, DsoEditMetadataFieldValuesComponent, AlertComponent, ThemedLoadingComponent, AsyncPipe, TranslateModule], }) export class DsoEditMetadataComponent extends BaseComponent { } diff --git a/src/themes/custom/app/footer/footer.component.ts b/src/themes/custom/app/footer/footer.component.ts index 2378d31016..a2e782a0db 100644 --- a/src/themes/custom/app/footer/footer.component.ts +++ b/src/themes/custom/app/footer/footer.component.ts @@ -10,7 +10,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { FooterComponent as BaseComponent } from '../../../../app/footer/footer.component'; @Component({ - selector: 'ds-footer', + selector: 'ds-themed-footer', // styleUrls: ['./footer.component.scss'], styleUrls: ['../../../../app/footer/footer.component.scss'], // templateUrl: './footer.component.html' diff --git a/src/themes/custom/app/forbidden/forbidden.component.ts b/src/themes/custom/app/forbidden/forbidden.component.ts index 2377b71249..58c32581c1 100644 --- a/src/themes/custom/app/forbidden/forbidden.component.ts +++ b/src/themes/custom/app/forbidden/forbidden.component.ts @@ -6,7 +6,7 @@ import { ForbiddenComponent as BaseComponent } from '../../../../app/forbidden/f @Component({ - selector: 'ds-forbidden', + selector: 'ds-themed-forbidden', // templateUrl: './forbidden.component.html', templateUrl: '../../../../app/forbidden/forbidden.component.html', // styleUrls: ['./forbidden.component.scss'] diff --git a/src/themes/custom/app/forgot-password/forgot-password-email/forgot-email.component.ts b/src/themes/custom/app/forgot-password/forgot-password-email/forgot-email.component.ts index 954d3a3419..ac334902a3 100644 --- a/src/themes/custom/app/forgot-password/forgot-password-email/forgot-email.component.ts +++ b/src/themes/custom/app/forgot-password/forgot-password-email/forgot-email.component.ts @@ -2,17 +2,15 @@ import { Component } from '@angular/core'; import { ThemedRegisterEmailFormComponent } from 'src/app/register-email-form/themed-registry-email-form.component'; import { ForgotEmailComponent as BaseComponent } from '../../../../../app/forgot-password/forgot-password-email/forgot-email.component'; -import { RegisterEmailFormComponent } from '../../../../../app/register-email-form/register-email-form.component'; @Component({ - selector: 'ds-forgot-email', + selector: 'ds-themed-forgot-email', // styleUrls: ['./forgot-email.component.scss'], styleUrls: ['../../../../../app/forgot-password/forgot-password-email/forgot-email.component.scss'], // templateUrl: './forgot-email.component.html' templateUrl: '../../../../../app/forgot-password/forgot-password-email/forgot-email.component.html', standalone: true, imports: [ - RegisterEmailFormComponent, ThemedRegisterEmailFormComponent, ], }) diff --git a/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts b/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts index 52c0cb565d..9656e7b85c 100644 --- a/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts +++ b/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts @@ -10,7 +10,7 @@ import { ProfilePageSecurityFormComponent } from '../../../../../app/profile-pag import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pipe'; @Component({ - selector: 'ds-forgot-password-form', + selector: 'ds-themed-forgot-password-form', // styleUrls: ['./forgot-password-form.component.scss'], styleUrls: ['../../../../../app/forgot-password/forgot-password-form/forgot-password-form.component.scss'], // templateUrl: './forgot-password-form.component.html' @@ -18,8 +18,8 @@ import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pi standalone: true, imports: [ TranslateModule, - ProfilePageSecurityFormComponent, BrowserOnlyPipe, + ProfilePageSecurityFormComponent, AsyncPipe, NgIf, ], diff --git a/src/themes/custom/app/header-nav-wrapper/header-navbar-wrapper.component.ts b/src/themes/custom/app/header-nav-wrapper/header-navbar-wrapper.component.ts index 28b8f54fc4..ac1ac94140 100644 --- a/src/themes/custom/app/header-nav-wrapper/header-navbar-wrapper.component.ts +++ b/src/themes/custom/app/header-nav-wrapper/header-navbar-wrapper.component.ts @@ -12,7 +12,7 @@ import { ThemedNavbarComponent } from '../../../../app/navbar/themed-navbar.comp * This component represents a wrapper for the horizontal navbar and the header */ @Component({ - selector: 'ds-header-navbar-wrapper', + selector: 'ds-themed-header-navbar-wrapper', // styleUrls: ['./header-navbar-wrapper.component.scss'], styleUrls: ['../../../../app/header-nav-wrapper/header-navbar-wrapper.component.scss'], // templateUrl: './header-navbar-wrapper.component.html', diff --git a/src/themes/custom/app/header/header.component.ts b/src/themes/custom/app/header/header.component.ts index fbfe8d5a84..f6ae52de4f 100644 --- a/src/themes/custom/app/header/header.component.ts +++ b/src/themes/custom/app/header/header.component.ts @@ -1,3 +1,7 @@ +import { + AsyncPipe, + NgIf, +} from '@angular/common'; import { Component } from '@angular/core'; import { RouterLink } from '@angular/router'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; @@ -9,19 +13,18 @@ import { HeaderComponent as BaseComponent } from '../../../../app/header/header. import { ThemedSearchNavbarComponent } from '../../../../app/search-navbar/themed-search-navbar.component'; import { ThemedAuthNavMenuComponent } from '../../../../app/shared/auth-nav-menu/themed-auth-nav-menu.component'; import { ImpersonateNavbarComponent } from '../../../../app/shared/impersonate-navbar/impersonate-navbar.component'; -import { LangSwitchComponent } from '../../../../app/shared/lang-switch/lang-switch.component'; /** * Represents the header with the logo and simple navigation */ @Component({ - selector: 'ds-header', + selector: 'ds-themed-header', // styleUrls: ['header.component.scss'], styleUrls: ['../../../../app/header/header.component.scss'], // templateUrl: 'header.component.html', templateUrl: '../../../../app/header/header.component.html', standalone: true, - imports: [RouterLink, ThemedLangSwitchComponent, NgbDropdownModule, ThemedSearchNavbarComponent, LangSwitchComponent, ContextHelpToggleComponent, ThemedAuthNavMenuComponent, ImpersonateNavbarComponent, TranslateModule], + imports: [RouterLink, ThemedLangSwitchComponent, NgbDropdownModule, ThemedSearchNavbarComponent, ContextHelpToggleComponent, ThemedAuthNavMenuComponent, ImpersonateNavbarComponent, TranslateModule, AsyncPipe, NgIf], }) export class HeaderComponent extends BaseComponent { } diff --git a/src/themes/custom/app/home-page/home-news/home-news.component.ts b/src/themes/custom/app/home-page/home-news/home-news.component.ts index cc2efa0429..9827589e8b 100644 --- a/src/themes/custom/app/home-page/home-news/home-news.component.ts +++ b/src/themes/custom/app/home-page/home-news/home-news.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { HomeNewsComponent as BaseComponent } from '../../../../../app/home-page/home-news/home-news.component'; @Component({ - selector: 'ds-home-news', + selector: 'ds-themed-home-news', // styleUrls: ['./home-news.component.scss'], styleUrls: ['../../../../../app/home-page/home-news/home-news.component.scss'], // templateUrl: './home-news.component.html' diff --git a/src/themes/custom/app/home-page/home-page.component.ts b/src/themes/custom/app/home-page/home-page.component.ts index 53ccbf4526..2b45f69754 100644 --- a/src/themes/custom/app/home-page/home-page.component.ts +++ b/src/themes/custom/app/home-page/home-page.component.ts @@ -2,6 +2,7 @@ import { AsyncPipe, NgClass, NgIf, + NgTemplateOutlet, } from '@angular/common'; import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; @@ -12,20 +13,19 @@ import { HomePageComponent as BaseComponent } from '../../../../app/home-page/ho import { RecentItemListComponent } from '../../../../app/home-page/recent-item-list/recent-item-list.component'; import { ThemedTopLevelCommunityListComponent } from '../../../../app/home-page/top-level-community-list/themed-top-level-community-list.component'; import { SuggestionsPopupComponent } from '../../../../app/notifications/suggestions-popup/suggestions-popup.component'; -import { ConfigurationSearchPageComponent } from '../../../../app/search-page/configuration-search-page.component'; import { ThemedConfigurationSearchPageComponent } from '../../../../app/search-page/themed-configuration-search-page.component'; import { ThemedSearchFormComponent } from '../../../../app/shared/search-form/themed-search-form.component'; import { PageWithSidebarComponent } from '../../../../app/shared/sidebar/page-with-sidebar.component'; import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dspace/view-tracker.component'; @Component({ - selector: 'ds-home-page', + selector: 'ds-themed-home-page', // styleUrls: ['./home-page.component.scss'], styleUrls: ['../../../../app/home-page/home-page.component.scss'], // templateUrl: './home-page.component.html' templateUrl: '../../../../app/home-page/home-page.component.html', standalone: true, - imports: [ThemedHomeNewsComponent, NgIf, ViewTrackerComponent, ThemedSearchFormComponent, ThemedTopLevelCommunityListComponent, RecentItemListComponent, AsyncPipe, TranslateModule, NgClass, ConfigurationSearchPageComponent, SuggestionsPopupComponent, ThemedConfigurationSearchPageComponent, PageWithSidebarComponent, HomeCoarComponent], + imports: [ThemedHomeNewsComponent, NgTemplateOutlet, NgIf, ViewTrackerComponent, ThemedSearchFormComponent, ThemedTopLevelCommunityListComponent, RecentItemListComponent, AsyncPipe, TranslateModule, NgClass, SuggestionsPopupComponent, ThemedConfigurationSearchPageComponent, PageWithSidebarComponent, HomeCoarComponent], }) export class HomePageComponent extends BaseComponent { diff --git a/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts b/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts index 532c6f8064..0613377e14 100644 --- a/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts +++ b/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts @@ -12,7 +12,7 @@ import { ObjectCollectionComponent } from '../../../../../app/shared/object-coll import { VarDirective } from '../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-top-level-community-list', + selector: 'ds-themed-top-level-community-list', // styleUrls: ['./top-level-community-list.component.scss'], styleUrls: ['../../../../../app/home-page/top-level-community-list/top-level-community-list.component.scss'], // templateUrl: './top-level-community-list.component.html' diff --git a/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts b/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts index e884972bbd..05f2252216 100644 --- a/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts +++ b/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts @@ -6,7 +6,7 @@ import { EndUserAgreementComponent as BaseComponent } from '../../../../../app/i import { EndUserAgreementContentComponent } from '../../../../../app/info/end-user-agreement/end-user-agreement-content/end-user-agreement-content.component'; @Component({ - selector: 'ds-end-user-agreement', + selector: 'ds-themed-end-user-agreement', // styleUrls: ['./end-user-agreement.component.scss'], styleUrls: ['../../../../../app/info/end-user-agreement/end-user-agreement.component.scss'], // templateUrl: './end-user-agreement.component.html' diff --git a/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts b/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts index bd0f55f153..b3cd90e73e 100644 --- a/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts +++ b/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts @@ -10,7 +10,7 @@ import { FeedbackFormComponent as BaseComponent } from '../../../../../../app/in import { ErrorComponent } from '../../../../../../app/shared/error/error.component'; @Component({ - selector: 'ds-feedback-form', + selector: 'ds-themed-feedback-form', // templateUrl: './feedback-form.component.html', templateUrl: '../../../../../../app/info/feedback/feedback-form/feedback-form.component.html', // styleUrls: ['./feedback-form.component.scss'], diff --git a/src/themes/custom/app/info/feedback/feedback.component.ts b/src/themes/custom/app/info/feedback/feedback.component.ts index 01d377e616..e31cfd46cf 100644 --- a/src/themes/custom/app/info/feedback/feedback.component.ts +++ b/src/themes/custom/app/info/feedback/feedback.component.ts @@ -4,7 +4,7 @@ import { FeedbackComponent as BaseComponent } from '../../../../../app/info/feed import { ThemedFeedbackFormComponent } from '../../../../../app/info/feedback/feedback-form/themed-feedback-form.component'; @Component({ - selector: 'ds-feedback', + selector: 'ds-themed-feedback', // styleUrls: ['./feedback.component.scss'], styleUrls: ['../../../../../app/info/feedback/feedback.component.scss'], // templateUrl: './feedback.component.html' diff --git a/src/themes/custom/app/info/privacy/privacy.component.ts b/src/themes/custom/app/info/privacy/privacy.component.ts index c9632c1ee8..463a89a092 100644 --- a/src/themes/custom/app/info/privacy/privacy.component.ts +++ b/src/themes/custom/app/info/privacy/privacy.component.ts @@ -4,7 +4,7 @@ import { PrivacyComponent as BaseComponent } from '../../../../../app/info/priva import { PrivacyContentComponent } from '../../../../../app/info/privacy/privacy-content/privacy-content.component'; @Component({ - selector: 'ds-privacy', + selector: 'ds-themed-privacy', // styleUrls: ['./privacy.component.scss'], styleUrls: ['../../../../../app/info/privacy/privacy.component.scss'], // templateUrl: './privacy.component.html' diff --git a/src/themes/custom/app/item-page/alerts/item-alerts.component.ts b/src/themes/custom/app/item-page/alerts/item-alerts.component.ts index 494013369c..4cfa632f02 100644 --- a/src/themes/custom/app/item-page/alerts/item-alerts.component.ts +++ b/src/themes/custom/app/item-page/alerts/item-alerts.component.ts @@ -10,7 +10,7 @@ import { ItemAlertsComponent as BaseComponent } from '../../../../../app/item-pa import { AlertComponent } from '../../../../../app/shared/alert/alert.component'; @Component({ - selector: 'ds-item-alerts', + selector: 'ds-themed-item-alerts', // templateUrl: './item-alerts.component.html', templateUrl: '../../../../../app/item-page/alerts/item-alerts.component.html', // styleUrls: ['./item-alerts.component.scss'], diff --git a/src/themes/custom/app/item-page/edit-item-page/item-status/item-status.component.ts b/src/themes/custom/app/item-page/edit-item-page/item-status/item-status.component.ts index 0f358fac4b..a39d2e4cda 100644 --- a/src/themes/custom/app/item-page/edit-item-page/item-status/item-status.component.ts +++ b/src/themes/custom/app/item-page/edit-item-page/item-status/item-status.component.ts @@ -19,7 +19,7 @@ import { } from '../../../../../../app/shared/animations/fade'; @Component({ - selector: 'ds-item-status', + selector: 'ds-themed-item-status', // templateUrl: './item-status.component.html', templateUrl: '../../../../../../app/item-page/edit-item-page/item-status/item-status.component.html', changeDetection: ChangeDetectionStrategy.Default, diff --git a/src/themes/custom/app/item-page/full/field-components/file-section/full-file-section.component.ts b/src/themes/custom/app/item-page/full/field-components/file-section/full-file-section.component.ts index 72aa62c36a..1475cd04ee 100644 --- a/src/themes/custom/app/item-page/full/field-components/file-section/full-file-section.component.ts +++ b/src/themes/custom/app/item-page/full/field-components/file-section/full-file-section.component.ts @@ -15,7 +15,7 @@ import { VarDirective } from '../../../../../../../app/shared/utils/var.directiv import { ThemedThumbnailComponent } from '../../../../../../../app/thumbnail/themed-thumbnail.component'; @Component({ - selector: 'ds-item-page-full-file-section', + selector: 'ds-themed-item-page-full-file-section', // styleUrls: ['./full-file-section.component.scss'], styleUrls: ['../../../../../../../app/item-page/full/field-components/file-section/full-file-section.component.scss'], // templateUrl: './full-file-section.component.html', diff --git a/src/themes/custom/app/item-page/full/full-item-page.component.ts b/src/themes/custom/app/item-page/full/full-item-page.component.ts index 7f9caa1e05..c1bad7ba89 100644 --- a/src/themes/custom/app/item-page/full/full-item-page.component.ts +++ b/src/themes/custom/app/item-page/full/full-item-page.component.ts @@ -31,7 +31,7 @@ import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/ */ @Component({ - selector: 'ds-full-item-page', + selector: 'ds-themed-full-item-page', // styleUrls: ['./full-item-page.component.scss'], styleUrls: ['../../../../../app/item-page/full/full-item-page.component.scss'], // templateUrl: './full-item-page.component.html', diff --git a/src/themes/custom/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts b/src/themes/custom/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts index fe68a94ea6..da2f62eb9b 100644 --- a/src/themes/custom/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts +++ b/src/themes/custom/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts @@ -5,7 +5,7 @@ import { NgxGalleryModule } from '@kolkov/ngx-gallery'; import { MediaViewerImageComponent as BaseComponent } from '../../../../../../app/item-page/media-viewer/media-viewer-image/media-viewer-image.component'; @Component({ - selector: 'ds-media-viewer-image', + selector: 'ds-themed-media-viewer-image', // templateUrl: './media-viewer-image.component.html', templateUrl: '../../../../../../app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.html', // styleUrls: ['./media-viewer-image.component.scss'], diff --git a/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts b/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts index 6a1778b5f5..5c6c7f3507 100644 --- a/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts +++ b/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts @@ -9,7 +9,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { MediaViewerVideoComponent as BaseComponent } from '../../../../../../app/item-page/media-viewer/media-viewer-video/media-viewer-video.component'; @Component({ - selector: 'ds-media-viewer-video', + selector: 'ds-themed-media-viewer-video', // templateUrl: './media-viewer-video.component.html', templateUrl: '../../../../../../app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html', // styleUrls: ['./media-viewer-video.component.scss'], diff --git a/src/themes/custom/app/item-page/media-viewer/media-viewer.component.ts b/src/themes/custom/app/item-page/media-viewer/media-viewer.component.ts index fcceeaf352..35336e6086 100644 --- a/src/themes/custom/app/item-page/media-viewer/media-viewer.component.ts +++ b/src/themes/custom/app/item-page/media-viewer/media-viewer.component.ts @@ -10,10 +10,10 @@ import { ThemedMediaViewerImageComponent } from '../../../../../app/item-page/me import { ThemedMediaViewerVideoComponent } from '../../../../../app/item-page/media-viewer/media-viewer-video/themed-media-viewer-video.component'; import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component'; import { VarDirective } from '../../../../../app/shared/utils/var.directive'; -import { ThumbnailComponent } from '../../../../../app/thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../app/thumbnail/themed-thumbnail.component'; @Component({ - selector: 'ds-media-viewer', + selector: 'ds-themed-media-viewer', // templateUrl: './media-viewer.component.html', templateUrl: '../../../../../app/item-page/media-viewer/media-viewer.component.html', // styleUrls: ['./media-viewer.component.scss'], @@ -21,7 +21,7 @@ import { ThumbnailComponent } from '../../../../../app/thumbnail/thumbnail.compo standalone: true, imports: [ ThemedMediaViewerImageComponent, - ThumbnailComponent, + ThemedThumbnailComponent, AsyncPipe, NgIf, ThemedMediaViewerVideoComponent, diff --git a/src/themes/custom/app/item-page/simple/field-components/file-section/file-section.component.ts b/src/themes/custom/app/item-page/simple/field-components/file-section/file-section.component.ts index 10559cfb7f..e39f7536eb 100644 --- a/src/themes/custom/app/item-page/simple/field-components/file-section/file-section.component.ts +++ b/src/themes/custom/app/item-page/simple/field-components/file-section/file-section.component.ts @@ -11,7 +11,7 @@ import { FileSizePipe } from '../../../../../../../app/shared/utils/file-size-pi import { VarDirective } from '../../../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-item-page-file-section', + selector: 'ds-themed-item-page-file-section', // templateUrl: './file-section.component.html', templateUrl: '../../../../../../../app/item-page/simple/field-components/file-section/file-section.component.html', animations: [slideSidebarPadding], diff --git a/src/themes/custom/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts b/src/themes/custom/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts index 65d69b4f52..4b0bfa4c91 100644 --- a/src/themes/custom/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts +++ b/src/themes/custom/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts @@ -5,7 +5,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { ItemPageTitleFieldComponent as BaseComponent } from '../../../../../../../../app/item-page/simple/field-components/specific-field/title/item-page-title-field.component'; @Component({ - selector: 'ds-item-page-title-field', + selector: 'ds-themed-item-page-title-field', // templateUrl: './item-page-title-field.component.html', templateUrl: '../../../../../../../../app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.html', standalone: true, diff --git a/src/themes/custom/app/item-page/simple/item-page.component.ts b/src/themes/custom/app/item-page/simple/item-page.component.ts index 58c8583015..7daa65287a 100644 --- a/src/themes/custom/app/item-page/simple/item-page.component.ts +++ b/src/themes/custom/app/item-page/simple/item-page.component.ts @@ -27,7 +27,7 @@ import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/ * All fields of the item that should be displayed, are defined in its template. */ @Component({ - selector: 'ds-item-page', + selector: 'ds-themed-item-page', // styleUrls: ['./item-page.component.scss'], styleUrls: ['../../../../../app/item-page/simple/item-page.component.scss'], // templateUrl: './item-page.component.html', @@ -44,11 +44,11 @@ import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/ ItemVersionsComponent, ErrorComponent, ThemedLoadingComponent, - NotifyRequestsStatusComponent, - QaEventNotificationComponent, TranslateModule, AsyncPipe, NgIf, + NotifyRequestsStatusComponent, + QaEventNotificationComponent, ], }) export class ItemPageComponent extends BaseComponent { diff --git a/src/themes/custom/app/item-page/simple/item-types/publication/publication.component.ts b/src/themes/custom/app/item-page/simple/item-types/publication/publication.component.ts index e558cc6e42..ce56724e4a 100644 --- a/src/themes/custom/app/item-page/simple/item-types/publication/publication.component.ts +++ b/src/themes/custom/app/item-page/simple/item-types/publication/publication.component.ts @@ -1,4 +1,7 @@ -import { CommonModule } from '@angular/common'; +import { + AsyncPipe, + NgIf, +} from '@angular/common'; import { ChangeDetectionStrategy, Component, @@ -39,26 +42,7 @@ import { ThemedThumbnailComponent } from '../../../../../../../app/thumbnail/the templateUrl: '../../../../../../../app/item-page/simple/item-types/publication/publication.component.html', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [ - CommonModule, - ThemedResultsBackButtonComponent, - MiradorViewerComponent, - ThemedItemPageTitleFieldComponent, - DsoEditMenuComponent, - MetadataFieldWrapperComponent, - ThemedThumbnailComponent, - ThemedMediaViewerComponent, - ThemedFileSectionComponent, - ItemPageDateFieldComponent, - ThemedMetadataRepresentationListComponent, - GenericItemPageFieldComponent, - RelatedItemsComponent, - ItemPageAbstractFieldComponent, - TranslateModule, - ItemPageUriFieldComponent, - CollectionsComponent, - RouterLink, - ], + imports: [NgIf, ThemedResultsBackButtonComponent, MiradorViewerComponent, ThemedItemPageTitleFieldComponent, DsoEditMenuComponent, MetadataFieldWrapperComponent, ThemedThumbnailComponent, ThemedMediaViewerComponent, ThemedFileSectionComponent, ItemPageDateFieldComponent, ThemedMetadataRepresentationListComponent, GenericItemPageFieldComponent, RelatedItemsComponent, ItemPageAbstractFieldComponent, ItemPageUriFieldComponent, CollectionsComponent, RouterLink, AsyncPipe, TranslateModule], }) export class PublicationComponent extends BaseComponent { diff --git a/src/themes/custom/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts b/src/themes/custom/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts index d9b5fabc0f..aeae9a519a 100644 --- a/src/themes/custom/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts +++ b/src/themes/custom/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts @@ -1,4 +1,7 @@ -import { CommonModule } from '@angular/common'; +import { + AsyncPipe, + NgIf, +} from '@angular/common'; import { ChangeDetectionStrategy, Component, @@ -38,25 +41,7 @@ import { ThemedThumbnailComponent } from '../../../../../../../app/thumbnail/the templateUrl: '../../../../../../../app/item-page/simple/item-types/untyped-item/untyped-item.component.html', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [ - CommonModule, - ThemedItemPageTitleFieldComponent, - DsoEditMenuComponent, - MetadataFieldWrapperComponent, - ThemedThumbnailComponent, - ThemedMediaViewerComponent, - ThemedFileSectionComponent, - ItemPageDateFieldComponent, - ThemedMetadataRepresentationListComponent, - GenericItemPageFieldComponent, - TranslateModule, - MiradorViewerComponent, - ThemedResultsBackButtonComponent, - CollectionsComponent, - RouterLink, - ItemPageUriFieldComponent, - ItemPageAbstractFieldComponent, - ], + imports: [NgIf, ThemedResultsBackButtonComponent, MiradorViewerComponent, ThemedItemPageTitleFieldComponent, DsoEditMenuComponent, MetadataFieldWrapperComponent, ThemedThumbnailComponent, ThemedMediaViewerComponent, ThemedFileSectionComponent, ItemPageDateFieldComponent, ThemedMetadataRepresentationListComponent, GenericItemPageFieldComponent, ItemPageAbstractFieldComponent, ItemPageUriFieldComponent, CollectionsComponent, RouterLink, AsyncPipe, TranslateModule], }) export class UntypedItemComponent extends BaseComponent { } diff --git a/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts b/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts index 6f73ecb60c..6d2ddb8f1f 100644 --- a/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts +++ b/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts @@ -13,7 +13,7 @@ import { MetadataRepresentationLoaderComponent } from '../../../../../../app/sha import { VarDirective } from '../../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-metadata-representation-list', + selector: 'ds-themed-metadata-representation-list', // templateUrl: './metadata-representation-list.component.html' templateUrl: '../../../../../../app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html', standalone: true, diff --git a/src/themes/custom/app/login-page/login-page.component.html b/src/themes/custom/app/login-page/login-page.component.html index 1a83892c24..84059877f4 100644 --- a/src/themes/custom/app/login-page/login-page.component.html +++ b/src/themes/custom/app/login-page/login-page.component.html @@ -3,8 +3,8 @@

{{"login.form.header" | translate}}

- +
diff --git a/src/themes/custom/app/login-page/login-page.component.ts b/src/themes/custom/app/login-page/login-page.component.ts index ae733a495a..68a36b182d 100644 --- a/src/themes/custom/app/login-page/login-page.component.ts +++ b/src/themes/custom/app/login-page/login-page.component.ts @@ -3,19 +3,18 @@ import { TranslateModule } from '@ngx-translate/core'; import { ThemedLogInComponent } from 'src/app/shared/log-in/themed-log-in.component'; import { LoginPageComponent as BaseComponent } from '../../../../app/login-page/login-page.component'; -import { LogInComponent } from '../../../../app/shared/log-in/log-in.component'; /** * This component represents the login page */ @Component({ - selector: 'ds-login-page', + selector: 'ds-themed-login-page', // styleUrls: ['./login-page.component.scss'], styleUrls: ['../../../../app/login-page/login-page.component.scss'], // templateUrl: './login-page.component.html' templateUrl: '../../../../app/login-page/login-page.component.html', standalone: true, - imports: [LogInComponent, ThemedLogInComponent ,TranslateModule], + imports: [ThemedLogInComponent ,TranslateModule], }) export class LoginPageComponent extends BaseComponent { } diff --git a/src/themes/custom/app/logout-page/logout-page.component.ts b/src/themes/custom/app/logout-page/logout-page.component.ts index 04cc80223c..97f82c1728 100644 --- a/src/themes/custom/app/logout-page/logout-page.component.ts +++ b/src/themes/custom/app/logout-page/logout-page.component.ts @@ -5,7 +5,7 @@ import { LogoutPageComponent as BaseComponent } from '../../../../app/logout-pag import { LogOutComponent } from '../../../../app/shared/log-out/log-out.component'; @Component({ - selector: 'ds-logout-page', + selector: 'ds-themed-logout-page', // styleUrls: ['./logout-page.component.scss'], styleUrls: ['../../../../app/logout-page/logout-page.component.scss'], // templateUrl: './logout-page.component.html' diff --git a/src/themes/custom/app/lookup-by-id/objectnotfound/objectnotfound.component.ts b/src/themes/custom/app/lookup-by-id/objectnotfound/objectnotfound.component.ts index 3014ab961d..ea599d8a61 100644 --- a/src/themes/custom/app/lookup-by-id/objectnotfound/objectnotfound.component.ts +++ b/src/themes/custom/app/lookup-by-id/objectnotfound/objectnotfound.component.ts @@ -8,7 +8,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { ObjectNotFoundComponent as BaseComponent } from '../../../../../app/lookup-by-id/objectnotfound/objectnotfound.component'; @Component({ - selector: 'ds-objnotfound', + selector: 'ds-themed-objnotfound', // styleUrls: ['./objectnotfound.component.scss'], styleUrls: ['../../../../../app/lookup-by-id/objectnotfound/objectnotfound.component.scss'], // templateUrl: './objectnotfound.component.html', diff --git a/src/themes/custom/app/my-dspace-page/my-dspace-page.component.ts b/src/themes/custom/app/my-dspace-page/my-dspace-page.component.ts index 379c8670c5..39156a0ac7 100644 --- a/src/themes/custom/app/my-dspace-page/my-dspace-page.component.ts +++ b/src/themes/custom/app/my-dspace-page/my-dspace-page.component.ts @@ -23,7 +23,7 @@ import { ThemedSearchComponent } from '../../../../app/shared/search/themed-sear * This component represents the whole mydspace page */ @Component({ - selector: 'ds-my-dspace-page', + selector: 'ds-themed-my-dspace-page', // styleUrls: ['./my-dspace-page.component.scss'], styleUrls: ['../../../../app/my-dspace-page/my-dspace-page.component.scss'], // templateUrl: './my-dspace-page.component.html', @@ -40,11 +40,11 @@ import { ThemedSearchComponent } from '../../../../app/shared/search/themed-sear imports: [ ThemedSearchComponent, MyDSpaceNewSubmissionComponent, - MyDspaceQaEventsNotificationsComponent, - SuggestionsNotificationComponent, AsyncPipe, RoleDirective, NgIf, + SuggestionsNotificationComponent, + MyDspaceQaEventsNotificationsComponent, ], }) export class MyDSpacePageComponent extends BaseComponent { diff --git a/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts b/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts index dcadc0d7c8..f0e2ebd502 100644 --- a/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts +++ b/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts @@ -1,19 +1,28 @@ +import { + AsyncPipe, + NgComponentOutlet, + NgFor, + NgIf, +} from '@angular/common'; import { Component } from '@angular/core'; +import { RouterLinkActive } from '@angular/router'; import { ExpandableNavbarSectionComponent as BaseComponent } from '../../../../../app/navbar/expandable-navbar-section/expandable-navbar-section.component'; import { slide } from '../../../../../app/shared/animations/slide'; +import { VarDirective } from '../../../../../app/shared/utils/var.directive'; /** * Represents an expandable section in the navbar */ @Component({ - selector: 'ds-expandable-navbar-section', + selector: 'ds-themed-expandable-navbar-section', // templateUrl: './expandable-navbar-section.component.html', templateUrl: '../../../../../app/navbar/expandable-navbar-section/expandable-navbar-section.component.html', // styleUrls: ['./expandable-navbar-section.component.scss'], styleUrls: ['../../../../../app/navbar/expandable-navbar-section/expandable-navbar-section.component.scss'], animations: [slide], standalone: true, + imports: [VarDirective, RouterLinkActive, NgComponentOutlet, NgIf, NgFor, AsyncPipe], }) export class ExpandableNavbarSectionComponent extends BaseComponent { } diff --git a/src/themes/custom/app/navbar/navbar.component.ts b/src/themes/custom/app/navbar/navbar.component.ts index 1eb910347f..9a5ee91b60 100644 --- a/src/themes/custom/app/navbar/navbar.component.ts +++ b/src/themes/custom/app/navbar/navbar.component.ts @@ -12,20 +12,19 @@ import { ThemedUserMenuComponent } from 'src/app/shared/auth-nav-menu/user-menu/ import { NavbarComponent as BaseComponent } from '../../../../app/navbar/navbar.component'; import { slideMobileNav } from '../../../../app/shared/animations/slide'; -import { UserMenuComponent } from '../../../../app/shared/auth-nav-menu/user-menu/user-menu.component'; /** * Component representing the public navbar */ @Component({ - selector: 'ds-navbar', + selector: 'ds-themed-navbar', // styleUrls: ['./navbar.component.scss'], styleUrls: ['../../../../app/navbar/navbar.component.scss'], // templateUrl: './navbar.component.html', templateUrl: '../../../../app/navbar/navbar.component.html', animations: [slideMobileNav], standalone: true, - imports: [NgbDropdownModule, NgClass, NgIf, UserMenuComponent, ThemedUserMenuComponent, NgFor, NgComponentOutlet, AsyncPipe, TranslateModule], + imports: [NgbDropdownModule, NgClass, NgIf, ThemedUserMenuComponent, NgFor, NgComponentOutlet, AsyncPipe, TranslateModule], }) export class NavbarComponent extends BaseComponent { } diff --git a/src/themes/custom/app/pagenotfound/pagenotfound.component.ts b/src/themes/custom/app/pagenotfound/pagenotfound.component.ts index a8448a6159..f74af21914 100644 --- a/src/themes/custom/app/pagenotfound/pagenotfound.component.ts +++ b/src/themes/custom/app/pagenotfound/pagenotfound.component.ts @@ -8,7 +8,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { PageNotFoundComponent as BaseComponent } from '../../../../app/pagenotfound/pagenotfound.component'; @Component({ - selector: 'ds-pagenotfound', + selector: 'ds-themed-pagenotfound', // styleUrls: ['./pagenotfound.component.scss'], styleUrls: ['../../../../app/pagenotfound/pagenotfound.component.scss'], // templateUrl: './pagenotfound.component.html' diff --git a/src/themes/custom/app/profile-page/profile-page.component.ts b/src/themes/custom/app/profile-page/profile-page.component.ts index b13745c0bf..54ea8bb7b5 100644 --- a/src/themes/custom/app/profile-page/profile-page.component.ts +++ b/src/themes/custom/app/profile-page/profile-page.component.ts @@ -14,7 +14,7 @@ import { ProfilePageSecurityFormComponent } from '../../../../app/profile-page/p import { VarDirective } from '../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-profile-page', + selector: 'ds-themed-profile-page', // styleUrls: ['./profile-page.component.scss'], styleUrls: ['../../../../app/profile-page/profile-page.component.scss'], // templateUrl: './profile-page.component.html' @@ -23,13 +23,13 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive'; imports: [ ProfilePageMetadataFormComponent, ProfilePageSecurityFormComponent, - SuggestionsNotificationComponent, AsyncPipe, TranslateModule, ProfilePageResearcherFormComponent, VarDirective, NgIf, NgForOf, + SuggestionsNotificationComponent, ], }) /** diff --git a/src/themes/custom/app/register-email-form/register-email-form.component.ts b/src/themes/custom/app/register-email-form/register-email-form.component.ts index c27a436e88..44426c527f 100644 --- a/src/themes/custom/app/register-email-form/register-email-form.component.ts +++ b/src/themes/custom/app/register-email-form/register-email-form.component.ts @@ -14,7 +14,7 @@ import { GoogleRecaptchaComponent } from 'src/app/shared/google-recaptcha/google import { RegisterEmailFormComponent as BaseComponent } from '../../../../app/register-email-form/register-email-form.component'; @Component({ - selector: 'ds-register-email-form', + selector: 'ds-themed-register-email-form', // templateUrl: './register-email-form.component.html', templateUrl: '../../../../app/register-email-form/register-email-form.component.html', standalone: true, diff --git a/src/themes/custom/app/register-page/create-profile/create-profile.component.ts b/src/themes/custom/app/register-page/create-profile/create-profile.component.ts index 04f5942ecd..ac2491cc4e 100644 --- a/src/themes/custom/app/register-page/create-profile/create-profile.component.ts +++ b/src/themes/custom/app/register-page/create-profile/create-profile.component.ts @@ -14,7 +14,7 @@ import { CreateProfileComponent as BaseComponent } from '../../../../../app/regi * Component that renders the create profile page to be used by a user registering through a token */ @Component({ - selector: 'ds-create-profile', + selector: 'ds-themed-create-profile', // styleUrls: ['./create-profile.component.scss'], styleUrls: ['../../../../../app/register-page/create-profile/create-profile.component.scss'], // templateUrl: './create-profile.component.html' diff --git a/src/themes/custom/app/register-page/register-email/register-email.component.ts b/src/themes/custom/app/register-page/register-email/register-email.component.ts index 28d22cceec..7296e1eebb 100644 --- a/src/themes/custom/app/register-page/register-email/register-email.component.ts +++ b/src/themes/custom/app/register-page/register-email/register-email.component.ts @@ -1,18 +1,16 @@ import { Component } from '@angular/core'; import { ThemedRegisterEmailFormComponent } from 'src/app/register-email-form/themed-registry-email-form.component'; -import { RegisterEmailFormComponent } from '../../../../../app/register-email-form/register-email-form.component'; import { RegisterEmailComponent as BaseComponent } from '../../../../../app/register-page/register-email/register-email.component'; @Component({ - selector: 'ds-register-email', + selector: 'ds-themed-register-email', // styleUrls: ['./register-email.component.scss'], styleUrls: ['../../../../../app/register-page/register-email/register-email.component.scss'], // templateUrl: './register-email.component.html' templateUrl: '../../../../../app/register-page/register-email/register-email.component.html', standalone: true, imports: [ - RegisterEmailFormComponent, ThemedRegisterEmailFormComponent, ], }) diff --git a/src/themes/custom/app/request-copy/deny-request-copy/deny-request-copy.component.ts b/src/themes/custom/app/request-copy/deny-request-copy/deny-request-copy.component.ts index 08cab9ad1a..f15193dd43 100644 --- a/src/themes/custom/app/request-copy/deny-request-copy/deny-request-copy.component.ts +++ b/src/themes/custom/app/request-copy/deny-request-copy/deny-request-copy.component.ts @@ -11,7 +11,7 @@ import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed import { VarDirective } from '../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-deny-request-copy', + selector: 'ds-themed-deny-request-copy', // styleUrls: ['./deny-request-copy.component.scss'], styleUrls: [], // templateUrl: './deny-request-copy.component.html', diff --git a/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts b/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts index 61475b3072..1876b134a2 100644 --- a/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts +++ b/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts @@ -8,7 +8,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { EmailRequestCopyComponent as BaseComponent } from 'src/app/request-copy/email-request-copy/email-request-copy.component'; @Component({ - selector: 'ds-email-request-copy', + selector: 'ds-themed-email-request-copy', // styleUrls: ['./email-request-copy.component.scss'], styleUrls: [], // templateUrl: './email-request-copy.component.html', diff --git a/src/themes/custom/app/request-copy/grant-request-copy/grant-request-copy.component.ts b/src/themes/custom/app/request-copy/grant-request-copy/grant-request-copy.component.ts index da5c011ee5..b121c09cdb 100644 --- a/src/themes/custom/app/request-copy/grant-request-copy/grant-request-copy.component.ts +++ b/src/themes/custom/app/request-copy/grant-request-copy/grant-request-copy.component.ts @@ -12,7 +12,7 @@ import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed import { VarDirective } from '../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-grant-request-copy', + selector: 'ds-themed-grant-request-copy', // styleUrls: ['./grant-request-copy.component.scss'], styleUrls: [], // templateUrl: './grant-request-copy.component.html', diff --git a/src/themes/custom/app/root/root.component.ts b/src/themes/custom/app/root/root.component.ts index 193595b3ed..bac434eeb3 100644 --- a/src/themes/custom/app/root/root.component.ts +++ b/src/themes/custom/app/root/root.component.ts @@ -1,5 +1,6 @@ import { AsyncPipe, + NgClass, NgIf, } from '@angular/common'; import { Component } from '@angular/core'; @@ -17,14 +18,27 @@ import { NotificationsBoardComponent } from '../../../../app/shared/notification import { SystemWideAlertBannerComponent } from '../../../../app/system-wide-alert/alert-banner/system-wide-alert-banner.component'; @Component({ - selector: 'ds-root', + selector: 'ds-themed-root', // styleUrls: ['./root.component.scss'], styleUrls: ['../../../../app/root/root.component.scss'], // templateUrl: './root.component.html', templateUrl: '../../../../app/root/root.component.html', animations: [slideSidebarPadding], standalone: true, - imports: [TranslateModule, ThemedAdminSidebarComponent, SystemWideAlertBannerComponent, ThemedHeaderNavbarWrapperComponent, ThemedBreadcrumbsComponent, NgIf, ThemedLoadingComponent, RouterOutlet, ThemedFooterComponent, NotificationsBoardComponent, AsyncPipe], + imports: [ + TranslateModule, + ThemedAdminSidebarComponent, + SystemWideAlertBannerComponent, + ThemedHeaderNavbarWrapperComponent, + ThemedBreadcrumbsComponent, + NgIf, + NgClass, + ThemedLoadingComponent, + RouterOutlet, + ThemedFooterComponent, + NotificationsBoardComponent, + AsyncPipe, + ], }) export class RootComponent extends BaseComponent { diff --git a/src/themes/custom/app/search-navbar/search-navbar.component.ts b/src/themes/custom/app/search-navbar/search-navbar.component.ts index 8242896559..59f6bf08a1 100644 --- a/src/themes/custom/app/search-navbar/search-navbar.component.ts +++ b/src/themes/custom/app/search-navbar/search-navbar.component.ts @@ -10,7 +10,7 @@ import { BrowserOnlyPipe } from '../../../../app/shared/utils/browser-only.pipe' import { ClickOutsideDirective } from '../../../../app/shared/utils/click-outside.directive'; @Component({ - selector: 'ds-search-navbar', + selector: 'ds-themed-search-navbar', // styleUrls: ['./search-navbar.component.scss'], styleUrls: ['../../../../app/search-navbar/search-navbar.component.scss'], // templateUrl: './search-navbar.component.html' diff --git a/src/themes/custom/app/search-page/configuration-search-page.component.ts b/src/themes/custom/app/search-page/configuration-search-page.component.ts index 05f142c19f..8635cd2edb 100644 --- a/src/themes/custom/app/search-page/configuration-search-page.component.ts +++ b/src/themes/custom/app/search-page/configuration-search-page.component.ts @@ -21,7 +21,7 @@ import { PageWithSidebarComponent } from '../../../../app/shared/sidebar/page-wi import { ViewModeSwitchComponent } from '../../../../app/shared/view-mode-switch/view-mode-switch.component'; @Component({ - selector: 'ds-configuration-search-page', + selector: 'ds-themed-configuration-search-page', // styleUrls: ['./configuration-search-page.component.scss'], styleUrls: ['../../../../app/shared/search/search.component.scss'], // templateUrl: './configuration-search-page.component.html' diff --git a/src/themes/custom/app/search-page/search-page.component.ts b/src/themes/custom/app/search-page/search-page.component.ts index c4b22850e7..2d8093c754 100644 --- a/src/themes/custom/app/search-page/search-page.component.ts +++ b/src/themes/custom/app/search-page/search-page.component.ts @@ -6,7 +6,7 @@ import { SearchPageComponent as BaseComponent } from '../../../../app/search-pag import { ThemedSearchComponent } from '../../../../app/shared/search/themed-search.component'; @Component({ - selector: 'ds-search-page', + selector: 'ds-themed-search-page', // styleUrls: ['./search-page.component.scss'], // templateUrl: './search-page.component.html' templateUrl: '../../../../app/search-page/search-page.component.html', diff --git a/src/themes/custom/app/shared/auth-nav-menu/auth-nav-menu.component.ts b/src/themes/custom/app/shared/auth-nav-menu/auth-nav-menu.component.ts index 6fc7c9b9d2..bddca78604 100644 --- a/src/themes/custom/app/shared/auth-nav-menu/auth-nav-menu.component.ts +++ b/src/themes/custom/app/shared/auth-nav-menu/auth-nav-menu.component.ts @@ -18,22 +18,20 @@ import { fadeOut, } from '../../../../../app/shared/animations/fade'; import { AuthNavMenuComponent as BaseComponent } from '../../../../../app/shared/auth-nav-menu/auth-nav-menu.component'; -import { UserMenuComponent } from '../../../../../app/shared/auth-nav-menu/user-menu/user-menu.component'; -import { LogInComponent } from '../../../../../app/shared/log-in/log-in.component'; import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pipe'; /** * Component representing the {@link AuthNavMenuComponent} of a page */ @Component({ - selector: 'ds-auth-nav-menu', + selector: 'ds-themed-auth-nav-menu', // templateUrl: './auth-nav-menu.component.html', templateUrl: '../../../../../app/shared/auth-nav-menu/auth-nav-menu.component.html', // styleUrls: ['./auth-nav-menu.component.scss'], styleUrls: ['../../../../../app/shared/auth-nav-menu/auth-nav-menu.component.scss'], animations: [fadeInOut, fadeOut], standalone: true, - imports: [NgClass, NgIf, NgbDropdownModule, LogInComponent, ThemedLogInComponent, RouterLink, RouterLinkActive, UserMenuComponent, ThemedUserMenuComponent, AsyncPipe, TranslateModule, BrowserOnlyPipe], + imports: [NgClass, NgIf, NgbDropdownModule, ThemedLogInComponent, RouterLink, RouterLinkActive, ThemedUserMenuComponent, AsyncPipe, TranslateModule, BrowserOnlyPipe], }) export class AuthNavMenuComponent extends BaseComponent { } diff --git a/src/themes/custom/app/shared/auth-nav-menu/user-menu/user-menu.component.ts b/src/themes/custom/app/shared/auth-nav-menu/user-menu/user-menu.component.ts index cd0bbeb5da..80df685729 100644 --- a/src/themes/custom/app/shared/auth-nav-menu/user-menu/user-menu.component.ts +++ b/src/themes/custom/app/shared/auth-nav-menu/user-menu/user-menu.component.ts @@ -18,7 +18,7 @@ import { UserMenuComponent as BaseComponent } from '../../../../../../app/shared * Component representing the {@link UserMenuComponent} of a page */ @Component({ - selector: 'ds-user-menu', + selector: 'ds-themed-user-menu', // templateUrl: 'user-menu.component.html', templateUrl: '../../../../../../app/shared/auth-nav-menu/user-menu/user-menu.component.html', // styleUrls: ['user-menu.component.scss'], diff --git a/src/themes/custom/app/shared/browse-by/browse-by.component.ts b/src/themes/custom/app/shared/browse-by/browse-by.component.ts index 579875e547..34c0bf965a 100644 --- a/src/themes/custom/app/shared/browse-by/browse-by.component.ts +++ b/src/themes/custom/app/shared/browse-by/browse-by.component.ts @@ -20,7 +20,7 @@ import { BrowseByComponent as BaseComponent } from '../../../../../app/shared/br import { StartsWithLoaderComponent } from '../../../../../app/shared/starts-with/starts-with-loader.component'; @Component({ - selector: 'ds-browse-by', + selector: 'ds-themed-browse-by', // styleUrls: ['./browse-by.component.scss'], styleUrls: ['../../../../../app/shared/browse-by/browse-by.component.scss'], // templateUrl: './browse-by.component.html', @@ -30,8 +30,7 @@ import { StartsWithLoaderComponent } from '../../../../../app/shared/starts-with fadeInOut, ], standalone: true, - imports: [VarDirective, NgClass, NgComponentOutlet, NgIf, ThemedResultsBackButtonComponent, ObjectCollectionComponent, - ThemedLoadingComponent, ErrorComponent, AsyncPipe, TranslateModule, StartsWithLoaderComponent], + imports: [VarDirective, NgClass, NgComponentOutlet, NgIf, ThemedResultsBackButtonComponent, ObjectCollectionComponent, ThemedLoadingComponent, ErrorComponent, AsyncPipe, TranslateModule, StartsWithLoaderComponent], }) export class BrowseByComponent extends BaseComponent { } diff --git a/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts b/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts index a0a0bd5fab..0217a309f6 100644 --- a/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts +++ b/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts @@ -15,7 +15,7 @@ import { CollectionDropdownComponent as BaseComponent } from '../../../../../app import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component'; @Component({ - selector: 'ds-collection-dropdown', + selector: 'ds-themed-collection-dropdown', templateUrl: '../../../../../app/shared/collection-dropdown/collection-dropdown.component.html', // templateUrl: './collection-dropdown.component.html', styleUrls: ['../../../../../app/shared/collection-dropdown/collection-dropdown.component.scss'], diff --git a/src/themes/custom/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts b/src/themes/custom/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts index 957b79491b..38e5c78815 100644 --- a/src/themes/custom/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts +++ b/src/themes/custom/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts @@ -1,6 +1,7 @@ import { AsyncPipe, NgForOf, + NgIf, } from '@angular/common'; import { Component } from '@angular/core'; import { FormsModule } from '@angular/forms'; @@ -17,7 +18,7 @@ import { ComcolPageBrowseByComponent as BaseComponent } from '../../../../../app * It expects the ID of the Community or Collection as input to be passed on as a scope */ @Component({ - selector: 'ds-comcol-page-browse-by', + selector: 'ds-base-comcol-page-browse-by', // styleUrls: ['./comcol-page-browse-by.component.scss'], styleUrls: ['../../../../../app/shared/comcol/comcol-page-browse-by/comcol-page-browse-by.component.scss'], // templateUrl: './comcol-page-browse-by.component.html' @@ -30,6 +31,7 @@ import { ComcolPageBrowseByComponent as BaseComponent } from '../../../../../app RouterLinkActive, TranslateModule, AsyncPipe, + NgIf, ], }) export class ComcolPageBrowseByComponent extends BaseComponent {} diff --git a/src/themes/custom/app/shared/comcol-page-handle/comcol-page-handle.component.ts b/src/themes/custom/app/shared/comcol-page-handle/comcol-page-handle.component.ts index 3db41cfc29..ad2760e380 100644 --- a/src/themes/custom/app/shared/comcol-page-handle/comcol-page-handle.component.ts +++ b/src/themes/custom/app/shared/comcol-page-handle/comcol-page-handle.component.ts @@ -10,7 +10,7 @@ import { ComcolPageHandleComponent as BaseComponent } from '../../../../../app/s */ @Component({ - selector: 'ds-comcol-page-handle', + selector: 'ds-base-comcol-page-handle', // templateUrl: './comcol-page-handle.component.html', templateUrl: '../../../../../app/shared/comcol/comcol-page-handle/comcol-page-handle.component.html', // styleUrls: ['./comcol-page-handle.component.scss'], diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts index 20be3969fb..4b7ee16d68 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts @@ -6,7 +6,7 @@ import { DSOSelectorComponent } from '../../../../../../../app/shared/dso-select import { CreateCollectionParentSelectorComponent as BaseComponent } from '../../../../../../../app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component'; @Component({ - selector: 'ds-create-collection-parent-selector', + selector: 'ds-themed-create-collection-parent-selector', // styleUrls: ['./create-collection-parent-selector.component.scss'], // templateUrl: './create-collection-parent-selector.component.html', templateUrl: '../../../../../../../app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html', diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts index d32fc2b870..6c4aa8082c 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts @@ -5,7 +5,7 @@ import { DSOSelectorComponent } from '../../../../../../../app/shared/dso-select import { CreateCommunityParentSelectorComponent as BaseComponent } from '../../../../../../../app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; @Component({ - selector: 'ds-create-community-parent-selector', + selector: 'ds-themed-create-community-parent-selector', // styleUrls: ['./create-community-parent-selector.component.scss'], styleUrls: ['../../../../../../../app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.scss'], // templateUrl: './create-community-parent-selector.component.html', diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts index 8f89bab746..8b7867e362 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts @@ -6,7 +6,7 @@ import { AuthorizedCollectionSelectorComponent } from '../../../../../../../app/ import { CreateItemParentSelectorComponent as BaseComponent } from '../../../../../../../app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; @Component({ - selector: 'ds-create-item-parent-selector', + selector: 'ds-themed-create-item-parent-selector', // styleUrls: ['./create-item-parent-selector.component.scss'], // templateUrl: './create-item-parent-selector.component.html', templateUrl: '../../../../../../../app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.html', diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts index 4aa9033fc1..89616d560a 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts @@ -6,7 +6,7 @@ import { DSOSelectorComponent } from '../../../../../../../app/shared/dso-select import { EditCollectionSelectorComponent as BaseComponent } from '../../../../../../../app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; @Component({ - selector: 'ds-edit-collection-selector', + selector: 'ds-themed-edit-collection-selector', // styleUrls: ['./edit-collection-selector.component.scss'], // templateUrl: './edit-collection-selector.component.html', templateUrl: '../../../../../../../app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html', diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts index 02533a7bcd..491a99aae3 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts @@ -6,7 +6,7 @@ import { DSOSelectorComponent } from '../../../../../../../app/shared/dso-select import { EditCommunitySelectorComponent as BaseComponent } from '../../../../../../../app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; @Component({ - selector: 'ds-edit-item-selector', + selector: 'ds-themed-edit-item-selector', // styleUrls: ['./edit-community-selector.component.scss'], // templateUrl: './edit-community-selector.component.html', templateUrl: '../../../../../../../app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html', diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts index ba1ec9a74b..fa65ffd691 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts @@ -6,7 +6,7 @@ import { EditItemSelectorComponent as BaseComponent } from 'src/app/shared/dso-s import { DSOSelectorComponent } from '../../../../../../../app/shared/dso-selector/dso-selector/dso-selector.component'; @Component({ - selector: 'ds-edit-item-selector', + selector: 'ds-themed-edit-item-selector', // styleUrls: ['./edit-item-selector.component.scss'], // templateUrl: './edit-item-selector.component.html', templateUrl: '../../../../../../../app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html', 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 df52bf5804..491d20e79c 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 @@ -11,7 +11,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { FileDownloadLinkComponent as BaseComponent } from '../../../../../app/shared/file-download-link/file-download-link.component'; @Component({ - selector: 'ds-file-download-link', + selector: 'ds-themed-file-download-link', // templateUrl: './file-download-link.component.html', templateUrl: '../../../../../app/shared/file-download-link/file-download-link.component.html', // styleUrls: ['./file-download-link.component.scss'], diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts index 20eb34e7a9..ff1f3d9c5e 100644 --- a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts @@ -20,7 +20,7 @@ import { ThemedSearchFormComponent } from '../../../../../../../../../app/shared import { VarDirective } from '../../../../../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-dynamic-lookup-relation-external-source-tab', + selector: 'ds-themed-dynamic-lookup-relation-external-source-tab', // styleUrls: ['./dynamic-lookup-relation-external-source-tab.component.scss'], styleUrls: ['../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.scss'], // templateUrl: './dynamic-lookup-relation-external-source-tab.component.html', diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts index c622263a28..424adb7942 100644 --- a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts @@ -6,17 +6,17 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { ExternalSourceEntryImportModalComponent as BaseComponent } from '../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; -import { SearchResultsComponent } from '../../../../../../../../../../app/shared/search/search-results/search-results.component'; +import { ThemedSearchResultsComponent } from '../../../../../../../../../../app/shared/search/search-results/themed-search-results.component'; @Component({ - selector: 'ds-external-source-entry-import-modal', + selector: 'ds-themed-external-source-entry-import-modal', styleUrls: ['../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.scss'], // styleUrls: ['./external-source-entry-import-modal.component.scss'], templateUrl: '../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.html', standalone: true, imports: [ TranslateModule, - SearchResultsComponent, + ThemedSearchResultsComponent, NgIf, AsyncPipe, ], diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts index 0a27a05cf9..3843c95811 100644 --- a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts @@ -13,7 +13,7 @@ import { ThemedSearchComponent } from '../../../../../../../../../app/shared/sea import { VarDirective } from '../../../../../../../../../app/shared/utils/var.directive'; @Component({ - selector: 'ds-dynamic-lookup-relation-search-tab', + selector: 'ds-themed-dynamic-lookup-relation-search-tab', // styleUrls: ['./dynamic-lookup-relation-search-tab.component.scss'], styleUrls: ['../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.scss'], // templateUrl: './dynamic-lookup-relation-search-tab.component.html', diff --git a/src/themes/custom/app/shared/lang-switch/lang-switch.component.ts b/src/themes/custom/app/shared/lang-switch/lang-switch.component.ts index 32a9a00616..ce9c192723 100644 --- a/src/themes/custom/app/shared/lang-switch/lang-switch.component.ts +++ b/src/themes/custom/app/shared/lang-switch/lang-switch.component.ts @@ -1,5 +1,5 @@ import { - NgForOf, + NgFor, NgIf, } from '@angular/common'; import { Component } from '@angular/core'; @@ -9,13 +9,13 @@ import { TranslateModule } from '@ngx-translate/core'; import { LangSwitchComponent as BaseComponent } from '../../../../../app/shared/lang-switch/lang-switch.component'; @Component({ - selector: 'ds-lang-switch', + selector: 'ds-themed-lang-switch', // styleUrls: ['./lang-switch.component.scss'], styleUrls: ['../../../../../app/shared/lang-switch/lang-switch.component.scss'], // templateUrl: './lang-switch.component.html', templateUrl: '../../../../../app/shared/lang-switch/lang-switch.component.html', standalone: true, - imports: [NgIf, NgbDropdownModule, NgForOf, TranslateModule], + imports: [NgIf, NgbDropdownModule, NgFor, TranslateModule], }) export class LangSwitchComponent extends BaseComponent { } diff --git a/src/themes/custom/app/shared/loading/loading.component.ts b/src/themes/custom/app/shared/loading/loading.component.ts index d99499e1b7..891381e77e 100644 --- a/src/themes/custom/app/shared/loading/loading.component.ts +++ b/src/themes/custom/app/shared/loading/loading.component.ts @@ -1,14 +1,16 @@ +import { NgIf } from '@angular/common'; import { Component } from '@angular/core'; import { LoadingComponent as BaseComponent } from '../../../../../app/shared/loading/loading.component'; @Component({ - selector: 'ds-loading', + selector: 'ds-themed-loading', styleUrls: ['../../../../../app/shared/loading/loading.component.scss'], // styleUrls: ['./loading.component.scss'], templateUrl: '../../../../../app/shared/loading/loading.component.html', // templateUrl: './loading.component.html' standalone: true, + imports: [NgIf], }) export class LoadingComponent extends BaseComponent { diff --git a/src/themes/custom/app/shared/log-in/log-in.component.ts b/src/themes/custom/app/shared/log-in/log-in.component.ts index 7acd36d667..1af5505835 100644 --- a/src/themes/custom/app/shared/log-in/log-in.component.ts +++ b/src/themes/custom/app/shared/log-in/log-in.component.ts @@ -10,7 +10,7 @@ import { LogInContainerComponent } from 'src/app/shared/log-in/container/log-in- import { LogInComponent as BaseComponent } from '../../../../../app/shared/log-in/log-in.component'; @Component({ - selector: 'ds-log-in', + selector: 'ds-themed-log-in', // templateUrl: './log-in.component.html', templateUrl: '../../../../../app/shared/log-in/log-in.component.html', // styleUrls: ['./log-in.component.scss'], diff --git a/src/themes/custom/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts b/src/themes/custom/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts index 19f10b9ceb..24e0006b88 100644 --- a/src/themes/custom/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts +++ b/src/themes/custom/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.ts @@ -7,7 +7,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { AccessStatusBadgeComponent as BaseComponent } from 'src/app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component'; @Component({ - selector: 'ds-access-status-badge', + selector: 'ds-themed-access-status-badge', // styleUrls: ['./access-status-badge.component.scss'], // templateUrl: './access-status-badge.component.html', templateUrl: '../../../../../../../../app/shared/object-collection/shared/badges/access-status-badge/access-status-badge.component.html', diff --git a/src/themes/custom/app/shared/object-collection/shared/badges/badges.component.ts b/src/themes/custom/app/shared/object-collection/shared/badges/badges.component.ts index 9a9d0dec51..f374a9707c 100644 --- a/src/themes/custom/app/shared/object-collection/shared/badges/badges.component.ts +++ b/src/themes/custom/app/shared/object-collection/shared/badges/badges.component.ts @@ -8,7 +8,7 @@ import { ThemedStatusBadgeComponent } from '../../../../../../../app/shared/obje import { ThemedTypeBadgeComponent } from '../../../../../../../app/shared/object-collection/shared/badges/type-badge/themed-type-badge.component'; @Component({ - selector: 'ds-badges', + selector: 'ds-themed-badges', // styleUrls: ['./badges.component.scss'], styleUrls: ['../../../../../../../app/shared/object-collection/shared/badges/badges.component.scss'], // templateUrl: './badges.component.html', diff --git a/src/themes/custom/app/shared/object-collection/shared/badges/my-dspace-status-badge/my-dspace-status-badge.component.ts b/src/themes/custom/app/shared/object-collection/shared/badges/my-dspace-status-badge/my-dspace-status-badge.component.ts index ead269067b..428f51711b 100644 --- a/src/themes/custom/app/shared/object-collection/shared/badges/my-dspace-status-badge/my-dspace-status-badge.component.ts +++ b/src/themes/custom/app/shared/object-collection/shared/badges/my-dspace-status-badge/my-dspace-status-badge.component.ts @@ -3,7 +3,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { MyDSpaceStatusBadgeComponent as BaseComponent } from 'src/app/shared/object-collection/shared/badges/my-dspace-status-badge/my-dspace-status-badge.component'; @Component({ - selector: 'ds-my-dspace-status-badge', + selector: 'ds-themed-my-dspace-status-badge', // styleUrls: ['./my-dspace-status-badge.component.scss'], styleUrls: ['../../../../../../../../app/shared/object-collection/shared/badges/my-dspace-status-badge/my-dspace-status-badge.component.scss'], // templateUrl: './my-dspace-status-badge.component.html', diff --git a/src/themes/custom/app/shared/object-collection/shared/badges/status-badge/status-badge.component.ts b/src/themes/custom/app/shared/object-collection/shared/badges/status-badge/status-badge.component.ts index 91c9aafca9..c39b0849ba 100644 --- a/src/themes/custom/app/shared/object-collection/shared/badges/status-badge/status-badge.component.ts +++ b/src/themes/custom/app/shared/object-collection/shared/badges/status-badge/status-badge.component.ts @@ -4,7 +4,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { StatusBadgeComponent as BaseComponent } from 'src/app/shared/object-collection/shared/badges/status-badge/status-badge.component'; @Component({ - selector: 'ds-status-badge', + selector: 'ds-themed-status-badge', // styleUrls: ['./status-badge.component.scss'], // templateUrl: './status-badge.component.html', templateUrl: '../../../../../../../../app/shared/object-collection/shared/badges/status-badge/status-badge.component.html', diff --git a/src/themes/custom/app/shared/object-collection/shared/badges/type-badge/type-badge.component.ts b/src/themes/custom/app/shared/object-collection/shared/badges/type-badge/type-badge.component.ts index 52be83adf0..5f7d87f706 100644 --- a/src/themes/custom/app/shared/object-collection/shared/badges/type-badge/type-badge.component.ts +++ b/src/themes/custom/app/shared/object-collection/shared/badges/type-badge/type-badge.component.ts @@ -4,7 +4,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { TypeBadgeComponent as BaseComponent } from 'src/app/shared/object-collection/shared/badges/type-badge/type-badge.component'; @Component({ - selector: 'ds-type-badge', + selector: 'ds-themed-type-badge', // styleUrls: ['./type-badge.component.scss'], // templateUrl: './type-badge.component.html', templateUrl: '../../../../../../../../app/shared/object-collection/shared/badges/type-badge/type-badge.component.html', diff --git a/src/themes/custom/app/shared/object-list/object-list.component.ts b/src/themes/custom/app/shared/object-list/object-list.component.ts index e64b36aef5..f94c31aeb0 100644 --- a/src/themes/custom/app/shared/object-list/object-list.component.ts +++ b/src/themes/custom/app/shared/object-list/object-list.component.ts @@ -17,15 +17,12 @@ import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pi * It expects the ID of the Community or Collection as input to be passed on as a scope */ @Component({ - selector: 'ds-object-list', + selector: 'ds-themed-object-list', // styleUrls: ['./object-list.component.scss'], styleUrls: ['../../../../../app/shared/object-list/object-list.component.scss'], // templateUrl: './object-list.component.html' templateUrl: '../../../../../app/shared/object-list/object-list.component.html', - imports: [ - PaginationComponent, NgIf, NgClass, NgFor, SelectableListItemControlComponent, - ImportableListItemControlComponent, ListableObjectComponentLoaderComponent, BrowserOnlyPipe, - ], + imports: [PaginationComponent, NgIf, NgClass, NgFor, SelectableListItemControlComponent, ImportableListItemControlComponent, ListableObjectComponentLoaderComponent, BrowserOnlyPipe], standalone: true, }) diff --git a/src/themes/custom/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts b/src/themes/custom/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts index eb639e5163..7d2913dc1f 100644 --- a/src/themes/custom/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts +++ b/src/themes/custom/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts @@ -15,7 +15,7 @@ import { listableObjectComponent } from '../../../../../../../../../app/shared/o import { ItemSearchResultListElementComponent as BaseComponent } from '../../../../../../../../../app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; import { TruncatableComponent } from '../../../../../../../../../app/shared/truncatable/truncatable.component'; import { TruncatablePartComponent } from '../../../../../../../../../app/shared/truncatable/truncatable-part/truncatable-part.component'; -import { ThumbnailComponent } from '../../../../../../thumbnail/thumbnail.component'; +import { ThemedThumbnailComponent } from '../../../../../../../../../app/thumbnail/themed-thumbnail.component'; @listableObjectComponent('PublicationSearchResult', ViewMode.ListElement, Context.Any, 'custom') @listableObjectComponent(ItemSearchResult, ViewMode.ListElement, Context.Any, 'custom') @@ -26,7 +26,7 @@ import { ThumbnailComponent } from '../../../../../../thumbnail/thumbnail.compon // templateUrl: './item-search-result-list-element.component.html', templateUrl: '../../../../../../../../../app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html', standalone: true, - imports: [NgIf, RouterLink, ThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], + imports: [NgIf, RouterLink, ThemedThumbnailComponent, NgClass, ThemedBadgesComponent, TruncatableComponent, TruncatablePartComponent, NgFor, AsyncPipe], }) export class ItemSearchResultListElementComponent extends BaseComponent { diff --git a/src/themes/custom/app/shared/results-back-button/results-back-button.component.ts b/src/themes/custom/app/shared/results-back-button/results-back-button.component.ts index 3e1b62a23e..2ec6d7d6ab 100644 --- a/src/themes/custom/app/shared/results-back-button/results-back-button.component.ts +++ b/src/themes/custom/app/shared/results-back-button/results-back-button.component.ts @@ -4,7 +4,7 @@ import { Component } from '@angular/core'; import { ResultsBackButtonComponent as BaseComponent } from '../../../../../app/shared/results-back-button/results-back-button.component'; @Component({ - selector: 'ds-results-back-button', + selector: 'ds-themed-results-back-button', // styleUrls: ['./results-back-button.component.scss'], styleUrls: ['../../../../../app/shared/results-back-button/results-back-button.component.scss'], //templateUrl: './results-back-button.component.html', diff --git a/src/themes/custom/app/shared/search-form/search-form.component.ts b/src/themes/custom/app/shared/search-form/search-form.component.ts index 07e6016eda..729a001f61 100644 --- a/src/themes/custom/app/shared/search-form/search-form.component.ts +++ b/src/themes/custom/app/shared/search-form/search-form.component.ts @@ -11,7 +11,7 @@ import { SearchFormComponent as BaseComponent } from '../../../../../app/shared/ import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pipe'; @Component({ - selector: 'ds-search-form', + selector: 'ds-themed-search-form', // styleUrls: ['./search-form.component.scss'], styleUrls: ['../../../../../app/shared/search-form/search-form.component.scss'], // templateUrl: './search-form.component.html', diff --git a/src/themes/custom/app/shared/search/search-filters/search-filters.component.ts b/src/themes/custom/app/shared/search/search-filters/search-filters.component.ts index 54b6c9b697..5b10c84145 100644 --- a/src/themes/custom/app/shared/search/search-filters/search-filters.component.ts +++ b/src/themes/custom/app/shared/search/search-filters/search-filters.component.ts @@ -22,7 +22,7 @@ import { SearchFiltersComponent as BaseComponent } from '../../../../../../app/s @Component({ - selector: 'ds-search-filters', + selector: 'ds-themed-search-filters', // styleUrls: ['./search-filters.component.scss'], styleUrls: ['../../../../../../app/shared/search/search-filters/search-filters.component.scss'], // templateUrl: './search-filters.component.html', diff --git a/src/themes/custom/app/shared/search/search-results/search-results.component.ts b/src/themes/custom/app/shared/search/search-results/search-results.component.ts index b2b864240f..b72297f32f 100644 --- a/src/themes/custom/app/shared/search/search-results/search-results.component.ts +++ b/src/themes/custom/app/shared/search/search-results/search-results.component.ts @@ -14,7 +14,7 @@ import { SearchExportCsvComponent } from '../../../../../../app/shared/search/se import { SearchResultsComponent as BaseComponent } from '../../../../../../app/shared/search/search-results/search-results.component'; @Component({ - selector: 'ds-search-results', + selector: 'ds-themed-search-results', // templateUrl: './search-results.component.html', templateUrl: '../../../../../../app/shared/search/search-results/search-results.component.html', // styleUrls: ['./search-results.component.scss'], diff --git a/src/themes/custom/app/shared/search/search-settings/search-settings.component.ts b/src/themes/custom/app/shared/search/search-settings/search-settings.component.ts index 75b86bf467..111b7b0c7c 100644 --- a/src/themes/custom/app/shared/search/search-settings/search-settings.component.ts +++ b/src/themes/custom/app/shared/search/search-settings/search-settings.component.ts @@ -21,7 +21,7 @@ import { SidebarDropdownComponent } from '../../../../../../app/shared/sidebar/s @Component({ - selector: 'ds-search-settings', + selector: 'ds-themed-search-settings', // styleUrls: ['./search-settings.component.scss'], styleUrls: ['../../../../../../app/shared/search/search-settings/search-settings.component.scss'], // templateUrl: './search-settings.component.html', diff --git a/src/themes/custom/app/shared/search/search-sidebar/search-sidebar.component.ts b/src/themes/custom/app/shared/search/search-sidebar/search-sidebar.component.ts index 3171488b62..93244d9678 100644 --- a/src/themes/custom/app/shared/search/search-sidebar/search-sidebar.component.ts +++ b/src/themes/custom/app/shared/search/search-sidebar/search-sidebar.component.ts @@ -19,7 +19,7 @@ import { ViewModeSwitchComponent } from '../../../../../../app/shared/view-mode- @Component({ - selector: 'ds-search-sidebar', + selector: 'ds-themed-search-sidebar', // styleUrls: ['./search-sidebar.component.scss'], styleUrls: ['../../../../../../app/shared/search/search-sidebar/search-sidebar.component.scss'], // templateUrl: './search-sidebar.component.html', diff --git a/src/themes/custom/app/statistics-page/collection-statistics-page/collection-statistics-page.component.ts b/src/themes/custom/app/statistics-page/collection-statistics-page/collection-statistics-page.component.ts index 76d815bafd..3fbd6d0bca 100644 --- a/src/themes/custom/app/statistics-page/collection-statistics-page/collection-statistics-page.component.ts +++ b/src/themes/custom/app/statistics-page/collection-statistics-page/collection-statistics-page.component.ts @@ -8,7 +8,7 @@ import { CollectionStatisticsPageComponent as BaseComponent } from '../../../../ import { StatisticsTableComponent } from '../../../../../app/statistics-page/statistics-table/statistics-table.component'; @Component({ - selector: 'ds-collection-statistics-page', + selector: 'ds-themed-collection-statistics-page', // styleUrls: ['./collection-statistics-page.component.scss'], styleUrls: ['../../../../../app/statistics-page/collection-statistics-page/collection-statistics-page.component.scss'], // templateUrl: './collection-statistics-page.component.html', diff --git a/src/themes/custom/app/statistics-page/community-statistics-page/community-statistics-page.component.ts b/src/themes/custom/app/statistics-page/community-statistics-page/community-statistics-page.component.ts index 019447903b..7c76eeac7d 100644 --- a/src/themes/custom/app/statistics-page/community-statistics-page/community-statistics-page.component.ts +++ b/src/themes/custom/app/statistics-page/community-statistics-page/community-statistics-page.component.ts @@ -8,7 +8,7 @@ import { CommunityStatisticsPageComponent as BaseComponent } from '../../../../. import { StatisticsTableComponent } from '../../../../../app/statistics-page/statistics-table/statistics-table.component'; @Component({ - selector: 'ds-collection-statistics-page', + selector: 'ds-themed-collection-statistics-page', // styleUrls: ['./community-statistics-page.component.scss'], styleUrls: ['../../../../../app/statistics-page/community-statistics-page/community-statistics-page.component.scss'], // templateUrl: './community-statistics-page.component.html', diff --git a/src/themes/custom/app/statistics-page/item-statistics-page/item-statistics-page.component.ts b/src/themes/custom/app/statistics-page/item-statistics-page/item-statistics-page.component.ts index 66b50d4ae7..fe9d0a0a3a 100644 --- a/src/themes/custom/app/statistics-page/item-statistics-page/item-statistics-page.component.ts +++ b/src/themes/custom/app/statistics-page/item-statistics-page/item-statistics-page.component.ts @@ -8,7 +8,7 @@ import { ItemStatisticsPageComponent as BaseComponent } from '../../../../../app import { StatisticsTableComponent } from '../../../../../app/statistics-page/statistics-table/statistics-table.component'; @Component({ - selector: 'ds-item-statistics-page', + selector: 'ds-themed-item-statistics-page', // styleUrls: ['./item-statistics-page.component.scss'], styleUrls: ['../../../../../app/statistics-page/item-statistics-page/item-statistics-page.component.scss'], // templateUrl: './item-statistics-page.component.html', diff --git a/src/themes/custom/app/statistics-page/site-statistics-page/site-statistics-page.component.ts b/src/themes/custom/app/statistics-page/site-statistics-page/site-statistics-page.component.ts index de5c8afd77..1301949963 100644 --- a/src/themes/custom/app/statistics-page/site-statistics-page/site-statistics-page.component.ts +++ b/src/themes/custom/app/statistics-page/site-statistics-page/site-statistics-page.component.ts @@ -8,7 +8,7 @@ import { SiteStatisticsPageComponent as BaseComponent } from '../../../../../app import { StatisticsTableComponent } from '../../../../../app/statistics-page/statistics-table/statistics-table.component'; @Component({ - selector: 'ds-site-statistics-page', + selector: 'ds-themed-site-statistics-page', // styleUrls: ['./site-statistics-page.component.scss'], styleUrls: ['../../../../../app/statistics-page/site-statistics-page/site-statistics-page.component.scss'], // templateUrl: './site-statistics-page.component.html', diff --git a/src/themes/custom/app/submission/edit/submission-edit.component.ts b/src/themes/custom/app/submission/edit/submission-edit.component.ts index 31eb84ffbc..c41b4321fa 100644 --- a/src/themes/custom/app/submission/edit/submission-edit.component.ts +++ b/src/themes/custom/app/submission/edit/submission-edit.component.ts @@ -7,7 +7,7 @@ import { SubmissionFormComponent } from '../../../../../app/submission/form/subm * This component allows to edit an existing workspaceitem/workflowitem. */ @Component({ - selector: 'ds-submission-edit', + selector: 'ds-themed-submission-edit', // styleUrls: ['./submission-edit.component.scss'], styleUrls: ['../../../../../app/submission/edit/submission-edit.component.scss'], // templateUrl: './submission-edit.component.html' diff --git a/src/themes/custom/app/submission/import-external/submission-import-external.component.ts b/src/themes/custom/app/submission/import-external/submission-import-external.component.ts index 6a5632b8b6..cda5c207bf 100644 --- a/src/themes/custom/app/submission/import-external/submission-import-external.component.ts +++ b/src/themes/custom/app/submission/import-external/submission-import-external.component.ts @@ -18,7 +18,7 @@ import { SubmissionImportExternalComponent as BaseComponent } from '../../../../ * This component allows to submit a new workspaceitem importing the data from an external source. */ @Component({ - selector: 'ds-submission-import-external', + selector: 'ds-themed-submission-import-external', // styleUrls: ['./submission-import-external.component.scss'], styleUrls: ['../../../../../app/submission/import-external/submission-import-external.component.scss'], // templateUrl: './submission-import-external.component.html', diff --git a/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts b/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts index e6ed853f6d..13f5f97650 100644 --- a/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts +++ b/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts @@ -14,7 +14,7 @@ import { SubmissionSectionUploadFileViewComponent } from '../../../../../../../a * This component represents a single bitstream contained in the submission */ @Component({ - selector: 'ds-submission-upload-section-file', + selector: 'ds-themed-submission-upload-section-file', // styleUrls: ['./section-upload-file.component.scss'], styleUrls: ['../../../../../../../app/submission/sections/upload/file/section-upload-file.component.scss'], // templateUrl: './section-upload-file.component.html' diff --git a/src/themes/custom/app/submission/submit/submission-submit.component.ts b/src/themes/custom/app/submission/submit/submission-submit.component.ts index 9a2a5c51ff..9c84aeedc3 100644 --- a/src/themes/custom/app/submission/submit/submission-submit.component.ts +++ b/src/themes/custom/app/submission/submit/submission-submit.component.ts @@ -6,7 +6,7 @@ import { SubmissionSubmitComponent as BaseComponent } from '../../../../../app/s * This component allows to submit a new workspaceitem. */ @Component({ - selector: 'ds-submission-submit', + selector: 'ds-themed-submission-submit', // styleUrls: ['./submission-submit.component.scss'], styleUrls: ['../../../../../app/submission/submit/submission-submit.component.scss'], // templateUrl: './submission-submit.component.html' diff --git a/src/themes/custom/app/thumbnail/thumbnail.component.ts b/src/themes/custom/app/thumbnail/thumbnail.component.ts index 4247e8df84..fbd2e22cd1 100644 --- a/src/themes/custom/app/thumbnail/thumbnail.component.ts +++ b/src/themes/custom/app/thumbnail/thumbnail.component.ts @@ -8,7 +8,7 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive'; import { ThumbnailComponent as BaseComponent } from '../../../../app/thumbnail/thumbnail.component'; @Component({ - selector: 'ds-thumbnail', + selector: 'ds-themed-thumbnail', // styleUrls: ['./thumbnail.component.scss'], styleUrls: ['../../../../app/thumbnail/thumbnail.component.scss'], // templateUrl: './thumbnail.component.html', diff --git a/src/themes/custom/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts b/src/themes/custom/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts index d852d3ac3e..591ff5dd44 100644 --- a/src/themes/custom/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts +++ b/src/themes/custom/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts @@ -7,7 +7,7 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; import { WorkflowItemDeleteComponent as BaseComponent } from '../../../../../app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component'; @Component({ - selector: 'ds-workflow-item-delete', + selector: 'ds-themed-workflow-item-delete', // styleUrls: ['workflow-item-delete.component.scss'], // templateUrl: './workflow-item-delete.component.html' templateUrl: '../../../../../app/workflowitems-edit-page/workflow-item-action-page.component.html', diff --git a/src/themes/custom/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts b/src/themes/custom/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts index 450cb88837..9d3ea16193 100644 --- a/src/themes/custom/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts +++ b/src/themes/custom/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts @@ -7,7 +7,7 @@ import { VarDirective } from '../../../../../app/shared/utils/var.directive'; import { WorkflowItemSendBackComponent as BaseComponent } from '../../../../../app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component'; @Component({ - selector: 'ds-workflow-item-send-back', + selector: 'ds-themed-workflow-item-send-back', // NOTE: the SCSS file for workflow-item-action-page does not have a corresponding file in the original // implementation, so this commented out line below is a stub, here if you // need it, but you probably don't need it. diff --git a/src/themes/custom/app/workspace-items-delete-page/workspace-items-delete/workspace-items-delete.component.ts b/src/themes/custom/app/workspace-items-delete-page/workspace-items-delete/workspace-items-delete.component.ts index 94b89f4c24..ca8fc7bcae 100644 --- a/src/themes/custom/app/workspace-items-delete-page/workspace-items-delete/workspace-items-delete.component.ts +++ b/src/themes/custom/app/workspace-items-delete-page/workspace-items-delete/workspace-items-delete.component.ts @@ -7,7 +7,7 @@ import { WorkspaceItemsDeletePageComponent as BaseComponent } from '../../../../ @Component({ - selector: 'ds-workspaceitems-delete-page', + selector: 'ds-base-workspaceitems-delete-page', templateUrl: '../../../../../app/workspaceitems-edit-page/workspaceitems-delete-page/workspaceitems-delete-page.component.html', standalone: true, imports: [ diff --git a/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.html b/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.html index 5f51689df8..d2b977ff84 100644 --- a/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.html +++ b/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.html @@ -1,9 +1,9 @@
- +
diff --git a/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.ts b/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.ts index c474142233..cc9a3d727e 100644 --- a/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.ts +++ b/src/themes/dspace/app/header-nav-wrapper/header-navbar-wrapper.component.ts @@ -15,7 +15,7 @@ import { slideMobileNav } from '../../../../app/shared/animations/slide'; * This component represents a wrapper for the horizontal navbar and the header */ @Component({ - selector: 'ds-header-navbar-wrapper', + selector: 'ds-themed-header-navbar-wrapper', styleUrls: ['header-navbar-wrapper.component.scss'], templateUrl: 'header-navbar-wrapper.component.html', standalone: true, diff --git a/src/themes/dspace/app/header/header.component.html b/src/themes/dspace/app/header/header.component.html index 51373e8cd1..e78d19053d 100644 --- a/src/themes/dspace/app/header/header.component.html +++ b/src/themes/dspace/app/header/header.component.html @@ -9,17 +9,17 @@
- +
diff --git a/src/themes/dspace/app/header/header.component.ts b/src/themes/dspace/app/header/header.component.ts index 1a8144ed96..1931838923 100644 --- a/src/themes/dspace/app/header/header.component.ts +++ b/src/themes/dspace/app/header/header.component.ts @@ -18,17 +18,16 @@ import { ThemedNavbarComponent } from '../../../../app/navbar/themed-navbar.comp import { ThemedSearchNavbarComponent } from '../../../../app/search-navbar/themed-search-navbar.component'; import { ThemedAuthNavMenuComponent } from '../../../../app/shared/auth-nav-menu/themed-auth-nav-menu.component'; import { ImpersonateNavbarComponent } from '../../../../app/shared/impersonate-navbar/impersonate-navbar.component'; -import { LangSwitchComponent } from '../../../../app/shared/lang-switch/lang-switch.component'; /** * Represents the header with the logo and simple navigation */ @Component({ - selector: 'ds-header', + selector: 'ds-themed-header', styleUrls: ['header.component.scss'], templateUrl: 'header.component.html', standalone: true, - imports: [NgbDropdownModule, ThemedLangSwitchComponent, RouterLink, ThemedSearchNavbarComponent, LangSwitchComponent, ContextHelpToggleComponent, ThemedAuthNavMenuComponent, ImpersonateNavbarComponent, ThemedNavbarComponent, TranslateModule, AsyncPipe, NgIf], + imports: [NgbDropdownModule, ThemedLangSwitchComponent, RouterLink, ThemedSearchNavbarComponent, ContextHelpToggleComponent, ThemedAuthNavMenuComponent, ImpersonateNavbarComponent, ThemedNavbarComponent, TranslateModule, AsyncPipe, NgIf], }) export class HeaderComponent extends BaseComponent implements OnInit { public isNavBarCollapsed$: Observable; diff --git a/src/themes/dspace/app/home-page/home-news/home-news.component.ts b/src/themes/dspace/app/home-page/home-news/home-news.component.ts index 820d6ceaf6..cebea38ee8 100644 --- a/src/themes/dspace/app/home-page/home-news/home-news.component.ts +++ b/src/themes/dspace/app/home-page/home-news/home-news.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { HomeNewsComponent as BaseComponent } from '../../../../../app/home-page/home-news/home-news.component'; @Component({ - selector: 'ds-home-news', + selector: 'ds-themed-home-news', styleUrls: ['./home-news.component.scss'], templateUrl: './home-news.component.html', standalone: true, diff --git a/src/themes/dspace/app/navbar/navbar.component.html b/src/themes/dspace/app/navbar/navbar.component.html index f1c8c66847..d828206e7a 100644 --- a/src/themes/dspace/app/navbar/navbar.component.html +++ b/src/themes/dspace/app/navbar/navbar.component.html @@ -1,5 +1,5 @@ - +