Merge branch 'master' into w2p-65240_Community-and-collection-logos

This commit is contained in:
Kristof De Langhe
2019-11-28 11:39:26 +01:00
121 changed files with 27910 additions and 613 deletions

View File

@@ -3,13 +3,12 @@
dspace-angular dspace-angular
============== ==============
> The next UI for DSpace, based on Angular Universal. > The next UI for DSpace 7, based on Angular Universal.
This project is currently in pre-alpha. This project is currently under active development. For more information on the DSpace 7 release see the [DSpace 7.0 Release Status wiki page](https://wiki.lyrasis.org/display/DSPACE/DSpace+Release+7.0+Status)
You can find additional information on the [wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+-+Angular+UI) or [the project board (waffle.io)](https://waffle.io/DSpace/dspace-angular). You can find additional information on the DSpace 7 Angular UI on the [wiki](https://wiki.lyrasis.org/display/DSPACE/DSpace+7+-+Angular+UI+Development).
If you're looking for the 2016 Angular 2 DSpace UI prototype, you can find it [here](https://github.com/DSpace-Labs/angular2-ui-prototype)
Quick start Quick start
----------- -----------
@@ -32,8 +31,6 @@ yarn start
Then go to [http://localhost:3000](http://localhost:3000) in your browser Then go to [http://localhost:3000](http://localhost:3000) in your browser
NOTE: currently there's not much to see at that URL. We really do need your help. If you're interested in jumping in, and you've made it this far, please look at the [the project board (waffle.io)](https://waffle.io/DSpace/dspace-angular), grab a card, and get to work. Thanks!
Not sure where to start? watch the training videos linked in the [Introduction to the technology](#introduction-to-the-technology) section below. Not sure where to start? watch the training videos linked in the [Introduction to the technology](#introduction-to-the-technology) section below.
Table of Contents Table of Contents
@@ -42,24 +39,27 @@ Table of Contents
- [Introduction to the technology](#introduction-to-the-technology) - [Introduction to the technology](#introduction-to-the-technology)
- [Requirements](#requirements) - [Requirements](#requirements)
- [Installing](#installing) - [Installing](#installing)
- [Configuring](#configuring) - [Configuring](#configuring)
- [Running the app](#running-the-app) - [Running the app](#running-the-app)
- [Running in production mode](#running-in-production-mode) - [Running in production mode](#running-in-production-mode)
- [Deploy](#deploy)
- [Running the application with Docker](#running-the-application-with-docker)
- [Cleaning](#cleaning) - [Cleaning](#cleaning)
- [Testing](#testing) - [Testing](#testing)
- [Test a Pull Request](#test-a-pull-request)
- [Documentation](#documentation) - [Documentation](#documentation)
- [Other commands](#other-commands) - [Other commands](#other-commands)
- [Recommended Editors/IDEs](#recommended-editorsides) - [Recommended Editors/IDEs](#recommended-editorsides)
- [Collaborating](#collaborating) - [Collaborating](#collaborating)
- [File Structure](#file-structure) - [File Structure](#file-structure)
- [3rd Party Library Installation](#3rd-party-library-installation) - [Managing Dependencies (via yarn)](#managing-dependencies-via-yarn)
- [Frequently asked questions](#frequently-asked-questions) - [Frequently asked questions](#frequently-asked-questions)
- [License](#license) - [License](#license)
Introduction to the technology Introduction to the technology
------------------------------ ------------------------------
You can find more information on the technologies used in this project (Angular 2, Typescript, Angular Universal, RxJS, etc) on the [DuraSpace wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Technology+Stack) You can find more information on the technologies used in this project (Angular.io, Typescript, Angular Universal, RxJS, etc) on the [LYRASIS wiki](https://wiki.lyrasis.org/display/DSPACE/DSpace+7+UI+Technology+Stack)
Requirements Requirements
------------ ------------
@@ -75,8 +75,7 @@ Installing
- `yarn run global` to install the required global dependencies - `yarn run global` to install the required global dependencies
- `yarn install` to install the local dependencies - `yarn install` to install the local dependencies
Configuring ### Configuring
-----------
Default configuration file is located in `config/` folder. Default configuration file is located in `config/` folder.
@@ -98,8 +97,7 @@ Running the app
After you have installed all dependencies you can now run the app. Run `yarn run watch` to start a local server which will watch for changes, rebuild the code, and reload the server for you. You can visit it at `http://localhost:3000`. After you have installed all dependencies you can now run the app. Run `yarn run watch` to start a local server which will watch for changes, rebuild the code, and reload the server for you. You can visit it at `http://localhost:3000`.
Running in production mode ### Running in production mode
--------------------------
When building for production we're using Ahead of Time (AoT) compilation. With AoT, the browser downloads a pre-compiled version of the application, so it can render the application immediately, without waiting to compile the app first. The compiler is roughly half the size of Angular itself, so omitting it dramatically reduces the application payload. When building for production we're using Ahead of Time (AoT) compilation. With AoT, the browser downloads a pre-compiled version of the application, so it can render the application immediately, without waiting to compile the app first. The compiler is roughly half the size of Angular itself, so omitting it dramatically reduces the application payload.
@@ -117,6 +115,19 @@ yarn run build:prod
This will build the application and put the result in the `dist` folder This will build the application and put the result in the `dist` folder
### Deploy
```bash
# deploy production in standalone pm2 container
yarn run deploy
# remove production from standalone pm2 container
yarn run undeploy
```
### Running the application with Docker
See [Docker Runtime Options](docker/README.md)
Cleaning Cleaning
-------- --------
@@ -131,10 +142,6 @@ yarn run clean:prod
yarn run clean:dist yarn run clean:dist
``` ```
Running the application with Docker
-----------------------------------
See [Docker Runtime Options](docker/README.md)
Testing Testing
------- -------
@@ -189,21 +196,14 @@ To run all the tests (e.g.: to run tests with Continuous Integration software) y
Documentation Documentation
-------------- --------------
See [`./docs`](docs) for further documentation.
### Building code documentation
To build the code documentation we use [TYPEDOC](http://typedoc.org). TYPEDOC is a documentation generator for TypeScript projects. It extracts informations from properly formatted comments that can be written within the code files. Follow the instructions [here](http://typedoc.org/guides/doccomments/) to know how to make those comments. To build the code documentation we use [TYPEDOC](http://typedoc.org). TYPEDOC is a documentation generator for TypeScript projects. It extracts informations from properly formatted comments that can be written within the code files. Follow the instructions [here](http://typedoc.org/guides/doccomments/) to know how to make those comments.
Run:`yarn run docs` to produce the documentation that will be available in the 'doc' folder. Run:`yarn run docs` to produce the documentation that will be available in the 'doc' folder.
Deploy
------
```bash
# deploy production in standalone pm2 container
yarn run deploy
# remove production from standalone pm2 container
yarn run undeploy
```
Other commands Other commands
-------------- --------------
@@ -229,7 +229,7 @@ To get the most out of TypeScript, you'll need a TypeScript-aware editor. We've
Collaborating Collaborating
------------- -------------
See [the guide on the wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+-+Angular+2+UI#DSpace7-Angular2UI-Howtocontribute) See [the guide on the wiki](https://wiki.lyrasis.org/display/DSPACE/DSpace+7+-+Angular+UI+Development#DSpace7-AngularUIDevelopment-Howtocontribute)
File Structure File Structure
-------------- --------------
@@ -335,10 +335,20 @@ dspace-angular
└── yarn.lock * Yarn lockfile (https://yarnpkg.com/en/docs/yarn-lock) └── yarn.lock * Yarn lockfile (https://yarnpkg.com/en/docs/yarn-lock)
``` ```
3rd Party Library Installation Managing Dependencies (via yarn)
------------------------------ -------------
Install your library via `yarn add lib-name --save` and import it in your code. `--save` will add it to `package.json`. This project makes use of [`yarn`](https://yarnpkg.com/en/) to ensure that the exact same dependency versions are used every time you install it.
* `yarn` creates a [`yarn.lock`](https://yarnpkg.com/en/docs/yarn-lock) to track those versions. That file is updated automatically by whenever dependencies are added/updated/removed via yarn.
* **Adding new dependencies**: To install/add a new dependency (third party library), use [`yarn add`](https://yarnpkg.com/en/docs/cli/add). For example: `yarn add some-lib`.
* If you are adding a new build tool dependency (to `devDependencies`), use `yarn add some-lib --dev`
* **Upgrading existing dependencies**: To upgrade existing dependencies, you can use [`yarn upgrade`](https://yarnpkg.com/en/docs/cli/upgrade). For example: `yarn upgrade some-lib` or `yarn upgrade some-lib@version`
* **Removing dependencies**: If a dependency is no longer needed, or replaced, use [`yarn remove`](https://yarnpkg.com/en/docs/cli/remove) to remove it.
As you can see above, using `yarn` commandline tools means that you should never need to modify the `package.json` manually. *We recommend always using `yarn` to keep dependencies updated / in sync.*
### Adding Typings for libraries
If the library does not include typings, you can install them using yarn: If the library does not include typings, you can install them using yarn:
@@ -370,24 +380,6 @@ If you're importing a module that uses CommonJS you need to import as
import * as _ from 'lodash'; import * as _ from 'lodash';
``` ```
Managing Dependencies (via yarn)
-------------
This project makes use of [`yarn`](https://yarnpkg.com/en/) to ensure that the exact same dependency versions are used every time you install it.
* `yarn` creates a [`yarn.lock`](https://yarnpkg.com/en/docs/yarn-lock) to track those versions. That file is updated automatically by whenever dependencies are added/updated/removed via yarn.
* **Adding new dependencies**: To install/add a new dependency (third party library), use [`yarn add`](https://yarnpkg.com/en/docs/cli/add). For example: `yarn add some-lib`.
* If you are adding a new build tool dependency (to `devDependencies`), use `yarn add some-lib --dev`
* **Upgrading existing dependencies**: To upgrade existing dependencies, you can use [`yarn upgrade`](https://yarnpkg.com/en/docs/cli/upgrade). For example: `yarn upgrade some-lib` or `yarn upgrade some-lib@version`
* **Removing dependencies**: If a dependency is no longer needed, or replaced, use [`yarn remove`](https://yarnpkg.com/en/docs/cli/remove) to remove it.
As you can see above, using `yarn` commandline tools means that you should never need to modify the `package.json` manually. *We recommend always using `yarn` to keep dependencies updated / in sync.*
Further Documentation
---------------------
See [`./docs`](docs) for further documentation.
Frequently asked questions Frequently asked questions
-------------------------- --------------------------
@@ -411,5 +403,4 @@ Frequently asked questions
License License
------- -------
This project's source code is made available under the DSpace BSD License: http://www.dspace.org/license
http://www.dspace.org/license

View File

@@ -141,6 +141,10 @@ module.exports = {
code: 'nl', code: 'nl',
label: 'Nederlands', label: 'Nederlands',
active: false, active: false,
}, {
code: 'pt',
label: 'Português',
active: true,
}], }],
// Browse-By Pages // Browse-By Pages
browseBy: { browseBy: {

3220
resources/i18n/ar.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -86,9 +86,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}",
// "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are are hidden from the user, and used for administrative purposes.", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.",
// TODO New key - Add a translation // TODO New key - Add a translation
"admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are are hidden from the user, and used for administrative purposes.", "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.",
// "admin.registries.bitstream-formats.edit.internal.label": "Internal", // "admin.registries.bitstream-formats.edit.internal.label": "Internal",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -1125,9 +1125,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.",
// "item.edit.move.error": "An error occured when attempting to move the item", // "item.edit.move.error": "An error occurred when attempting to move the item",
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.error": "An error occured when attempting to move the item", "item.edit.move.error": "An error occurred when attempting to move the item",
// "item.edit.move.head": "Move item: {{id}}", // "item.edit.move.head": "Move item: {{id}}",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -1153,9 +1153,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.search.placeholder": "Enter a search query to look for collections", "item.edit.move.search.placeholder": "Enter a search query to look for collections",
// "item.edit.move.success": "The item has been moved succesfully", // "item.edit.move.success": "The item has been moved successfully",
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.success": "The item has been moved succesfully", "item.edit.move.success": "The item has been moved successfully",
// "item.edit.move.title": "Move item", // "item.edit.move.title": "Move item",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -2911,9 +2911,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):",
// "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>", // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>",
// TODO New key - Add a translation // TODO New key - Add a translation
"submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>", "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>",
// "submission.sections.upload.no-entry": "No", // "submission.sections.upload.no-entry": "No",
// TODO New key - Add a translation // TODO New key - Add a translation

View File

@@ -44,7 +44,7 @@
"admin.registries.bitstream-formats.edit.failure.head": "Fehler", "admin.registries.bitstream-formats.edit.failure.head": "Fehler",
// "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}",
"admin.registries.bitstream-formats.edit.head": "Dateiformat: {{ format }}", "admin.registries.bitstream-formats.edit.head": "Dateiformat: {{ format }}",
// "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are are hidden from the user, and used for administrative purposes.", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.",
"admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnit sind, dienen administrativen Zwecken und bleiben dem Endnutzer verborgen.", "admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnit sind, dienen administrativen Zwecken und bleiben dem Endnutzer verborgen.",
// "admin.registries.bitstream-formats.edit.internal.label": "Internal", // "admin.registries.bitstream-formats.edit.internal.label": "Internal",
"admin.registries.bitstream-formats.edit.internal.label": "Intern", "admin.registries.bitstream-formats.edit.internal.label": "Intern",
@@ -587,7 +587,7 @@
"item.edit.move.cancel": "Abbrechen", "item.edit.move.cancel": "Abbrechen",
// "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", // "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.",
"item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.",
// "item.edit.move.error": "An error occured when attempting to move the item", // "item.edit.move.error": "An error occurred when attempting to move the item",
"item.edit.move.error": "Ein Fehler ist beim Verschieben der Ressource aufgetreten", "item.edit.move.error": "Ein Fehler ist beim Verschieben der Ressource aufgetreten",
// "item.edit.move.head": "Move item: {{id}}", // "item.edit.move.head": "Move item: {{id}}",
"item.edit.move.head": "Ressource verschieben: {{id}}", "item.edit.move.head": "Ressource verschieben: {{id}}",
@@ -601,7 +601,7 @@
"item.edit.move.processing": "Verschieben...", "item.edit.move.processing": "Verschieben...",
// "item.edit.move.search.placeholder": "Enter a search query to look for collections", // "item.edit.move.search.placeholder": "Enter a search query to look for collections",
"item.edit.move.search.placeholder": "Geben Sie einen Begriff ein, um nach Sammlungen zu suchen", "item.edit.move.search.placeholder": "Geben Sie einen Begriff ein, um nach Sammlungen zu suchen",
// "item.edit.move.success": "The item has been moved succesfully", // "item.edit.move.success": "The item has been moved successfully",
"item.edit.move.success": "Die Ressource wurde erfolgreich verschoben", "item.edit.move.success": "Die Ressource wurde erfolgreich verschoben",
// "item.edit.move.title": "Move item", // "item.edit.move.title": "Move item",
"item.edit.move.title": "Ressource verschieben", "item.edit.move.title": "Ressource verschieben",
@@ -1515,7 +1515,7 @@
"submission.sections.upload.header.policy.default.nolist": "In diese Sammlung {{collectionName}} hochgeladene Dateien werden für folgende(n) Gruppe(n) zugänglich sein:", "submission.sections.upload.header.policy.default.nolist": "In diese Sammlung {{collectionName}} hochgeladene Dateien werden für folgende(n) Gruppe(n) zugänglich sein:",
// "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):",
"submission.sections.upload.header.policy.default.withlist": "Bitte beachten Sie, dass in diese Sammlung {{collectionName}} hochgeladene Dateien zugüglich zu dem, was für einzelne Dateien entschieden wurde, für folgende Gruppe(n) zugänglich sein:", "submission.sections.upload.header.policy.default.withlist": "Bitte beachten Sie, dass in diese Sammlung {{collectionName}} hochgeladene Dateien zugüglich zu dem, was für einzelne Dateien entschieden wurde, für folgende Gruppe(n) zugänglich sein:",
// "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>", // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>",
"submission.sections.upload.info": "Hier finden Sie alle Dateien, die aktuell zur Ressource gehören. Sie können die Metadaten und Zugriffsrechte bearbeiten oder <strong>weitere Dateien hinzufügen, indem Sie sie einfach irgenwo auf diese Seite ziehen.</strong>", "submission.sections.upload.info": "Hier finden Sie alle Dateien, die aktuell zur Ressource gehören. Sie können die Metadaten und Zugriffsrechte bearbeiten oder <strong>weitere Dateien hinzufügen, indem Sie sie einfach irgenwo auf diese Seite ziehen.</strong>",
// "submission.sections.upload.no-entry": "No", // "submission.sections.upload.no-entry": "No",
"submission.sections.upload.no-entry": "Kein Eintrag", "submission.sections.upload.no-entry": "Kein Eintrag",

View File

@@ -46,7 +46,7 @@
"admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}",
"admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are are hidden from the user, and used for administrative purposes.", "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.",
"admin.registries.bitstream-formats.edit.internal.label": "Internal", "admin.registries.bitstream-formats.edit.internal.label": "Internal",
@@ -696,7 +696,7 @@
"item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.",
"item.edit.move.error": "An error occured when attempting to move the item", "item.edit.move.error": "An error occurred when attempting to move the item",
"item.edit.move.head": "Move item: {{id}}", "item.edit.move.head": "Move item: {{id}}",
@@ -710,7 +710,7 @@
"item.edit.move.search.placeholder": "Enter a search query to look for collections", "item.edit.move.search.placeholder": "Enter a search query to look for collections",
"item.edit.move.success": "The item has been moved succesfully", "item.edit.move.success": "The item has been moved successfully",
"item.edit.move.title": "Move item", "item.edit.move.title": "Move item",
@@ -1674,7 +1674,7 @@
"submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):",
"submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>", "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>",
"submission.sections.upload.no-entry": "No", "submission.sections.upload.no-entry": "No",

1610
resources/i18n/es.json5 Normal file

File diff suppressed because it is too large Load Diff

3220
resources/i18n/fi.json5 Normal file

File diff suppressed because it is too large Load Diff

3220
resources/i18n/fr.json5 Normal file

File diff suppressed because it is too large Load Diff

3220
resources/i18n/ja.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -32,24 +32,21 @@
"admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.",
// "admin.registries.bitstream-formats.create.success.head": "Success", // "admin.registries.bitstream-formats.create.success.head": "Success",
// TODO New key - Add a translation "admin.registries.bitstream-formats.create.success.head": "Succes",
"admin.registries.bitstream-formats.create.success.head": "Success",
// "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)",
// TODO New key - Add a translation // TODO New key - Add a translation
"admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)",
// "admin.registries.bitstream-formats.delete.failure.head": "Failure", // "admin.registries.bitstream-formats.delete.failure.head": "Failure",
// TODO New key - Add a translation "admin.registries.bitstream-formats.delete.failure.head": "Gefaald",
"admin.registries.bitstream-formats.delete.failure.head": "Failure",
// "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)",
// TODO New key - Add a translation // TODO New key - Add a translation
"admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)",
// "admin.registries.bitstream-formats.delete.success.head": "Success", // "admin.registries.bitstream-formats.delete.success.head": "Success",
// TODO New key - Add a translation "admin.registries.bitstream-formats.delete.success.head": "Succes",
"admin.registries.bitstream-formats.delete.success.head": "Success",
// "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.",
"admin.registries.bitstream-formats.description": "Deze lijst van Bitstream formaten biedt informatie over de formaten die in deze repository zijn toegelaten en op welke manier ze ondersteund worden. De term Bitstream wordt in DSpace gebruikt om een bestand aan te duiden dat samen met metadata onderdeel uitmaakt van een item. De naam bitstream duidt op het feit dat het bestand achterliggend wordt opgeslaan zonder bestandsextensie.", "admin.registries.bitstream-formats.description": "Deze lijst van Bitstream formaten biedt informatie over de formaten die in deze repository zijn toegelaten en op welke manier ze ondersteund worden. De term Bitstream wordt in DSpace gebruikt om een bestand aan te duiden dat samen met metadata onderdeel uitmaakt van een item. De naam bitstream duidt op het feit dat het bestand achterliggend wordt opgeslaan zonder bestandsextensie.",
@@ -86,9 +83,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}",
// "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are are hidden from the user, and used for administrative purposes.", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.",
// TODO New key - Add a translation // TODO New key - Add a translation
"admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are are hidden from the user, and used for administrative purposes.", "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.",
// "admin.registries.bitstream-formats.edit.internal.label": "Internal", // "admin.registries.bitstream-formats.edit.internal.label": "Internal",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -1125,9 +1122,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.",
// "item.edit.move.error": "An error occured when attempting to move the item", // "item.edit.move.error": "An error occurred when attempting to move the item",
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.error": "An error occured when attempting to move the item", "item.edit.move.error": "An error occurred when attempting to move the item",
// "item.edit.move.head": "Move item: {{id}}", // "item.edit.move.head": "Move item: {{id}}",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -1153,9 +1150,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.search.placeholder": "Enter a search query to look for collections", "item.edit.move.search.placeholder": "Enter a search query to look for collections",
// "item.edit.move.success": "The item has been moved succesfully", // "item.edit.move.success": "The item has been moved successfully",
// TODO New key - Add a translation // TODO New key - Add a translation
"item.edit.move.success": "The item has been moved succesfully", "item.edit.move.success": "The item has been moved successfully",
// "item.edit.move.title": "Move item", // "item.edit.move.title": "Move item",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -2911,9 +2908,9 @@
// TODO New key - Add a translation // TODO New key - Add a translation
"submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):",
// "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>", // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>",
// TODO New key - Add a translation // TODO New key - Add a translation
"submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>", "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or <strong>upload additional files just dragging & dropping them everywhere in the page</strong>",
// "submission.sections.upload.no-entry": "No", // "submission.sections.upload.no-entry": "No",
// TODO New key - Add a translation // TODO New key - Add a translation
@@ -3087,4 +3084,4 @@
} }

3220
resources/i18n/pl.json5 Normal file

File diff suppressed because it is too large Load Diff

2457
resources/i18n/pt.json5 Normal file

File diff suppressed because it is too large Load Diff

3220
resources/i18n/sw.json5 Normal file

File diff suppressed because it is too large Load Diff

3220
resources/i18n/tr.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ import {
} from '../../shared/testing/utils'; } from '../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -50,7 +50,7 @@ describe('ItemPageFieldComponent', () => {
export function mockItemWithMetadataFieldAndValue(field: string, value: string): Item { export function mockItemWithMetadataFieldAndValue(field: string, value: string): Item {
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: new MetadataMap() metadata: new MetadataMap()
}); });
item.metadata[field] = [{ item.metadata[field] = [{

View File

@@ -22,7 +22,7 @@ import {
} from '../../shared/testing/utils'; } from '../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });

View File

@@ -17,7 +17,7 @@ import { MetadataMap } from '../../../../core/shared/metadata.models';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: new MetadataMap(), metadata: new MetadataMap(),
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });

View File

@@ -11,17 +11,17 @@ import { RelationshipService } from '../../../core/data/relationship.service';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
const parentItem: Item = Object.assign(new Item(), { const parentItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });
const mockItem1: Item = Object.assign(new Item(), { const mockItem1: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });
const mockItem2: Item = Object.assign(new Item(), { const mockItem2: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });

View File

@@ -22,7 +22,7 @@ import { SearchConfigurationServiceStub } from '../shared/testing/search-configu
import { SearchService } from '../+search-page/search-service/search.service'; import { SearchService } from '../+search-page/search-service/search.service';
import { SearchConfigurationService } from '../+search-page/search-service/search-configuration.service'; import { SearchConfigurationService } from '../+search-page/search-service/search-configuration.service';
import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model';
import { SearchSidebarService } from '../+search-page/search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { SearchFilterService } from '../+search-page/search-filters/search-filter/search-filter.service'; import { SearchFilterService } from '../+search-page/search-filters/search-filter/search-filter.service';
import { RoleDirective } from '../shared/roles/role.directive'; import { RoleDirective } from '../shared/roles/role.directive';
import { RoleService } from '../core/roles/role.service'; import { RoleService } from '../core/roles/role.service';
@@ -109,7 +109,7 @@ describe('MyDSpacePageComponent', () => {
}) })
}, },
{ {
provide: SearchSidebarService, provide: SidebarService,
useValue: sidebarService useValue: sidebarService
}, },
{ {

View File

@@ -17,7 +17,7 @@ import { pushInOut } from '../shared/animations/push';
import { HostWindowService } from '../shared/host-window.service'; import { HostWindowService } from '../shared/host-window.service';
import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model';
import { SearchService } from '../+search-page/search-service/search.service'; import { SearchService } from '../+search-page/search-service/search.service';
import { SearchSidebarService } from '../+search-page/search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { hasValue } from '../shared/empty.util'; import { hasValue } from '../shared/empty.util';
import { getSucceededRemoteData } from '../core/shared/operators'; import { getSucceededRemoteData } from '../core/shared/operators';
import { MyDSpaceResponseParsingService } from '../core/data/mydspace-response-parsing.service'; import { MyDSpaceResponseParsingService } from '../core/data/mydspace-response-parsing.service';
@@ -102,7 +102,7 @@ export class MyDSpacePageComponent implements OnInit {
context$: Observable<Context>; context$: Observable<Context>;
constructor(private service: SearchService, constructor(private service: SearchService,
private sidebarService: SearchSidebarService, private sidebarService: SidebarService,
private windowService: HostWindowService, private windowService: HostWindowService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: MyDSpaceConfigurationService) { @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: MyDSpaceConfigurationService) {
this.isXsOrSm$ = this.windowService.isXsOrSm(); this.isXsOrSm$ = this.windowService.isXsOrSm();

View File

@@ -1,6 +1,6 @@
import { HostWindowService } from '../shared/host-window.service'; import { HostWindowService } from '../shared/host-window.service';
import { SearchService } from './search-service/search.service'; import { SearchService } from './search-service/search.service';
import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { SearchPageComponent } from './search-page.component'; import { SearchPageComponent } from './search-page.component';
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
import { pushInOut } from '../shared/animations/push'; import { pushInOut } from '../shared/animations/push';
@@ -36,7 +36,7 @@ export class ConfigurationSearchPageComponent extends SearchPageComponent implem
@Input() configuration: string; @Input() configuration: string;
constructor(protected service: SearchService, constructor(protected service: SearchService,
protected sidebarService: SearchSidebarService, protected sidebarService: SidebarService,
protected windowService: HostWindowService, protected windowService: HostWindowService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
protected routeService: RouteService) { protected routeService: RouteService) {

View File

@@ -1,6 +1,6 @@
import { HostWindowService } from '../shared/host-window.service'; import { HostWindowService } from '../shared/host-window.service';
import { SearchService } from './search-service/search.service'; import { SearchService } from './search-service/search.service';
import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { SearchPageComponent } from './search-page.component'; import { SearchPageComponent } from './search-page.component';
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
import { pushInOut } from '../shared/animations/push'; import { pushInOut } from '../shared/animations/push';
@@ -38,7 +38,7 @@ export class FilteredSearchPageComponent extends SearchPageComponent implements
@Input() fixedFilterQuery: string; @Input() fixedFilterQuery: string;
constructor(protected service: SearchService, constructor(protected service: SearchService,
protected sidebarService: SearchSidebarService, protected sidebarService: SidebarService,
protected windowService: HostWindowService, protected windowService: HostWindowService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
protected routeService: RouteService) { protected routeService: RouteService) {

View File

@@ -1,7 +1,18 @@
<div class="facet-filter d-block mb-3 p-3" *ngIf="active$ | async"> <div class="facet-filter d-block mb-3 p-3" *ngIf="active$ | async">
<div (click)="toggle()" class="filter-name"><h5 class="d-inline-block mb-0">{{'search.filters.filter.' + filter.name + '.head'| translate}}</h5> <span class="filter-toggle fas float-right" <div (click)="toggle()" class="filter-name">
[ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'"></span></div> <h5 class="d-inline-block mb-0">
<div [@slide]="(collapsed$ | async) ? 'collapsed' : 'expanded'" (@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)" class="search-filter-wrapper" [ngClass]="{'closed' : closed}"> {{'search.filters.filter.' + filter.name + '.head'| translate}}
<ds-search-facet-filter-wrapper [filterConfig]="filter" [inPlaceSearch]="inPlaceSearch"></ds-search-facet-filter-wrapper> </h5>
</div> <span class="filter-toggle fas float-right"
[ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'">
</span>
</div>
<div [@slide]="(collapsed$ | async) ? 'collapsed' : 'expanded'"
(@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)"
class="search-filter-wrapper" [ngClass]="{'closed' : closed}">
<ds-search-facet-filter-wrapper
[filterConfig]="filter"
[inPlaceSearch]="inPlaceSearch">
</ds-search-facet-filter-wrapper>
</div>
</div> </div>

View File

@@ -138,7 +138,7 @@ describe('SearchFilterService', () => {
service.expand(mockFilterConfig.name); service.expand(mockFilterConfig.name);
}); });
it('SearchSidebarExpandAction should be dispatched to the store', () => { it('SidebarExpandAction should be dispatched to the store', () => {
expect(store.dispatch).toHaveBeenCalledWith(new SearchFilterExpandAction(mockFilterConfig.name)); expect(store.dispatch).toHaveBeenCalledWith(new SearchFilterExpandAction(mockFilterConfig.name));
}); });
}); });

View File

@@ -1,43 +1,50 @@
<div class="container"> <div class="container" *ngIf="(isXsOrSm$ | async)">
<div class="search-page row"> <div class="row">
<ds-search-sidebar *ngIf="!(isXsOrSm$ | async)" class="col-{{sideBarWidth}} sidebar-md-sticky" <div class="col-12">
id="search-sidebar" <ng-template *ngTemplateOutlet="searchForm"></ng-template>
[resultCount]="(resultsRD$ | async)?.payload?.totalElements" [inPlaceSearch]="inPlaceSearch"></ds-search-sidebar>
<div class="col-12 col-md-{{12 - sideBarWidth}}">
<ds-search-form *ngIf="searchEnabled" id="search-form"
[query]="(searchOptions$ | async)?.query"
[scope]="(searchOptions$ | async)?.scope"
[currentUrl]="searchLink"
[scopes]="(scopeListRD$ | async)"
[inPlaceSearch]="inPlaceSearch">
</ds-search-form>
<ds-search-labels *ngIf="searchEnabled" [inPlaceSearch]="inPlaceSearch"></ds-search-labels>
<div class="row">
<div id="search-body"
class="row-offcanvas row-offcanvas-left"
[@pushInOut]="(isSidebarCollapsed$ | async) ? 'collapsed' : 'expanded'">
<ds-search-sidebar *ngIf="(isXsOrSm$ | async)" class="col-12"
id="search-sidebar-sm"
[resultCount]="(resultsRD$ | async)?.payload.totalElements"
(toggleSidebar)="closeSidebar()"
[ngClass]="{'active': !(isSidebarCollapsed$ | async)}">
</ds-search-sidebar>
<div id="search-content" class="col-12">
<div class="d-block d-md-none search-controls clearfix">
<ds-view-mode-switch [inPlaceSearch]="inPlaceSearch"></ds-view-mode-switch>
<button (click)="openSidebar()" aria-controls="#search-body"
class="btn btn-outline-primary float-right open-sidebar"><i
class="fas fa-sliders"></i> {{"search.sidebar.open"
| translate}}
</button>
</div>
<ds-search-results [searchResults]="resultsRD$ | async"
[searchConfig]="searchOptions$ | async"
[configuration]="configuration$ | async"
[disableHeader]="!searchEnabled"></ds-search-results>
</div>
</div>
</div>
</div>
</div> </div>
</div>
</div> </div>
<ds-page-with-sidebar [id]="'search-page'" [sidebarContent]="sidebarContent">
<div class="row">
<div class="col-12" *ngIf="!(isXsOrSm$ | async)">
<ng-template *ngTemplateOutlet="searchForm"></ng-template>
</div>
<div id="search-content" class="col-12">
<div class="d-block d-md-none search-controls clearfix">
<ds-view-mode-switch [inPlaceSearch]="inPlaceSearch"></ds-view-mode-switch>
<button (click)="openSidebar()" aria-controls="#search-body"
class="btn btn-outline-primary float-right open-sidebar"><i
class="fas fa-sliders"></i> {{"search.sidebar.open"
| translate}}
</button>
</div>
<ds-search-results [searchResults]="resultsRD$ | async"
[searchConfig]="searchOptions$ | async"
[configuration]="configuration$ | async"
[disableHeader]="!searchEnabled"></ds-search-results>
</div>
</div>
</ds-page-with-sidebar>
<ng-template #sidebarContent>
<ds-search-sidebar id="search-sidebar" *ngIf="!(isXsOrSm$ | async)"
[resultCount]="(resultsRD$ | async)?.payload?.totalElements"
[inPlaceSearch]="inPlaceSearch"></ds-search-sidebar>
<ds-search-sidebar id="search-sidebar-sm" *ngIf="(isXsOrSm$ | async)"
[resultCount]="(resultsRD$ | async)?.payload.totalElements"
(toggleSidebar)="closeSidebar()"
>
</ds-search-sidebar>
</ng-template>
<ng-template #searchForm>
<ds-search-form *ngIf="searchEnabled" id="search-form"
[query]="(searchOptions$ | async)?.query"
[scope]="(searchOptions$ | async)?.scope"
[currentUrl]="searchLink"
[scopes]="(scopeListRD$ | async)"
[inPlaceSearch]="inPlaceSearch">
</ds-search-form>
<ds-search-labels *ngIf="searchEnabled" [inPlaceSearch]="inPlaceSearch"></ds-search-labels>
</ng-template>

View File

@@ -1,52 +1,10 @@
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
.container { .container {
width: 100%; width: 100%;
max-width: none; max-width: none;
} }
} }
/deep/ .search-controls { /deep/ .search-controls {
margin-bottom: $spacer; margin-bottom: $spacer;
} }
#search-body {
&.row-offcanvas {
width: 100%;
}
@include media-breakpoint-down(sm) {
position: relative;
&.row-offcanvas {
position: relative;
}
&.row-offcanvas-right #search-sidebar-sm {
right: -100%;
}
&.row-offcanvas-left #search-sidebar-sm {
left: -100%;
}
#search-sidebar-sm {
position: absolute;
top: 0;
width: 100%;
}
}
}
@include media-breakpoint-up(md) {
.sidebar-md-sticky {
position: sticky;
position: -webkit-sticky;
top: 0;
z-index: $zindex-sticky;
padding-top: $content-spacing;
margin-top: -$content-spacing;
align-self: flex-start;
display: block;
}
}

View File

@@ -16,7 +16,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { SearchFilterService } from './search-filters/search-filter/search-filter.service'; import { SearchFilterService } from './search-filters/search-filter/search-filter.service';
import { SearchConfigurationService } from './search-service/search-configuration.service'; import { SearchConfigurationService } from './search-service/search-configuration.service';
import { RemoteData } from '../core/data/remote-data'; import { RemoteData } from '../core/data/remote-data';
@@ -115,7 +115,7 @@ export function configureSearchComponentTestingModule(compType) {
}) })
}, },
{ {
provide: SearchSidebarService, provide: SidebarService,
useValue: sidebarService useValue: sidebarService
}, },
{ {
@@ -191,34 +191,4 @@ describe('SearchPageComponent', () => {
}); });
}); });
describe('when sidebarCollapsed is true in mobile view', () => {
let menu: HTMLElement;
beforeEach(() => {
menu = fixture.debugElement.query(By.css('#search-sidebar-sm')).nativeElement;
(comp as any).isSidebarCollapsed$ = observableOf(true);
fixture.detectChanges();
});
it('should close the sidebar', () => {
expect(menu.classList).not.toContain('active');
});
});
describe('when sidebarCollapsed is false in mobile view', () => {
let menu: HTMLElement;
beforeEach(() => {
menu = fixture.debugElement.query(By.css('#search-sidebar-sm')).nativeElement;
(comp as any).isSidebarCollapsed$ = observableOf(false);
fixture.detectChanges();
});
it('should open the menu', () => {
expect(menu.classList).toContain('active');
});
});
}); });

View File

@@ -9,7 +9,7 @@ import { HostWindowService } from '../shared/host-window.service';
import { PaginatedSearchOptions } from './paginated-search-options.model'; import { PaginatedSearchOptions } from './paginated-search-options.model';
import { SearchResult } from './search-result.model'; import { SearchResult } from './search-result.model';
import { SearchService } from './search-service/search.service'; import { SearchService } from './search-service/search.service';
import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { hasValue, isNotEmpty } from '../shared/empty.util'; import { hasValue, isNotEmpty } from '../shared/empty.util';
import { SearchConfigurationService } from './search-service/search-configuration.service'; import { SearchConfigurationService } from './search-service/search-configuration.service';
import { getSucceededRemoteData } from '../core/shared/operators'; import { getSucceededRemoteData } from '../core/shared/operators';
@@ -102,7 +102,7 @@ export class SearchPageComponent implements OnInit {
isSidebarCollapsed$: Observable<boolean>; isSidebarCollapsed$: Observable<boolean>;
constructor(protected service: SearchService, constructor(protected service: SearchService,
protected sidebarService: SearchSidebarService, protected sidebarService: SidebarService,
protected windowService: HostWindowService, protected windowService: HostWindowService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
protected routeService: RouteService) { protected routeService: RouteService) {

View File

@@ -8,8 +8,8 @@ import { SearchResultsComponent } from './search-results/search-results.componen
import { CommunitySearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component' import { CommunitySearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component'
import { CollectionSearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; import { CollectionSearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component';
import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component'; import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component';
import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SidebarService } from '../shared/sidebar/sidebar.service';
import { SearchSidebarEffects } from './search-sidebar/search-sidebar.effects'; import { SidebarEffects } from '../shared/sidebar/sidebar-effects.service';
import { SearchSettingsComponent } from './search-settings/search-settings.component'; import { SearchSettingsComponent } from './search-settings/search-settings.component';
import { EffectsModule } from '@ngrx/effects'; import { EffectsModule } from '@ngrx/effects';
import { SearchFiltersComponent } from './search-filters/search-filters.component'; import { SearchFiltersComponent } from './search-filters/search-filters.component';
@@ -33,9 +33,10 @@ import { SearchLabelComponent } from './search-labels/search-label/search-label.
import { ConfigurationSearchPageComponent } from './configuration-search-page.component'; import { ConfigurationSearchPageComponent } from './configuration-search-page.component';
import { ConfigurationSearchPageGuard } from './configuration-search-page.guard'; import { ConfigurationSearchPageGuard } from './configuration-search-page.guard';
import { FilteredSearchPageComponent } from './filtered-search-page.component'; import { FilteredSearchPageComponent } from './filtered-search-page.component';
import { SidebarFilterService } from '../shared/sidebar/filter/sidebar-filter.service';
const effects = [ const effects = [
SearchSidebarEffects SidebarEffects
]; ];
const components = [ const components = [
@@ -69,11 +70,12 @@ const components = [
CommonModule, CommonModule,
SharedModule, SharedModule,
EffectsModule.forFeature(effects), EffectsModule.forFeature(effects),
CoreModule.forRoot() CoreModule.forRoot(),
], ],
declarations: components, declarations: components,
providers: [ providers: [
SearchSidebarService, SidebarService,
SidebarFilterService,
SearchFilterService, SearchFilterService,
SearchFixedFilterService, SearchFixedFilterService,
ConfigurationSearchPageGuard, ConfigurationSearchPageGuard,

View File

@@ -1,24 +1,32 @@
<ng-container *ngVar="(searchOptions$ | async) as config"> <ng-container *ngVar="(searchOptions$ | async) as config">
<h3>{{ 'search.sidebar.settings.title' | translate}}</h3> <h3>{{ 'search.sidebar.settings.title' | translate}}</h3>
<div *ngIf="config?.sort" class="setting-option result-order-settings mb-3 p-3">
<h5>{{ 'search.sidebar.settings.sort-by' | translate}}</h5>
<select class="form-control" (change)="reloadOrder($event)">
<option *ngFor="let sortOption of searchOptionPossibilities"
[value]="sortOption.field + ',' + sortOption.direction.toString()"
[selected]="sortOption.field === config?.sort.field && sortOption.direction === (config?.sort.direction)? 'selected': null">
{{'sorting.' + sortOption.field + '.' + sortOption.direction | translate}}
</option>
</select>
</div>
<div class="setting-option page-size-settings mb-3 p-3"> <div class="result-order-settings">
<h5>{{ 'search.sidebar.settings.rpp' | translate}}</h5> <ds-sidebar-dropdown
<select class="form-control" (change)="reloadRPP($event)"> *ngIf="config?.sort"
<option *ngFor="let pageSizeOption of config?.pagination.pageSizeOptions" [id]="'search-sidebar-sort'"
[value]="pageSizeOption" [label]="'search.sidebar.settings.sort-by'"
[selected]="pageSizeOption === +config?.pagination.pageSize ? 'selected': null"> (change)="reloadOrder($event)"
{{pageSizeOption}} >
</option> <option *ngFor="let sortOption of searchOptionPossibilities"
</select> [value]="sortOption.field + ',' + sortOption.direction.toString()"
</div> [selected]="sortOption.field === config?.sort.field && sortOption.direction === (config?.sort.direction)? 'selected': null">
</ng-container> {{'sorting.' + sortOption.field + '.' + sortOption.direction | translate}}
</option>
</ds-sidebar-dropdown>
</div>
<div class="page-size-settings">
<ds-sidebar-dropdown
[id]="'search-sidebar-rpp'"
[label]="'search.sidebar.settings.rpp'"
(change)="reloadRPP($event)"
>
<option *ngFor="let pageSizeOption of config?.pagination.pageSizeOptions"
[value]="pageSizeOption"
[selected]="pageSizeOption === +config?.pagination.pageSize ? 'selected': null">
{{pageSizeOption}}
</option>
</ds-sidebar-dropdown>
</div>
</ng-container>

View File

@@ -7,84 +7,92 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { SearchSidebarService } from '../search-sidebar/search-sidebar.service'; import { SidebarService } from '../../shared/sidebar/sidebar.service';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe'; import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { SearchFilterService } from '../search-filters/search-filter/search-filter.service'; import { SearchFilterService } from '../search-filters/search-filter/search-filter.service';
import { hot } from 'jasmine-marbles';
import { VarDirective } from '../../shared/utils/var.directive'; import { VarDirective } from '../../shared/utils/var.directive';
import { first } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.component'; import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.component';
describe('SearchSettingsComponent', () => { describe('SearchSettingsComponent', () => {
let comp: SearchSettingsComponent; let comp:SearchSettingsComponent;
let fixture: ComponentFixture<SearchSettingsComponent>; let fixture:ComponentFixture<SearchSettingsComponent>;
let searchServiceObject: SearchService; let searchServiceObject:SearchService;
const pagination: PaginationComponentOptions = new PaginationComponentOptions(); let pagination:PaginationComponentOptions;
pagination.id = 'search-results-pagination'; let sort:SortOptions;
pagination.currentPage = 1; let mockResults;
pagination.pageSize = 10; let searchServiceStub;
const sort: SortOptions = new SortOptions('score', SortDirection.DESC);
const mockResults = ['test', 'data'];
const searchServiceStub = {
searchOptions: { pagination: pagination, sort: sort },
search: () => mockResults
};
const queryParam = 'test query'; let queryParam;
const scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f'; let scopeParam;
const paginatedSearchOptions = { let paginatedSearchOptions;
query: queryParam,
scope: scopeParam,
pagination,
sort
};
const activatedRouteStub = { let activatedRouteStub;
queryParams: observableOf({
query: queryParam,
scope: scopeParam
})
};
const sidebarService = { let sidebarService;
isCollapsed: observableOf(true),
collapse: () => this.isCollapsed = observableOf(true),
expand: () => this.isCollapsed = observableOf(false)
};
beforeEach(async(() => { beforeEach(async(() => {
pagination = new PaginationComponentOptions();
pagination.id = 'search-results-pagination';
pagination.currentPage = 1;
pagination.pageSize = 10;
sort = new SortOptions('score', SortDirection.DESC);
mockResults = ['test', 'data'];
searchServiceStub = {
searchOptions: {pagination: pagination, sort: sort},
search: () => mockResults,
};
queryParam = 'test query';
scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f';
paginatedSearchOptions = {
query: queryParam,
scope: scopeParam,
pagination,
sort,
};
activatedRouteStub = {
queryParams: observableOf({
query: queryParam,
scope: scopeParam,
}),
};
sidebarService = {
isCollapsed: observableOf(true),
collapse: () => this.isCollapsed = observableOf(true),
expand: () => this.isCollapsed = observableOf(false),
};
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])], imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])],
declarations: [SearchSettingsComponent, EnumKeysPipe, VarDirective], declarations: [SearchSettingsComponent, EnumKeysPipe, VarDirective],
providers: [ providers: [
{ provide: SearchService, useValue: searchServiceStub }, {provide: SearchService, useValue: searchServiceStub},
{ provide: ActivatedRoute, useValue: activatedRouteStub }, {provide: ActivatedRoute, useValue: activatedRouteStub},
{ {
provide: SearchSidebarService, provide: SidebarService,
useValue: sidebarService useValue: sidebarService,
}, },
{ {
provide: SearchFilterService, provide: SearchFilterService,
useValue: {} useValue: {},
}, },
{ {
provide: SEARCH_CONFIG_SERVICE, provide: SEARCH_CONFIG_SERVICE,
useValue: { useValue: {
paginatedSearchOptions: hot('a', { paginatedSearchOptions: observableOf(paginatedSearchOptions),
a: paginatedSearchOptions getCurrentScope: observableOf('test-id'),
}), },
getCurrentScope: hot('a', {
a: 'test-id'
}),
}
}, },
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA],
}).compileComponents(); }).compileComponents();
})); }));
@@ -101,42 +109,46 @@ describe('SearchSettingsComponent', () => {
}); });
it('it should show the order settings with the respective selectable options', () => { it('it should show the order settings with the respective selectable options', (done) => {
(comp as any).searchOptions$.pipe(first()).subscribe((options) => { (comp as any).searchOptions$.pipe(take(1)).subscribe((options) => {
fixture.detectChanges(); fixture.detectChanges();
const orderSetting = fixture.debugElement.query(By.css('div.result-order-settings')); const orderSetting = fixture.debugElement.query(By.css('div.result-order-settings'));
expect(orderSetting).toBeDefined(); expect(orderSetting).toBeDefined();
const childElements = orderSetting.query(By.css('.form-control')).children; const childElements = orderSetting.queryAll(By.css('option'));
expect(childElements.length).toEqual(comp.searchOptionPossibilities.length); expect(childElements.length).toEqual(comp.searchOptionPossibilities.length);
done();
}); });
}); });
it('it should show the size settings with the respective selectable options', () => { it('it should show the size settings with the respective selectable options', (done) => {
(comp as any).searchOptions$.pipe(first()).subscribe((options) => { (comp as any).searchOptions$.pipe(take(1)).subscribe((options) => {
fixture.detectChanges(); fixture.detectChanges();
const pageSizeSetting = fixture.debugElement.query(By.css('div.page-size-settings')); const pageSizeSetting = fixture.debugElement.query(By.css('div.page-size-settings'));
expect(pageSizeSetting).toBeDefined(); expect(pageSizeSetting).toBeDefined();
const childElements = pageSizeSetting.query(By.css('.form-control')).children; const childElements = pageSizeSetting.queryAll(By.css('option'));
expect(childElements.length).toEqual(options.pagination.pageSizeOptions.length); expect(childElements.length).toEqual(options.pagination.pageSizeOptions.length);
} done();
) },
);
}); });
it('should have the proper order value selected by default', () => { it('should have the proper order value selected by default', (done) => {
(comp as any).searchOptions$.pipe(first()).subscribe((options) => { (comp as any).searchOptions$.pipe(take(1)).subscribe((options) => {
fixture.detectChanges(); fixture.detectChanges();
const orderSetting = fixture.debugElement.query(By.css('div.result-order-settings')); const orderSetting = fixture.debugElement.query(By.css('div.result-order-settings'));
const childElementToBeSelected = orderSetting.query(By.css('.form-control option[value="0"][selected="selected"]')); const childElementToBeSelected = orderSetting.query(By.css('option[value="0"][selected="selected"]'));
expect(childElementToBeSelected).toBeDefined(); expect(childElementToBeSelected).toBeDefined();
done();
}); });
}); });
it('should have the proper rpp value selected by default', () => { it('should have the proper rpp value selected by default', (done) => {
(comp as any).searchOptions$.pipe(first()).subscribe((options) => { (comp as any).searchOptions$.pipe(take(1)).subscribe((options) => {
fixture.detectChanges(); fixture.detectChanges();
const pageSizeSetting = fixture.debugElement.query(By.css('div.page-size-settings')); const pageSizeSetting = fixture.debugElement.query(By.css('div.page-size-settings'));
const childElementToBeSelected = pageSizeSetting.query(By.css('.form-control option[value="10"][selected="selected"]')); const childElementToBeSelected = pageSizeSetting.query(By.css('option[value="10"][selected="selected"]'));
expect(childElementToBeSelected).toBeDefined(); expect(childElementToBeSelected).toBeDefined();
done();
}); });
}); });

View File

@@ -1,47 +0,0 @@
import { SearchSidebarAction, SearchSidebarActionTypes } from './search-sidebar.actions';
/**
* Interface that represents the state of the sidebar
*/
export interface SearchSidebarState {
sidebarCollapsed: boolean;
}
const initialState: SearchSidebarState = {
sidebarCollapsed: true
};
/**
* Performs a search sidebar action on the current state
* @param {SearchSidebarState} state The state before the action is performed
* @param {SearchSidebarAction} action The action that should be performed
* @returns {SearchSidebarState} The state after the action is performed
*/
export function sidebarReducer(state = initialState, action: SearchSidebarAction): SearchSidebarState {
switch (action.type) {
case SearchSidebarActionTypes.COLLAPSE: {
return Object.assign({}, state, {
sidebarCollapsed: true
});
}
case SearchSidebarActionTypes.EXPAND: {
return Object.assign({}, state, {
sidebarCollapsed: false
});
}
case SearchSidebarActionTypes.TOGGLE: {
return Object.assign({}, state, {
sidebarCollapsed: !state.sidebarCollapsed
});
}
default: {
return state;
}
}
}

View File

@@ -1,11 +1,15 @@
import { ActionReducerMap, createSelector, MemoizedSelector } from '@ngrx/store'; import { ActionReducerMap, createSelector, MemoizedSelector, State } from '@ngrx/store';
import * as fromRouter from '@ngrx/router-store'; import * as fromRouter from '@ngrx/router-store';
import { hostWindowReducer, HostWindowState } from './shared/host-window.reducer'; import { hostWindowReducer, HostWindowState } from './shared/host-window.reducer';
import { formReducer, FormState } from './shared/form/form.reducer'; import { formReducer, FormState } from './shared/form/form.reducer';
import { import {
SearchSidebarState, SidebarState,
sidebarReducer sidebarReducer
} from './+search-page/search-sidebar/search-sidebar.reducer'; } from './shared/sidebar/sidebar.reducer';
import {
SidebarFilterState,
sidebarFilterReducer, SidebarFiltersState
} from './shared/sidebar/filter/sidebar-filter.reducer';
import { import {
filterReducer, filterReducer,
SearchFiltersState SearchFiltersState
@@ -37,7 +41,8 @@ export interface AppState {
metadataRegistry: MetadataRegistryState; metadataRegistry: MetadataRegistryState;
bitstreamFormats: BitstreamFormatRegistryState; bitstreamFormats: BitstreamFormatRegistryState;
notifications: NotificationsState; notifications: NotificationsState;
searchSidebar: SearchSidebarState; sidebar: SidebarState;
sidebarFilter: SidebarFiltersState;
searchFilter: SearchFiltersState; searchFilter: SearchFiltersState;
truncatable: TruncatablesState; truncatable: TruncatablesState;
cssVariables: CSSVariablesState; cssVariables: CSSVariablesState;
@@ -53,7 +58,8 @@ export const appReducers: ActionReducerMap<AppState> = {
metadataRegistry: metadataRegistryReducer, metadataRegistry: metadataRegistryReducer,
bitstreamFormats: bitstreamFormatReducer, bitstreamFormats: bitstreamFormatReducer,
notifications: notificationsReducer, notifications: notificationsReducer,
searchSidebar: sidebarReducer, sidebar: sidebarReducer,
sidebarFilter: sidebarFilterReducer,
searchFilter: filterReducer, searchFilter: filterReducer,
truncatable: truncatableReducer, truncatable: truncatableReducer,
cssVariables: cssVariablesReducer, cssVariables: cssVariablesReducer,

View File

@@ -11,6 +11,13 @@ import { Bitstream } from '../../shared/bitstream.model';
@mapsTo(Bundle) @mapsTo(Bundle)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> { export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> {
/**
* The bundle's name
*/
@autoserialize
name: string;
/** /**
* The primary bitstream of this Bundle * The primary bitstream of this Bundle
*/ */

View File

@@ -3,13 +3,9 @@ import { inheritSerialization, deserialize, autoserialize, autoserializeAs } fro
import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
import { Item } from '../../shared/item.model'; import { Item } from '../../shared/item.model';
import { mapsTo, relationship } from '../builders/build-decorators'; import { mapsTo, relationship } from '../builders/build-decorators';
import { ResourceType } from '../../shared/resource-type';
import { NormalizedCollection } from './normalized-collection.model';
import { NormalizedBitstream } from './normalized-bitstream.model';
import { NormalizedRelationship } from './items/normalized-relationship.model';
import { Collection } from '../../shared/collection.model'; import { Collection } from '../../shared/collection.model';
import { Bitstream } from '../../shared/bitstream.model';
import { Relationship } from '../../shared/item-relationships/relationship.model'; import { Relationship } from '../../shared/item-relationships/relationship.model';
import { Bundle } from '../../shared/bundle.model';
/** /**
* Normalized model class for a DSpace Item * Normalized model class for a DSpace Item
@@ -66,8 +62,8 @@ export class NormalizedItem extends NormalizedDSpaceObject<Item> {
* List of Bitstreams that are owned by this Item * List of Bitstreams that are owned by this Item
*/ */
@deserialize @deserialize
@relationship(Bitstream, true) @relationship(Bundle, true)
bitstreams: string[]; bundles: string[];
@autoserialize @autoserialize
@relationship(Relationship, true) @relationship(Relationship, true)

View File

@@ -0,0 +1,46 @@
import { Injectable } from '@angular/core';
import { DataService } from './data.service';
import { Bundle } from '../shared/bundle.model';
import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { FindAllOptions } from './request.models';
import { Observable } from 'rxjs/internal/Observable';
/**
* A service responsible for fetching/sending data from/to the REST API on the bundles endpoint
*/
@Injectable()
export class BundleDataService extends DataService<Bundle> {
protected linkPath = 'bundles';
protected forceBypassCache = false;
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<Bundle>) {
super();
}
/**
* Get the endpoint for browsing bundles
* @param {FindAllOptions} options
* @returns {Observable<string>}
*/
getBrowseEndpoint(options: FindAllOptions = {}, linkPath?: string): Observable<string> {
return this.halService.getEndpoint(this.linkPath);
}
}

View File

@@ -4,10 +4,16 @@ import { Item } from './item.model';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ResourceType } from './resource-type'; import { ResourceType } from './resource-type';
import { PaginatedList } from '../data/paginated-list';
export class Bundle extends DSpaceObject { export class Bundle extends DSpaceObject {
static type = new ResourceType('bundle'); static type = new ResourceType('bundle');
/**
* The bundle's name
*/
name: string;
/** /**
* The primary bitstream of this Bundle * The primary bitstream of this Bundle
*/ */
@@ -23,6 +29,9 @@ export class Bundle extends DSpaceObject {
*/ */
owner: Observable<RemoteData<Item>>; owner: Observable<RemoteData<Item>>;
bitstreams: Observable<RemoteData<Bitstream[]>> /**
* List of Bitstreams that are part of this Bundle
*/
bitstreams: Observable<RemoteData<PaginatedList<Bitstream>>>;
} }

View File

@@ -4,7 +4,7 @@ import { Item } from './item.model';
import { Bitstream } from './bitstream.model'; import { Bitstream } from './bitstream.model';
import { isEmpty } from '../../shared/empty.util'; import { isEmpty } from '../../shared/empty.util';
import { first, map } from 'rxjs/operators'; import { first, map } from 'rxjs/operators';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils'; import { createPaginatedList, createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
describe('Item', () => { describe('Item', () => {
@@ -18,8 +18,9 @@ describe('Item', () => {
const nonExistingBundleName = 'c1e568f7-d14e-496b-bdd7-07026998cc00'; const nonExistingBundleName = 'c1e568f7-d14e-496b-bdd7-07026998cc00';
let bitstreams; let bitstreams;
let remoteDataThumbnail; let remoteDataThumbnail;
let remoteDataThumbnailList;
let remoteDataFiles; let remoteDataFiles;
let remoteDataAll; let remoteDataBundles;
beforeEach(() => { beforeEach(() => {
const thumbnail = { const thumbnail = {
@@ -33,15 +34,16 @@ describe('Item', () => {
}]; }];
remoteDataThumbnail = createSuccessfulRemoteDataObject$(thumbnail); remoteDataThumbnail = createSuccessfulRemoteDataObject$(thumbnail);
remoteDataFiles = createSuccessfulRemoteDataObject$(bitstreams); remoteDataThumbnailList = createSuccessfulRemoteDataObject$(createPaginatedList([thumbnail]));
remoteDataAll = createSuccessfulRemoteDataObject$([...bitstreams, thumbnail]); remoteDataFiles = createSuccessfulRemoteDataObject$(createPaginatedList(bitstreams));
// Create Bundles // Create Bundles
const bundles = const bundles =
[ [
{ {
name: thumbnailBundleName, name: thumbnailBundleName,
primaryBitstream: remoteDataThumbnail primaryBitstream: remoteDataThumbnail,
bitstreams: remoteDataThumbnailList
}, },
{ {
@@ -49,7 +51,9 @@ describe('Item', () => {
bitstreams: remoteDataFiles bitstreams: remoteDataFiles
}]; }];
item = Object.assign(new Item(), { bitstreams: remoteDataAll }); remoteDataBundles = createSuccessfulRemoteDataObject$(createPaginatedList(bundles));
item = Object.assign(new Item(), { bundles: remoteDataBundles });
}); });
it('should return the bitstreams related to this item with the specified bundle name', () => { it('should return the bitstreams related to this item with the specified bundle name', () => {

View File

@@ -1,15 +1,16 @@
import { map, startWith, filter, take } from 'rxjs/operators'; import { map, startWith, filter, switchMap } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { DSpaceObject } from './dspace-object.model'; import { DSpaceObject } from './dspace-object.model';
import { Collection } from './collection.model'; import { Collection } from './collection.model';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Bitstream } from './bitstream.model'; import { Bitstream } from './bitstream.model';
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; import { hasValueOperator, isNotEmpty, isEmpty } from '../../shared/empty.util';
import { PaginatedList } from '../data/paginated-list'; import { PaginatedList } from '../data/paginated-list';
import { Relationship } from './item-relationships/relationship.model'; import { Relationship } from './item-relationships/relationship.model';
import { ResourceType } from './resource-type'; import { ResourceType } from './resource-type';
import { getSucceededRemoteData } from './operators'; import { getAllSucceededRemoteData, getSucceededRemoteData } from './operators';
import { Bundle } from './bundle.model';
import { GenericConstructor } from './generic-constructor'; import { GenericConstructor } from './generic-constructor';
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
import { DEFAULT_ENTITY_TYPE } from '../../shared/metadata-representation/metadata-representation.decorator'; import { DEFAULT_ENTITY_TYPE } from '../../shared/metadata-representation/metadata-representation.decorator';
@@ -59,7 +60,10 @@ export class Item extends DSpaceObject {
return this.owningCollection; return this.owningCollection;
} }
bitstreams: Observable<RemoteData<PaginatedList<Bitstream>>>; /**
* Bitstream bundles within this item
*/
bundles: Observable<RemoteData<PaginatedList<Bundle>>>;
relationships: Observable<RemoteData<PaginatedList<Relationship>>>; relationships: Observable<RemoteData<PaginatedList<Relationship>>>;
@@ -103,17 +107,15 @@ export class Item extends DSpaceObject {
* see https://github.com/DSpace/dspace-angular/issues/332 * see https://github.com/DSpace/dspace-angular/issues/332
*/ */
getBitstreamsByBundleName(bundleName: string): Observable<Bitstream[]> { getBitstreamsByBundleName(bundleName: string): Observable<Bitstream[]> {
return this.bitstreams.pipe( return this.bundles.pipe(
getSucceededRemoteData(), getSucceededRemoteData(),
map((rd: RemoteData<PaginatedList<Bundle>>) => rd.payload.page.find((bundle: Bundle) => bundle.name === bundleName)),
hasValueOperator(),
switchMap((bundle: Bundle) => bundle.bitstreams),
getAllSucceededRemoteData(),
map((rd: RemoteData<PaginatedList<Bitstream>>) => rd.payload.page), map((rd: RemoteData<PaginatedList<Bitstream>>) => rd.payload.page),
filter((bitstreams: Bitstream[]) => hasValue(bitstreams)), startWith([])
take(1), );
startWith([]),
map((bitstreams) => {
return bitstreams
.filter((bitstream) => hasValue(bitstream))
.filter((bitstream) => bitstream.bundleName === bundleName)
}));
} }
/** /**

View File

@@ -12,7 +12,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -12,7 +12,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -12,7 +12,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -9,7 +9,7 @@ import { JournalIssueSearchResultGridElementComponent } from './journal-issue-se
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -35,7 +35,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -9,7 +9,7 @@ import { JournalVolumeSearchResultGridElementComponent } from './journal-volume-
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -35,7 +35,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -9,7 +9,7 @@ import { JournalSearchResultGridElementComponent } from './journal-search-result
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -41,7 +41,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -43,7 +43,7 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -42,7 +42,7 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -37,7 +37,7 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -6,7 +6,7 @@ import { createRelationshipsObservable, getItemPageFieldsTest } from '../../../.
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'publicationissue.issueNumber': [ 'publicationissue.issueNumber': [
{ {

View File

@@ -11,7 +11,7 @@ import {
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'publicationvolume.volumeNumber': [ 'publicationvolume.volumeNumber': [
{ {

View File

@@ -18,7 +18,7 @@ let comp: JournalComponent;
let fixture: ComponentFixture<JournalComponent>; let fixture: ComponentFixture<JournalComponent>;
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'creativeworkseries.issn': [ 'creativeworkseries.issn': [
{ {

View File

@@ -12,7 +12,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -12,7 +12,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -12,7 +12,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -9,7 +9,7 @@ import { getEntityGridElementTestComponent } from '../../../../../shared/object-
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -41,7 +41,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -9,7 +9,7 @@ import { PersonSearchResultGridElementComponent } from './person-search-result-g
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -35,7 +35,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -9,7 +9,7 @@ import { getEntityGridElementTestComponent } from '../../../../../shared/object-
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -29,7 +29,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatableService } from '../../../../shared/truncatable/truncatable.s
import { ProjectListElementComponent } from './project-list-element.component'; import { ProjectListElementComponent } from './project-list-element.component';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -36,7 +36,7 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -36,7 +36,7 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -14,7 +14,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -36,7 +36,7 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
new ItemSearchResult(), new ItemSearchResult(),
{ {
indexableObject: Object.assign(new Item(), { indexableObject: Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -11,7 +11,7 @@ import {
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'organization.foundingDate': [ 'organization.foundingDate': [
{ {

View File

@@ -11,7 +11,7 @@ import {
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'person.email': [ 'person.email': [
{ {

View File

@@ -11,7 +11,7 @@ import {
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
// 'project.identifier.status': [ // 'project.identifier.status': [
// { // {

View File

@@ -4,6 +4,7 @@ import { Item } from '../../core/shared/item.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Bitstream } from '../../core/shared/bitstream.model'; import { Bitstream } from '../../core/shared/bitstream.model';
import { PaginatedList } from '../../core/data/paginated-list'; import { PaginatedList } from '../../core/data/paginated-list';
import { createPaginatedList, createSuccessfulRemoteDataObject$ } from '../testing/utils';
/* tslint:disable:no-shadowed-variable */ /* tslint:disable:no-shadowed-variable */
export const MockItem: Item = Object.assign(new Item(), { export const MockItem: Item = Object.assign(new Item(), {
@@ -12,102 +13,107 @@ export const MockItem: Item = Object.assign(new Item(), {
isArchived: true, isArchived: true,
isDiscoverable: true, isDiscoverable: true,
isWithdrawn: false, isWithdrawn: false,
bitstreams: observableOf(Object.assign({ bundles: createSuccessfulRemoteDataObject$(createPaginatedList([
self: 'dspace-angular://aggregated/object/1507836003548', {
requestPending: false, name: 'ORIGINAL',
responsePending: false, bitstreams: observableOf(Object.assign({
isSuccessful: true, self: 'dspace-angular://aggregated/object/1507836003548',
errorMessage: '', requestPending: false,
state: '', responsePending: false,
error: undefined, isSuccessful: true,
isRequestPending: false, errorMessage: '',
isResponsePending: false, state: '',
isLoading: false, error: undefined,
hasFailed: false, isRequestPending: false,
hasSucceeded: true, isResponsePending: false,
statusCode: '202', isLoading: false,
pageInfo: {}, hasFailed: false,
payload: { hasSucceeded: true,
pageInfo: { statusCode: '202',
elementsPerPage: 20, pageInfo: {},
totalElements: 3, payload: {
totalPages: 1, pageInfo: {
currentPage: 2 elementsPerPage: 20,
}, totalElements: 3,
page: [ totalPages: 1,
{ currentPage: 2
sizeBytes: 10201, },
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/content', page: [
format: observableOf({ {
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10', sizeBytes: 10201,
requestPending: false, content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/content',
responsePending: false, format: observableOf({
isSuccessful: true, self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10',
errorMessage: '', requestPending: false,
statusCode: '202', responsePending: false,
pageInfo: {}, isSuccessful: true,
payload: { errorMessage: '',
shortDescription: 'Microsoft Word XML', statusCode: '202',
description: 'Microsoft Word XML', pageInfo: {},
mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', payload: {
supportLevel: 0, shortDescription: 'Microsoft Word XML',
internal: false, description: 'Microsoft Word XML',
extensions: null, mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10' supportLevel: 0,
} internal: false,
}), extensions: null,
bundleName: 'ORIGINAL', self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10'
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713', }
id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713', }),
uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713', bundleName: 'ORIGINAL',
type: 'bitstream', self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713',
metadata: { id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
'dc.title': [ uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
{ type: 'bitstream',
language: null, metadata: {
value: 'test_word.docx' 'dc.title': [
{
language: null,
value: 'test_word.docx'
}
]
} }
] },
} {
}, sizeBytes: 31302,
{ content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content',
sizeBytes: 31302, format: observableOf({
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content', self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4',
format: observableOf({ requestPending: false,
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4', responsePending: false,
requestPending: false, isSuccessful: true,
responsePending: false, errorMessage: '',
isSuccessful: true, statusCode: '202',
errorMessage: '', pageInfo: {},
statusCode: '202', payload: {
pageInfo: {}, shortDescription: 'Adobe PDF',
payload: { description: 'Adobe Portable Document Format',
shortDescription: 'Adobe PDF', mimetype: 'application/pdf',
description: 'Adobe Portable Document Format', supportLevel: 0,
mimetype: 'application/pdf', internal: false,
supportLevel: 0, extensions: null,
internal: false, self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4'
extensions: null, }
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4' }),
} bundleName: 'ORIGINAL',
}), self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28',
bundleName: 'ORIGINAL', id: '99b00f3c-1cc6-4689-8158-91965bee6b28',
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28', uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28',
id: '99b00f3c-1cc6-4689-8158-91965bee6b28', type: 'bitstream',
uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28', metadata: {
type: 'bitstream', 'dc.title': [
metadata: { {
'dc.title': [ language: null,
{ value: 'test_pdf.pdf'
language: null, }
value: 'test_pdf.pdf' ]
} }
] }
} ]
} }
] }))
} }
}) as RemoteData<PaginatedList<Bitstream>>), ])),
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357', self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357',
id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357', id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
uuid: '0ec7ff22-f211-40ab-a69e-c819b0b1f357', uuid: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',

View File

@@ -41,7 +41,7 @@ const searchService = getMockSearchService();
const requestServce = getMockRequestService(); const requestServce = getMockRequestService();
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -25,7 +25,7 @@ let mockObject: Item;
const mockDataService = {}; const mockDataService = {};
mockObject = Object.assign(new Item(), { mockObject = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -38,7 +38,7 @@ const searchService = getMockSearchService();
const requestServce = getMockRequestService(); const requestServce = getMockRequestService();
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -32,7 +32,7 @@ const searchService = getMockSearchService();
const requestServce = getMockRequestService(); const requestServce = getMockRequestService();
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -37,7 +37,7 @@ const searchService = getMockSearchService();
const requestServce = getMockRequestService(); const requestServce = getMockRequestService();
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -21,7 +21,7 @@ const mockResultObject: ClaimedTaskSearchResult = new ClaimedTaskSearchResult();
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ let component: ItemDetailPreviewFieldComponent;
let fixture: ComponentFixture<ItemDetailPreviewFieldComponent>; let fixture: ComponentFixture<ItemDetailPreviewFieldComponent>;
const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), { const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.contributor.author': [ 'dc.contributor.author': [
{ {

View File

@@ -30,7 +30,7 @@ let component: ItemDetailPreviewComponent;
let fixture: ComponentFixture<ItemDetailPreviewComponent>; let fixture: ComponentFixture<ItemDetailPreviewComponent>;
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(new PageInfo(), []))), bundles: observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(new PageInfo(), []))),
metadata: { metadata: {
'dc.contributor.author': [ 'dc.contributor.author': [
{ {
@@ -88,7 +88,7 @@ describe('ItemDetailPreviewComponent', () => {
component.object = { hitHighlights: {} } as any; component.object = { hitHighlights: {} } as any;
component.item = mockItem; component.item = mockItem;
component.separator = ', '; component.separator = ', ';
spyOn(component.item, 'getFiles').and.returnValue(mockItem.bitstreams); spyOn(component.item, 'getFiles').and.returnValue(mockItem.bundles);
fixture.detectChanges(); fixture.detectChanges();
})); }));

View File

@@ -18,7 +18,7 @@ const mockResultObject: ItemSearchResult = new ItemSearchResult();
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
mockResultObject.indexableObject = Object.assign(new Item(), { mockResultObject.indexableObject = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -21,7 +21,7 @@ const mockResultObject: PoolTaskSearchResult = new PoolTaskSearchResult();
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -20,7 +20,7 @@ const mockResultObject: WorkflowItemSearchResult = new WorkflowItemSearchResult(
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -20,7 +20,7 @@ const mockResultObject: WorkflowItemSearchResult = new WorkflowItemSearchResult(
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -12,7 +12,7 @@ import { PaginatedList } from '../../../../../core/data/paginated-list';
import { PageInfo } from '../../../../../core/shared/page-info.model'; import { PageInfo } from '../../../../../core/shared/page-info.model';
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -15,7 +15,7 @@ import { PublicationSearchResultGridElementComponent } from './publication-searc
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {}; mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), { mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -47,7 +47,7 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult(); const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {}; mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), { mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])), bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -8,7 +8,7 @@ import { TruncatableService } from '../../../../truncatable/truncatable.service'
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
const mockItem: Item = Object.assign(new Item(), { const mockItem: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -14,7 +14,7 @@ let fixture: ComponentFixture<ItemTypeBadgeComponent>;
const type = 'authorOfPublication'; const type = 'authorOfPublication';
const mockItemWithRelationshipType = Object.assign(new Item(), { const mockItemWithRelationshipType = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'relationship.type': [ 'relationship.type': [
{ {
@@ -26,7 +26,7 @@ const mockItemWithRelationshipType = Object.assign(new Item(), {
}); });
const mockItemWithoutRelationshipType = Object.assign(new Item(), { const mockItemWithoutRelationshipType = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -23,7 +23,7 @@ const mockResultObject: ClaimedTaskSearchResult = new ClaimedTaskSearchResult();
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -14,7 +14,7 @@ let component: ItemListPreviewComponent;
let fixture: ComponentFixture<ItemListPreviewComponent>; let fixture: ComponentFixture<ItemListPreviewComponent>;
const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), { const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.contributor.author': [ 'dc.contributor.author': [
{ {
@@ -31,7 +31,7 @@ const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), {
} }
}); });
const mockItemWithoutAuthorAndDate: Item = Object.assign(new Item(), { const mockItemWithoutAuthorAndDate: Item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -19,7 +19,7 @@ const mockResultObject: ItemSearchResult = new ItemSearchResult();
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
mockResultObject.indexableObject = Object.assign(new Item(), { mockResultObject.indexableObject = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -22,7 +22,7 @@ const mockResultObject: PoolTaskSearchResult = new PoolTaskSearchResult();
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -21,7 +21,7 @@ const mockResultObject: WorkflowItemSearchResult = new WorkflowItemSearchResult(
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -21,7 +21,7 @@ const mockResultObject: WorkflowItemSearchResult = new WorkflowItemSearchResult(
mockResultObject.hitHighlights = {}; mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), { const item = Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -14,7 +14,7 @@ let fixture: ComponentFixture<PublicationSearchResultListElementComponent>;
const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), { const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), {
indexableObject: indexableObject:
Object.assign(new Item(), { Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -52,7 +52,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResul
const mockItemWithoutMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), { const mockItemWithoutMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), {
indexableObject: indexableObject:
Object.assign(new Item(), { Object.assign(new Item(), {
bitstreams: observableOf({}), bundles: observableOf({}),
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ {

View File

@@ -24,7 +24,7 @@ describe('ItemSelectComponent', () => {
const mockItemList = [ const mockItemList = [
Object.assign(new Item(), { Object.assign(new Item(), {
id: 'id1', id: 'id1',
bitstreams: of({}), bundles: of({}),
metadata: [ metadata: [
{ {
key: 'dc.title', key: 'dc.title',
@@ -39,7 +39,7 @@ describe('ItemSelectComponent', () => {
}), }),
Object.assign(new Item(), { Object.assign(new Item(), {
id: 'id2', id: 'id2',
bitstreams: of({}), bundles: of({}),
metadata: [ metadata: [
{ {
key: 'dc.title', key: 'dc.title',

View File

@@ -147,6 +147,10 @@ import { ListableObjectDirective } from './object-collection/shared/listable-obj
import { CommunitySearchResultGridElementComponent } from './object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component'; import { CommunitySearchResultGridElementComponent } from './object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component';
import { CollectionSearchResultGridElementComponent } from './object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; import { CollectionSearchResultGridElementComponent } from './object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component';
import { ItemMetadataRepresentationListElementComponent } from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; import { ItemMetadataRepresentationListElementComponent } from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component';
import { PageWithSidebarComponent } from './sidebar/page-with-sidebar.component';
import { SidebarDropdownComponent } from './sidebar/sidebar-dropdown.component';
import { SidebarFilterComponent } from './sidebar/filter/sidebar-filter.component';
import { SidebarFilterSelectedOptionComponent } from './sidebar/filter/sidebar-filter-selected-option.component';
const MODULES = [ const MODULES = [
// Do NOT include UniversalModule, HttpModule, or JsonpModule here // Do NOT include UniversalModule, HttpModule, or JsonpModule here
@@ -230,6 +234,10 @@ const COMPONENTS = [
ObjectCollectionComponent, ObjectCollectionComponent,
PaginationComponent, PaginationComponent,
SearchFormComponent, SearchFormComponent,
PageWithSidebarComponent,
SidebarDropdownComponent,
SidebarFilterComponent,
SidebarFilterSelectedOptionComponent,
ThumbnailComponent, ThumbnailComponent,
GridThumbnailComponent, GridThumbnailComponent,
UploaderComponent, UploaderComponent,

View File

@@ -0,0 +1,6 @@
<a class="d-flex flex-row" (click)="click.emit($event)">
<label>
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
<span class="filter-value pl-1 text-capitalize">{{label}}</span>
</label>
</a>

View File

@@ -0,0 +1,11 @@
a {
color: $body-color;
&:hover, &focus {
text-decoration: none;
}
span.badge {
vertical-align: text-top;
}
}

View File

@@ -0,0 +1,15 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'ds-sidebar-filter-selected-option',
styleUrls: ['./sidebar-filter-selected-option.component.scss'],
templateUrl: './sidebar-filter-selected-option.component.html',
})
/**
* Represents a single selected option in a sidebar filter
*/
export class SidebarFilterSelectedOptionComponent {
@Input() label:string;
@Output() click:EventEmitter<any> = new EventEmitter<any>();
}

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