Merge remote-tracking branch 'dspace/main' into feature-process_polling

This commit is contained in:
Koen Pauwels
2023-09-07 11:02:10 +02:00
115 changed files with 4458 additions and 1338 deletions

View File

@@ -1,26 +0,0 @@
# This workflow runs whenever a new pull request is created
# TEMPORARILY DISABLED. Unfortunately this doesn't work for PRs created from forked repositories (which is how we tend to create PRs).
# There is no known workaround yet. See https://github.community/t/how-to-use-github-token-for-prs-from-forks/16818
name: Pull Request opened
# Only run for newly opened PRs against the "main" branch
on:
pull_request:
types: [opened]
branches:
- main
jobs:
automation:
runs-on: ubuntu-latest
steps:
# Assign the PR to whomever created it. This is useful for visualizing assignments on project boards
# See https://github.com/marketplace/actions/pull-request-assigner
- name: Assign PR to creator
uses: thomaseizinger/assign-pr-creator-action@v1.0.0
# Note, this authentication token is created automatically
# See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Ignore errors. It is possible the PR was created by someone who cannot be assigned
continue-on-error: true

View File

@@ -5,12 +5,16 @@
# because CodeQL requires a fresh build with all tests *disabled*. # because CodeQL requires a fresh build with all tests *disabled*.
name: "Code Scanning" name: "Code Scanning"
# Run this code scan for all pushes / PRs to main branch. Also run once a week. # Run this code scan for all pushes / PRs to main or maintenance branches. Also run once a week.
on: on:
push: push:
branches: [ main ] branches:
- main
- 'dspace-**'
pull_request: pull_request:
branches: [ main ] branches:
- main
- 'dspace-**'
# Don't run if PR is only updating static documentation # Don't run if PR is only updating static documentation
paths-ignore: paths-ignore:
- '**/*.md' - '**/*.md'

View File

@@ -15,29 +15,35 @@ on:
permissions: permissions:
contents: read # to fetch code (actions/checkout) contents: read # to fetch code (actions/checkout)
env:
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
# For a new commit on default branch (main), use the literal tag 'latest' on Docker image.
# For a new commit on other branches, use the branch name as the tag for Docker image.
# For a new tag, copy that tag name as the tag for Docker image.
IMAGE_TAGS: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=tag
# Define default tag "flavor" for docker/metadata-action per
# https://github.com/docker/metadata-action#flavor-input
# We manage the 'latest' tag ourselves to the 'main' branch (see settings above)
TAGS_FLAVOR: |
latest=false
# Architectures / Platforms for which we will build Docker images
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
# If this is NOT a PR (e.g. a tag or merge commit), also build for ARM64.
PLATFORMS: linux/amd64${{ github.event_name != 'pull_request' && ', linux/arm64' || '' }}
jobs: jobs:
docker: ###############################################
# Build/Push the 'dspace/dspace-angular' image
###############################################
dspace-angular:
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular' # Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular'
if: github.repository == 'dspace/dspace-angular' if: github.repository == 'dspace/dspace-angular'
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
# For a new commit on default branch (main), use the literal tag 'dspace-7_x' on Docker image.
# For a new commit on other branches, use the branch name as the tag for Docker image.
# For a new tag, copy that tag name as the tag for Docker image.
IMAGE_TAGS: |
type=raw,value=dspace-7_x,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=tag
# Define default tag "flavor" for docker/metadata-action per
# https://github.com/docker/metadata-action#flavor-input
# We turn off 'latest' tag by default.
TAGS_FLAVOR: |
latest=false
# Architectures / Platforms for which we will build Docker images
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
# If this is NOT a PR (e.g. a tag or merge commit), also build for ARM64.
PLATFORMS: linux/amd64${{ github.event_name != 'pull_request' && ', linux/arm64' || '' }}
steps: steps:
# https://github.com/actions/checkout # https://github.com/actions/checkout
@@ -61,9 +67,6 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }} password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
###############################################
# Build/Push the 'dspace/dspace-angular' image
###############################################
# https://github.com/docker/metadata-action # https://github.com/docker/metadata-action
# Get Metadata for docker_build step below # Get Metadata for docker_build step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular' image - name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular' image
@@ -77,7 +80,7 @@ jobs:
# https://github.com/docker/build-push-action # https://github.com/docker/build-push-action
- name: Build and push 'dspace-angular' image - name: Build and push 'dspace-angular' image
id: docker_build id: docker_build
uses: docker/build-push-action@v3 uses: docker/build-push-action@v4
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
@@ -89,9 +92,36 @@ jobs:
tags: ${{ steps.meta_build.outputs.tags }} tags: ${{ steps.meta_build.outputs.tags }}
labels: ${{ steps.meta_build.outputs.labels }} labels: ${{ steps.meta_build.outputs.labels }}
##################################################### #############################################################
# Build/Push the 'dspace/dspace-angular' image ('-dist' tag) # Build/Push the 'dspace/dspace-angular' image ('-dist' tag)
##################################################### #############################################################
dspace-angular-dist:
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular'
if: github.repository == 'dspace/dspace-angular'
runs-on: ubuntu-latest
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v3
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU emulation to build for multiple architectures
uses: docker/setup-qemu-action@v2
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
# https://github.com/docker/metadata-action # https://github.com/docker/metadata-action
# Get Metadata for docker_build_dist step below # Get Metadata for docker_build_dist step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular-dist' image - name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular-dist' image
@@ -107,7 +137,7 @@ jobs:
- name: Build and push 'dspace-angular-dist' image - name: Build and push 'dspace-angular-dist' image
id: docker_build_dist id: docker_build_dist
uses: docker/build-push-action@v3 uses: docker/build-push-action@v4
with: with:
context: . context: .
file: ./Dockerfile.dist file: ./Dockerfile.dist

View File

@@ -1,11 +1,12 @@
# This workflow checks open PRs for merge conflicts and labels them when conflicts are found # This workflow checks open PRs for merge conflicts and labels them when conflicts are found
name: Check for merge conflicts name: Check for merge conflicts
# Run whenever the "main" branch is updated # Run this for all pushes (i.e. merges) to 'main' or maintenance branches
# NOTE: This means merge conflicts are only checked for when a PR is merged to main.
on: on:
push: push:
branches: [ main ] branches:
- main
- 'dspace-**'
# So that the `conflict_label_name` is removed if conflicts are resolved, # So that the `conflict_label_name` is removed if conflicts are resolved,
# we allow this to run for `pull_request_target` so that github secrets are available. # we allow this to run for `pull_request_target` so that github secrets are available.
pull_request_target: pull_request_target:
@@ -24,6 +25,8 @@ jobs:
# See: https://github.com/prince-chrismc/label-merge-conflicts-action # See: https://github.com/prince-chrismc/label-merge-conflicts-action
- name: Auto-label PRs with merge conflicts - name: Auto-label PRs with merge conflicts
uses: prince-chrismc/label-merge-conflicts-action@v3 uses: prince-chrismc/label-merge-conflicts-action@v3
# Ignore any failures -- may occur (randomly?) for older, outdated PRs.
continue-on-error: true
# Add "merge conflict" label if a merge conflict is detected. Remove it when resolved. # Add "merge conflict" label if a merge conflict is detected. Remove it when resolved.
# Note, the authentication token is created automatically # Note, the authentication token is created automatically
# See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token

View File

@@ -0,0 +1,46 @@
# This workflow will attempt to port a merged pull request to
# the branch specified in a "port to" label (if exists)
name: Port merged Pull Request
# Only run for merged PRs against the "main" or maintenance branches
# We allow this to run for `pull_request_target` so that github secrets are available
# (This is required when the PR comes from a forked repo)
on:
pull_request_target:
types: [ closed ]
branches:
- main
- 'dspace-**'
permissions:
contents: write # so action can add comments
pull-requests: write # so action can create pull requests
jobs:
port_pr:
runs-on: ubuntu-latest
# Don't run on closed *unmerged* pull requests
if: github.event.pull_request.merged
steps:
# Checkout code
- uses: actions/checkout@v3
# Port PR to other branch (ONLY if labeled with "port to")
# See https://github.com/korthout/backport-action
- name: Create backport pull requests
uses: korthout/backport-action@v1
with:
# Trigger based on a "port to [branch]" label on PR
# (This label must specify the branch name to port to)
label_pattern: '^port to ([^ ]+)$'
# Title to add to the (newly created) port PR
pull_title: '[Port ${target_branch}] ${pull_title}'
# Description to add to the (newly created) port PR
pull_description: 'Port of #${pull_number} by @${pull_author} to `${target_branch}`.'
# Copy all labels from original PR to (newly created) port PR
# NOTE: The labels matching 'label_pattern' are automatically excluded
copy_labels_pattern: '.*'
# Skip any merge commits in the ported PR. This means only non-merge commits are cherry-picked to the new PR
merge_commits: 'skip'
# Use a personal access token (PAT) to create PR as 'dspace-bot' user.
# A PAT is required in order for the new PR to trigger its own actions (for CI checks)
github_token: ${{ secrets.PR_PORT_TOKEN }}

View File

@@ -0,0 +1,24 @@
# This workflow runs whenever a new pull request is created
name: Pull Request opened
# Only run for newly opened PRs against the "main" or maintenance branches
# We allow this to run for `pull_request_target` so that github secrets are available
# (This is required to assign a PR back to the creator when the PR comes from a forked repo)
on:
pull_request_target:
types: [ opened ]
branches:
- main
- 'dspace-**'
permissions:
pull-requests: write
jobs:
automation:
runs-on: ubuntu-latest
steps:
# Assign the PR to whomever created it. This is useful for visualizing assignments on project boards
# See https://github.com/toshimaru/auto-author-assign
- name: Assign PR to creator
uses: toshimaru/auto-author-assign@v1.6.2

View File

@@ -2,7 +2,7 @@
# See https://github.com/DSpace/dspace-angular/tree/main/docker for usage details # See https://github.com/DSpace/dspace-angular/tree/main/docker for usage details
# Test build: # Test build:
# docker build -f Dockerfile.dist -t dspace/dspace-angular:dspace-7_x-dist . # docker build -f Dockerfile.dist -t dspace/dspace-angular:latest-dist .
FROM node:18-alpine as build FROM node:18-alpine as build

View File

@@ -157,8 +157,8 @@ DSPACE_UI_SSL => DSPACE_SSL
The same settings can also be overwritten by setting system environment variables instead, E.g.: The same settings can also be overwritten by setting system environment variables instead, E.g.:
```bash ```bash
export DSPACE_HOST=api7.dspace.org export DSPACE_HOST=demo.dspace.org
export DSPACE_UI_PORT=4200 export DSPACE_UI_PORT=4000
``` ```
The priority works as follows: **environment variable** overrides **variable in `.env` file** overrides external config set by `DSPACE_APP_CONFIG_PATH` overrides **`config.(prod or dev).yml`** The priority works as follows: **environment variable** overrides **variable in `.env` file** overrides external config set by `DSPACE_APP_CONFIG_PATH` overrides **`config.(prod or dev).yml`**
@@ -288,7 +288,7 @@ E2E tests (aka integration tests) use [Cypress.io](https://www.cypress.io/). Con
The test files can be found in the `./cypress/integration/` folder. The test files can be found in the `./cypress/integration/` folder.
Before you can run e2e tests, two things are REQUIRED: Before you can run e2e tests, two things are REQUIRED:
1. You MUST be running the DSpace backend (i.e. REST API) locally. The e2e tests will *NOT* succeed if run against our demo REST API (https://api7.dspace.org/server/), as that server is uncontrolled and may have content added/removed at any time. 1. You MUST be running the DSpace backend (i.e. REST API) locally. The e2e tests will *NOT* succeed if run against our demo/sandbox REST API (https://demo.dspace.org/server/ or https://sandbox.dspace.org/server/), as those sites may have content added/removed at any time.
* After starting up your backend on localhost, make sure either your `config.prod.yml` or `config.dev.yml` has its `rest` settings defined to use that localhost backend. * After starting up your backend on localhost, make sure either your `config.prod.yml` or `config.dev.yml` has its `rest` settings defined to use that localhost backend.
* If you'd prefer, you may instead use environment variables as described at [Configuring](#configuring). For example: * If you'd prefer, you may instead use environment variables as described at [Configuring](#configuring). For example:
``` ```

View File

@@ -22,7 +22,7 @@ ui:
# 'synced' with the 'dspace.server.url' setting in your backend's local.cfg. # 'synced' with the 'dspace.server.url' setting in your backend's local.cfg.
rest: rest:
ssl: true ssl: true
host: api7.dspace.org host: sandbox.dspace.org
port: 443 port: 443
# NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript # NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: /server nameSpace: /server
@@ -292,33 +292,33 @@ themes:
# #
# # A theme with a handle property will match the community, collection or item with the given # # A theme with a handle property will match the community, collection or item with the given
# # handle, and all collections and/or items within it # # handle, and all collections and/or items within it
# - name: 'custom', # - name: custom
# handle: '10673/1233' # handle: 10673/1233
# #
# # A theme with a regex property will match the route using a regular expression. If it # # A theme with a regex property will match the route using a regular expression. If it
# # matches the route for a community or collection it will also apply to all collections # # matches the route for a community or collection it will also apply to all collections
# # and/or items within it # # and/or items within it
# - name: 'custom', # - name: custom
# regex: 'collections\/e8043bc2.*' # regex: collections\/e8043bc2.*
# #
# # A theme with a uuid property will match the community, collection or item with the given # # A theme with a uuid property will match the community, collection or item with the given
# # ID, and all collections and/or items within it # # ID, and all collections and/or items within it
# - name: 'custom', # - name: custom
# uuid: '0958c910-2037-42a9-81c7-dca80e3892b4' # uuid: 0958c910-2037-42a9-81c7-dca80e3892b4
# #
# # The extends property specifies an ancestor theme (by name). Whenever a themed component is not found # # The extends property specifies an ancestor theme (by name). Whenever a themed component is not found
# # in the current theme, its ancestor theme(s) will be checked recursively before falling back to default. # # in the current theme, its ancestor theme(s) will be checked recursively before falling back to default.
# - name: 'custom-A', # - name: custom-A
# extends: 'custom-B', # extends: custom-B
# # Any of the matching properties above can be used # # Any of the matching properties above can be used
# handle: '10673/34' # handle: 10673/34
# #
# - name: 'custom-B', # - name: custom-B
# extends: 'custom', # extends: custom
# handle: '10673/12' # handle: 10673/12
# #
# # A theme with only a name will match every route # # A theme with only a name will match every route
# name: 'custom' # name: custom
# #
# # This theme will use the default bootstrap styling for DSpace components # # This theme will use the default bootstrap styling for DSpace components
# - name: BASE_THEME_NAME # - name: BASE_THEME_NAME

View File

@@ -1,5 +1,5 @@
rest: rest:
ssl: true ssl: true
host: api7.dspace.org host: sandbox.dspace.org
port: 443 port: 443
nameSpace: /server nameSpace: /server

View File

@@ -1,4 +1,3 @@
import { Options } from 'cypress-axe';
import { testA11y } from 'cypress/support/utils'; import { testA11y } from 'cypress/support/utils';
describe('Community List Page', () => { describe('Community List Page', () => {
@@ -13,13 +12,6 @@ describe('Community List Page', () => {
cy.get('[data-test="expand-button"]').click({ multiple: true }); cy.get('[data-test="expand-button"]').click({ multiple: true });
// Analyze <ds-community-list-page> for accessibility issues // Analyze <ds-community-list-page> for accessibility issues
// Disable heading-order checks until it is fixed testA11y('ds-community-list-page');
testA11y('ds-community-list-page',
{
rules: {
'heading-order': { enabled: false }
}
} as Options
);
}); });
}); });

View File

@@ -11,8 +11,7 @@ describe('Header', () => {
testA11y({ testA11y({
include: ['ds-header'], include: ['ds-header'],
exclude: [ exclude: [
['#search-navbar-container'], // search in navbar has duplicative ID. Will be fixed in #1174 ['#search-navbar-container'] // search in navbar has duplicative ID. Will be fixed in #1174
['.dropdownLogin'] // "Log in" link has color contrast issues. Will be fixed in #1149
], ],
}); });
}); });

View File

@@ -1,4 +1,3 @@
import { Options } from 'cypress-axe';
import { TEST_ENTITY_PUBLICATION } from 'cypress/support/e2e'; import { TEST_ENTITY_PUBLICATION } from 'cypress/support/e2e';
import { testA11y } from 'cypress/support/utils'; import { testA11y } from 'cypress/support/utils';
@@ -19,13 +18,16 @@ describe('Item Page', () => {
cy.get('ds-item-page').should('be.visible'); cy.get('ds-item-page').should('be.visible');
// Analyze <ds-item-page> for accessibility issues // Analyze <ds-item-page> for accessibility issues
// Disable heading-order checks until it is fixed testA11y('ds-item-page');
testA11y('ds-item-page', });
{
rules: { it('should pass accessibility tests on full item page', () => {
'heading-order': { enabled: false } cy.visit(ENTITYPAGE + '/full');
}
} as Options // <ds-full-item-page> tag must be loaded
); cy.get('ds-full-item-page').should('be.visible');
// Analyze <ds-full-item-page> for accessibility issues
testA11y('ds-full-item-page');
}); });
}); });

View File

@@ -1,4 +1,5 @@
import { TEST_ADMIN_PASSWORD, TEST_ADMIN_USER, TEST_ENTITY_PUBLICATION } from 'cypress/support/e2e'; import { TEST_ADMIN_PASSWORD, TEST_ADMIN_USER, TEST_ENTITY_PUBLICATION } from 'cypress/support/e2e';
import { testA11y } from 'cypress/support/utils';
const page = { const page = {
openLoginMenu() { openLoginMenu() {
@@ -123,4 +124,15 @@ describe('Login Modal', () => {
cy.location('pathname').should('eq', '/forgot'); cy.location('pathname').should('eq', '/forgot');
cy.get('ds-forgot-email').should('exist'); cy.get('ds-forgot-email').should('exist');
}); });
it('should pass accessibility tests', () => {
cy.visit('/');
page.openLoginMenu();
cy.get('ds-log-in').should('exist');
// Analyze <ds-log-in> for accessibility issues
testA11y('ds-log-in');
});
}); });

View File

@@ -19,21 +19,7 @@ describe('My DSpace page', () => {
cy.get('.filter-toggle').click({ multiple: true }); cy.get('.filter-toggle').click({ multiple: true });
// Analyze <ds-my-dspace-page> for accessibility issues // Analyze <ds-my-dspace-page> for accessibility issues
testA11y( testA11y('ds-my-dspace-page');
{
include: ['ds-my-dspace-page'],
exclude: [
['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175
],
},
{
rules: {
// Search filters fail these two "moderate" impact rules
'heading-order': { enabled: false },
'landmark-unique': { enabled: false }
}
} as Options
);
}); });
it('should have a working detailed view that passes accessibility tests', () => { it('should have a working detailed view that passes accessibility tests', () => {

View File

@@ -1,8 +1,13 @@
import { testA11y } from 'cypress/support/utils';
describe('PageNotFound', () => { describe('PageNotFound', () => {
it('should contain element ds-pagenotfound when navigating to page that doesnt exist', () => { it('should contain element ds-pagenotfound when navigating to page that doesnt exist', () => {
// request an invalid page (UUIDs at root path aren't valid) // request an invalid page (UUIDs at root path aren't valid)
cy.visit('/e9019a69-d4f1-4773-b6a3-bd362caa46f2', { failOnStatusCode: false }); cy.visit('/e9019a69-d4f1-4773-b6a3-bd362caa46f2', { failOnStatusCode: false });
cy.get('ds-pagenotfound').should('be.visible'); cy.get('ds-pagenotfound').should('be.visible');
// Analyze <ds-pagenotfound> for accessibility issues
testA11y('ds-pagenotfound');
}); });
it('should not contain element ds-pagenotfound when navigating to existing page', () => { it('should not contain element ds-pagenotfound when navigating to existing page', () => {

View File

@@ -27,21 +27,7 @@ describe('Search Page', () => {
cy.get('[data-test="filter-toggle"]').click({ multiple: true }); cy.get('[data-test="filter-toggle"]').click({ multiple: true });
// Analyze <ds-search-page> for accessibility issues // Analyze <ds-search-page> for accessibility issues
testA11y( testA11y('ds-search-page');
{
include: ['ds-search-page'],
exclude: [
['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175
],
},
{
rules: {
// Search filters fail these two "moderate" impact rules
'heading-order': { enabled: false },
'landmark-unique': { enabled: false }
}
} as Options
);
}); });
it('should have a working grid view that passes accessibility tests', () => { it('should have a working grid view that passes accessibility tests', () => {

View File

@@ -23,14 +23,14 @@ the Docker compose scripts in this 'docker' folder.
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 7 Angular UI image, published as 'dspace/dspace-angular'
``` ```
docker build -t dspace/dspace-angular:dspace-7_x . docker build -t dspace/dspace-angular:latest .
``` ```
This image is built *automatically* after each commit is made to the `main` branch. This image is built *automatically* after each commit is made to the `main` branch.
Admins to our DockerHub repo can manually publish with the following command. Admins to our DockerHub repo can manually publish with the following command.
``` ```
docker push dspace/dspace-angular:dspace-7_x docker push dspace/dspace-angular:latest
``` ```
### Dockerfile.dist ### Dockerfile.dist
@@ -39,7 +39,7 @@ The `Dockerfile.dist` is used to generate a *production* build and runtime envir
```bash ```bash
# build the latest image # build the latest image
docker build -f Dockerfile.dist -t dspace/dspace-angular:dspace-7_x-dist . docker build -f Dockerfile.dist -t dspace/dspace-angular:latest-dist .
``` ```
A default/demo version of this image is built *automatically*. A default/demo version of this image is built *automatically*.
@@ -101,8 +101,8 @@ and the backend at http://localhost:8080/server/
## Run DSpace Angular dist build with DSpace Demo site backend ## Run DSpace Angular dist build with DSpace Demo site backend
This allows you to run the Angular UI in *production* mode, pointing it at the demo backend This allows you to run the Angular UI in *production* mode, pointing it at the demo or sandbox backend
(https://api7.dspace.org/server/). (https://demo.dspace.org/server/ or https://sandbox.dspace.org/server/).
``` ```
docker-compose -f docker/docker-compose-dist.yml pull docker-compose -f docker/docker-compose-dist.yml pull

View File

@@ -16,7 +16,7 @@ version: "3.7"
services: services:
dspace-cli: dspace-cli:
image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}" image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-latest}"
container_name: dspace-cli container_name: dspace-cli
environment: environment:
# Below syntax may look odd, but it is how to override dspace.cfg settings via env variables. # Below syntax may look odd, but it is how to override dspace.cfg settings via env variables.

View File

@@ -35,7 +35,7 @@ services:
solr__D__statistics__P__autoCommit: 'false' solr__D__statistics__P__autoCommit: 'false'
depends_on: depends_on:
- dspacedb - dspacedb
image: dspace/dspace:dspace-7_x-test image: dspace/dspace:latest-test
networks: networks:
dspacenet: dspacenet:
ports: ports:

View File

@@ -24,10 +24,10 @@ services:
# This is because Server Side Rendering (SSR) currently requires a public URL, # This is because Server Side Rendering (SSR) currently requires a public URL,
# see this bug: https://github.com/DSpace/dspace-angular/issues/1485 # see this bug: https://github.com/DSpace/dspace-angular/issues/1485
DSPACE_REST_SSL: 'true' DSPACE_REST_SSL: 'true'
DSPACE_REST_HOST: api7.dspace.org DSPACE_REST_HOST: sandbox.dspace.org
DSPACE_REST_PORT: 443 DSPACE_REST_PORT: 443
DSPACE_REST_NAMESPACE: /server DSPACE_REST_NAMESPACE: /server
image: dspace/dspace-angular:dspace-7_x-dist image: dspace/dspace-angular:${DSPACE_VER:-latest}-dist
build: build:
context: .. context: ..
dockerfile: Dockerfile.dist dockerfile: Dockerfile.dist

View File

@@ -39,7 +39,7 @@ services:
# proxies.trusted.ipranges: This setting is required for a REST API running in Docker to trust requests # 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. # from the host machine. This IP range MUST correspond to the 'dspacenet' subnet defined above.
proxies__P__trusted__P__ipranges: '172.23.0' proxies__P__trusted__P__ipranges: '172.23.0'
image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-7_x-test}" image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-latest-test}"
depends_on: depends_on:
- dspacedb - dspacedb
networks: networks:
@@ -82,7 +82,7 @@ services:
# DSpace Solr container # DSpace Solr container
dspacesolr: dspacesolr:
container_name: dspacesolr container_name: dspacesolr
image: "${DOCKER_OWNER:-dspace}/dspace-solr:${DSPACE_VER:-dspace-7_x}" image: "${DOCKER_OWNER:-dspace}/dspace-solr:${DSPACE_VER:-latest}"
# Needs main 'dspace' container to start first to guarantee access to solr_configs # Needs main 'dspace' container to start first to guarantee access to solr_configs
depends_on: depends_on:
- dspace - dspace

View File

@@ -24,7 +24,7 @@ services:
DSPACE_REST_HOST: localhost DSPACE_REST_HOST: localhost
DSPACE_REST_PORT: 8080 DSPACE_REST_PORT: 8080
DSPACE_REST_NAMESPACE: /server DSPACE_REST_NAMESPACE: /server
image: dspace/dspace-angular:dspace-7_x image: dspace/dspace-angular:${DSPACE_VER:-latest}
build: build:
context: .. context: ..
dockerfile: Dockerfile dockerfile: Dockerfile

View File

@@ -48,7 +48,7 @@ dspace-angular connects to your DSpace installation by using its REST endpoint.
```yaml ```yaml
rest: rest:
ssl: true ssl: true
host: api7.dspace.org host: demo.dspace.org
port: 443 port: 443
nameSpace: /server nameSpace: /server
} }
@@ -57,7 +57,7 @@ rest:
Alternately you can set the following environment variables. If any of these are set, it will override all configuration files: Alternately you can set the following environment variables. If any of these are set, it will override all configuration files:
``` ```
DSPACE_REST_SSL=true DSPACE_REST_SSL=true
DSPACE_REST_HOST=api7.dspace.org DSPACE_REST_HOST=demo.dspace.org
DSPACE_REST_PORT=443 DSPACE_REST_PORT=443
DSPACE_REST_NAMESPACE=/server DSPACE_REST_NAMESPACE=/server
``` ```

View File

@@ -1,6 +1,6 @@
{ {
"name": "dspace-angular", "name": "dspace-angular",
"version": "7.6.0", "version": "8.0.0-next",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"config:watch": "nodemon", "config:watch": "nodemon",
@@ -116,12 +116,12 @@
"morgan": "^1.10.0", "morgan": "^1.10.0",
"ng-mocks": "^14.10.0", "ng-mocks": "^14.10.0",
"ng2-file-upload": "1.4.0", "ng2-file-upload": "1.4.0",
"ng2-nouislider": "^1.8.3", "ng2-nouislider": "^2.0.0",
"ngx-infinite-scroll": "^15.0.0", "ngx-infinite-scroll": "^15.0.0",
"ngx-pagination": "6.0.3", "ngx-pagination": "6.0.3",
"ngx-sortablejs": "^11.1.0", "ngx-sortablejs": "^11.1.0",
"ngx-ui-switch": "^14.0.3", "ngx-ui-switch": "^14.0.3",
"nouislider": "^14.6.3", "nouislider": "^15.7.1",
"pem": "1.14.7", "pem": "1.14.7",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react-copy-to-clipboard": "^5.1.0", "react-copy-to-clipboard": "^5.1.0",
@@ -159,11 +159,11 @@
"@types/sanitize-html": "^2.9.0", "@types/sanitize-html": "^2.9.0",
"@typescript-eslint/eslint-plugin": "^5.59.1", "@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1", "@typescript-eslint/parser": "^5.59.1",
"axe-core": "^4.7.0", "axe-core": "^4.7.2",
"compression-webpack-plugin": "^9.2.0", "compression-webpack-plugin": "^9.2.0",
"copy-webpack-plugin": "^6.4.1", "copy-webpack-plugin": "^6.4.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cypress": "12.10.0", "cypress": "12.17.4",
"cypress-axe": "^1.4.0", "cypress-axe": "^1.4.0",
"deep-freeze": "0.0.1", "deep-freeze": "0.0.1",
"eslint": "^8.39.0", "eslint": "^8.39.0",

View File

@@ -16,23 +16,23 @@
[submitLabel]="submitLabel" [submitLabel]="submitLabel"
(submitForm)="onSubmit()"> (submitForm)="onSubmit()">
<div before class="btn-group"> <div before class="btn-group">
<button (click)="onCancel()" <button (click)="onCancel()" type="button"
class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button> class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button>
</div> </div>
<div *ngIf="displayResetPassword" between class="btn-group"> <div *ngIf="displayResetPassword" between class="btn-group">
<button class="btn btn-primary" [disabled]="!(canReset$ | async)" (click)="resetPassword()"> <button class="btn btn-primary" [disabled]="!(canReset$ | async)" type="button" (click)="resetPassword()">
<i class="fa fa-key"></i> {{'admin.access-control.epeople.actions.reset' | translate}} <i class="fa fa-key"></i> {{'admin.access-control.epeople.actions.reset' | translate}}
</button> </button>
</div> </div>
<div between class="btn-group ml-1"> <div between class="btn-group ml-1">
<button *ngIf="!isImpersonated" class="btn btn-primary" [ngClass]="{'d-none' : !(canImpersonate$ | async)}" (click)="impersonate()"> <button *ngIf="!isImpersonated" class="btn btn-primary" type="button" [ngClass]="{'d-none' : !(canImpersonate$ | async)}" (click)="impersonate()">
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.impersonate' | translate}} <i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.impersonate' | translate}}
</button> </button>
<button *ngIf="isImpersonated" class="btn btn-primary" (click)="stopImpersonating()"> <button *ngIf="isImpersonated" class="btn btn-primary" type="button" (click)="stopImpersonating()">
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.stop-impersonating' | translate}} <i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.stop-impersonating' | translate}}
</button> </button>
</div> </div>
<button after class="btn btn-danger delete-button" [disabled]="!(canDelete$ | async)" (click)="delete()"> <button after class="btn btn-danger delete-button" type="button" [disabled]="!(canDelete$ | async)" (click)="delete()">
<i class="fas fa-trash"></i> {{'admin.access-control.epeople.actions.delete' | translate}} <i class="fas fa-trash"></i> {{'admin.access-control.epeople.actions.delete' | translate}}
</button> </button>
</ds-form> </ds-form>

View File

@@ -36,12 +36,12 @@
[displayCancel]="false" [displayCancel]="false"
(submitForm)="onSubmit()"> (submitForm)="onSubmit()">
<div before class="btn-group"> <div before class="btn-group">
<button (click)="onCancel()" <button (click)="onCancel()" type="button"
class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button> class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button>
</div> </div>
<div after *ngIf="groupBeingEdited != null" class="btn-group"> <div after *ngIf="groupBeingEdited != null" class="btn-group">
<button class="btn btn-danger delete-button" [disabled]="!(canEdit$ | async) || groupBeingEdited.permanent" <button class="btn btn-danger delete-button" [disabled]="!(canEdit$ | async) || groupBeingEdited.permanent"
(click)="delete()"> (click)="delete()" type="button">
<i class="fa fa-trash"></i> {{ messagePrefix + '.actions.delete' | translate}} <i class="fa fa-trash"></i> {{ messagePrefix + '.actions.delete' | translate}}
</button> </button>
</div> </div>

View File

@@ -37,7 +37,7 @@ import {
getFirstCompletedRemoteData, getFirstCompletedRemoteData,
getFirstSucceededRemoteDataPayload getFirstSucceededRemoteDataPayload
} from '../../../core/shared/operators'; } from '../../../core/shared/operators';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component'; import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component';
import { hasValue, isNotEmpty, hasValueOperator } from '../../../shared/empty.util'; import { hasValue, isNotEmpty, hasValueOperator } from '../../../shared/empty.util';
import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../shared/form/builder/form-builder.service';

View File

@@ -98,9 +98,8 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
// retrieve all entity types to populate the dropdowns selection // retrieve all entity types to populate the dropdowns selection
entities$.subscribe((entityTypes: ItemType[]) => { entities$.subscribe((entityTypes: ItemType[]) => {
entityTypes entityTypes = entityTypes.filter((type: ItemType) => type.label !== NONE_ENTITY_TYPE);
.filter((type: ItemType) => type.label !== NONE_ENTITY_TYPE) entityTypes.forEach((type: ItemType, index: number) => {
.forEach((type: ItemType, index: number) => {
this.entityTypeSelection.add({ this.entityTypeSelection.add({
disabled: false, disabled: false,
label: type.label, label: type.label,
@@ -112,7 +111,7 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
} }
}); });
this.formModel = [...collectionFormModels, this.entityTypeSelection]; this.formModel = entityTypes.length === 0 ? collectionFormModels : [...collectionFormModels, this.entityTypeSelection];
super.ngOnInit(); super.ngOnInit();
this.chd.detectChanges(); this.chd.detectChanges();

View File

@@ -8,7 +8,7 @@ import { ItemTemplateDataService } from '../../core/data/item-template-data.serv
import { getCollectionEditRoute } from '../collection-page-routing-paths'; import { getCollectionEditRoute } from '../collection-page-routing-paths';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/alert-type';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
@Component({ @Component({

View File

@@ -1,4 +1,4 @@
<div class="container"> <div class="container">
<h2>{{ 'communityList.title' | translate }}</h2> <h1>{{ 'communityList.title' | translate }}</h1>
<ds-themed-community-list></ds-themed-community-list> <ds-themed-community-list></ds-themed-community-list>
</div> </div>

View File

@@ -25,7 +25,7 @@ import { ShowMoreFlatNode } from './show-more-flat-node.model';
import { FindListOptions } from '../core/data/find-list-options.model'; import { FindListOptions } from '../core/data/find-list-options.model';
import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface'; import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
// Helper method to combine an flatten an array of observables of flatNode arrays // Helper method to combine and flatten an array of observables of flatNode arrays
export const combineAndFlatten = (obsList: Observable<FlatNode[]>[]): Observable<FlatNode[]> => export const combineAndFlatten = (obsList: Observable<FlatNode[]>[]): Observable<FlatNode[]> =>
observableCombineLatest([...obsList]).pipe( observableCombineLatest([...obsList]).pipe(
map((matrix: any[][]) => [].concat(...matrix)), map((matrix: any[][]) => [].concat(...matrix)),
@@ -199,7 +199,7 @@ export class CommunityListService {
* Transforms a community in a list of FlatNodes containing firstly a flatnode of the community itself, * Transforms a community in a list of FlatNodes containing firstly a flatnode of the community itself,
* followed by flatNodes of its possible subcommunities and collection * followed by flatNodes of its possible subcommunities and collection
* It gets called recursively for each subcommunity to add its subcommunities and collections to the list * It gets called recursively for each subcommunity to add its subcommunities and collections to the list
* Number of subcommunities and collections added, is dependant on the current page the parent is at for respectively subcommunities and collections. * Number of subcommunities and collections added, is dependent on the current page the parent is at for respectively subcommunities and collections.
* @param community Community being transformed * @param community Community being transformed
* @param level Depth of the community in the list, subcommunities and collections go one level deeper * @param level Depth of the community in the list, subcommunities and collections go one level deeper
* @param parent Flatnode of the parent community * @param parent Flatnode of the parent community
@@ -275,7 +275,7 @@ export class CommunityListService {
/** /**
* Checks if a community has subcommunities or collections by querying the respective services with a pageSize = 0 * Checks if a community has subcommunities or collections by querying the respective services with a pageSize = 0
* Returns an observable that combines the result.payload.totalElements fo the observables that the * Returns an observable that combines the result.payload.totalElements of the observables that the
* respective services return when queried * respective services return when queried
* @param community Community being checked whether it is expandable (if it has subcommunities or collections) * @param community Community being checked whether it is expandable (if it has subcommunities or collections)
*/ */

View File

@@ -1,5 +1,5 @@
<ds-themed-loading *ngIf="(dataSource.loading$ | async) && !loadingNode" class="ds-themed-loading"></ds-themed-loading> <ds-themed-loading *ngIf="(dataSource.loading$ | async) && !loadingNode" class="ds-themed-loading"></ds-themed-loading>
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl"> <cdk-tree [dataSource]="dataSource" [treeControl]="treeControl" [trackBy]="trackBy">
<!-- This is the tree node template for show more node --> <!-- This is the tree node template for show more node -->
<cdk-tree-node *cdkTreeNodeDef="let node; when: isShowMore" cdkTreeNodePadding <cdk-tree-node *cdkTreeNodeDef="let node; when: isShowMore" cdkTreeNodePadding
class="example-tree-node show-more-node"> class="example-tree-node show-more-node">
@@ -34,13 +34,13 @@
aria-hidden="true"></span> aria-hidden="true"></span>
</button> </button>
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<h5 class="align-middle pt-2"> <span class="align-middle pt-2 lead">
<a [routerLink]="node.route" class="lead"> <a [routerLink]="node.route" class="lead">
{{ dsoNameService.getName(node.payload) }} {{ dsoNameService.getName(node.payload) }}
</a> </a>
<span class="pr-2">&nbsp;</span> <span class="pr-2">&nbsp;</span>
<span *ngIf="node.payload.archivedItemsCount >= 0" class="badge badge-pill badge-secondary align-top archived-items-lead">{{node.payload.archivedItemsCount}}</span> <span *ngIf="node.payload.archivedItemsCount >= 0" class="badge badge-pill badge-secondary align-top archived-items-lead">{{node.payload.archivedItemsCount}}</span>
</h5> </span>
</div> </div>
</div> </div>
<ds-truncatable [id]="node.id"> <ds-truncatable [id]="node.id">

View File

@@ -28,10 +28,9 @@ export class CommunityListComponent implements OnInit, OnDestroy {
treeControl = new FlatTreeControl<FlatNode>( treeControl = new FlatTreeControl<FlatNode>(
(node: FlatNode) => node.level, (node: FlatNode) => true (node: FlatNode) => node.level, (node: FlatNode) => true
); );
dataSource: CommunityListDatasource; dataSource: CommunityListDatasource;
paginationConfig: FindListOptions; paginationConfig: FindListOptions;
trackBy = (index, node: FlatNode) => node.id;
constructor( constructor(
protected communityListService: CommunityListService, protected communityListService: CommunityListService,
@@ -58,18 +57,28 @@ export class CommunityListComponent implements OnInit, OnDestroy {
this.communityListService.saveCommunityListStateToStore(this.expandedNodes, this.loadingNode); this.communityListService.saveCommunityListStateToStore(this.expandedNodes, this.loadingNode);
} }
// whether or not this node has children (subcommunities or collections) /**
* Whether this node has children (subcommunities or collections)
* @param _
* @param node
*/
hasChild(_: number, node: FlatNode) { hasChild(_: number, node: FlatNode) {
return node.isExpandable$; return node.isExpandable$;
} }
// whether or not it is a show more node (contains no data, but is indication that there are more topcoms, subcoms or collections /**
* Whether this is a show more node that contains no data, but indicates that there is
* one or more community or collection.
* @param _
* @param node
*/
isShowMore(_: number, node: FlatNode) { isShowMore(_: number, node: FlatNode) {
return node.isShowMoreNode; return node.isShowMoreNode;
} }
/** /**
* Toggles the expanded variable of a node, adds it to the expanded nodes list and reloads the tree so this node is expanded * Toggles the expanded variable of a node, adds it to the expanded nodes list and reloads the tree
* so this node is expanded
* @param node Node we want to expand * @param node Node we want to expand
*/ */
toggleExpanded(node: FlatNode) { toggleExpanded(node: FlatNode) {
@@ -92,9 +101,12 @@ export class CommunityListComponent implements OnInit, OnDestroy {
/** /**
* Makes sure the next page of a node is added to the tree (top community, sub community of collection) * Makes sure the next page of a node is added to the tree (top community, sub community of collection)
* > Finds its parent (if not top community) and increases its corresponding collection/subcommunity currentPage * > Finds its parent (if not top community) and increases its corresponding collection/subcommunity
* > Reloads tree with new page added to corresponding top community lis, sub community list or collection list * currentPage
* @param node The show more node indicating whether it's an increase in top communities, sub communities or collections * > Reloads tree with new page added to corresponding top community lis, sub community list or
* collection list
* @param node The show more node indicating whether it's an increase in top communities, sub communities
* or collections
*/ */
getNextPage(node: FlatNode): void { getNextPage(node: FlatNode): void {
this.loadingNode = node; this.loadingNode = node;

View File

@@ -1,6 +1,6 @@
/** /**
* The show more links in the community tree are also represented by a flatNode so we know where in * The show more links in the community tree are also represented by a flatNode so we know where in
* the tree it should be rendered an who its parent is (needed for the action resulting in clicking this link) * the tree it should be rendered and who its parent is (needed for the action resulting in clicking this link)
*/ */
export class ShowMoreFlatNode { export class ShowMoreFlatNode {
} }

View File

@@ -38,8 +38,8 @@ export class BrowserHardRedirectService extends HardRedirectService {
/** /**
* Get the origin of the current URL * Get the origin of the current URL
* i.e. <scheme> "://" <hostname> [ ":" <port> ] * i.e. <scheme> "://" <hostname> [ ":" <port> ]
* e.g. if the URL is https://demo7.dspace.org/search?query=test, * e.g. if the URL is https://demo.dspace.org/search?query=test,
* the origin would be https://demo7.dspace.org * the origin would be https://demo.dspace.org
*/ */
getCurrentOrigin(): string { getCurrentOrigin(): string {
return this.location.origin; return this.location.origin;

View File

@@ -25,8 +25,8 @@ export abstract class HardRedirectService {
/** /**
* Get the origin of the current URL * Get the origin of the current URL
* i.e. <scheme> "://" <hostname> [ ":" <port> ] * i.e. <scheme> "://" <hostname> [ ":" <port> ]
* e.g. if the URL is https://demo7.dspace.org/search?query=test, * e.g. if the URL is https://demo.dspace.org/search?query=test,
* the origin would be https://demo7.dspace.org * the origin would be https://demo.dspace.org
*/ */
abstract getCurrentOrigin(): string; abstract getCurrentOrigin(): string;
} }

View File

@@ -69,8 +69,8 @@ export class ServerHardRedirectService extends HardRedirectService {
/** /**
* Get the origin of the current URL * Get the origin of the current URL
* i.e. <scheme> "://" <hostname> [ ":" <port> ] * i.e. <scheme> "://" <hostname> [ ":" <port> ]
* e.g. if the URL is https://demo7.dspace.org/search?query=test, * e.g. if the URL is https://demo.dspace.org/search?query=test,
* the origin would be https://demo7.dspace.org * the origin would be https://demo.dspace.org
*/ */
getCurrentOrigin(): string { getCurrentOrigin(): string {
return this.req.protocol + '://' + this.req.headers.host; return this.req.protocol + '://' + this.req.headers.host;

View File

@@ -1,5 +1,5 @@
import { Component, Inject, Injector, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Component, Inject, Injector, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/alert-type';
import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { DsoEditMetadataForm } from './dso-edit-metadata-form'; import { DsoEditMetadataForm } from './dso-edit-metadata-form';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';

View File

@@ -3,7 +3,7 @@ import { Component, Input } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { HealthComponent } from '../../models/health-component.model'; import { HealthComponent } from '../../models/health-component.model';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
/** /**
* A component to render a "health component" object. * A component to render a "health component" object.

View File

@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/alert-type';
@Component({ @Component({
selector: 'ds-item-alerts', selector: 'ds-item-alerts',

View File

@@ -5,7 +5,7 @@ import { Item } from '../../../core/shared/item.model';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { getFirstSucceededRemoteData } from '../../../core/shared/operators'; import { getFirstSucceededRemoteData } from '../../../core/shared/operators';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
@Component({ @Component({
selector: 'ds-item-version-history', selector: 'ds-item-version-history',

View File

@@ -15,7 +15,7 @@ import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
import { hasValue } from '../../../shared/empty.util'; import { hasValue } from '../../../shared/empty.util';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { Item } from '../../../core/shared/item.model'; import { Item } from '../../../core/shared/item.model';
import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service'; import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service';

View File

@@ -1,6 +1,6 @@
<h2 class="item-page-title-field"> <h1 class="item-page-title-field">
<div *ngIf="item.firstMetadataValue('dspace.entity.type') as type" class="d-inline"> <div *ngIf="item.firstMetadataValue('dspace.entity.type') as type" class="d-inline">
{{ type.toLowerCase() + '.page.titleprefix' | translate }} {{ type.toLowerCase() + '.page.titleprefix' | translate }}
</div> </div>
<span class="dont-break-out">{{ dsoNameService.getName(item) }}</span> <span class="dont-break-out">{{ dsoNameService.getName(item) }}</span>
</h2> </h1>

View File

@@ -5,8 +5,7 @@ import { RemoteData } from '../../../../core/data/remote-data';
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model'; import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
import { Item } from '../../../../core/shared/item.model'; import { Item } from '../../../../core/shared/item.model';
import { import {
getFirstSucceededRemoteDataPayload, getFirstCompletedRemoteData
getFirstSucceededRemoteData
} from '../../../../core/shared/operators'; } from '../../../../core/shared/operators';
import { hasValue } from '../../../../shared/empty.util'; import { hasValue } from '../../../../shared/empty.util';
import { InjectionToken } from '@angular/core'; import { InjectionToken } from '@angular/core';
@@ -77,24 +76,42 @@ export const relationsToItems = (thisId: string) =>
* @param {string} thisId The item's id of which the relations belong to * @param {string} thisId The item's id of which the relations belong to
* @returns {(source: Observable<Relationship[]>) => Observable<Item[]>} * @returns {(source: Observable<Relationship[]>) => Observable<Item[]>}
*/ */
export const paginatedRelationsToItems = (thisId: string) => export const paginatedRelationsToItems = (thisId: string) => (source: Observable<RemoteData<PaginatedList<Relationship>>>): Observable<RemoteData<PaginatedList<Item>>> =>
(source: Observable<RemoteData<PaginatedList<Relationship>>>): Observable<RemoteData<PaginatedList<Item>>> =>
source.pipe( source.pipe(
getFirstSucceededRemoteData(), getFirstCompletedRemoteData(),
switchMap((relationshipsRD: RemoteData<PaginatedList<Relationship>>) => { switchMap((relationshipsRD: RemoteData<PaginatedList<Relationship>>) => {
return observableCombineLatest( return observableCombineLatest(
relationshipsRD.payload.page.map((rel: Relationship) => relationshipsRD.payload.page.map((rel: Relationship) =>
observableCombineLatest([ observableCombineLatest([
rel.leftItem.pipe(getFirstSucceededRemoteDataPayload()), rel.leftItem.pipe(
rel.rightItem.pipe(getFirstSucceededRemoteDataPayload())] getFirstCompletedRemoteData(),
map((rd: RemoteData<Item>) => {
if (rd.hasSucceeded) {
return rd.payload;
} else {
return null;
}
})
),
rel.rightItem.pipe(
getFirstCompletedRemoteData(),
map((rd: RemoteData<Item>) => {
if (rd.hasSucceeded) {
return rd.payload;
} else {
return null;
}
})
),
]
) )
)).pipe( )
).pipe(
map((arr) => map((arr) =>
arr arr.map(([leftItem, rightItem]) => {
.map(([leftItem, rightItem]) => { if (hasValue(leftItem) && leftItem.id === thisId) {
if (leftItem.id === thisId) {
return rightItem; return rightItem;
} else if (rightItem.id === thisId) { } else if (hasValue(rightItem) && rightItem.id === thisId) {
return leftItem; return leftItem;
} }
}) })

View File

@@ -2,5 +2,6 @@
[fixedFilterQuery]="fixedFilter" [fixedFilterQuery]="fixedFilter"
[configuration]="configuration" [configuration]="configuration"
[searchEnabled]="searchEnabled" [searchEnabled]="searchEnabled"
[sideBarWidth]="sideBarWidth"> [sideBarWidth]="sideBarWidth"
[showCsvExport]="true">
</ds-configuration-search-page> </ds-configuration-search-page>

View File

@@ -23,7 +23,7 @@ import { PaginatedList } from '../../core/data/paginated-list.model';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { VersionHistoryDataService } from '../../core/data/version-history-data.service'; import { VersionHistoryDataService } from '../../core/data/version-history-data.service';
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/alert-type';
import { followLink } from '../../shared/utils/follow-link-config.model'; import { followLink } from '../../shared/utils/follow-link-config.model';
import { hasValue, hasValueOperator } from '../../shared/empty.util'; import { hasValue, hasValueOperator } from '../../shared/empty.util';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';

View File

@@ -12,7 +12,7 @@ import {
} from '../../../core/shared/operators'; } from '../../../core/shared/operators';
import { map, startWith, switchMap } from 'rxjs/operators'; import { map, startWith, switchMap } from 'rxjs/operators';
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service'; import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { getItemPageRoute } from '../../item-page-routing-paths'; import { getItemPageRoute } from '../../item-page-routing-paths';
@Component({ @Component({

View File

@@ -17,7 +17,7 @@ import {
getFirstSucceededRemoteDataPayload, getAllSucceededRemoteDataPayload getFirstSucceededRemoteDataPayload, getAllSucceededRemoteDataPayload
} from '../../core/shared/operators'; } from '../../core/shared/operators';
import { URLCombiner } from '../../core/url-combiner/url-combiner'; import { URLCombiner } from '../../core/url-combiner/url-combiner';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/alert-type';
import { hasValue } from '../../shared/empty.util'; import { hasValue } from '../../shared/empty.util';
import { ProcessStatus } from '../processes/process-status.model'; import { ProcessStatus } from '../processes/process-status.model';
import { Process } from '../processes/process.model'; import { Process } from '../processes/process.model';

View File

@@ -161,7 +161,7 @@ export class ProfilePageComponent implements OnInit {
} else { } else {
this.notificationsService.error( this.notificationsService.error(
this.translate.instant(this.PASSWORD_NOTIFICATIONS_PREFIX + 'error.title'), this.translate.instant(this.PASSWORD_NOTIFICATIONS_PREFIX + 'error.title'),
this.translate.instant(this.PASSWORD_NOTIFICATIONS_PREFIX + 'error.change-failed') this.getPasswordErrorMessage(response)
); );
} }
}); });
@@ -199,4 +199,18 @@ export class ProfilePageComponent implements OnInit {
return this.isResearcherProfileEnabled$.asObservable(); return this.isResearcherProfileEnabled$.asObservable();
} }
/**
* Returns an error message from a password validation request with a specific reason or
* a default message without specific reason.
* @param response from the validation password patch request.
*/
getPasswordErrorMessage(response) {
if (response.hasFailed && isNotEmpty(response.errorMessage)) {
// Response has a specific error message. Show this message in the error notification.
return this.translate.instant(response.errorMessage);
}
// Show default error message notification.
return this.translate.instant(this.PASSWORD_NOTIFICATIONS_PREFIX + 'error.change-failed');
}
} }

View File

@@ -13,7 +13,7 @@ import {isNotEmpty} from '../shared/empty.util';
import {BehaviorSubject, combineLatest, Observable, of, switchMap} from 'rxjs'; import {BehaviorSubject, combineLatest, Observable, of, switchMap} from 'rxjs';
import {map, startWith, take} from 'rxjs/operators'; import {map, startWith, take} from 'rxjs/operators';
import {CAPTCHA_NAME, GoogleRecaptchaService} from '../core/google-recaptcha/google-recaptcha.service'; import {CAPTCHA_NAME, GoogleRecaptchaService} from '../core/google-recaptcha/google-recaptcha.service';
import {AlertType} from '../shared/alert/aletr-type'; import {AlertType} from '../shared/alert/alert-type';
import {KlaroService} from '../shared/cookies/klaro.service'; import {KlaroService} from '../shared/cookies/klaro.service';
import {CookieService} from '../core/services/cookie.service'; import {CookieService} from '../core/services/cookie.service';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';

View File

@@ -1,7 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ThemedComponent } from 'src/app/shared/theme-support/themed.component'; import { ThemedComponent } from 'src/app/shared/theme-support/themed.component';
import { DenyRequestCopyComponent } from 'src/themes/custom/app/request-copy/deny-request-copy/deny-request-copy.component'; import { DenyRequestCopyComponent } from './deny-request-copy.component';
/** /**
* Themed wrapper for deny-request-copy.component * Themed wrapper for deny-request-copy.component

View File

@@ -15,7 +15,7 @@ import {
import { BulkAccessConfigDataService } from '../../core/config/bulk-access-config-data.service'; import { BulkAccessConfigDataService } from '../../core/config/bulk-access-config-data.service';
import { getFirstCompletedRemoteData } from '../../core/shared/operators'; import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { BulkAccessConditionOptions } from '../../core/config/models/bulk-access-condition-options.model'; import { BulkAccessConditionOptions } from '../../core/config/models/bulk-access-condition-options.model';
import { AlertType } from '../alert/aletr-type'; import { AlertType } from '../alert/alert-type';
import { import {
createAccessControlInitialFormState createAccessControlInitialFormState
} from './access-control-form-container-intial-state'; } from './access-control-form-container-intial-state';

View File

@@ -8,7 +8,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { AlertComponent } from './alert.component'; import { AlertComponent } from './alert.component';
import { createTestComponent } from '../testing/utils.test'; import { createTestComponent } from '../testing/utils.test';
import { AlertType } from './aletr-type'; import { AlertType } from './alert-type';
describe('AlertComponent test suite', () => { describe('AlertComponent test suite', () => {

View File

@@ -1,7 +1,7 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { trigger } from '@angular/animations'; import { trigger } from '@angular/animations';
import { AlertType } from './aletr-type'; import { AlertType } from './alert-type';
import { fadeOutLeave, fadeOutState } from '../animations/fade'; import { fadeOutLeave, fadeOutState } from '../animations/fade';
/** /**

View File

@@ -42,7 +42,7 @@
[formModel]="formModel" [formModel]="formModel"
[displayCancel]="false" [displayCancel]="false"
(submitForm)="onSubmit()"> (submitForm)="onSubmit()">
<button before (click)="back.emit()" class="btn btn-outline-secondary"> <button before (click)="back.emit()" class="btn btn-outline-secondary" type="button">
<i class="fas fa-arrow-left"></i> {{ type.value + '.edit.return' | translate }} <i class="fas fa-arrow-left"></i> {{ type.value + '.edit.return' | translate }}
</button> </button>
</ds-form> </ds-form>

View File

@@ -3,7 +3,7 @@ import { Component, Input } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { AlertType } from '../alert/aletr-type'; import { AlertType } from '../alert/alert-type';
@Component({ @Component({
selector: 'ds-error', selector: 'ds-error',

View File

@@ -130,7 +130,7 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
(v) => v.value === option.value)); (v) => v.value === option.value));
const item: ListItem = { const item: ListItem = {
id: value, id: `${this.model.id}_${value}`,
label: option.display, label: option.display,
value: checked, value: checked,
index: key index: key

View File

@@ -43,7 +43,7 @@
<button class="dropdown-item disabled" *ngIf="optionsList && optionsList.length == 0">{{'form.no-results' | translate}}</button> <button class="dropdown-item disabled" *ngIf="optionsList && optionsList.length == 0">{{'form.no-results' | translate}}</button>
<button class="dropdown-item collection-item text-truncate" *ngFor="let listEntry of optionsList" <button class="dropdown-item collection-item text-truncate" *ngFor="let listEntry of optionsList"
(click)="onSelect(listEntry); sdRef.close()" (mousedown)="onSelect(listEntry); sdRef.close()" (keydown.enter)="onSelect(listEntry); sdRef.close()" (mousedown)="onSelect(listEntry); sdRef.close()"
title="{{ listEntry.display }}" role="option" title="{{ listEntry.display }}" role="option"
[attr.id]="listEntry.display == (currentValue|async) ? ('combobox_' + id + '_selected') : null"> [attr.id]="listEntry.display == (currentValue|async) ? ('combobox_' + id + '_selected') : null">
{{inputFormatter(listEntry)}} {{inputFormatter(listEntry)}}

View File

@@ -159,14 +159,15 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
let de: any = scrollableDropdownFixture.debugElement.query(By.css('input.form-control')); let de: any = scrollableDropdownFixture.debugElement.query(By.css('input.form-control'));
let btnEl = de.nativeElement; let btnEl = de.nativeElement;
btnEl.click(); const mousedownEvent = new MouseEvent('mousedown');
btnEl.dispatchEvent(mousedownEvent);
scrollableDropdownFixture.detectChanges(); scrollableDropdownFixture.detectChanges();
de = scrollableDropdownFixture.debugElement.queryAll(By.css('button.dropdown-item')); de = scrollableDropdownFixture.debugElement.queryAll(By.css('button.dropdown-item'));
btnEl = de[0].nativeElement; btnEl = de[0].nativeElement;
btnEl.click(); btnEl.dispatchEvent(mousedownEvent);
scrollableDropdownFixture.detectChanges(); scrollableDropdownFixture.detectChanges();
expect((scrollableDropdownComp.model as any).value).toEqual(selectedValue); expect((scrollableDropdownComp.model as any).value).toEqual(selectedValue);

View File

@@ -1,5 +1,5 @@
import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
@@ -28,7 +28,7 @@ import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operato
templateUrl: './vocabulary-treeview.component.html', templateUrl: './vocabulary-treeview.component.html',
styleUrls: ['./vocabulary-treeview.component.scss'] styleUrls: ['./vocabulary-treeview.component.scss']
}) })
export class VocabularyTreeviewComponent implements OnDestroy, OnInit { export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges {
/** /**
* The {@link VocabularyOptions} object * The {@link VocabularyOptions} object
@@ -322,4 +322,9 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit {
private getEntryId(entry: VocabularyEntry): string { private getEntryId(entry: VocabularyEntry): string {
return entry.authority || entry.otherInformation.id || undefined; return entry.authority || entry.otherInformation.id || undefined;
} }
ngOnChanges(changes: SimpleChanges): void {
this.reset();
this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.selectedItems, null);
}
} }

View File

@@ -1,5 +1,5 @@
<div class="simple-view-element" [class.d-none]="hideIfNoTextContent && content.textContent.trim().length === 0"> <div class="simple-view-element" [class.d-none]="hideIfNoTextContent && content.textContent.trim().length === 0">
<h5 class="simple-view-element-header" *ngIf="label">{{ label }}</h5> <h2 class="simple-view-element-header" *ngIf="label">{{ label }}</h2>
<div #content class="simple-view-element-body"> <div #content class="simple-view-element-body">
<ng-content></ng-content> <ng-content></ng-content>
</div> </div>

View File

@@ -2,4 +2,7 @@
.simple-view-element { .simple-view-element {
margin-bottom: 15px; margin-bottom: 15px;
} }
.simple-view-element-header {
font-size: 1.25rem;
}
} }

View File

@@ -28,6 +28,7 @@ describe('SearchFormComponent', () => {
const searchService = new SearchServiceStub(); const searchService = new SearchServiceStub();
const paginationService = new PaginationServiceStub(); const paginationService = new PaginationServiceStub();
const searchConfigService = { paginationID: 'test-id' }; const searchConfigService = { paginationID: 'test-id' };
const firstPage = { 'spc.page': 1 };
const dspaceObjectService = { const dspaceObjectService = {
findById: () => createSuccessfulRemoteDataObject$(undefined), findById: () => createSuccessfulRemoteDataObject$(undefined),
}; };
@@ -104,16 +105,16 @@ describe('SearchFormComponent', () => {
const scope = 'MCU'; const scope = 'MCU';
let searchQuery = {}; let searchQuery = {};
it('should navigate to the search page even when no parameters are provided', () => { it('should navigate to the search first page even when no parameters are provided', () => {
comp.updateSearch(searchQuery); comp.updateSearch(searchQuery);
expect(router.navigate).toHaveBeenCalledWith(comp.getSearchLinkParts(), { expect(router.navigate).toHaveBeenCalledWith(comp.getSearchLinkParts(), {
queryParams: searchQuery, queryParams: { ...searchQuery, ...firstPage },
queryParamsHandling: 'merge' queryParamsHandling: 'merge'
}); });
}); });
it('should navigate to the search page with parameters only query if only query is provided', () => { it('should navigate to the search first page with parameters only query if only query is provided', () => {
searchQuery = { searchQuery = {
query: query query: query
}; };
@@ -121,12 +122,12 @@ describe('SearchFormComponent', () => {
comp.updateSearch(searchQuery); comp.updateSearch(searchQuery);
expect(router.navigate).toHaveBeenCalledWith(comp.getSearchLinkParts(), { expect(router.navigate).toHaveBeenCalledWith(comp.getSearchLinkParts(), {
queryParams: searchQuery, queryParams: { ...searchQuery, ...firstPage },
queryParamsHandling: 'merge' queryParamsHandling: 'merge'
}); });
}); });
it('should navigate to the search page with parameters only query if only scope is provided', () => { it('should navigate to the search first page with parameters only query if only scope is provided', () => {
searchQuery = { searchQuery = {
scope: scope scope: scope
}; };
@@ -134,7 +135,7 @@ describe('SearchFormComponent', () => {
comp.updateSearch(searchQuery); comp.updateSearch(searchQuery);
expect(router.navigate).toHaveBeenCalledWith(comp.getSearchLinkParts(), { expect(router.navigate).toHaveBeenCalledWith(comp.getSearchLinkParts(), {
queryParams: searchQuery, queryParams: {...searchQuery, ...firstPage},
queryParamsHandling: 'merge' queryParamsHandling: 'merge'
}); });
}); });

View File

@@ -114,7 +114,14 @@ export class SearchFormComponent implements OnChanges {
* @param data Updated parameters * @param data Updated parameters
*/ */
updateSearch(data: any) { updateSearch(data: any) {
const queryParams = Object.assign({}, data); const goToFirstPage = { 'spc.page': 1 };
const queryParams = Object.assign(
{
...goToFirstPage
},
data
);
void this.router.navigate(this.getSearchLinkParts(), { void this.router.navigate(this.getSearchLinkParts(), {
queryParams: queryParams, queryParams: queryParams,

View File

@@ -94,6 +94,19 @@ export class SearchExportCsvComponent implements OnInit {
} }
}); });
} }
if (isNotEmpty(this.searchConfig.fixedFilter)) {
const fixedFilter = this.searchConfig.fixedFilter.substring(2);
const keyAndValue = fixedFilter.split('=');
if (keyAndValue.length > 1) {
const key = keyAndValue[0];
const valueAndOperator = keyAndValue[1].split(',');
if (valueAndOperator.length > 1) {
const value = valueAndOperator[0];
const operator = valueAndOperator[1];
parameters.push({name: '-f', value: `${key},${operator}=${value}`});
}
}
}
} }
this.scriptDataService.invoke('metadata-export-search', parameters, []).pipe( this.scriptDataService.invoke('metadata-export-search', parameters, []).pipe(

View File

@@ -6,9 +6,9 @@
[attr.aria-label]="(((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate) + ' ' + (('search.filters.filter.' + filter.name + '.head') | translate | lowercase)" [attr.aria-label]="(((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate) + ' ' + (('search.filters.filter.' + filter.name + '.head') | translate | lowercase)"
[attr.data-test]="'filter-toggle' | dsBrowserOnly" [attr.data-test]="'filter-toggle' | dsBrowserOnly"
> >
<h5 class="d-inline-block mb-0"> <h4 class="d-inline-block mb-0">
{{'search.filters.filter.' + filter.name + '.head'| translate}} {{'search.filters.filter.' + filter.name + '.head'| translate}}
</h5> </h4>
<span class="filter-toggle flex-grow-1 fas p-auto" <span class="filter-toggle flex-grow-1 fas p-auto"
[ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'" [ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'"
[title]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate"> [title]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate">

View File

@@ -9,8 +9,8 @@
</span> </span>
<input type="text" [(ngModel)]="range[0]" [name]="filterConfig.paramName + '.min'" <input type="text" [(ngModel)]="range[0]" [name]="filterConfig.paramName + '.min'"
class="form-control" (blur)="onSubmit()" class="form-control" (blur)="onSubmit()"
aria-label="Mininum value" [attr.aria-label]="minLabel"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.min.placeholder' | translate" [placeholder]="minLabel"
/> />
</label> </label>
</div> </div>
@@ -21,8 +21,8 @@
</span> </span>
<input type="text" [(ngModel)]="range[1]" [name]="filterConfig.paramName + '.max'" <input type="text" [(ngModel)]="range[1]" [name]="filterConfig.paramName + '.max'"
class="form-control" (blur)="onSubmit()" class="form-control" (blur)="onSubmit()"
aria-label="Maximum value" [attr.aria-label]="maxLabel"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.max.placeholder' | translate" [placeholder]="maxLabel"
/> />
</label> </label>
</div> </div>
@@ -33,7 +33,7 @@
</form> </form>
<ng-container *ngIf="shouldShowSlider()"> <ng-container *ngIf="shouldShowSlider()">
<nouislider [connect]="true" [min]="min" [max]="max" [step]="1" <nouislider [connect]="true" [config]="config" [min]="min" [max]="max" [step]="1"
[dsDebounce]="250" (onDebounce)="onSubmit()" [dsDebounce]="250" (onDebounce)="onSubmit()"
(keydown)="startKeyboardControl()" (keyup)="stopKeyboardControl()" (keydown)="startKeyboardControl()" (keyup)="stopKeyboardControl()"
[(ngModel)]="range" ngDefaultControl> [(ngModel)]="range" ngDefaultControl>

View File

@@ -2,6 +2,7 @@ import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription
import { map, startWith } from 'rxjs/operators'; import { map, startWith } from 'rxjs/operators';
import { isPlatformBrowser } from '@angular/common'; import { isPlatformBrowser } from '@angular/common';
import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core'; import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
import { FilterType } from '../../../models/filter-type.model'; import { FilterType } from '../../../models/filter-type.model';
import { renderFacetFor } from '../search-filter-type-decorator'; import { renderFacetFor } from '../search-filter-type-decorator';
@@ -53,11 +54,27 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
*/ */
min = 1950; min = 1950;
/**
* i18n Label to use for minimum field
*/
minLabel: string;
/** /**
* Fallback maximum for the range * Fallback maximum for the range
*/ */
max = new Date().getUTCFullYear(); max = new Date().getUTCFullYear();
/**
* i18n Label to use for maximum field
*/
maxLabel: string;
/**
* Base configuration for nouislider
* https://refreshless.com/nouislider/slider-options/
*/
config = {};
/** /**
* The current range of the filter * The current range of the filter
*/ */
@@ -78,6 +95,7 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
protected filterService: SearchFilterService, protected filterService: SearchFilterService,
protected router: Router, protected router: Router,
protected rdbs: RemoteDataBuildService, protected rdbs: RemoteDataBuildService,
private translateService: TranslateService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
@Inject(IN_PLACE_SEARCH) public inPlaceSearch: boolean, @Inject(IN_PLACE_SEARCH) public inPlaceSearch: boolean,
@Inject(FILTER_CONFIG) public filterConfig: SearchFilterConfig, @Inject(FILTER_CONFIG) public filterConfig: SearchFilterConfig,
@@ -96,6 +114,8 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
super.ngOnInit(); super.ngOnInit();
this.min = yearFromString(this.filterConfig.minValue) || this.min; this.min = yearFromString(this.filterConfig.minValue) || this.min;
this.max = yearFromString(this.filterConfig.maxValue) || this.max; this.max = yearFromString(this.filterConfig.maxValue) || this.max;
this.minLabel = this.translateService.instant('search.filters.filter.' + this.filterConfig.name + '.min.placeholder');
this.maxLabel = this.translateService.instant('search.filters.filter.' + this.filterConfig.name + '.max.placeholder');
const iniMin = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MIN_SUFFIX).pipe(startWith(undefined)); const iniMin = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MIN_SUFFIX).pipe(startWith(undefined));
const iniMax = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MAX_SUFFIX).pipe(startWith(undefined)); const iniMax = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MAX_SUFFIX).pipe(startWith(undefined));
this.sub = observableCombineLatest(iniMin, iniMax).pipe( this.sub = observableCombineLatest(iniMin, iniMax).pipe(
@@ -105,6 +125,15 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
return [minimum, maximum]; return [minimum, maximum];
}) })
).subscribe((minmax) => this.range = minmax); ).subscribe((minmax) => this.range = minmax);
// Default/base config for nouislider
this.config = {
// Ensure draggable handles have labels
handleAttributes: [
{ 'aria-label': this.minLabel },
{ 'aria-label': this.maxLabel },
],
};
} }
/** /**

View File

@@ -1,5 +1,5 @@
<div class="setting-option mb-3 p-3"> <div class="setting-option mb-3 p-3">
<h5><label for="{{id}}">{{label | translate}}</label></h5> <h4><label for="{{id}}">{{label | translate}}</label></h4>
<select id="{{id}}" class="form-control" (change)="change.emit($event)"> <select id="{{id}}" class="form-control" (change)="change.emit($event)">
<ng-content></ng-content> <ng-content></ng-content>
</select> </select>

View File

@@ -29,7 +29,7 @@ export const themeStateSelector = createFeatureSelector<ThemeState>('theme');
export const currentThemeSelector = createSelector( export const currentThemeSelector = createSelector(
themeStateSelector, themeStateSelector,
(state: ThemeState): string => hasValue(state) ? state.currentTheme : undefined (state: ThemeState): string => hasValue(state) ? state.currentTheme : BASE_THEME_NAME,
); );
@Injectable({ @Injectable({
@@ -240,14 +240,7 @@ export class ThemeService {
if (hasValue(parentThemeName)) { if (hasValue(parentThemeName)) {
// inherit the head tags of the parent theme // inherit the head tags of the parent theme
return this.createHeadTags(parentThemeName); return this.createHeadTags(parentThemeName);
} } else {
const defaultThemeConfig = getDefaultThemeConfig();
const defaultThemeName = defaultThemeConfig.name;
if (
hasNoValue(defaultThemeName) ||
themeName === defaultThemeName ||
themeName === BASE_THEME_NAME
) {
// last resort, use fallback favicon.ico // last resort, use fallback favicon.ico
return [ return [
this.createHeadTag({ this.createHeadTag({
@@ -260,9 +253,6 @@ export class ThemeService {
}) })
]; ];
} }
// inherit the head tags of the default theme
return this.createHeadTags(defaultThemeConfig.name);
} }
return headTagConfigs.map(this.createHeadTag.bind(this)); return headTagConfigs.map(this.createHeadTag.bind(this));
@@ -425,9 +415,10 @@ export class ThemeService {
* @private * @private
*/ */
private getActionForMatch(newTheme: Theme, currentThemeName: string): SetThemeAction | NoOpAction { private getActionForMatch(newTheme: Theme, currentThemeName: string): SetThemeAction | NoOpAction {
if (hasValue(newTheme) && newTheme.config.name !== currentThemeName) { const newThemeName: string = newTheme?.config.name ?? BASE_THEME_NAME;
if (newThemeName !== currentThemeName) {
// If we have a match, and it isn't already the active theme, set it as the new theme // If we have a match, and it isn't already the active theme, set it as the new theme
return new SetThemeAction(newTheme.config.name); return new SetThemeAction(newThemeName);
} else { } else {
// Otherwise, do nothing // Otherwise, do nothing
return new NoOpAction(); return new NoOpAction();

View File

@@ -1,10 +1,10 @@
import { import {
AfterViewInit,
Component, Component,
ViewChild, ViewChild,
ViewContainerRef, ViewContainerRef,
ComponentRef, ComponentRef,
SimpleChanges, SimpleChanges,
OnInit,
OnDestroy, OnDestroy,
ComponentFactoryResolver, ComponentFactoryResolver,
ChangeDetectorRef, ChangeDetectorRef,
@@ -24,7 +24,7 @@ import { BASE_THEME_NAME } from './theme.constants';
styleUrls: ['./themed.component.scss'], styleUrls: ['./themed.component.scss'],
templateUrl: './themed.component.html', templateUrl: './themed.component.html',
}) })
export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges { export abstract class ThemedComponent<T> implements AfterViewInit, OnDestroy, OnChanges {
@ViewChild('vcr', { read: ViewContainerRef }) vcr: ViewContainerRef; @ViewChild('vcr', { read: ViewContainerRef }) vcr: ViewContainerRef;
@ViewChild('content') themedElementContent: ElementRef; @ViewChild('content') themedElementContent: ElementRef;
protected compRef: ComponentRef<T>; protected compRef: ComponentRef<T>;
@@ -74,8 +74,7 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
} }
} }
ngOnInit(): void { ngAfterViewInit(): void {
this.destroyComponentInstance();
this.initComponentInstance(); this.initComponentInstance();
} }
@@ -96,8 +95,6 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
} }
if (hasNoValue(this.lazyLoadObs)) { if (hasNoValue(this.lazyLoadObs)) {
this.destroyComponentInstance();
this.lazyLoadObs = combineLatest([ this.lazyLoadObs = combineLatest([
observableOf(changes), observableOf(changes),
this.resolveThemedComponent(this.themeService.getThemeName()).pipe( this.resolveThemedComponent(this.themeService.getThemeName()).pipe(
@@ -120,6 +117,7 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
} }
this.lazyLoadSub = this.lazyLoadObs.subscribe(([simpleChanges, constructor]: [SimpleChanges, GenericConstructor<T>]) => { this.lazyLoadSub = this.lazyLoadObs.subscribe(([simpleChanges, constructor]: [SimpleChanges, GenericConstructor<T>]) => {
this.destroyComponentInstance();
const factory = this.resolver.resolveComponentFactory(constructor); const factory = this.resolver.resolveComponentFactory(constructor);
this.compRef = this.vcr.createComponent(factory, undefined, undefined, [this.themedElementContent.nativeElement.childNodes]); this.compRef = this.vcr.createComponent(factory, undefined, undefined, [this.themedElementContent.nativeElement.childNodes]);
if (hasValue(simpleChanges)) { if (hasValue(simpleChanges)) {

View File

@@ -67,7 +67,9 @@ export class MarkdownPipe implements PipeTransform {
// sanitize-html doesn't let through SVG by default, so we extend its allowlists to cover MathJax SVG // sanitize-html doesn't let through SVG by default, so we extend its allowlists to cover MathJax SVG
allowedTags: [ allowedTags: [
...sanitizeHtml.defaults.allowedTags, ...sanitizeHtml.defaults.allowedTags,
'mjx-container', 'svg', 'g', 'path', 'rect', 'text' 'mjx-container', 'svg', 'g', 'path', 'rect', 'text',
// Also let the mjx-assistive-mml tag (and it's children) through (for screen readers)
'mjx-assistive-mml', 'math', 'mrow', 'mi',
], ],
allowedAttributes: { allowedAttributes: {
...sanitizeHtml.defaults.allowedAttributes, ...sanitizeHtml.defaults.allowedAttributes,
@@ -88,7 +90,16 @@ export class MarkdownPipe implements PipeTransform {
], ],
text: [ text: [
'transform', 'font-size' 'transform', 'font-size'
] ],
'mjx-assistive-mml': [
'unselectable', 'display', 'style',
],
math: [
'xmlns',
],
mrow: [
'data-mjx-texclass',
],
}, },
parser: { parser: {
lowerCaseAttributeNames: false, lowerCaseAttributeNames: false,

View File

@@ -3,7 +3,7 @@ import { Component, Injector, Input, OnInit, ViewChild } from '@angular/core';
import { SectionsDirective } from '../sections.directive'; import { SectionsDirective } from '../sections.directive';
import { SectionDataObject } from '../models/section-data.model'; import { SectionDataObject } from '../models/section-data.model';
import { rendersSectionType } from '../sections-decorator'; import { rendersSectionType } from '../sections-decorator';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
/** /**
* This component represents a section that contains the submission license form. * This component represents a section that contains the submission license form.

View File

@@ -7,7 +7,7 @@ import { SectionModelComponent } from '../models/section.model';
import { renderSectionFor } from '../sections-decorator'; import { renderSectionFor } from '../sections-decorator';
import { SectionDataObject } from '../models/section-data.model'; import { SectionDataObject } from '../models/section-data.model';
import { SubmissionService } from '../../submission.service'; import { SubmissionService } from '../../submission.service';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { SectionsService } from '../sections.service'; import { SectionsService } from '../sections.service';
import { WorkspaceitemSectionIdentifiersObject } from '../../../core/submission/models/workspaceitem-section-identifiers.model'; import { WorkspaceitemSectionIdentifiersObject } from '../../../core/submission/models/workspaceitem-section-identifiers.model';

View File

@@ -1,7 +1,7 @@
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { Policy } from '../../../../core/submission/models/sherpa-policies-details.model'; import { Policy } from '../../../../core/submission/models/sherpa-policies-details.model';
import { AlertType } from '../../../../shared/alert/aletr-type'; import { AlertType } from '../../../../shared/alert/alert-type';
/** /**
* This component represents a section that contains the publisher policy informations. * This component represents a section that contains the publisher policy informations.

View File

@@ -1,4 +1,4 @@
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { BehaviorSubject, Observable, of, Subscription } from 'rxjs'; import { BehaviorSubject, Observable, of, Subscription } from 'rxjs';

View File

@@ -21,7 +21,7 @@ import { SectionsType } from '../sections-type';
import { renderSectionFor } from '../sections-decorator'; import { renderSectionFor } from '../sections-decorator';
import { SectionDataObject } from '../models/section-data.model'; import { SectionDataObject } from '../models/section-data.model';
import { SubmissionObjectEntry } from '../../objects/submission-objects.reducer'; import { SubmissionObjectEntry } from '../../objects/submission-objects.reducer';
import { AlertType } from '../../../shared/alert/aletr-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { Group } from '../../../core/eperson/models/group.model'; import { Group } from '../../../core/eperson/models/group.model';
import { SectionsService } from '../sections.service'; import { SectionsService } from '../sections.service';

View File

@@ -4276,25 +4276,25 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.show.workspace": "Your Submissions", "mydspace.show.workspace": "Your Submissions",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.archived": "Archived", "mydspace.status.mydspaceArchived": "Archived",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.validation": "Validation", "mydspace.status.mydspaceValidation": "Validation",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.waiting-for-controller": "Waiting for controller", "mydspace.status.mydspaceWaitingController": "Waiting for controller",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.workflow": "Workflow", "mydspace.status.mydspaceWorkflow": "Workflow",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.workspace": "Workspace", "mydspace.status.mydspaceWorkspace": "Workspace",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
// TODO New key - Add a translation // TODO New key - Add a translation

View File

@@ -3880,20 +3880,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "আপনার জমাগুলো", "mydspace.show.workspace": "আপনার জমাগুলো",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "সংরক্ষণাগারভুক্ত", "mydspace.status.mydspaceArchived": "সংরক্ষণাগারভুক্ত",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "বৈধতা", "mydspace.status.mydspaceValidation": "বৈধতা",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "নিয়ামক জন্য অপেক্ষা করছে", "mydspace.status.mydspaceWaitingController": "নিয়ামক জন্য অপেক্ষা করছে",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "ওয়ার্কফ্লো", "mydspace.status.mydspaceWorkflow": "ওয়ার্কফ্লো",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "কর্মক্ষেত্র", "mydspace.status.mydspaceWorkspace": "কর্মক্ষেত্র",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "আমার ডিস্পেস", "mydspace.title": "আমার ডিস্পেস",

View File

@@ -4190,20 +4190,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Els seus enviaments", "mydspace.show.workspace": "Els seus enviaments",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Arxivat", "mydspace.status.mydspaceArchived": "Arxivat",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Validació", "mydspace.status.mydspaceValidation": "Validació",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Esperant el controlador", "mydspace.status.mydspaceWaitingController": "Esperant el controlador",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Flux de treball", "mydspace.status.mydspaceWorkflow": "Flux de treball",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Espai de treball", "mydspace.status.mydspaceWorkspace": "Espai de treball",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "El meu DSpace", "mydspace.title": "El meu DSpace",

View File

@@ -4187,25 +4187,25 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.show.workspace": "Your Submissions", "mydspace.show.workspace": "Your Submissions",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.archived": "Archived", "mydspace.status.mydspaceArchived": "Archived",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.validation": "Validation", "mydspace.status.mydspaceValidation": "Validation",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.waiting-for-controller": "Waiting for controller", "mydspace.status.mydspaceWaitingController": "Waiting for controller",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.workflow": "Workflow", "mydspace.status.mydspaceWorkflow": "Workflow",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.workspace": "Workspace", "mydspace.status.mydspaceWorkspace": "Workspace",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
// TODO New key - Add a translation // TODO New key - Add a translation

View File

@@ -1712,7 +1712,8 @@
// "curation-task.task.vscan.label": "Virus Scan", // "curation-task.task.vscan.label": "Virus Scan",
"curation-task.task.vscan.label": "Virenscan", "curation-task.task.vscan.label": "Virenscan",
// "curation-task.task.registerdoi.label": "Register DOI",
"curation-task.task.registerdoi.label": "DOI registrieren",
// "curation.form.task-select.label": "Task:", // "curation.form.task-select.label": "Task:",
"curation.form.task-select.label": "Aufgabe:", "curation.form.task-select.label": "Aufgabe:",
@@ -3484,20 +3485,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Ihre Veröffentlichungen", "mydspace.show.workspace": "Ihre Veröffentlichungen",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Archiviert", "mydspace.status.mydspaceArchived": "Archiviert",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Validierung", "mydspace.status.mydspaceValidation": "Validierung",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Warten auf die Überprüfung", "mydspace.status.mydspaceWaitingController": "Warten auf die Überprüfung",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Geschäftsgang", "mydspace.status.mydspaceWorkflow": "Geschäftsgang",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Arbeitsbereich", "mydspace.status.mydspaceWorkspace": "Arbeitsbereich",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "Mein DSpace", "mydspace.title": "Mein DSpace",
@@ -4487,6 +4488,21 @@
// "search.filters.discoverable.false": "Yes", // "search.filters.discoverable.false": "Yes",
"search.filters.discoverable.false": "Ja", "search.filters.discoverable.false": "Ja",
// "search.filters.namedresourcetype.Archived": "Archived",
"search.filters.namedresourcetype.Archived": "Archiviert",
// "search.filters.namedresourcetype.Validation": "Validation",
"search.filters.namedresourcetype.Validation": "Validierung",
// "search.filters.namedresourcetype.Waiting for Controller": "Waiting for Controller",
"search.filters.namedresourcetype.Waiting for Controller": "Warten auf die Überprüfung",
// "search.filters.namedresourcetype.Workflow": "Workflow",
"search.filters.namedresourcetype.Workflow": "Geschäftsgang",
// "search.filters.namedresourcetype.Workspace": "Workspace",
"search.filters.namedresourcetype.Workspace": "Arbeitsbereich",
// "search.filters.withdrawn.true": "Yes", // "search.filters.withdrawn.true": "Yes",
"search.filters.withdrawn.true": "Ja", "search.filters.withdrawn.true": "Ja",

View File

@@ -1315,11 +1315,11 @@
"mydspace.search-form.placeholder": "Αναζήτηση στο mydspace...", "mydspace.search-form.placeholder": "Αναζήτηση στο mydspace...",
"mydspace.show.workflow": "Εργασίες ροής εργασιών", "mydspace.show.workflow": "Εργασίες ροής εργασιών",
"mydspace.show.workspace": "Οι Υποβολές σας", "mydspace.show.workspace": "Οι Υποβολές σας",
"mydspace.status.archived": "Αρχειοθετημένα", "mydspace.status.mydspaceArchived": "Αρχειοθετημένα",
"mydspace.status.validation": "Επικύρωση", "mydspace.status.mydspaceValidation": "Επικύρωση",
"mydspace.status.waiting-for-controller": "Αναμονή για τον ελεγκτή", "mydspace.status.mydspaceWaitingController": "Αναμονή για τον ελεγκτή",
"mydspace.status.workflow": "Ροή εργασιών", "mydspace.status.mydspaceWorkflow": "Ροή εργασιών",
"mydspace.status.workspace": "Χώρος εργασίας", "mydspace.status.mydspaceWorkspace": "Χώρος εργασίας",
"mydspace.title": "MyDSpace", "mydspace.title": "MyDSpace",
"mydspace.upload.upload-failed": "Σφάλμα κατά τη δημιουργία νέου χώρου εργασίας. Επαληθεύστε το περιεχόμενο που ανεβάσατε πριν δοκιμάσετε ξανά.", "mydspace.upload.upload-failed": "Σφάλμα κατά τη δημιουργία νέου χώρου εργασίας. Επαληθεύστε το περιεχόμενο που ανεβάσατε πριν δοκιμάσετε ξανά.",
"mydspace.upload.upload-failed-manyentries": "Μη επεξεργάσιμο αρχείο. Εντοπίστηκαν πάρα πολλές καταχωρίσεις, αλλά επιτρέπεται μόνο μία για αρχείο.", "mydspace.upload.upload-failed-manyentries": "Μη επεξεργάσιμο αρχείο. Εντοπίστηκαν πάρα πολλές καταχωρίσεις, αλλά επιτρέπεται μόνο μία για αρχείο.",

View File

@@ -782,6 +782,8 @@
"browse.comcol.by.srsc": "By Subject Category", "browse.comcol.by.srsc": "By Subject Category",
"browse.comcol.by.nsi": "By Norwegian Science Index",
"browse.comcol.by.title": "By Title", "browse.comcol.by.title": "By Title",
"browse.comcol.head": "Browse", "browse.comcol.head": "Browse",
@@ -804,6 +806,8 @@
"browse.metadata.srsc.breadcrumbs": "Browse by Subject Category", "browse.metadata.srsc.breadcrumbs": "Browse by Subject Category",
"browse.metadata.nsi.breadcrumbs": "Browse by Norwegian Science Index",
"browse.metadata.title.breadcrumbs": "Browse by Title", "browse.metadata.title.breadcrumbs": "Browse by Title",
"pagination.next.button": "Next", "pagination.next.button": "Next",
@@ -1392,7 +1396,7 @@
"curation-task.task.vscan.label": "Virus Scan", "curation-task.task.vscan.label": "Virus Scan",
"curation-task.task.register-doi.label": "Register DOI", "curation-task.task.registerdoi.label": "Register DOI",
"curation.form.task-select.label": "Task:", "curation.form.task-select.label": "Task:",
@@ -2826,6 +2830,8 @@
"menu.section.browse_global_by_srsc": "By Subject Category", "menu.section.browse_global_by_srsc": "By Subject Category",
"menu.section.browse_global_by_nsi": "By Norwegian Science Index",
"menu.section.browse_global_by_title": "By Title", "menu.section.browse_global_by_title": "By Title",
"menu.section.browse_global_communities_and_collections": "Communities & Collections", "menu.section.browse_global_communities_and_collections": "Communities & Collections",
@@ -3814,6 +3820,16 @@
"search.filters.discoverable.false": "Yes", "search.filters.discoverable.false": "Yes",
"search.filters.namedresourcetype.Archived": "Archived",
"search.filters.namedresourcetype.Validation": "Validation",
"search.filters.namedresourcetype.Waiting for Controller": "Waiting for Controller",
"search.filters.namedresourcetype.Workflow": "Workflow",
"search.filters.namedresourcetype.Workspace": "Workspace",
"search.filters.withdrawn.true": "Yes", "search.filters.withdrawn.true": "Yes",
"search.filters.withdrawn.false": "No", "search.filters.withdrawn.false": "No",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3822,20 +3822,20 @@
//"mydspace.show.supervisedWorkspace": "Supervised items", //"mydspace.show.supervisedWorkspace": "Supervised items",
"mydspace.show.supervisedWorkspace": "Items supervisés", "mydspace.show.supervisedWorkspace": "Items supervisés",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Archivés", "mydspace.status.mydspaceArchived": "Archivés",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "En cours de validation", "mydspace.status.mydspaceValidation": "En cours de validation",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "En attente d'assignation", "mydspace.status.mydspaceWaitingController": "En attente d'assignation",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "En traitement", "mydspace.status.mydspaceWorkflow": "En traitement",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Dépôts en cours", "mydspace.status.mydspaceWorkspace": "Dépôts en cours",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "Mon compte DSpace", "mydspace.title": "Mon compte DSpace",

View File

@@ -3867,20 +3867,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Do Chur-a-steachan", "mydspace.show.workspace": "Do Chur-a-steachan",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "San Tasglann", "mydspace.status.mydspaceArchived": "San Tasglann",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Dearbhadh", "mydspace.status.mydspaceValidation": "Dearbhadh",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "A' feitheamh riaghladair", "mydspace.status.mydspaceWaitingController": "A' feitheamh riaghladair",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Sruth-obrach", "mydspace.status.mydspaceWorkflow": "Sruth-obrach",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Raon-obrach", "mydspace.status.mydspaceWorkspace": "Raon-obrach",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "MoDSpace", "mydspace.title": "MoDSpace",

View File

@@ -2677,15 +2677,15 @@
"mydspace.show.workspace": "आपकी प्रस्तुतियां", "mydspace.show.workspace": "आपकी प्रस्तुतियां",
"mydspace.status.archived": "संग्रहीत", "mydspace.status.mydspaceArchived": "संग्रहीत",
"mydspace.status.validation": "सत्यापन", "mydspace.status.mydspaceValidation": "सत्यापन",
"mydspace.status.waiting-for-controller": "नियंत्रक की प्रतीक्षा कर रहा है", "mydspace.status.mydspaceWaitingController": "नियंत्रक की प्रतीक्षा कर रहा है",
"mydspace.status.workflow": "कार्यप्रवाह", "mydspace.status.mydspaceWorkflow": "कार्यप्रवाह",
"mydspace.status.workspace": "कार्यस्थान", "mydspace.status.mydspaceWorkspace": "कार्यस्थान",
"mydspace.title": "मेरा डीस्पेस", "mydspace.title": "मेरा डीस्पेस",

View File

@@ -2228,9 +2228,9 @@
// "curation-task.task.vscan.label": "Virus Scan", // "curation-task.task.vscan.label": "Virus Scan",
"curation-task.task.vscan.label": "Virus ellenőrzés", "curation-task.task.vscan.label": "Virus ellenőrzés",
// "curation-task.task.register-doi.label": "Register DOI", // "curation-task.task.registerdoi.label": "Register DOI",
// TODO New key - Add a translation // TODO New key - Add a translation
"curation-task.task.register-doi.label": "Register DOI", "curation-task.task.registerdoi.label": "Register DOI",
@@ -4983,20 +4983,20 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.show.supervisedWorkspace": "Supervised items", "mydspace.show.supervisedWorkspace": "Supervised items",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Tárolva", "mydspace.status.mydspaceArchived": "Tárolva",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Érvényesítés", "mydspace.status.mydspaceValidation": "Érvényesítés",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Várakozás a kontrollerre", "mydspace.status.mydspaceWaitingController": "Várakozás a kontrollerre",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Munkafolyamat", "mydspace.status.mydspaceWorkflow": "Munkafolyamat",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Munkafelület", "mydspace.status.mydspaceWorkspace": "Munkafelület",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "MyDSpace", "mydspace.title": "MyDSpace",

View File

@@ -2160,9 +2160,9 @@
// "curation-task.task.vscan.label": "Virus Scan", // "curation-task.task.vscan.label": "Virus Scan",
"curation-task.task.vscan.label": "Scansione antivirus", "curation-task.task.vscan.label": "Scansione antivirus",
// "curation-task.task.register-doi.label": "Register DOI", // "curation-task.task.registerdoi.label": "Register DOI",
// TODO New key - Add a translation // TODO New key - Add a translation
"curation-task.task.register-doi.label": "Register DOI", "curation-task.task.registerdoi.label": "Register DOI",
@@ -4813,20 +4813,20 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.show.supervisedWorkspace": "Supervised items", "mydspace.show.supervisedWorkspace": "Supervised items",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Archiviati", "mydspace.status.mydspaceArchived": "Archiviati",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Convalida", "mydspace.status.mydspaceValidation": "Convalida",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "In attesa del controllo", "mydspace.status.mydspaceWaitingController": "In attesa del controllo",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Workflow", "mydspace.status.mydspaceWorkflow": "Workflow",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Workspace", "mydspace.status.mydspaceWorkspace": "Workspace",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "MyDSpace", "mydspace.title": "MyDSpace",

View File

@@ -4276,25 +4276,25 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.show.workspace": "Your Submissions", "mydspace.show.workspace": "Your Submissions",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.archived": "Archived", "mydspace.status.mydspaceArchived": "Archived",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.validation": "Validation", "mydspace.status.mydspaceValidation": "Validation",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.waiting-for-controller": "Waiting for controller", "mydspace.status.mydspaceWaitingController": "Waiting for controller",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.workflow": "Workflow", "mydspace.status.mydspaceWorkflow": "Workflow",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
// TODO New key - Add a translation // TODO New key - Add a translation
"mydspace.status.workspace": "Workspace", "mydspace.status.mydspaceWorkspace": "Workspace",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
// TODO New key - Add a translation // TODO New key - Add a translation

View File

@@ -4139,20 +4139,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Сіздің өтініштеріңіз", "mydspace.show.workspace": "Сіздің өтініштеріңіз",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Мұрағатталған", "mydspace.status.mydspaceArchived": "Мұрағатталған",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Валидация", "mydspace.status.mydspaceValidation": "Валидация",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Контроллерді күтуде", "mydspace.status.mydspaceWaitingController": "Контроллерді күтуде",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Жұмыс барысы", "mydspace.status.mydspaceWorkflow": "Жұмыс барысы",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Жұмыс кеңістігі", "mydspace.status.mydspaceWorkspace": "Жұмыс кеңістігі",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "MyDSpace", "mydspace.title": "MyDSpace",

View File

@@ -3492,20 +3492,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Jūsu Iesniegumi", "mydspace.show.workspace": "Jūsu Iesniegumi",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Arhivēts", "mydspace.status.mydspaceArchived": "Arhivēts",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Validācija", "mydspace.status.mydspaceValidation": "Validācija",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Gaida kontrolieri", "mydspace.status.mydspaceWaitingController": "Gaida kontrolieri",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Darba plūsma", "mydspace.status.mydspaceWorkflow": "Darba plūsma",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Darbavieta", "mydspace.status.mydspaceWorkspace": "Darbavieta",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "Mans DSpace", "mydspace.title": "Mans DSpace",

View File

@@ -3764,20 +3764,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Uw Submissions", "mydspace.show.workspace": "Uw Submissions",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Opgeslagen", "mydspace.status.mydspaceArchived": "Opgeslagen",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Validatie", "mydspace.status.mydspaceValidation": "Validatie",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Wachten op controlleur", "mydspace.status.mydspaceWaitingController": "Wachten op controlleur",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Workflow", "mydspace.status.mydspaceWorkflow": "Workflow",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Workspace", "mydspace.status.mydspaceWorkspace": "Workspace",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "MyDSpace", "mydspace.title": "MyDSpace",

View File

@@ -57,7 +57,7 @@
"admin.registries.bitstream-formats.table.supportLevel.head": "Obsługiwany format", "admin.registries.bitstream-formats.table.supportLevel.head": "Obsługiwany format",
"admin.registries.bitstream-formats.title": "Rejestr formatów plików", "admin.registries.bitstream-formats.title": "Rejestr formatów plików",
"admin.registries.metadata.breadcrumbs": "Rejestr metadanych", "admin.registries.metadata.breadcrumbs": "Rejestr metadanych",
"admin.registries.metadata.description": "W rejestrze metadanych przechowywana jest lista wszystkich pól metadanych dostępnych w repozytorium. Przechowywane pola są przechowywane w kilku rejestrach. DSpace wymaga kwalifikowanego rejestru metadanych Dublin Core.", "admin.registries.metadata.description": "W rejestrze metadanych przechowywana jest lista wszystkich pól metadanych dostępnych w repozytorium. Przechowywane pola są przechowywane w kilku rejestrach. DSpace wymaga kwalifikowanego rejestru metadanych Dublin Core.",
"admin.registries.metadata.form.create": "Utwórz schemat metadanych", "admin.registries.metadata.form.create": "Utwórz schemat metadanych",
"admin.registries.metadata.form.edit": "Edytuj schemat metadanych", "admin.registries.metadata.form.edit": "Edytuj schemat metadanych",
"admin.registries.metadata.form.name": "Nazwa", "admin.registries.metadata.form.name": "Nazwa",
@@ -885,7 +885,7 @@
"item.edit.tabs.curate.head": "Administruj", "item.edit.tabs.curate.head": "Administruj",
"item.edit.tabs.curate.title": "Edytowanie pozycji - administruj", "item.edit.tabs.curate.title": "Edytowanie pozycji - administruj",
"item.edit.tabs.metadata.head": "Metadane", "item.edit.tabs.metadata.head": "Metadane",
"item.edit.tabs.metadata.title": "Edycja pozycji - metadane", "item.edit.tabs.metadata.title": "Edycja pozycji - metadane",
"item.edit.tabs.relationships.head": "Relacje", "item.edit.tabs.relationships.head": "Relacje",
"item.edit.tabs.relationships.title": "Edycja pozycja - relacje", "item.edit.tabs.relationships.title": "Edycja pozycja - relacje",
"item.edit.tabs.status.buttons.authorizations.button": "Dostępy...", "item.edit.tabs.status.buttons.authorizations.button": "Dostępy...",
@@ -911,12 +911,12 @@
"item.edit.tabs.status.labels.id": "ID pozycji", "item.edit.tabs.status.labels.id": "ID pozycji",
"item.edit.tabs.status.labels.itemPage": "Strona pozycji", "item.edit.tabs.status.labels.itemPage": "Strona pozycji",
"item.edit.tabs.status.labels.lastModified": "Ostatnia modyfikacja", "item.edit.tabs.status.labels.lastModified": "Ostatnia modyfikacja",
"item.edit.tabs.status.title": "Edycja pozycji - Status", "item.edit.tabs.status.title": "Edycja pozycji - Status",
"item.edit.tabs.versionhistory.head": "Historia wersji", "item.edit.tabs.versionhistory.head": "Historia wersji",
"item.edit.tabs.versionhistory.title": "Edycja pozycji - historia wersji", "item.edit.tabs.versionhistory.title": "Edycja pozycji - historia wersji",
"item.edit.tabs.versionhistory.under-construction": "Edytowanie lub dodawanie nowych wersji jest niedostępne w tego poziomu interfejsu.", "item.edit.tabs.versionhistory.under-construction": "Edytowanie lub dodawanie nowych wersji jest niedostępne w tego poziomu interfejsu.",
"item.edit.tabs.view.head": "Widok pozycji", "item.edit.tabs.view.head": "Widok pozycji",
"item.edit.tabs.view.title": "Edycja pozycji - widok", "item.edit.tabs.view.title": "Edycja pozycji - widok",
"item.edit.withdraw.cancel": "Anuluj", "item.edit.withdraw.cancel": "Anuluj",
"item.edit.withdraw.confirm": "Wycofaj", "item.edit.withdraw.confirm": "Wycofaj",
"item.edit.withdraw.description": "Czy na pewno chcesz wycofać pozycję?", "item.edit.withdraw.description": "Czy na pewno chcesz wycofać pozycję?",
@@ -1207,11 +1207,11 @@
"mydspace.search-form.placeholder": "Wyszukaj w mydspace...", "mydspace.search-form.placeholder": "Wyszukaj w mydspace...",
"mydspace.show.workflow": "Wszystkie zadania", "mydspace.show.workflow": "Wszystkie zadania",
"mydspace.show.workspace": "Twoje zadania", "mydspace.show.workspace": "Twoje zadania",
"mydspace.status.archived": "Zarchiwizowano", "mydspace.status.mydspaceArchived": "Zarchiwizowano",
"mydspace.status.validation": "Walidacja", "mydspace.status.mydspaceValidation": "Walidacja",
"mydspace.status.waiting-for-controller": "Oczekiwanie na redaktora", "mydspace.status.mydspaceWaitingController": "Oczekiwanie na redaktora",
"mydspace.status.workflow": "Workflow", "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workspace": "Wersja robocza", "mydspace.status.mydspaceWorkspace": "Wersja robocza",
"mydspace.title": "Mój DSpace", "mydspace.title": "Mój DSpace",
"mydspace.upload.upload-failed": "Bład podczas tworzenia nowej wersji roboczej. Sprawdź poprawność plików i spróbuj ponownie.", "mydspace.upload.upload-failed": "Bład podczas tworzenia nowej wersji roboczej. Sprawdź poprawność plików i spróbuj ponownie.",
"mydspace.upload.upload-failed-manyentries": "Plik jest niemożliwy do przetworzenia. Wykryto wiele wejść, a dopuszczalne jest tylko jedno dla jednego pliku.", "mydspace.upload.upload-failed-manyentries": "Plik jest niemożliwy do przetworzenia. Wykryto wiele wejść, a dopuszczalne jest tylko jedno dla jednego pliku.",
@@ -1953,7 +1953,7 @@
"submission.submit.breadcrumbs": "Nowe zgłoszenie", "submission.submit.breadcrumbs": "Nowe zgłoszenie",
"submission.submit.title": "Nowe zgłoszenie", "submission.submit.title": "Nowe zgłoszenie",
"submission.workflow.generic.delete": "Usuń", "submission.workflow.generic.delete": "Usuń",
"submission.workflow.generic.delete-help": "Jeśli chcesz odrzucić tę pozycję, wybierz \"Delete\". Będzie wymagane potwierdzenie tej decyzji.", "submission.workflow.generic.delete-help": "Jeśli chcesz odrzucić tę pozycję, wybierz \"Delete\". Będzie wymagane potwierdzenie tej decyzji.",
"submission.workflow.generic.edit": "Edytuj", "submission.workflow.generic.edit": "Edytuj",
"submission.workflow.generic.edit-help": "Wybierz tę opcję, aby zmienić metadane pozycji.", "submission.workflow.generic.edit-help": "Wybierz tę opcję, aby zmienić metadane pozycji.",
"submission.workflow.generic.view": "Podgląd", "submission.workflow.generic.view": "Podgląd",
@@ -1967,7 +1967,7 @@
"submission.workflow.tasks.claimed.reject.reason.submit": "Odrzuć pozycję", "submission.workflow.tasks.claimed.reject.reason.submit": "Odrzuć pozycję",
"submission.workflow.tasks.claimed.reject.reason.title": "Powód", "submission.workflow.tasks.claimed.reject.reason.title": "Powód",
"submission.workflow.tasks.claimed.reject.submit": "Odrzuć", "submission.workflow.tasks.claimed.reject.submit": "Odrzuć",
"submission.workflow.tasks.claimed.reject_help": "Jeśli po przejrzeniu pozycji stwierdzono, że nie nadaje się ona do włączenia do kolekcji, wybierz opcję \"Reject\". Zostaniesz wtedy poproszony o określenie powodu odrzucenia, i wskazanie czy zgłaszający powinien wprowadzić zmiany i przesłać ponownie pozycję.", "submission.workflow.tasks.claimed.reject_help": "Jeśli po przejrzeniu pozycji stwierdzono, że nie nadaje się ona do włączenia do kolekcji, wybierz opcję \"Reject\". Zostaniesz wtedy poproszony o określenie powodu odrzucenia, i wskazanie czy zgłaszający powinien wprowadzić zmiany i przesłać ponownie pozycję.",
"submission.workflow.tasks.claimed.return": "Cofnij do puli zadań", "submission.workflow.tasks.claimed.return": "Cofnij do puli zadań",
"submission.workflow.tasks.claimed.return_help": "Cofnij zadanie do puli, aby inny użytkownik mógł się go podjąć.", "submission.workflow.tasks.claimed.return_help": "Cofnij zadanie do puli, aby inny użytkownik mógł się go podjąć.",
"submission.workflow.tasks.generic.error": "Podczas działania wystąpił błąd...", "submission.workflow.tasks.generic.error": "Podczas działania wystąpił błąd...",
@@ -2296,4 +2296,326 @@
"submission.sections.license.required": "Najpierw musisz zaakceptować licencję", "submission.sections.license.required": "Najpierw musisz zaakceptować licencję",
"confirmation-modal.export-batch.confirm": "Eksportuj", "confirmation-modal.export-batch.confirm": "Eksportuj",
"confirmation-modal.export-batch.cancel": "Anuluj", "confirmation-modal.export-batch.cancel": "Anuluj",
"admin.access-control.bulk-access.breadcrumbs": "Zbiorcza edycja dostępu do osiągnięć",
"administrativeBulkAccess.search.results.head": "Wyniki wyszukiwania",
"admin.access-control.bulk-access": "Zbiorcza edycja dostępu do osiągnięć",
"admin.access-control.bulk-access.title": "Zbiorcza edycja dostępu do osiągnięć",
"admin.access-control.bulk-access-browse.header": "Krok 1: Wybierz pozycje",
"admin.access-control.bulk-access-browse.search.header": "Wyszukaj",
"admin.access-control.bulk-access-browse.selected.header": "Obecny wybór({{number}})",
"admin.access-control.bulk-access-settings.header": "Krok 2: Działanie do wykonania",
"admin.access-control.groups.form.tooltip.editGroupPage": "Na tej stronie można edytować opcje grupy i przypisane do niej osoby. W górnej sekcji można edytować nazwę i opis grupy, chyba że jest to grupa administratorów dla zbioru i kolekcji. W tym przypadku nazwa i opis grupy są generowane automatycznie i nie można ich edytować. W kolejnych sekcjach można edytować przypisanie użytkowników do grupy. Szczegóły na [stronie](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group).",
"admin.access-control.groups.form.tooltip.editGroup.addEpeople": "Aby dodać lub usunąć użytkownika do/z tej grupy, kliknij przycisk 'Przeglądaj wszystko' lub użyj paska wyszukiwania poniżej, aby wyszukać użytkowników (użyj listy rozwijanej po lewej stronie paska wyszukiwania, aby wybrać, czy chcesz wyszukiwać według imienia i nazwiska, czy według adresu e-mail). Następnie kliknij ikonę plusa przy każdym użytkowniku, którego chcesz dodać do poniższej listy, lub ikonę kosza przy każdym użytkowniku, którego chcesz usunąć. Poniższa lista może mieć kilka stron: użyj strzałek pod listą, aby przejść do kolejnych stron. Gdy wszystkie zmiany zostaną wprowadzone, zapisz je, klikając przycisk 'Zapisz' w górnej sekcji.",
"admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "Aby dodać lub usunąć podgrupę do/z tej grupy, kliknij przycisk 'Przeglądaj wszystko' lub użyj wyszukiwarki poniżej, aby wyszukać użytkowników. Następnie kliknij ikonę plusa przy każdym użytkowniku, którego chcesz dodać do poniższej listy, lub ikonę kosza przy każdym użytkowniku, którego chcesz usunąć. Poniższa lista może składać się z kilku stron: użyj przycisków pod listą, aby przejść do kolejnych stron. Gdy wszystkie zmiany zostaną wprowadzone, zapisz je, klikając przycisk 'Zapisz' w górnej sekcji.",
"admin.workflow.item.workspace": "Przestrzeń robocza",
"admin.workflow.item.policies": "Polityki",
"admin.workflow.item.supervision": "Recenzja",
"admin.batch-import.page.toggle.help": "It is possible to perform import either with file upload or via URL, use above toggle to set the input source",
"admin.metadata-import.page.error.addFileUrl": "Najpierw wpisz URL pliku!",
"admin.metadata-import.page.toggle.upload": "Prześlij",
"admin.metadata-import.page.toggle.url": "URL",
"admin.metadata-import.page.urlMsg": "Wpisz URL pliku ZIP, aby wykonać import masowy",
"advanced-workflow-action.rating.form.rating.label": "Ocena",
"advanced-workflow-action.rating.form.rating.error": "Ta pozycja musi zostać oceniona",
"advanced-workflow-action.rating.form.review.label": "Recenzja",
"advanced-workflow-action.rating.form.review.error": "Musisz wpisać tekst recenzji",
"advanced-workflow-action.rating.description": "Wybierz ocenę poniżej",
"advanced-workflow-action.rating.description-requiredDescription": "Wybierz ocenę poniżej i wpisz uzasadnienie",
"advanced-workflow-action.select-reviewer.description-single": "Wybierz recenzenta przed zdeponowaniem pozycji",
"advanced-workflow-action.select-reviewer.description-multiple": "Wybierz jednego lub więcej recenzentów przed zdeponowaniem pozycji",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.head": "Użytkownicy",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.head": "Dodaj użytkownika",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.button.see-all": "Przeglądaj wszystko",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Aktualni użytkownicy",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.scope.metadata": "Metadane",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.scope.email": "Adres e-mail (dokładny)",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Wyszukaj",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.id": "ID",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.name": "Nazwa",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.identity": "Tożsamość",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.email": "Adres e-mail",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.netid": "NetID",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit": "Usuń / Dodaj",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.remove": "Usuń użytkownika z nazwę \"{{name}}\"",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.addMember": "Dodano użytkownika o nazwie: \"{{name}}\"",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.addMember": "Nie dodano użytkownika: \"{{name}}\"",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.deleteMember": "Usunięto użytkownika: \"{{name}}\"",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.deleteMember": "Nie usunięto użytkownika: \"{{name}}\"",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.add": "Dodano użytkownika \"{{name}}\"",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "Brak aktywnej grupy, najpierw wpisz nazwę.",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "W tej grupie nie ma użytkowników, wyszukaj ich i dodaj.",
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-items": "Nie znaleziono żadnych użytkowników",
"advanced-workflow-action.select-reviewer.no-reviewer-selected.error": "Recenzent nie jest wybrany.",
"bitstream.edit.notifications.error.primaryBitstream.title": "Wystąpił błąd podczas zapisu pliku.",
"browse.comcol.by.srsc": "Wg słów kluczowych",
"browse.metadata.srsc.breadcrumbs": "Przeglądaj wg słów kluczowych",
"browse.startsWith.input": "Filtr",
"browse.taxonomy.button": "Przeglądaj",
"search.browse.item-back": "Powrót do wyników wyszukiwania",
"claimed-approved-search-result-list-element.title": "Zaakceptowano",
"claimed-declined-search-result-list-element.title": "Odrzucono i przesłano do deponującego",
"claimed-declined-task-search-result-list-element.title": "Odrzucono i przesłano do recenzenta",
"collection.edit.tabs.access-control.head": "Dostępy",
"collection.edit.tabs.access-control.title": "Edycja kolekcji - dostępy",
"collection.listelement.badge": "Kolekcja",
"community.edit.tabs.access-control.head": "Dostępy",
"community.edit.tabs.access-control.title": "Edycja zbioru - dostępy",
"comcol-role.edit.scorereviewers.name": "Ocena recenzenta",
"comcol-role.edit.scorereviewers.description": "Recenzenci mogą oceniać zdeponowane pozycje, co określi, czy pozycja zostanie przyjęta lub odrzucona.",
"curation-task.task.register-doi.label": "Rejestracja DOI",
"dso.name.unnamed": "Bez nazwy",
"dso-selector.create.community.or-divider": "lub",
"dso-selector.set-scope.community.or-divider": "lub",
"dso-selector.results-could-not-be-retrieved": "Wystąpił błąd, proszę odświeżyć stronę",
"supervision-group-selector.header": "Wybór grupy recenzenckiej",
"supervision-group-selector.select.type-of-order.label": "Wybierz typ funkcji",
"supervision-group-selector.select.type-of-order.option.none": "BRAK",
"supervision-group-selector.select.type-of-order.option.editor": "REDAKTOR",
"supervision-group-selector.select.type-of-order.option.observer": "OBSERWATOR",
"supervision-group-selector.select.group.label": "Wybierz grupę",
"supervision-group-selector.button.cancel": "Anuluj",
"supervision-group-selector.button.save": "Zapisz",
"supervision-group-selector.select.type-of-order.error": "Wybierz typ funkcji",
"supervision-group-selector.select.group.error": "Wybierz grupę",
"supervision-group-selector.notification.create.success.title": "Grupa recenzencka został dodana dla grupy {{ name }}",
"supervision-group-selector.notification.create.failure.title": "Błąd",
"supervision-group-selector.notification.create.already-existing": "Funkcja recenzenta już jest przypisana do tej grupy",
"confirmation-modal.delete-subscription.header": "Usuń subksrypcje",
"confirmation-modal.delete-subscription.info": "Czy na pewno chcesz usunąć subskrypcję: \"{{ dsoName }}\"",
"confirmation-modal.delete-subscription.cancel": "Anuluj",
"confirmation-modal.delete-subscription.confirm": "Usuń",
"error.validation.metadata.name.invalid-pattern": "To pole nie może zawierać kropek, przecinków i spacji. Zamiast tego This field cannot contain dots, commas or spaces. Zamiast tego może użyć pól z notacji SNEQ",
"error.validation.metadata.name.max-length": "To pole nie może zawierać więcej niż 32 znaki",
"error.validation.metadata.namespace.max-length": "To pole nie może zawierać więcej niż 256 znaków",
"error.validation.metadata.element.invalid-pattern": "To pole nie może zawierać kropek, przecinków i spacji. Zamiast tego This field cannot contain dots, commas or spaces. Zamiast tego może użyć pól z notacji SNEQ",
"error.validation.metadata.element.max-length": "To pole nie może zawierać więcej niż 64 znaki",
"error.validation.metadata.qualifier.invalid-pattern": "To pole nie może zawierać kropek, przecinków i spacji",
"error.validation.metadata.qualifier.max-length": "To pole nie może zawierać więcej niż 64 znaki",
"forgot-email.form.email.error.not-email-form": "Wpisz prawidłowy adres e-mail",
"form.other-information.email": "Adres e-mail",
"form.other-information.first-name": "Imię",
"form.other-information.insolr": "Solr Index",
"form.other-information.institution": "Instytucja",
"form.other-information.last-name": "Nazwisko",
"form.other-information.orcid": "ORCID",
"form.create": "Utwórz",
"info.end-user-agreement.hosting-country": "Stany Zjednoczone",
"item.edit.identifiers.doi.status.UNKNOWN": "Nieznane",
"item.edit.identifiers.doi.status.TO_BE_REGISTERED": "W kolejce do rejestracji",
"item.edit.identifiers.doi.status.TO_BE_RESERVED": "W kolejce do rezerwacji",
"item.edit.identifiers.doi.status.IS_REGISTERED": "Zarejestrowane",
"item.edit.identifiers.doi.status.IS_RESERVED": "Zarezerwowane",
"item.edit.identifiers.doi.status.UPDATE_RESERVED": "Zarezerwowane (aktualizacja w kolejce)",
"item.edit.identifiers.doi.status.UPDATE_REGISTERED": "Zarejestrowane (aktualizacja w kolejce)",
"item.edit.identifiers.doi.status.UPDATE_BEFORE_REGISTRATION": "W kolejce do aktualizacji i rejestracji",
"item.edit.identifiers.doi.status.TO_BE_DELETED": "Zakolejkowane do usunięcia",
"item.edit.identifiers.doi.status.DELETED": "Usunięte",
"item.edit.identifiers.doi.status.PENDING": "Oczekujące (niezarejestrowane)",
"item.edit.identifiers.doi.status.MINTED": "Rezerwowanie nazwy (niezarejestrowane)",
"item.edit.tabs.status.buttons.register-doi.label": "Zarejestruj nowe lub oczekujące DOI",
"item.edit.tabs.status.buttons.register-doi.button": "Rejestruj DOI...",
"item.edit.register-doi.header": "Zarejestruj nowe lub oczekujące DOI",
"item.edit.register-doi.description": "Zweryfikuj poniższe identyfikatory i metadane pozycji i rozpocznij rejestrację DOI lub anuluj",
"item.edit.register-doi.confirm": "Zatwierdź",
"item.edit.register-doi.cancel": "Anuluj",
"item.edit.register-doi.success": "DOI jest w kolejce do rejestracji.",
"item.edit.register-doi.error": "Wystąpił błąd poczas rejestracji DOI",
"item.edit.register-doi.to-update": "To DOI zostało zarezerwowane i będzie znajdować się w kolejce do rejestracji",
"item.edit.metadata.edit.buttons.confirm": "Zatwierdź",
"item.edit.metadata.edit.buttons.drag": "Przeciągnij, aby zmienić kolejność",
"item.edit.metadata.edit.buttons.virtual": "To pole przechowuje wirutalne wartości metadanych, np. wartość pobraną z encji, z którą jest połączona ta pozycja. Dodaj lub usuń relację w zakładce 'Relacje' ",
"item.edit.metadata.metadatafield.error": "Wystąpił błąd podczas walidcji pól metadanych",
"item.edit.metadata.reset-order-button": "Cofnij zamianę kolejności",
"item.edit.curate.title": "Zarządzaj pozycją: {{item}}",
"item.edit.tabs.access-control.head": "Dostęp",
"item.edit.tabs.access-control.title": "Edycja pozycji - dostęp",
"workflow-item.search.result.delete-supervision.modal.header": "Usuń zadanie dla recenzenta",
"workflow-item.search.result.delete-supervision.modal.info": "Czy na pewno usunąć zadanie dla recenzenta",
"workflow-item.search.result.delete-supervision.modal.cancel": "Anuluj",
"workflow-item.search.result.delete-supervision.modal.confirm": "Usuń",
"workflow-item.search.result.notification.deleted.success": "Usunięto zadanie dla recenzenta \"{{name}}\"",
"workflow-item.search.result.notification.deleted.failure": "Nie usunięto zadania dla recenzenta \"{{name}}\"",
"workflow-item.search.result.list.element.supervised-by": "Recenzja:",
"workflow-item.search.result.list.element.supervised.remove-tooltip": "Usuń grupę recenzencką",
"item.preview.dc.subject": "Słowo kluczowe:",
"item.preview.dc.publisher": "Wydawca:",
"itemtemplate.edit.metadata.add-button": "Dodaj",
"itemtemplate.edit.metadata.discard-button": "Cofnij",
"itemtemplate.edit.metadata.edit.buttons.confirm": "Zatwierdź",
"itemtemplate.edit.metadata.edit.buttons.drag": "Przeciągnij, aby zmienić kolejność",
"itemtemplate.edit.metadata.edit.buttons.edit": "Edytuj",
"itemtemplate.edit.metadata.edit.buttons.remove": "Usuń",
"itemtemplate.edit.metadata.edit.buttons.undo": "Cofnij zmiany",
"itemtemplate.edit.metadata.edit.buttons.unedit": "Nie edytuj",
"itemtemplate.edit.metadata.empty": "To pozycja nie zawiera żadnych metadanych. Wybierz Dodaj, aby je wprowadzić.",
"itemtemplate.edit.metadata.headers.edit": "Edytuj",
"itemtemplate.edit.metadata.headers.field": "Pole",
"itemtemplate.edit.metadata.headers.language": "Język",
"itemtemplate.edit.metadata.headers.value": "Wartość",
"itemtemplate.edit.metadata.metadatafield.error": "Wystąpił błąd podczas walidowania pola metadanych",
"itemtemplate.edit.metadata.metadatafield.invalid": "Wybierz odpowiednie pole metadanych",
"itemtemplate.edit.metadata.notifications.discarded.content": "Twoje zmiany nie zostały zachowane. Aby spróbować wprowadzić je ponownie wybierz Cofnij",
"itemtemplate.edit.metadata.notifications.discarded.title": "Zmiany nie zostały zachowane",
"itemtemplate.edit.metadata.notifications.error.title": "Wystąpił błąd",
"itemtemplate.edit.metadata.notifications.invalid.content": "Twoje zmiany nie zostały zapisane. Upewnij się, że wszystkie pola zostały wypełnione prawidłowo.",
"itemtemplate.edit.metadata.notifications.invalid.title": "Nieprawidłowe metadan",
"itemtemplate.edit.metadata.notifications.outdated.content": "Wzór dla pozycji, na którą w tym momencie pracujesz, został zmodyfikowany przez innego użytkownika. Twoje zmiany zostały odrzucone, aby uniknąć konfliktów pomiędzy wersjami.",
"itemtemplate.edit.metadata.notifications.outdated.title": "Zmiany zostały odrzucone",
"itemtemplate.edit.metadata.notifications.saved.content": "Zmiany w metadanych wzoru pozycji zostały zapisane.",
"itemtemplate.edit.metadata.notifications.saved.title": "Metadane zostały zapisane",
"itemtemplate.edit.metadata.reinstate-button": "Cofnij",
"itemtemplate.edit.metadata.reset-order-button": "Cofnij zmianę kolejności",
"itemtemplate.edit.metadata.save-button": "Zapisz",
"menu.section.access_control_bulk": "Zbiorowe zarządzanie dostępem",
"menu.section.browse_global_by_srsc": "Wg słów kluczowych",
"mydspace.show.supervisedWorkspace": "Pozycje recenzowane",
"mydspace.status.mydspaceArchived": "Opublikowano",
"mydspace.status.mydspaceValidation": "Walidacja",
"mydspace.status.mydspaceWaitingController": "Oczekiwanie na redakctora",
"mydspace.status.mydspaceWorkflow": "Redakcja",
"mydspace.status.mydspaceWorkspace": "Przestrzeń robocza",
"nav.context-help-toggle": "Przełącz pomoc kontekstową",
"nav.search.button": "Wpisz wyszukiwaną frazę",
"nav.subscriptions": "Subksrypcje",
"process.new.notification.error.max-upload.content": "Plik jest większy niż maksymalny dozwolony rozmiar pliku",
"register-page.registration.email.error.not-email-form": "Wprowadź poprawny adres e-mail",
"register-page.registration.email.error.not-valid-domain": "Użyj adresu e-mail z domeny: {{ domains }}",
"register-page.registration.error.maildomain": "Tego adresu e-mail nie możesz zarejestrować, ponieważ nie ma go na liście domen. Dozwolone domeny to: {{ domains }}",
"register-page.registration.info.maildomain": "Konta mogą być założone dla adresów e-mail z domeną",
"repository.title": "Repozytorium DSpace",
"search.filters.applied.f.supervisedBy": "Recenzent",
"search.filters.filter.show-tree": "Przeglądaj {{ name }} strukturę recenzentów",
"search.filters.filter.supervisedBy.head": "Recenzent",
"search.filters.filter.supervisedBy.placeholder": "Recenzent",
"search.filters.filter.supervisedBy.label": "Wyszukaj recenzenta",
"statistics.table.no-name": "(nazwa obiektu nie może zostać załadowana)",
"submission.import-external.source.datacite": "DataCite",
"submission.sections.describe.relationship-lookup.search-tab.tab-title.isPublicationOfAuthor": "Publikacje autora",
"submission.sections.describe.relationship-lookup.title.isPublicationOfAuthor": "Publikacje",
"submission.sections.identifiers.info": "Te identyfikatory zostaną utworzone dla pozycji:",
"submission.sections.identifiers.no_handle": "Do tej pozycji nie zostały przypisane żadne Handle",
"submission.sections.identifiers.no_doi": "Do tej pozycji nie zostały przypisane żadne DOI",
"submission.sections.identifiers.handle_label": "Handle: ",
"submission.sections.identifiers.doi_label": "DOI: ",
"submission.sections.identifiers.otherIdentifiers_label": "Inne identyfikatory: ",
"submission.sections.submit.progressbar.identifiers": "Identyfikatory",
"submission.workflow.generic.submit_select_reviewer": "Wybierz recenzenta",
"submission.workflow.generic.submit_select_reviewer-help": "",
"submission.workflow.generic.submit_score": "Wynik",
"submission.workflow.generic.submit_score-help": "",
"submission.workflow.tasks.claimed.decline": "Odrzuć",
"submission.workflow.tasks.claimed.decline_help": "",
"submitter.empty": "n.d.",
"subscriptions.title": "Subskrypcje",
"subscriptions.item": "Subskrypcje pozycji",
"subscriptions.collection": "Subskrypcje kolekcji",
"subscriptions.community": "Subskrypcje zbiorów",
"subscriptions.subscription_type": "Typ subksrypcji",
"subscriptions.frequency": "Częstotliwość subskrypcji",
"subscriptions.frequency.D": "Codziennie",
"subscriptions.frequency.M": "Co miesiąc",
"subscriptions.frequency.W": "Co tydzień",
"subscriptions.tooltip": "Subskrybuj",
"subscriptions.modal.title": "Subksrypcje",
"subscriptions.modal.type-frequency": "Rodzaj i częstotliwość subksrypcji",
"subscriptions.modal.close": "Zamknij",
"subscriptions.modal.delete-info": "Aby usunąć tę subksrypcję przejdź do strony 'Subskrypcje', która znajduje się w profilu użytkownika",
"subscriptions.modal.new-subscription-form.type.content": "Zawartość",
"subscriptions.modal.new-subscription-form.frequency.D": "Codziennie",
"subscriptions.modal.new-subscription-form.frequency.W": "Co tydzień",
"subscriptions.modal.new-subscription-form.frequency.M": "Co miesiąc",
"subscriptions.modal.new-subscription-form.submit": "Zapisz",
"subscriptions.modal.new-subscription-form.processing": "Ładowanie...",
"subscriptions.modal.create.success": "Zasubskrybowano {{ type }}",
"subscriptions.modal.delete.success": "Subskrypcja została anulowana",
"subscriptions.modal.update.success": "Twoja subskrypcja {{ type }} została zaktualizowana",
"subscriptions.modal.create.error": "Wystąpił bład podczas tworzenia subskrypcji",
"subscriptions.modal.delete.error": "Wystąpił bład podczas usuwania subskrypcji",
"subscriptions.modal.update.error": "Wystąpił bład podczas aktualizacji subskrypcji",
"subscriptions.table.dso": "Słowo kluczowe",
"subscriptions.table.subscription_type": "Typ subskrypcji",
"subscriptions.table.subscription_frequency": "Częstotliwość subskrypcji",
"subscriptions.table.action": "Akcja",
"subscriptions.table.edit": "Edytuj",
"subscriptions.table.delete": "Usuń",
"subscriptions.table.not-available": "Niedostępne",
"subscriptions.table.not-available-message": "Ta pozycja została usunięta lun nie masz do niej dostępu, aby ją wyswietlić",
"subscriptions.table.empty.message": "Ta pozycja nie ma w tym momencie żadnych subksrypcji. Aby zasubkrybować i otrzymywać aktualizacje o tym zbiorze lub kolekcji, wybierz przycisk subskrypcji na stronie pozycji.",
"vocabulary-treeview.info": "Wybierz słowo kluczowe, aby dodać je do filtra",
"supervisedWorkspace.search.results.head": "Pozycje recenzowane",
"supervision.search.results.head": "Status zadań: Szkic i redakcja",
"workspace-item.delete.breadcrumbs": "Usunięto wersję roboczą",
"workspace-item.delete.header": "Usuń wersję roboczą",
"workspace-item.delete.button.confirm": "Usuń",
"workspace-item.delete.button.cancel": "Anuluj",
"workspace-item.delete.notification.success.title": "Usunięto",
"workspace-item.delete.title": "Wersja robocza została usunieta",
"workspace-item.delete.notification.error.title": "Coś poszło nie tak",
"workspace-item.delete.notification.error.content": "Wersja robocza nie może zostać usunieta",
"workflow-item.advanced.title": "Zaawansowane workflow",
"workflow-item.selectrevieweraction.notification.success.title": "Wybrany recenzent",
"workflow-item.selectrevieweraction.notification.success.content": "Recenzent został przypisany",
"workflow-item.selectrevieweraction.notification.error.title": "Coś poszło nie tak",
"workflow-item.selectrevieweraction.notification.error.content": "Nie udało się wybrać recenzenta dla pozycji",
"workflow-item.selectrevieweraction.title": "Wybierz recenzenta",
"workflow-item.selectrevieweraction.header": "Wybierz recenzenta",
"workflow-item.selectrevieweraction.button.cancel": "Anuluj",
"workflow-item.selectrevieweraction.button.confirm": "Zatwierdź",
"workflow-item.scorereviewaction.notification.success.title": "Ocena recenzji",
"workflow-item.scorereviewaction.notification.success.content": "Ocena tej pozycji została zapisana",
"workflow-item.scorereviewaction.notification.error.title": "Coś poszło nie tak",
"workflow-item.scorereviewaction.notification.error.content": "Nie można ocenić tej pozycji",
"workflow-item.scorereviewaction.title": "Oceń pozycję",
"workflow-item.scorereviewaction.header": "Oceń pozycję",
"workflow-item.scorereviewaction.button.cancel": "Anuluj",
"workflow-item.scorereviewaction.button.confirm": "Potwierdź",
"listable-notification-object.default-message": "Ta pozycja nie może być odzyskana",
"system-wide-alert-banner.retrieval.error": "Coś poszło nie tak podczas odzyskiwania alertu systemowego",
"system-wide-alert-banner.countdown.prefix": "W",
"system-wide-alert-banner.countdown.days": "{{days}} dni,",
"system-wide-alert-banner.countdown.hours": "{{hours}} godziny",
"system-wide-alert-banner.countdown.minutes": "{{minutes}} minut:",
"menu.section.system-wide-alert": "Alert systemowy",
"system-wide-alert.form.header": "Alert systemowy",
"system-wide-alert-form.retrieval.error": "Coś poszło nie tak podczas odzyskiwania alertu systemowego",
"system-wide-alert.form.cancel": "Anuluj",
"system-wide-alert.form.save": "Zapisz",
"system-wide-alert.form.label.active": "AKTYWNE",
"system-wide-alert.form.label.inactive": "NIEAKTYWNE",
"system-wide-alert.form.error.message": "Alert systemowy musi zawierać wiadomość",
"system-wide-alert.form.label.message": "Alert systemowy",
"system-wide-alert.form.label.countdownTo.enable": "Wprowadź licznik czasowy",
"system-wide-alert.form.label.countdownTo.hint": "Wskazówka: Wpisz wartość licznika czasu. Kiedy licznik jest włączony, alert systemowy zostanie wyświetlony o wybranym czasie. Kiedy odliczanie zostanie zakończone, alert systemowy zostanie wyłączony. Serwer NIE zostanie zatrzymany automatycznie.",
"system-wide-alert.form.label.preview": "Podgląd alertu systemowego",
"system-wide-alert.form.update.success": "Alert systemowy został zaktualizowany",
"system-wide-alert.form.update.error": "Coś poszło nie tak podczas aktualizacji alertu systemowego",
"system-wide-alert.form.create.success": "Alert systemowy został utworzony",
"system-wide-alert.form.create.error": "Coś poszło nie tak podczas tworzenia alertu systemowego",
"admin.system-wide-alert.breadcrumbs": "Alerty systemowe",
"admin.system-wide-alert.title": "Alerty systemowe",
"item-access-control-title": "Ta strona pozwala na zmianę dostępów metadanych pozycji i plików do nich dołączonych.",
"collection-access-control-title": "Ta strona pozwala na zmianę warunków dostępu dla wszystkich pozycji w tej kolekcji. Zmiany mogą być wykonywane zarówno na metadanych pozycji jak i plikach do nich dołączonych.",
"community-access-control-title": "Ta strona pozwala na zmianę warunków dostępu dla wszystkich pozycji w każdej kolekcji w tym zbiorze. Zmiany mogą być wykonywane zarówno na metadanych pozycji jak i plikach do nich dołączonych.",
"access-control-item-header-toggle": "Metadane pozycji",
"access-control-bitstream-header-toggle": "Pliki",
"access-control-mode": "Tryb",
"access-control-access-conditions": "Warunki dostępu",
"access-control-no-access-conditions-warning-message": "W tym momencie żadne warunki dostępu nie zostały określone. Jeśli zadanie zostanie rozpoczęte, obecne warunki dostępu zostaną zastąpione domyślnymi warunkami dostępu z nadrzędnej kolekcji.",
"access-control-replace-all": "Zastąp warunki dostępu",
"access-control-add-to-existing": "Dodaj do już istniejących",
"access-control-limit-to-specific": "Ogranicz zmiany do wybranych plików",
"access-control-process-all-bitstreams": "Zaktualizuj wszystkie pliki dla tej pozycji",
"access-control-bitstreams-selected": "wybrane pliki",
"access-control-cancel": "Anuluj",
"access-control-execute": "Wykonaj",
"access-control-add-more": "Dodaj więcej",
"access-control-select-bitstreams-modal.title": "Wybierz pliki",
"access-control-select-bitstreams-modal.no-items": "Brak pozycji do wyświetlenia.",
"access-control-select-bitstreams-modal.close": "Zamknij",
"access-control-option-label": "Typ warunków dostępu",
"access-control-option-note": "Wybierz warunki dostępu, które chcesz przypisać do zaznaczonych pozycji.",
"access-control-option-start-date": "Dostęp od",
"access-control-option-start-date-note": "Wybierz datę, kiedy wybrane warunki dostępu mają obowiązywać",
"access-control-option-end-date": "Dostęp do",
"access-control-option-end-date-note": "Wybierz datę, kiedy wybrane warunki dostępu mają obowiązywać",
} }

View File

@@ -3972,20 +3972,20 @@
// "mydspace.show.workspace": "Your Submissions", // "mydspace.show.workspace": "Your Submissions",
"mydspace.show.workspace": "Minhas Submissões", "mydspace.show.workspace": "Minhas Submissões",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Arquivado", "mydspace.status.mydspaceArchived": "Arquivado",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Validação", "mydspace.status.mydspaceValidation": "Validação",
// "mydspace.status.waiting-for-controller": "Waiting for controller", // "mydspace.status.mydspaceWaitingController": "Waiting for controller",
"mydspace.status.waiting-for-controller": "Esperando pelo controlador", "mydspace.status.mydspaceWaitingController": "Esperando pelo controlador",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Fluxo de trabalho", "mydspace.status.mydspaceWorkflow": "Fluxo de trabalho",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Espaço de trabalho", "mydspace.status.mydspaceWorkspace": "Espaço de trabalho",
// "mydspace.title": "MyDSpace", // "mydspace.title": "MyDSpace",
"mydspace.title": "MeuDSpace", "mydspace.title": "MeuDSpace",

View File

@@ -2054,8 +2054,8 @@
// "curation-task.task.vscan.label": "Virus Scan", // "curation-task.task.vscan.label": "Virus Scan",
"curation-task.task.vscan.label": "Scan de vírus", "curation-task.task.vscan.label": "Scan de vírus",
// "curation-task.task.register-doi.label": "Register DOI", // "curation-task.task.registerdoi.label": "Register DOI",
"curation-task.task.register-doi.label": "Registo DOI", "curation-task.task.registerdoi.label": "Registo DOI",
// "curation.form.task-select.label": "Task:", // "curation.form.task-select.label": "Task:",
"curation.form.task-select.label": "Tarefa:", "curation.form.task-select.label": "Tarefa:",
@@ -7713,20 +7713,20 @@
// "browse.metadata.srsc": "Subject Category", // "browse.metadata.srsc": "Subject Category",
"browse.metadata.srsc": "vocabulário controlado (SRSC)", "browse.metadata.srsc": "vocabulário controlado (SRSC)",
// "mydspace.status.archived": "Archived", // "mydspace.status.mydspaceArchived": "Archived",
"mydspace.status.archived": "Depositado", "mydspace.status.mydspaceArchived": "Depositado",
// "mydspace.status.validation": "Validation", // "mydspace.status.mydspaceValidation": "Validation",
"mydspace.status.validation": "Em validação", "mydspace.status.mydspaceValidation": "Em validação",
// "mydspace.status.waiting-for-controller": "Waiting for Controller", // "mydspace.status.mydspaceWaitingController": "Waiting for Controller",
"mydspace.status.waiting-for-controller": "Aguarda validador", "mydspace.status.mydspaceWaitingController": "Aguarda validador",
// "mydspace.status.workflow": "Workflow", // "mydspace.status.mydspaceWorkflow": "Workflow",
"mydspace.status.workflow": "Em fluxo de trabalho", "mydspace.status.mydspaceWorkflow": "Em fluxo de trabalho",
// "mydspace.status.workspace": "Workspace", // "mydspace.status.mydspaceWorkspace": "Workspace",
"mydspace.status.workspace": "Depósito por terminar", "mydspace.status.mydspaceWorkspace": "Depósito por terminar",
// "search.filters.namedresourcetype.Archived": "Archived", // "search.filters.namedresourcetype.Archived": "Archived",
"search.filters.namedresourcetype.Archived": "Depositado", "search.filters.namedresourcetype.Archived": "Depositado",

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