### Clone and Install DSpace-Angular Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Clone the repository, navigate into the project directory, install dependencies, and start the development server. Ensure you have the correct Node.js and npm versions installed. ```bash git clone https://github.com/4Science/dspace-angular.git cd dspace-angular npm install npm start ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Run these commands to clean, install, and start the project locally. This is useful for testing pull requests without a local DSpace backend. ```bash npm run clean npm install npm start ``` -------------------------------- ### Starting DSpace Angular in Development Mode Source: https://context7.com/4science/dspace-angular/llms.txt Install dependencies and start the application with live-reloading. The default address is http://localhost:4000. ```bash # Install dependencies npm install # Start with live-reload (default: http://localhost:4000) npm run start:dev ``` -------------------------------- ### Build and Start SSR Server Source: https://context7.com/4science/dspace-angular/llms.txt Build the production application and then start the SSR server. Verify SSR functionality by checking the response for rendered HTML. ```bash # Build and start the SSR server npm run build:prod npm run serve:ssr # Verify SSR is working (page should contain rendered HTML, not just ) curl -s http://localhost:4000/ | grep ' DSPACE_CACHE_MSTOLIVE_DEFAULT ``` ```bash auth.ui.timeUntilIdle => DSPACE_AUTH_UI_TIMEUNTILIDLE ``` -------------------------------- ### DSpace Angular List Example Component Source: https://context7.com/4science/dspace-angular/llms.txt Demonstrates constructing `FindListOptions` for paginated, sorted, and searched lists, including embedding HAL links for related resources. Ensure `ItemDataService` and related models are imported. ```typescript import { Component, OnInit } from '@angular/core'; import { ItemDataService } from '../core/data/item-data.service'; import { FindListOptions } from '../core/data/find-list-options.model'; import { RequestParam } from '../core/cache/models/request-param.model'; import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model'; import { followLink } from '../shared/utils/follow-link-config.model'; @Component({ selector: 'ds-list-example', template: '' }) export class ListExampleComponent implements OnInit { constructor(private itemService: ItemDataService) {} ngOnInit() { // ── Paginated & sorted list ─────────────────────────────────────────── const opts: FindListOptions = { currentPage: 2, elementsPerPage: 25, sort: new SortOptions('dc.date.issued', SortDirection.DESC), }; // Resulting URL: .../items?page=1&size=25&sort=dc.date.issued,DESC // ── StartsWith for browse indices ───────────────────────────────────── const browseOpts: FindListOptions = { startsWith: 'Smith', currentPage: 1, elementsPerPage: 10, }; // Resulting URL: .../items?startsWith=Smith&page=0&size=10 // ── Custom search params ────────────────────────────────────────────── const searchOpts: FindListOptions = { searchParams: [ new RequestParam('query', 'climate change'), new RequestParam('scope', 'community-uuid'), ], currentPage: 1, elementsPerPage: 10, }; // ── With embedded HAL links (avoids extra round-trips) ──────────────── this.itemService.findAll(opts, followLink('bundles'), // embed bundles followLink('owningCollection'), // embed owning collection followLink('thumbnail'), // embed thumbnail bitstream ).subscribe(rd => { if (rd.hasSucceeded) { rd.payload.page.forEach(item => { console.log(item.uuid, item.name); // item.bundles is already resolved — no extra HTTP call needed }); const { currentPage, totalPages, totalElements } = rd.payload.pageInfo; console.log(`Page ${currentPage} of ${totalPages} (${totalElements} total)`); } }); } } ``` -------------------------------- ### Add New Dependency with npm Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Use this command to install and add a new third-party library to your project's dependencies. Ensure you use the correct flag for development dependencies. ```bash npm install some-lib ``` ```bash npm install some-lib --save--dev ``` -------------------------------- ### Angular AuthService Example Source: https://context7.com/4science/dspace-angular/llms.txt Demonstrates various functionalities of the AuthService, including checking authentication status, logging in, retrieving user information, refreshing tokens, setting redirect URLs, handling external authentication, managing user idle state, and logging out. ```typescript import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { AuthService } from '../core/auth/auth.service'; import { EPerson } from '../core/eperson/models/eperson.model'; @Component({ selector: 'ds-login-example', template: '' }) export class LoginExampleComponent implements OnInit { constructor( private authService: AuthService, private router: Router, ) {} ngOnInit() { // ── Check if user is currently authenticated ────────────────────────── this.authService.isAuthenticated().subscribe(authenticated => { console.log('Authenticated:', authenticated); }); // ── Login with username and password ────────────────────────────────── this.authService.authenticate('admin@example.org', 's3cr3t').subscribe({ next: (status) => { console.log('Login successful, token:', status.token?.accessToken); this.router.navigate(['/home']); }, error: (err) => { console.error('Login failed:', err.message); // err.message === 'auth.errors.invalid-user' for bad credentials }, }); // ── Get the authenticated EPerson from the store ─────────────────────── this.authService.getAuthenticatedUserFromStore().subscribe((user: EPerson) => { if (user) console.log('Logged in as:', user.email); }); // ── Refresh the current JWT token ───────────────────────────────────── this.authService.refreshAuthenticationToken(null).subscribe(token => { console.log('New token expiry:', token?.expires); }); // ── Set a redirect URL before sending user to login ─────────────────── this.authService.setRedirectUrl('/protected-page'); // ── Retrieve the stored redirect URL ───────────────────────────────── this.authService.getRedirectUrl().subscribe(url => { console.log('Will redirect to:', url); }); // ── Check for external (Shibboleth/OIDC) authentication ─────────────── this.authService.isExternalAuthentication().subscribe(external => { console.log('Using external auth:', external); }); // ── Mark user as idle / not idle ───────────────────────────────────── this.authService.setIdle(true); this.authService.isUserIdle().subscribe(idle => console.log('Idle:', idle)); // ── Logout ──────────────────────────────────────────────────────────── this.authService.logout().subscribe(() => { this.router.navigate(['/home']); }); } } ``` -------------------------------- ### Run End-to-End Tests Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Execute end-to-end tests using the 'ng e2e' command. This requires a locally running DSpace backend and specific test data setup. The tests will run against the backend configured in `config.prod.yml` by default. ```bash ng e2e ``` -------------------------------- ### Browse Community Hierarchy with CommunityDataService Source: https://context7.com/4science/dspace-angular/llms.txt Demonstrates fetching top-level communities, authorized communities, and sub-communities using CommunityDataService. Includes examples for finding communities by parent ID and accessing the community endpoint. ```typescript import { Component, OnInit } from '@angular/core'; import { CommunityDataService } from '../core/data/community-data.service'; import { Community } from '../core/shared/community.model'; import { RemoteData } from '../core/data/remote-data'; import { PaginatedList } from '../core/data/paginated-list.model'; import { FindListOptions } from '../core/data/find-list-options.model'; import { followLink } from '../shared/utils/follow-link-config.model'; @Component({ selector: 'ds-community-example', template: '' }) export class CommunityExampleComponent implements OnInit { constructor(private communityService: CommunityDataService) {} ngOnInit() { const opts: FindListOptions = { currentPage: 1, elementsPerPage: 10 }; // ── Top-level communities ───────────────────────────────────────────── this.communityService.findTop(opts, followLink('logo')) .subscribe((rd: RemoteData>) => { if (rd.hasSucceeded) { rd.payload.page.forEach(c => console.log(c.name, c.archivedItemsCount)); } }); // ── All communities the current user administers ─────────────────────── this.communityService.getAuthorizedCommunity('', opts) .subscribe((rd: RemoteData>) => { if (rd.hasSucceeded) rd.payload.page.forEach(c => console.log(c.uuid)); }); // ── Sub-communities of a parent community ───────────────────────────── const parentId = 'parent-community-uuid'; this.communityService.findByParent(parentId, opts) .subscribe((rd: RemoteData>) => { if (rd.hasSucceeded) { console.log(`Sub-communities: ${rd.payload.page.length}`); console.log('Total:', rd.payload.pageInfo.totalElements); } }); // ── Direct endpoint access (community is public) ────────────────────── this.communityService.getEndpoint() .subscribe(href => console.log('Communities endpoint:', href)); } } ``` -------------------------------- ### Invalid: Sort multiple imports alphabetically Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/sort-standalone-imports.md Shows an example of unsorted multiple imports that will trigger the ESLint rule and require fixing. ```typescript @Component({ selector: 'ds-app', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], imports: [ RootComponent, AsyncPipe, ], }) export class AppComponent {} ``` -------------------------------- ### DSpace Angular Docker Quick-start Source: https://context7.com/4science/dspace-angular/llms.txt Launch the Angular UI and REST backend simultaneously using Docker Compose for testing purposes. Access the UI at http://localhost:4000. ```bash # Spin up Angular UI + REST backend for testing docker compose -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up # Access the UI open http://localhost:4000 ``` -------------------------------- ### Invalid: Multiple imports on the same line Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/sort-standalone-imports.md An example where multiple imports are placed on the same line, violating the sorting rule. ```typescript @Component({ selector: 'ds-app', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], imports: [AsyncPipe, RootComponent], }) export class AppComponent {} ``` -------------------------------- ### Invalid: Singular import not on one line when maxItems is 0 Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/sort-standalone-imports.md An example where a singular import is not on its own line, violating the `maxItems: 0` configuration. ```typescript @Component({ selector: 'ds-app', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], imports: [RootComponent], }) export class AppComponent {} ``` -------------------------------- ### Run DSpace-CRIS Angular Dist Build with Demo Backend Source: https://github.com/4science/dspace-angular/blob/main-cris/docker/README.md Sets up and runs the Angular UI in production mode, connecting to a demo or sandbox DSpace-CRIS REST backend. ```bash docker compose -f docker/docker-compose-dist.yml pull docker compose -f docker/docker-compose-dist.yml build docker compose -p dcris25 -f docker/docker-compose-dist.yml up -d ``` -------------------------------- ### Runtime Configuration via config.yml Source: https://context7.com/4science/dspace-angular/llms.txt Configure UI, REST API, caching, authentication, theming, languages, and submission settings. Ensure correct paths and values for your DSpace instance. ```yaml # config/config.prod.yml ui: ssl: false host: localhost port: 4000 nameSpace: / # Server-side rendering cache for anonymous users (120 seconds) cache: anonymousMax: 120 anonymousMaxAge: 120 rest: ssl: true host: sandbox.dspace.org port: 443 nameSpace: /server cache: msToLive: default: 900000 # 15 minutes default cache TTL serverSide: debug: false botCache: enabled: true # cache responses for bots max: 1000 timeToLive: 86400000 # 24 hours auth: ui: timeUntilIdle: 900 # seconds until idle logout warning idleGracePeriod: 300 # seconds of grace before forced logout themes: - name: dspace # Optionally scope to a handle: handle: '10673/1' languages: - code: en label: English active: true - code: de label: Deutsch active: true - code: fr label: Français active: true submission: autosave: metadata: [] # auto-save on these metadata field changes timer: 5 # auto-save interval in minutes icons: metadata: - name: dc.author style: fas fa-user ``` -------------------------------- ### Displaying Other Information for List Entries Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html Iterates through additional information associated with a list entry, filtering out keys that start with 'data-' and displaying the translated key and its value. ```html * {{entry.value}} ``` ```html @for (item of entry.otherInformation | dsObjNgFor; track item) { @if (!item.key.startsWith('data-')) {* {{ 'form.other-information.' + item.key | translate }} : {{item.value}} } } ``` -------------------------------- ### Building for Production Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Command to only build the application for production, placing the compiled output in the 'dist' folder. This output can then be deployed or served separately. ```bash npm run build:prod ``` -------------------------------- ### Configure Node.js Server UI Options Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/Configuration.md Define UI settings for the Node.js server, such as SSL, host, and port, in a configuration file. ```yaml ui: ssl: false host: localhost port: 4000 nameSpace: / ``` -------------------------------- ### Run Unit Tests Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Execute unit tests using the command below. Ensure tests are placed in files ending with '*.component.spec.ts'. ```bash npm test ``` -------------------------------- ### Iterate and Display Bitstreams Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html Iterates over bitstreams and their updates, displaying details like name, description, and format. Includes logic for handling pagination options. ```html @if ((bitstreamsRD$ | async)?.payload; as bitstreamsList) { @if ((updates$ | async); as updates) { @for (entry of (tableEntries$ | async); track entry) { @if (updates[entry.id]; as update) { } } } ``` ```html @for (size of paginationOptions.pageSizeOptions; track size) {* {{size}} } ``` -------------------------------- ### Set DSPACE_APP_CONFIG_PATH Environment Variable Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/Configuration.md Specify an external configuration file path using the DSPACE_APP_CONFIG_PATH environment variable. ```bash DSPACE_APP_CONFIG_PATH=/usr/local/dspace/config/config.yml ``` -------------------------------- ### Allow Wrapper Class Usages Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/themed-component-usages.md Demonstrates correct usage of `ThemedComponent` wrappers in configuration objects. ```typescript import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component'; const config = { a: ThemedTestThemeableComponent, b: ChipsComponent, } ``` -------------------------------- ### Build Production DSpace-CRIS Angular Image Source: https://github.com/4science/dspace-angular/blob/main-cris/docker/README.md Builds a production-ready image for DSpace-CRIS Angular using Dockerfile.dist. A default demo version is built automatically. ```bash docker build -f Dockerfile.dist -t 4science/dspace-cris-angular:dspace-cris-2025_02_x-dist . ``` -------------------------------- ### Cleaning Project Files Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Provides commands for cleaning various parts of the project. Use `npm run clean` to remove everything including node_modules, `npm run clean:prod` for production build artifacts, and `npm run clean:dist` for the distribution directory. ```bash # clean everything, including node_modules. You'll need to run npm install again afterwards. npm run clean ``` ```bash # clean files generated by the production build (.ngfactory files, css files, etc) npm run clean:prod ``` ```bash # cleans the distribution directory npm run clean:dist ``` -------------------------------- ### Configure DSpace-Angular Environment Variables Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Override default configuration values by creating a .env file in the project root. Non-convention settings like host, port, namespace, and SSL can be set directly. Other settings follow a DSPACE_ prefix convention. ```bash DSPACE_HOST # The host name of the angular application DSPACE_PORT # The port number of the angular application DSPACE_NAMESPACE # The namespace of the angular application DSPACE_SSL # Whether the angular application uses SSL [true/false] ``` ```bash # The host name of the REST application rest.host => DSPACE_REST_HOST # The port number of the REST application rest.port => DSPACE_REST_PORT # The namespace of the REST application rest.nameSpace => DSPACE_REST_NAMESPACE ``` -------------------------------- ### Environment Variable Overrides for Configuration Source: https://context7.com/4science/dspace-angular/llms.txt Override configuration settings at runtime using DSPACE-prefixed environment variables. Dots in keys are converted to underscores, and all variables are uppercased. ```bash # Override REST host and port export DSPACE_REST_HOST=repo.example.org export DSPACE_REST_PORT=8080 export DSPACE_REST_SSL=true export DSPACE_REST_NAMESPACE=/server # Override UI binding export DSPACE_HOST=0.0.0.0 export DSPACE_PORT=4000 ``` -------------------------------- ### Displaying Login Record Details Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/statistics-page/login-statistics-page/login-statistics-page.component.html Displays details for a single login record within a loop. This includes the index, user name, email, and login count. ```html {{ i + 1 }} ``` ```html {{login.name}} ``` ```html {{login.email}} ``` ```html {{login.count}} ``` -------------------------------- ### Display Bitstream Properties Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html Displays the name, description, and format of a bitstream entry. The format's short description is fetched asynchronously. ```html {{ entry.name }} ``` ```html {{ entry.description }} ``` ```html {{ (entry.format | async)?.shortDescription }} ``` -------------------------------- ### Show More Button Logic Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/community-list-page/community-list/community-list.component.html Renders a 'Show More' button when the data source is not actively loading. ```html @if ((dataSource.loading$ | async) !== true) { {{ 'communityList.showMore' | translate }} } ``` -------------------------------- ### Environment Variable Overrides Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Demonstrates how environment variables can override legacy settings and variables in a .env file. These settings are collected at run time and written to a configuration file. ```bash DSPACE_UI_HOST => DSPACE_HOST DSPACE_UI_PORT => DSPACE_PORT DSPACE_UI_NAMESPACE => DSPACE_NAMESPACE DSPACE_UI_SSL => DSPACE_SSL ``` ```bash export DSPACE_HOST=demo.dspace.org export DSPACE_UI_PORT=4000 ``` -------------------------------- ### Injecting App Configuration in TypeScript Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Shows how to inject the application configuration into a UI component using dependency injection in TypeScript. Ensure the AppConfig interface and APP_CONFIG provider are correctly imported. ```typescript import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface'; ... constructor(@Inject(APP_CONFIG) private appConfig: AppConfig) {} ... ``` -------------------------------- ### Run DSpace Angular Tests Source: https://context7.com/4science/dspace-angular/llms.txt Execute unit tests using Karma/Jasmine, generate coverage reports, run ESLint for linting, check for circular dependencies, and run end-to-end tests with Cypress. Ensure the DSpace backend is running and configured correctly for E2E tests. ```bash # ── Unit tests (all) ────────────────────────────────────────────────────── npm test # ── Unit tests with coverage report ───────────────────────────────────── npm run coverage # Coverage report available at http://localhost:9876/ # ── Lint (ESLint) ──────────────────────────────────────────────────────── npm run lint # ── Check for circular dependencies ───────────────────────────────────── npm run check-circ-deps # ── E2E tests (requires running DSpace backend with test data) ─────────── # 1. Configure your local backend in config/config.dev.yml: # rest: { host: localhost, port: 8080, ssl: false } # 2. Ingest the DSpace Entities test data set # 3. Run Cypress: NODE_ENV=development ng e2e ``` -------------------------------- ### Importing Environment Variables in TypeScript Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Demonstrates a common way to import environment-specific variables directly into your TypeScript code. This is useful for accessing build-time configurations. ```typescript import { environment } from '../environment.ts'; ``` -------------------------------- ### Valid Themed Component Usage in HTML Templates Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/html/rules/themed-component-usages.md Demonstrates correct usage of themeable components using their `ds-test-themeable` selector in HTML templates, including with attributes. ```html ``` -------------------------------- ### Handling No Results and Loading States Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html Displays messages for 'no results' when the options list is empty and a 'loading' indicator while data is being fetched. It also iterates over the options list to display entries. ```html @if (optionsList && optionsList.length === 0) { {{ 'form.no-results' | translate }} } ``` ```html @for (listEntry of optionsList; track listEntry) { } ``` ```html @if (loading) { {{'form.loading' | translate}} } ``` -------------------------------- ### Override Node.js Server UI Configuration with Environment Variables Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/Configuration.md Override Node.js server UI configuration using environment variables. These variables take precedence over configuration files. ```bash DSPACE_SSL=true DSPACE_HOST=localhost DSPACE_PORT=4000 DSPACE_NAMESPACE=/ ``` ```bash DSPACE_UI_SSL=true DSPACE_UI_HOST=localhost DSPACE_UI_PORT=4000 DSPACE_UI_NAMESPACE=/ ``` -------------------------------- ### Build DSpace-CRIS Images from Local Branch Source: https://github.com/4science/dspace-angular/blob/main-cris/docker/README.md Builds DSpace-CRIS images using the Docker Compose file and the code from your current local branch. ```bash docker compose -f docker/docker-compose.yml build ``` -------------------------------- ### Iterating and Displaying Dropdown Options Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html This Angular template syntax iterates over the 'optionsList' to display each entry. It uses 'track listEntry' for efficient change detection and 'let i = $index' to access the item's index. The 'inputFormatter' function is used to format how each option is displayed. ```html @for (listEntry of optionsList; track listEntry; let i = $index) { {{inputFormatter(listEntry)}} } ``` -------------------------------- ### Create DSpace-CRIS Administrator Source: https://github.com/4science/dspace-angular/blob/main-cris/docker/README.md Creates a new administrator user for the DSpace-CRIS instance using the CLI container. Ensure the DSpace-CRIS REST container is running. ```bash docker compose -p dcris25 -f docker/cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en ``` -------------------------------- ### Iterating and Rendering Suggestion Options Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/input-suggestions/validation-suggestions/validation-suggestions.component.html This code iterates over a list of suggestions and renders them as clickable links. It uses an Angular structural directive for iteration and a JavaScript void link as a placeholder. ```html @for (suggestionOption of suggestions; track suggestionOption) { [](javascript:void(0); } ``` -------------------------------- ### Display Timestamp with Date Formatting Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html Conditionally displays the 'queueLastStartTime' if it exists, formatted as 'yyyy/MM/d hh:mm:ss'. Shows 'n/a' if the timestamp is not available. ```html @if (message.queueLastStartTime) { {{ message.queueLastStartTime | date:"yyyy/MM/d hh:mm:ss" }} } @if (!message.queueLastStartTime) { n/a } ``` -------------------------------- ### Allow Wrapper Selectors in Test Queries Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/themed-component-usages.md Shows valid CSS selectors for themeable components in test files. ```typescript By.css('ds-themeable'); By.css('#test > ds-themeable > #nest'); ``` -------------------------------- ### Load Assetstore Content and Re-index Source: https://github.com/4science/dspace-angular/blob/main-cris/docker/README.md This command loads assetstore content and triggers a re-index of the repository. It utilizes specific Docker compose files for CLI operations. ```bash docker compose -p dcris25 -f docker/cli.yml -f docker/cli.assetstore.yml run --rm dspace-cli ``` -------------------------------- ### Upgrade Existing Dependency with npm Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md Use this command to upgrade existing dependencies to their latest versions or a specific version. This helps in keeping your project up-to-date with the latest features and security patches. ```bash npm update some-lib ``` ```bash npm update some-lib@version ``` -------------------------------- ### Generate Unit Test Coverage Report Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md This command generates a coverage report for unit tests, accessible at http://localhost:9876/. Ensure Karma's 'autoWatch' and 'singleRun' options are configured appropriately if needed. ```bash npm run coverage ``` -------------------------------- ### Iterating and Displaying Entities in Dropdown Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/entity-dropdown/entity-dropdown.component.html Renders a list of entities, sorted by their translated labels. Uses the dsSort pipe for sorting. ```html @for (listItem of searchListEntity | dsSort: 'translatedLabel'; track listItem) { * * {{ listItem.translatedLabel }} } ``` -------------------------------- ### Configure DSpace REST Endpoint Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/Configuration.md Set DSpace REST endpoint configuration, including SSL, host, port, and namespace, in a configuration file. ```yaml rest: ssl: true host: demo.dspace.org port: 443 nameSpace: /server } ``` -------------------------------- ### Iterate and Display Scripts Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/process-page/form/scripts-select/scripts-select.component.html Iterates over a list of scripts and displays their names. Also includes a conditional check for loading state. ```HTML @for (script of scripts; track script) { {{ script.name }} } @if ((isLoading$ | async)) { } ``` -------------------------------- ### Iterate and Render Content with Links Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/context-help-wrapper/context-help-wrapper.component.html Iterates over parsed content, rendering each item as a link if an href is present, otherwise as plain text. This is useful for displaying dynamic lists of information. ```html @for (elem of (parsedContent$ | async); track elem) { @if (elem.href) { [{{elem.text}}]({{elem.href}}) } @else { {{ elem.text }} } } ``` -------------------------------- ### Displaying Individual EPerson Data Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/access-control/epeople-registry/epeople-registry.component.html Renders the details for a single ePerson within the registry table, including their ID, name, and email. It also includes a conditional check for the ability to delete the ePerson. ```html {{epersonDto.eperson.id}} {{ dsoNameService.getName(epersonDto.eperson) }} {{epersonDto.eperson.email}} @if (epersonDto.ableToDelete) { } ``` -------------------------------- ### Configure DSpace REST API via Environment Variables Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md These environment variables can be used to configure the DSpace REST API endpoint for end-to-end tests, offering an alternative to modifying configuration files. ```bash DSPACE_REST_SSL = false DSPACE_REST_HOST = localhost DSPACE_REST_PORT = 8080 ``` -------------------------------- ### Iterate and Display Top Objects with Columns Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/explore/section-component/multi-column-top-section/multi-column-top-section.component.html Iterates over a list of top objects (likely fetched asynchronously) and for each object, iterates over columns to display their corresponding values. This is useful for rendering data rows in a table or list format. ```html @for (topObject of ( topObjects | async ); track topObject; let last = $last) { @for (column of getColumns(); track column) { {{getColumnValue(topObject,column)}} } } ``` -------------------------------- ### Conditional Rendering for Loading State Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/access-control/group-registry/groups-registry.component.html Uses the async pipe to conditionally render content based on the loading state. An empty block indicates no content is shown while loading. ```html @if (loading$ | async) { } ``` -------------------------------- ### Allow Inheriting from Base Class Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/themed-component-usages.md Illustrates extending a base themeable component class. ```typescript import { TestThemeableComponent } from './app/test/test-themeable.component'; export class ThemedAdminSidebarComponent extends ThemedComponent { } ``` -------------------------------- ### Valid Themed Component Usage in TypeScript Templates Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/html/rules/themed-component-usages.md Shows the correct way to use themeable components within TypeScript templates. ```html ``` -------------------------------- ### Find and List Items with ItemDataService Source: https://context7.com/4science/dspace-angular/llms.txt Demonstrates how to find a single item by its UUID and list items with pagination and sorting options. Ensure the `ItemDataService` is injected into your component. ```typescript import { Component, OnInit } from '@angular/core'; import { ItemDataService } from '../core/data/item-data.service'; import { Item } from '../core/shared/item.model'; import { RemoteData } from '../core/data/remote-data'; import { PaginatedList } from '../core/data/paginated-list.model'; import { FindListOptions } from '../core/data/find-list-options.model'; import { SortDirection } from '../core/cache/models/sort-options.model'; import { followLink } from '../shared/utils/follow-link-config.model'; @Component({ selector: 'ds-item-example', template: '' }) export class ItemExampleComponent implements OnInit { constructor(private itemService: ItemDataService) {} ngOnInit() { const itemId = 'a1b2c3d4-0000-0000-0000-000000000001'; // ── Find a single Item by UUID ──────────────────────────────────────── this.itemService.findById(itemId, true, true, followLink('bundles')) .subscribe((rd: RemoteData) => { if (rd.hasSucceeded) console.log('Item name:', rd.payload.name); }); // ── List Items with pagination and sorting ──────────────────────────── const opts: FindListOptions = { currentPage: 1, elementsPerPage: 10, sort: { field: 'dc.date.issued', direction: SortDirection.DESC }, }; this.itemService.findAll(opts).subscribe((rd: RemoteData>) => { if (rd.hasSucceeded) { rd.payload.page.forEach(item => console.log(item.uuid, item.name)); } }); } } ``` -------------------------------- ### Handle Array Replacements Correctly Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/themed-component-usages.md Shows how the linter automatically corrects themeable component usages within arrays. ```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, ]; ``` ``` -------------------------------- ### Display Metric Icon and Label Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/metric/metric-default/metric-default.component.html Conditionally displays the metric's icon if available. Translates the metric label using the 'translate' pipe. ```html @if (metric && metric.icon) { } ``` ```html {{ "item.page.metric.label." + metric.metricType | translate }} ``` -------------------------------- ### Server-Side Rendering (SSR) with Express Source: https://context7.com/4science/dspace-angular/llms.txt The Express server handles SSR, serving cached HTML for bots and using transfer state to prevent duplicate API calls between server and browser. Configure the engine with bootstrap module, document path, URL, public path, and providers. ```typescript // server.ts (simplified) import 'zone.js/node'; import { APP_BASE_HREF } from '@angular/common'; import { CommonEngine } from '@angular/ssr'; import express from 'express'; import { AppServerModule } from './src/main.server'; const server = express(); const engine = new CommonEngine(); server.get('*', (req, res) => { engine.render({ bootstrap: AppServerModule, documentFilePath: 'dist/browser/index.html', url: req.url, publicPath: 'dist/browser', providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }], }).then(html => res.send(html)) .catch(err => { console.error('SSR render error:', err); res.sendFile('dist/browser/index.html', { root: '.' }); }); }); server.listen(4000, () => console.log('SSR server running on port 4000')); ``` -------------------------------- ### Display Metric Acquisition Date Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/metric/metric-default/metric-default.component.html Displays the metric's acquisition date, formatted using the 'date' pipe for localization. ```html {{ "item.page.metric.acquisition-date" | translate }} {{ metric.acquisitionDate | date }} ``` -------------------------------- ### Translate and Display Bundle Name Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html Translates and displays the bundle name using the provided 'bundleName' variable. ```html {{'item.edit.bitstreams.bundle.name' | translate:{ name: bundleName } }} ``` -------------------------------- ### Conditional Rendering of Metadata Group Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metadata/rendering-types/metadataGroup/table/table.component.html This snippet demonstrates conditional rendering based on an asynchronous initialization status. It iterates over metadata groups and components to be rendered. ```html @if ((initialized | async)) { @for (field of metadataGroup; track field) { } @for (index of componentsToBeRenderedMap.keys(); track index) { @for (mdg of componentsToBeRenderedMap.get(index); track mdg) { } } } ``` -------------------------------- ### Display Collections and Loading State in Angular Template Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/item-page/field-components/collections/collections.component.html Iterates over collections, displays their names, and handles loading and 'load more' states using Angular's template syntax and async pipe. ```html @for (collection of (this.collections$ | async); track collection; let last = $last) { {{ dsoNameService.getName(collection) }}@if (!last) { } } @if (isLoading$ | async) { {{'item.page.collections.loading' | translate}} } @if ((isLoading$ | async) !== true && (hasMore$ | async)) { [{{'item.page.collections.load-more' | translate}}](javascript:void(0);) } ``` -------------------------------- ### Run End-to-End Tests with Development Configuration Source: https://github.com/4science/dspace-angular/blob/main-cris/README.md To run end-to-end tests against the development configuration, set the NODE_ENV environment variable to 'development' before executing the 'ng e2e' command. ```bash NODE_ENV=development ng e2e ``` -------------------------------- ### Configure Lazy-Loaded Application Routes Source: https://context7.com/4science/dspace-angular/llms.txt Define application routes in `app-routes.ts` for lazy loading modules. Use guards like `AuthenticatedGuard` and `SiteAdministratorGuard` to protect routes. ```typescript // src/app/app-routes.ts import { Route } from '@angular/router'; import { AuthenticatedGuard } from './core/auth/authenticated.guard'; import { SiteAdministratorGuard } from './core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; export const APP_ROUTES: Route[] = [ // Public routes { path: '', pathMatch: 'full', redirectTo: '/home' }, { path: 'home', loadChildren: () => import('./home-page/home-page-routes').then(m => m.HOME_PAGE_ROUTES) }, { path: 'communities/:id', loadChildren: () => import('./community-page/community-page-routes').then(m => m.COMMUNITY_PAGE_ROUTES) }, { path: 'collections/:id', loadChildren: () => import('./collection-page/collection-page-routes').then(m => m.COLLECTION_PAGE_ROUTES) }, { path: 'items/:id', loadChildren: () => import('./item-page/item-page-routes').then(m => m.ITEM_PAGE_ROUTES) }, { path: 'search', loadChildren: () => import('./search-page/search-page-routes').then(m => m.SEARCH_PAGE_ROUTES) }, // Authenticated routes { path: 'mydspace', canActivate: [AuthenticatedGuard], loadChildren: () => import('./my-dspace-page/my-dspace-page-routes').then(m => m.MY_DSPACE_PAGE_ROUTES) }, { path: 'submit', canActivate: [AuthenticatedGuard], loadChildren: () => import('./submit-page/submit-page-routes').then(m => m.SUBMIT_PAGE_ROUTES) }, { path: 'workspaceitems/:id/edit', canActivate: [AuthenticatedGuard], loadChildren: () => import('./submission/submission-edit-routes').then(m => m.SUBMISSION_EDIT_ROUTES) }, // Admin routes { path: 'admin', canActivate: [SiteAdministratorGuard], loadChildren: () => import('./admin/admin-routes').then(m => m.ADMIN_ROUTES) }, ]; ``` -------------------------------- ### Load Content from AIP Files Source: https://github.com/4science/dspace-angular/blob/main-cris/docker/README.md Loads content from AIP files into the DSpace-CRIS instance using the CLI container. This command requires the 'cli.ingest.yml' configuration file. ```bash docker compose -p dcris25 -f docker/cli.yml -f ./docker/cli.ingest.yml run --rm dspace-cli ``` -------------------------------- ### Display View Detail Button Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/metric/metric-default/metric-default.component.html Conditionally displays a 'View Detail' button if a URL is provided. The button's label is translated. ```html @if (url) { {{ "item.page.metric.label.view-detail-btn" | translate }} } ``` -------------------------------- ### Angular Iteration and Conditional Rendering Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/social/social.component.html Demonstrates Angular's @for and @if directives for iterating over a list of buttons and conditionally displaying a share button. ```html @for (button of buttonList; track button) { } @if (showPlusButton) { [](https://www.addtoany.com/share)} ``` -------------------------------- ### Valid Component Declarations Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/no-default-standalone-value.md Demonstrates valid ways to declare Angular components. Not setting the `standalone` value or explicitly setting it to `false` are both acceptable. ```typescript @Component({ selector: 'ds-test', }) class TestComponent {} ``` ```typescript @Component({ selector: 'ds-test', standalone: false, }) class TestComponent {} ``` -------------------------------- ### Display Page Size Options in Angular Template Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/page-size-selector/page-size-selector.component.html Iterates over available page size options from an observable and displays them. Ensure paginationOptions$ is properly defined and emits an object with pageSizeOptions. ```html @for (pageSizeOption of (paginationOptions$ | async).pageSizeOptions; track pageSizeOption) { {{pageSizeOption}} } ``` -------------------------------- ### Displaying Item Thumbnail and Title Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/metadata-link-view/metadata-link-view-popover/metadata-link-view-popover.component.html Conditionally displays the item's thumbnail if available, and then shows the first metadata value for 'dc.title'. ```html @if (item.thumbnail | async) { } {{item.firstMetadataValue('dc.title')}} ``` -------------------------------- ### Display Notification Detail and Reprocess Action Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/admin/admin-notify-dashboard/admin-notify-search-result/admin-notify-search-result.component.html Displays a 'detail' translation and conditionally renders a 'reprocess' translation if the 'queueStatusLabel' is not 'reprocessStatus' and is included in 'validStatusesForReprocess'. ```html {{ 'notify-message-result.detail' | translate }} @if (message.queueStatusLabel !== reprocessStatus && validStatusesForReprocess.includes(message.queueStatusLabel)) { {{ 'notify-message-result.reprocess' | translate }} } ``` -------------------------------- ### Display Item Metadata or Placeholder Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component.html Conditionally renders item metadata values if they exist, otherwise displays a translated placeholder. This is useful for showing field information in a user-friendly way. ```html @if (item.hasMetadata(metadata)) { @for (mdValue of allMetadataValues(metadata); track mdValue; let last = $last) { {{mdValue}}@if (!last) { } } } @if (!item.hasMetadata(metadata)) { {{(placeholder | translate)}} } ``` -------------------------------- ### Override DSpace REST Endpoint Configuration with Environment Variables Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/Configuration.md Override DSpace REST endpoint configuration using environment variables. These variables take precedence over configuration files. ```bash DSPACE_REST_SSL=true DSPACE_REST_HOST=demo.dspace.org DSPACE_REST_PORT=443 DSPACE_REST_NAMESPACE=/server ``` -------------------------------- ### Valid Regular Component Selector Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/themed-component-selectors.md Demonstrates a valid selector for a regular, non-themeable component. ```typescript @Component({ selector: 'ds-something', }) class Something { } ``` -------------------------------- ### Loading State Indicator Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.html Conditionally render content while data is being loaded, typically used to show a spinner or placeholder. ```html @if ((isLoading$ | async)) { } ``` -------------------------------- ### Valid Themeable Component Selectors Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/themed-component-selectors.md Shows the correct selector pattern for themeable components, including base, wrapper, and override classes. ```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 { } ``` -------------------------------- ### Expand/Collapse Button Logic Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/community-list-page/community-list/community-list.component.html Conditionally displays 'expand' or 'collapse' text based on the node's expansion state and whether it has children. Requires an asynchronous check for child existence. ```html @if (hasChild(null, node) | async) { {{ (node.isExpanded ? 'communityList.collapse' : 'communityList.expand') | translate:{ name: dsoNameService.getName(node.payload) } }} } ``` -------------------------------- ### Loading Indicator Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/search/search-results/search-results.component.html Displays a loading indicator when the isLoading function returns true. ```html @if (isLoading()) { } ``` -------------------------------- ### Iterate and Display Item Representations Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html Iterates over a list of objects and their associated representations. Includes conditional logic for displaying pagination controls. ```html @for (objectPage of objects; track objectPage; let i = $index) { @for (rep of representations; track rep) { } @if ((i + 1) === objects.length && (i > 0) && (!representations || representations?.length === 0)) { } @if ((i + 1) === objects.length && representations?.length > 0) { } } ``` -------------------------------- ### Conditional 'Show More' Link Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/search/search-filters/search-filter/search-text-filter/search-text-filter.component.html Conditionally display a 'show more' link if the current page is not the last page. The link navigates to a javascript:void(0) placeholder. ```html @if ((isLastPage$ | async) !== true) { [{{"search.filters.filter.show-more" | translate}}](javascript:void(0);) } ``` -------------------------------- ### Displaying 'More Info' Label Source: https://github.com/4science/dspace-angular/blob/main-cris/src/app/shared/metadata-link-view/metadata-link-view-popover/metadata-link-view-popover.component.html Displays a translated label for 'more info' at the end of the metadata list. ```html {{ "metadata-link-view.popover.label.more-info" | translate }} ``` -------------------------------- ### Dynamic API Endpoint Resolution with HALEndpointService Source: https://context7.com/4science/dspace-angular/llms.txt Utilize HALEndpointService to dynamically discover API URLs at runtime by traversing the HAL link graph. This avoids hardcoding URLs and ensures adaptability to API changes. ```typescript import { Component, OnInit } from '@angular/core'; import { HALEndpointService } from '../core/shared/hal-endpoint.service'; @Component({ selector: 'ds-example', template: '' }) export class ExampleComponent implements OnInit { constructor(private halService: HALEndpointService) {} ngOnInit() { // Resolve a top-level endpoint by its HAL link name this.halService.getEndpoint('items').subscribe(href => { console.log(href); // https://sandbox.dspace.org/server/api/core/items }); // Resolve a nested endpoint (traverses link chain) this.halService.getEndpoint('communities/subcommunities').subscribe(href => { console.log(href); // resolved subcommunities href }); // Check if an endpoint exists on the REST API this.halService.isEnabledOnRestApi('ldn').subscribe(enabled => { if (enabled) { console.log('LDN notifications are available'); } }); // Get the root REST URL directly const rootHref = this.halService.getRootHref(); // e.g. https://sandbox.dspace.org/server } } ``` -------------------------------- ### Correctly Aliased Import Source: https://github.com/4science/dspace-angular/blob/main-cris/docs/lint/ts/rules/alias-imports.md Demonstrates a correctly aliased import for 'rxjs/of' using the 'observableOf' alias. This is used when the alias is explicitly defined in the configuration. ```typescript import { of as observableOf } from 'rxjs'; ``` ```json { "aliases": [ { "package": "rxjs", "imported": "of", "local": "observableOf" } ] } ```