Compare commits

...

1032 Commits

Author SHA1 Message Date
Tim Donohue
e4f483c308 Minor updates to README for 7.2 2022-02-03 14:04:49 -06:00
Tim Donohue
d7f64d6139 Merge pull request #1438 from mspalti/iiif-bitstream-edit
Edit IIIF bitstream metadata
2022-02-01 11:21:04 -06:00
Tim Donohue
7777fa6229 Merge pull request #1509 from tdonohue/enable_scottish
Enable Scottish Gaelic
2022-02-01 10:48:09 -06:00
Tim Donohue
5290ca8756 Enable Scottish Gaelic 2022-02-01 10:00:03 -06:00
Tim Donohue
e6299030f0 Merge pull request #1508 from donaldi/main
Full Scottish Gaelic translation.
2022-02-01 09:41:50 -06:00
Donald I Macdonald
ffec5b7f74 Full Scottish Gaelic translation.
Translated and proofed by Stòrlann Nàiseanta na Gàidhlig.
2022-02-01 11:05:39 +00:00
Michael Spalti
ac716c4b99 Single form initialization. 2022-01-31 10:38:59 -08:00
Tim Donohue
0fbd48ede9 Merge pull request #1475 from 4Science/CST-4506_item_embargo
Add submission section for item embargo
2022-01-31 11:13:43 -06:00
Michael Spalti
94b2f53220 Removed unnecessary logging. 2022-01-31 07:40:52 -08:00
Tim Donohue
3d7fcef079 Merge pull request #1470 from hardyoyo/port-oidc-auth-plugin-from-dspace-cris
Port OIDC (OpenID Connect) auth plugin from DSpace-CRIS
2022-01-31 08:50:20 -06:00
Tim Donohue
ccdba9b307 Merge pull request #1507 from 4Science/fix_submission_upload
Fix submission upload
2022-01-28 10:06:24 -06:00
Tim Donohue
c98ffd21ea Merge pull request #1503 from atmire/fix-delete-item-with-empty-entity-type
Fix deleting an item with an empty or invalid entity type
2022-01-28 09:47:05 -06:00
Giuseppe Digilio
67d6c6fcbb [CST-4506] use default cursor when drag and drop is disabled 2022-01-28 14:13:21 +01:00
Giuseppe Digilio
4e5bf6e73d [CST-4506] Clean date fields when switching through access conditions 2022-01-28 11:11:34 +01:00
Giuseppe Digilio
f991b4edb2 [CST-4506] Fix item access condition form layout 2022-01-28 11:10:49 +01:00
Giuseppe Digilio
6c720b8031 [CST-4506] Fix item access condition remove operation 2022-01-28 11:09:48 +01:00
Giuseppe Digilio
232baf5973 [CST-4506] Fix bitstream access condition form layout 2022-01-28 11:08:32 +01:00
Giuseppe Digilio
4ca2e9a4b1 [CST-4506] Add i18n labels for item access conditions form 2022-01-28 11:07:29 +01:00
Giuseppe Digilio
9019b80993 [CST-4506] Disable drag and drop for access conditions form group 2022-01-28 09:02:04 +01:00
Michael Spalti
8bfd6ca031 Form re-initialization limited to iiif enabled item. 2022-01-27 18:56:34 -08:00
Michael Spalti
7c5d31fbbd Removed the unused imports. 2022-01-27 15:21:48 -08:00
Michael Spalti
47581db60a Updated test. 2022-01-27 15:08:20 -08:00
Michael Spalti
d91d12ed0d Updated dynamic form. 2022-01-27 14:46:00 -08:00
Tim Donohue
5f90b29d96 Merge pull request #1472 from 4Science/CST-4875-Feedback-form
Feedback form
2022-01-27 15:12:50 -06:00
Giuseppe Digilio
8a668a5073 [CST-4506] fix issue with delete button alignment 2022-01-27 18:58:28 +01:00
Art Lowel
16884682d8 track subscriptions and remove nested subscribe 2022-01-27 18:16:43 +01:00
Giuseppe Digilio
eca9088337 [CST-5198] fix issue with uploaded file that disappear on deposit 2022-01-27 17:59:31 +01:00
Giuseppe Digilio
2f4a667119 [CST-5197] fix issue with uploading file during workflow 2022-01-27 17:55:56 +01:00
Art Lowel
74a6e3ce6a Fix issue where an item with an empty or invalid entity type couldn't be deleted 2022-01-27 17:31:28 +01:00
Giuseppe Digilio
6bbc7f96c2 [CST-4875] remove unused imports 2022-01-27 16:35:32 +01:00
Giuseppe Digilio
42cc68f8b7 [CST-4506] remove unused mock event properties 2022-01-27 15:47:25 +01:00
Rezart Vata
3fa72ebcaa [CST-4875] Fix url redirect 2022-01-27 13:43:41 +01:00
Hardy Pottinger
56e7d4b8c6 Removed unneeded export in shared.module.ts 2022-01-26 14:45:50 -06:00
Hardy Pottinger
d98d3fe0de Removing un-used imports from DSpace-CRIS, and un-implemented ORCID auth 2022-01-26 09:47:26 -06:00
Luca Giamminonni
8c14193f32 [DSC-196] Added components to log in with OIDC 2022-01-26 09:45:01 -06:00
Giuseppe Digilio
d156e01517 [CST-4875] Fix related page using the complete url 2022-01-26 16:41:24 +01:00
Rezart Vata
ed6cb04de4 [CST-4875] Fix unit testing 2022-01-26 15:32:02 +01:00
Rezart Vata
2ac493cb19 [CST-4875] Fixes requested by Tim Gitlab 2022-01-26 14:31:16 +01:00
Tim Donohue
acb842edf0 Merge pull request #1500 from 4Science/search-grid-bug
Fix issue with grid view mode
2022-01-25 16:18:50 -06:00
Giuseppe Digilio
2ceaba742f [CST-5182 Fix issue with grid view mode 2022-01-25 19:28:03 +01:00
Tim Donohue
239888dc9e Merge pull request #1498 from 4Science/CST-4880_Show-an-error-page-if-the-REST-API-is-not-available
[CST-4880] Add ServerCheckGuard in order to show internal server error page when rest server is not available
2022-01-25 11:52:37 -06:00
Giuseppe Digilio
d9df7336df [CST-4880] Fix invalidateRootCache method 2022-01-25 10:57:08 +01:00
Giuseppe Digilio
db3d760f2b [CST-4506] Fix LGTM issues 2022-01-25 10:40:53 +01:00
Giuseppe Digilio
04c8cb7590 [CST-4506] Fix issue with submission bitstream edit 2022-01-25 10:40:11 +01:00
Michael Spalti
8a30748b41 Fixed spacing issue. 2022-01-24 15:28:05 -08:00
Michael Spalti
1ec61e4aec Merge branch 'main' into iiif-bitstream-edit 2022-01-24 14:10:12 -08:00
Giuseppe Digilio
944f605671 [CST-4875] Fix imports path 2022-01-24 22:42:27 +01:00
Giuseppe Digilio
4cfff33301 [CST-4880] Add ServerCheckGuard in order to show internal server error page when rest server is not available 2022-01-24 22:04:02 +01:00
Corrado Lombardi
6a78c1bcf8 [CST-4875] removed comment and redundant import 2022-01-24 21:48:00 +01:00
Corrado Lombardi
36e5a75325 [CST-4875] added spacing and updated validation messages 2022-01-24 21:47:17 +01:00
Corrado Lombardi
78ce20ab8f [CST-4875] feedback created using DataService 2022-01-24 21:46:32 +01:00
Giuseppe Digilio
89c9e9aba3 Merge remote-tracking branch 'origin/main' into CST-4506_item_embargo
# Conflicts:
#	src/app/core/core.module.ts
#	src/app/submission/objects/submission-objects.effects.ts
#	src/app/submission/submission.module.ts
2022-01-24 19:58:50 +01:00
Giuseppe Digilio
973ceb3b4b [CST-4506] Address feedback 2022-01-24 19:54:21 +01:00
Corrado Lombardi
fedb2fce12 Merge branch 'main' into CST-4875-Feedback-form
# Conflicts:
#	src/app/app.module.ts
#	src/app/core/core.module.ts
#	src/app/core/data/feature-authorization/feature-id.ts
#	src/app/footer/footer.component.html
#	src/themes/custom/theme.module.ts
2022-01-24 19:21:52 +01:00
Tim Donohue
4fdd3b84cb Merge pull request #1497 from atmire/replace-href-hash-with-void
Replace href="#" with href="javascript:void(0);" everywhere
2022-01-24 09:50:41 -06:00
Tim Donohue
f94820d70e Merge pull request #1496 from atmire/fix-profile-group-link-bug
Fix user profile page
2022-01-24 09:02:56 -06:00
Art Lowel
132e68a9f4 Provide the GroupDataservice in its module to ensure its @dataservice annotation gets registered in time 2022-01-24 09:54:28 +01:00
Art Lowel
c34f75b443 replace href="#" with href="javascript:void(0);" everywhere 2022-01-24 09:27:19 +01:00
Michael W Spalti
9649b5fb68 More layout changes. 2022-01-22 15:44:50 -08:00
Michael W Spalti
32b2e181bd Removed unused import. 2022-01-21 16:42:49 -08:00
Michael W Spalti
0e6dae2b61 Added semis. 2022-01-21 15:05:52 -08:00
Michael W Spalti
8d3b265038 Using DsDynamicInputModel* and updating scss for ds-dynamic-form-control-container. 2022-01-21 14:43:39 -08:00
Tim Donohue
70b456dbfc Merge pull request #1493 from DSpace/revert-1407-DSC-287-Show-an-error-page-if-the-REST-API-is-not-available
Revert "Show an error page if the rest api is not available"
2022-01-21 13:11:58 -06:00
Tim Donohue
e61de0682f Revert "Show an error page if the rest api is not available" 2022-01-21 11:50:08 -06:00
Tim Donohue
001ba43404 Merge pull request #1490 from tdonohue/fix_docker_compose
Docker-Compose Environment variables must be strings or numbers, not booleans
2022-01-20 15:55:21 -06:00
Tim Donohue
bcb96c522c Environment variables must be strings or numbers, not booleans 2022-01-20 14:08:22 -06:00
Tim Donohue
d75ab378ac Merge pull request #1407 from 4Science/DSC-287-Show-an-error-page-if-the-REST-API-is-not-available
Show an error page if the rest api is not available
2022-01-20 11:41:34 -06:00
Tim Donohue
9310d6e649 Merge pull request #1478 from 4Science/CST-4633-search-refactoring
MyDSpace Search component refactoring
2022-01-20 11:41:06 -06:00
Giuseppe Digilio
532d8fb9a3 [CST-4506] fix SubmissionSectionFormComponent name 2022-01-20 18:30:29 +01:00
Giuseppe Digilio
b81cc103ff [CST-4506] Optimize submission sections components declarations in the submission.module 2022-01-20 18:29:31 +01:00
Giuseppe Digilio
a95bf63ad0 [CST-4633] Fix issue with already selected relationship in the dynamic-lookup-relation-search-tab.component 2022-01-20 18:15:30 +01:00
Giuseppe Digilio
016bf4b368 [CST-4633] Add flag to hide view mode switcher 2022-01-20 18:08:57 +01:00
Tim Donohue
f65930276e Merge pull request #1479 from 4Science/CST-4981-statistics-are-always-accessible-even-if-are-restricted-to-administrator
Fix statistics page in order to show them only when user has authorizations
2022-01-20 10:20:21 -06:00
Giuseppe Digilio
98bdc59c28 [CST-4880] use getPageInternalServerErrorRoute function to determinate 500 page route 2022-01-20 14:26:04 +01:00
Giuseppe Digilio
fd610dbf4d [CST-4880] Set 500 response status to internal server error page 2022-01-20 14:24:54 +01:00
Tim Donohue
710d893187 Merge pull request #1465 from atmire/move-correlation-id-to-store
Move correlation ID to store
2022-01-14 10:14:46 -06:00
Giuseppe Digilio
1abcc027a5 Merge branch 'CST-4875-Feedback-form' of github.com:4Science/dspace-angular into CST-4875-Feedback-form 2022-01-14 16:40:47 +01:00
Giuseppe Digilio
746d0201e8 Merge remote-tracking branch 'origin/main' into CST-4633-search-refactoring 2022-01-14 15:21:19 +01:00
Giuseppe Digilio
b7c46ffe29 [CST-4633] Fix e2e test 2022-01-14 12:37:29 +01:00
Giuseppe Digilio
d7388bcfd8 [CST-4633] Change dynamic-lookup-relation-search-tab.component in order to use search-component 2022-01-14 12:24:44 +01:00
Giuseppe Digilio
1f01cbaa93 [CST-4633] Improve search.component in order to use selectable functionality 2022-01-14 12:21:36 +01:00
Giuseppe Digilio
0d73b6d164 [CST-4633] Fix issue with detail view mode 2022-01-14 12:18:42 +01:00
Tim Donohue
6a7691000b Merge pull request #1489 from atmire/Process-empty-parameters-fix
Scripts & Processes without parameters fix
2022-01-13 16:15:49 -06:00
Rezart Vata
aab544e723 [CST-4875] Fixed commenting, service test & compoent from issue 1472 2022-01-13 17:14:56 +01:00
Tim Donohue
9196610170 Merge pull request #1427 from atmire/Always-enable-deposit-button
Always enable deposit button
2022-01-13 09:45:24 -06:00
Tim Donohue
e321bbf9ab Merge pull request #1434 from atmire/shared-feature-authority-control
Allow facets to be authority controlled
2022-01-13 08:24:56 -06:00
Giuseppe Digilio
6b2efd2b16 [CST-4633] Change view mode labels 2022-01-13 15:17:06 +01:00
Giuseppe Digilio
539ae50214 [CST-4633] Change label translations 2022-01-13 15:16:40 +01:00
Rezart Vata
768c7f8b28 [CST-4505] Fixed canChangeDiscoverable managment and unit testing 2022-01-13 13:45:25 +01:00
Kristof De Langhe
8666ae74f6 86367: Process empty parameters fix 2022-01-13 10:48:46 +01:00
Giuseppe Digilio
6eca73bdec Merge remote-tracking branch 'origin/main' into CST-4633-search-refactoring 2022-01-13 09:42:44 +01:00
Giuseppe Digilio
0c9dc4286c [CST-4981] Fix error with yarn clean command 2022-01-12 20:09:48 +01:00
Giuseppe Digilio
6d1674cc8a [CST-4981] Fix issue with missing statistics menu 2022-01-12 20:09:21 +01:00
Giuseppe Digilio
7e7ad9a4f3 [CST-4880] Add fallback strategy for hanging server check cached requests 2022-01-12 18:32:33 +01:00
Michael Spalti
4f6b579204 Remove metatada field when no data is provided in form.
Updated comments.
2022-01-10 11:22:53 -08:00
Tim Donohue
2835597073 Merge pull request #1476 from 4Science/CST-5064
Show submitter in version history table
2022-01-10 10:03:25 -06:00
Davide Negretti
216eb40ab5 [CST-5064] console.log removed 2022-01-10 10:30:11 +01:00
Tim Donohue
3b618ff66f Merge pull request #1467 from 4Science/CST-5065
Admin is unable to reset other users' password
2022-01-05 14:10:11 -06:00
Tim Donohue
c7663dc311 Merge pull request #1454 from atmire/w2p-85979_canChangePassword-ui-change
Disallow Shibboleth users to change password
2022-01-04 10:09:04 -06:00
Tim Donohue
e7f6321f01 Merge pull request #1474 from tdonohue/docker_runtime_config
Update docker-compose scripts to use environment variables (to align with runtime configs)
2022-01-04 09:34:55 -06:00
Giuseppe Digilio
3b00d01466 [CST-4633] fix issue with view mode when not in params 2022-01-04 12:59:52 +01:00
Rezart Vata
99aef98443 [CST-4981] structure improvement,removed unecessary informations 2021-12-24 19:34:10 +01:00
Rezart Vata
f154fb60e0 [CST-4981] Fixed unit testing 2021-12-24 17:49:55 +01:00
Giuseppe Digilio
504604cfc7 Merge remote-tracking branch 'origin/main' into CST-4981-statistics-are-always-accessible-even-if-are-restricted-to-administrator
# Conflicts:
#	src/app/community-page/edit-community-page/community-authorizations/community-authorizations.component.ts
#	src/app/navbar/navbar.component.spec.ts
#	src/app/navbar/navbar.component.ts
#	src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts
2021-12-24 12:25:03 +01:00
Giuseppe Digilio
522816c29c Merge remote-tracking branch 'origin/main' into CST-4633-search-refactoring
# Conflicts:
#	src/app/shared/comcol/comcol-page-browse-by/comcol-page-browse-by.component.ts
2021-12-24 11:54:10 +01:00
Giuseppe Digilio
e76514ca39 [CST-4633] fix issue with view mode 2021-12-24 11:51:06 +01:00
Giuseppe Digilio
cff29539fb [CST-4633] fix issue with view mode list 2021-12-24 11:41:23 +01:00
Giuseppe Digilio
6f86824f23 [CST-4633] restored ds-my-dspace-new-submission from mydspace page 2021-12-24 11:16:16 +01:00
Davide Negretti
9fd34034b9 [CST-5064] Tests 2021-12-24 10:13:50 +01:00
Davide Negretti
ffaebabd3b [CST-5064] Tests WIP 2021-12-24 00:47:31 +01:00
Giuseppe Digilio
d2a4a55507 [CST-4633] fix issue with filter scope and configuration 2021-12-23 23:41:56 +01:00
Rezart Vata
12ab877ae4 [CST-4981] fixed and finished unit testing 2021-12-23 21:59:24 +01:00
Davide Negretti
0550cd55d1 [CST-5064] Show submitter in version history table 2021-12-23 20:12:25 +01:00
Giuseppe Digilio
bb64058f63 [CST-4506] fix test 2021-12-23 19:07:07 +01:00
Tim Donohue
13db7c8c19 Update docker-compose for runtime configs. Remove all config files & replace with env variables 2021-12-23 10:27:49 -06:00
Yura Bondarenko
fc059520a0 Fix LGTM issues 2021-12-23 17:09:44 +01:00
Yura Bondarenko
c1e8bbbeae 86016: Add typedocs 2021-12-23 16:55:48 +01:00
Yura Bondarenko
a2515c11e1 86016: Update log.interceptor.spec.ts 2021-12-23 16:55:48 +01:00
Yura Bondarenko
50d8719c41 Remove stray fdescribe 2021-12-23 16:55:48 +01:00
Yura Bondarenko
3c8c425843 86016: Add unit tests for correlationId reducer & service 2021-12-23 16:55:47 +01:00
Art Lowel
2fe5587e02 move the correlation id to the ngrx store 2021-12-23 16:55:46 +01:00
Giuseppe Digilio
db25e27bff [CST-4506] fix absolute paths 2021-12-23 16:31:59 +01:00
Corrado Lombardi
3452680b47 [CST-4875] removed comments, unused imports and variables 2021-12-23 09:11:00 +01:00
Tim Donohue
ba268d4f28 Merge pull request #1471 from wwelling/readme-corrections
Minor readme configuration corrections
2021-12-22 14:31:56 -06:00
William Welling
9646088931 minor readme configuration corrections 2021-12-22 14:29:37 -06:00
Tim Donohue
72aeeff5ca Merge pull request #1437 from wwelling/1422-deploy-time-config
Runtime configuration via YAML (Ensure UI config changes don't require a rebuild)
2021-12-22 14:18:10 -06:00
Rezart Vata
e594cabe4a [CST4981] finished task, working on unit testing 2021-12-22 18:01:37 +01:00
William Welling
f055d1676e add NODE_ENV development for yarn start:dev 2021-12-22 10:51:26 -06:00
William Welling
c43fdb9754 add missing break in switch 2021-12-22 10:50:06 -06:00
William Welling
3476fe3f0f remove browse by types from config example 2021-12-22 09:20:15 -06:00
William Welling
15fb55ccb5 Merge branch 'main' of github.com:DSpace/dspace-angular; branch '1422-deploy-time-config' of github.com:wwelling/dspace-angular into 1422-deploy-time-config 2021-12-22 09:18:14 -06:00
Tim Donohue
a34eb4682b Merge pull request #1468 from atmire/w2p-85993_browseby-from-rest
Use browse configuration from REST
2021-12-22 08:37:01 -06:00
Giuseppe Digilio
ebbae16fb3 Merge remote-tracking branch 'origin/main' into CST-4506_item_embargo 2021-12-22 15:28:58 +01:00
lotte
39e0f1a65b Added test and fixed lgtm errors 2021-12-22 07:58:13 +01:00
William Welling
f52dd92fbc Update config.server.ts 2021-12-21 23:57:38 -06:00
William Welling
e2c1319011 Update Configuration.md 2021-12-21 23:53:01 -06:00
Tim Donohue
1c63fb2b49 Merge pull request #1417 from 4Science/CST-4878
Upload files - Edit bitstream (improvements and bug fixes)
2021-12-21 14:33:22 -06:00
lotte
0e6c3a3a9d 85993: small changes and lint fixes 2021-12-21 16:48:31 +01:00
lotte
15dfa3cd82 85993: comcol/switcher/guard browse by changes + test updates 2021-12-21 15:38:50 +01:00
Davide Negretti
8f2ef71e3c [CST-5065] Fix 2021-12-21 13:53:17 +01:00
Rezart Vata
f04f4b4f34 [CST-4878] Finished working on embargo add part of form and unit testing 2021-12-21 13:35:29 +01:00
Davide Negretti
f46767be89 [CST-5065] Tests fixed 2021-12-21 13:06:16 +01:00
Davide Negretti
6a1bbc8afc [CST-5065] Admin is unable to reset other user password (function implementation) 2021-12-21 12:43:13 +01:00
Luca Giamminonni
21e78e33e5 [CST-5065] Admin is unable to reset other user password (cherry pick from DSC-215) 2021-12-21 11:50:55 +01:00
Davide Negretti
d246965cfb [CST-4879] TypeError fixed 2021-12-21 11:17:12 +01:00
William Welling
66555c9fc1 move NODE_ENV production to start:prod 2021-12-20 15:36:36 -06:00
William Welling
f9328da826 add theme head tags to example 2021-12-20 15:29:21 -06:00
William Welling
f75854b77b default to production 2021-12-20 15:29:04 -06:00
William Welling
d59e8becc3 specify NODE_ENV for production scripts 2021-12-20 15:28:19 -06:00
William Welling
f652490c1c Merge branch 'main' of github.com:DSpace/dspace-angular into 1422-deploy-time-config 2021-12-20 12:30:53 -06:00
William Welling
0fe6d4536c update readme 2021-12-20 12:22:52 -06:00
Tim Donohue
e86afacff1 Add e2e test notes 2021-12-20 12:17:50 -06:00
Tim Donohue
c43970ffd4 Merge pull request #1428 from atmire/w2p-85123_add-support-for-themeable-favicons
Add support for themeable favicons
2021-12-20 11:53:07 -06:00
Tim Donohue
1c2dcab82d Merge pull request #1459 from CICBA/fix-collection-load
Fix to collection selection window not loading successfully.
2021-12-20 11:15:13 -06:00
Giuseppe Digilio
c9b48ccb65 [CST-4633] fix tests 2021-12-19 17:36:03 +01:00
Tim Donohue
099582ee96 Merge pull request #1462 from tdonohue/e2e-retries
Tell Cypress to retry twice if an e2e test failure occurs
2021-12-17 13:30:01 -06:00
Giuseppe Digilio
f43317c2ee [CST-4633] fix build 2021-12-17 19:51:50 +01:00
Giuseppe Digilio
9722164705 [CST-4633] use search.component.ts for the mydspace page 2021-12-17 19:51:37 +01:00
Michael Spalti
b3808ba6a1 Minor update to setIIIFStatus method. 2021-12-17 10:38:35 -08:00
Tim Donohue
a818727ed7 Tell Cypress to retry twice if an e2e test failure occurs 2021-12-17 12:36:22 -06:00
Giuseppe Digilio
ef18308893 [CST-4633] Refactoring of search.component in order to have all functionality used during the different search components 2021-12-17 19:35:28 +01:00
Michael Spalti
4fbf99a451 Added change detection to assure the form updates. 2021-12-17 10:14:39 -08:00
Tim Donohue
7d88897afb Merge pull request #1458 from atmire/w2p-85862-handling-very-long-strings
Handling very long strings for metadata and file names
2021-12-17 10:05:45 -06:00
William Welling
4c46d9db2b refactor environment.prod.ts to environment.production.ts 2021-12-17 08:18:56 -06:00
Michael Spalti
e02bb75075 Unused import. 2021-12-16 16:14:02 -08:00
Michael Spalti
c1a0b21e2a Added additional conditions to check before adding iiif form elements. 2021-12-16 15:57:38 -08:00
Tim Donohue
982f7bcd17 Merge pull request #1457 from atmire/fix-legacy-links
Update legacy relative links to angular 11 format
2021-12-16 16:47:22 -06:00
Bruno Roemers
9f44cecdad 85123: Document head tags in environment.common.ts 2021-12-16 17:29:08 +01:00
lotte
0592e9a32d 85862: fixed test 2021-12-16 17:28:34 +01:00
Santiago Tettamanti
ff6cde76df Fix to collection selection window not loading successfully.
In collection dropdown component, moved the return statement that returned the collection list outside the condition that checks if it's the final page
2021-12-16 10:32:04 -03:00
lotte
c2b5ce191a 85862: Added .dont-break-out to truncatable part, item list titles and fixed breadcrumb overflow 2021-12-16 14:11:34 +01:00
lotte
e7f0921e6e 85862: Handling very long strings for metadata/files on item page, edit metadata/bitstreams page 2021-12-16 14:11:32 +01:00
Art Lowel
9801ae3414 update legacy relative links to angular 11 format 2021-12-16 10:56:29 +01:00
Giuseppe Digilio
b6ae15fbd2 [CST-4633] move search.component to search module and create search models folder 2021-12-16 10:00:08 +01:00
William Welling
21fcc9dde8 prefix dspace environment variables 2021-12-16 00:25:59 -06:00
Michael Spalti
c112a036df Clean up test. 2021-12-15 18:30:13 -08:00
Michael Spalti
b4b17136a6 Updated regex and condition for iiif.enabled metadata check. 2021-12-15 18:30:13 -08:00
Michael Spalti
fe5b7663e9 All edit component tests are running and passing 2021-12-15 18:30:12 -08:00
Michael Spalti
e521f2d579 Added tests for iiif form field content at startup 2021-12-15 18:30:12 -08:00
Michael Spalti
9ae38f4a6c Completed edit page and tests. 2021-12-15 18:30:12 -08:00
Michael Spalti
5865b83697 Added iiif form fields to the bitstream edit component. 2021-12-15 18:30:12 -08:00
Giuseppe Digilio
a4d91c37a7 [CST-4633] Create search.module and resolve dependencies issues 2021-12-15 22:38:08 +01:00
Tim Donohue
b8016d7fae Merge pull request #1448 from mspalti/update-mirador-deps
Updated Mirador dependencies.
2021-12-15 15:37:51 -06:00
Tim Donohue
7abdceb095 Merge pull request #1455 from tdonohue/fix_de_lang
German language syntax fix, add trailing quote
2021-12-15 15:04:27 -06:00
Tim Donohue
32ae686e36 Syntax fix, add trailing quote 2021-12-15 14:24:23 -06:00
Art Lowel
7529fcde35 remove fdescribe 2021-12-15 16:46:40 +01:00
lotte
b7d01127a5 Removed unnecessary import 2021-12-15 16:21:55 +01:00
lotte
dd69bc65ab Fixes to tests 2021-12-15 16:21:09 +01:00
lotte
a1578303fa 85993: Browse by from rest for menu and comcol page browse by 2021-12-15 16:15:06 +01:00
lotte
6594a3877f fixed lint/lgtm issues 2021-12-15 15:13:27 +01:00
Giuseppe Digilio
b4693b9bc4 Merge remote-tracking branch 'origin/main' into CST-4633-search-refactoring 2021-12-15 15:09:06 +01:00
Giuseppe Digilio
8f4379f3b4 Merge remote-tracking branch 'origin/main' into DSC-287-Show-an-error-page-if-the-REST-API-is-not-available
# Conflicts:
#	src/app/app-routing.module.ts
2021-12-15 15:00:47 +01:00
lotte
2f022f505d 85979: tests for canChangePassword UI changes 2021-12-15 14:41:10 +01:00
lotte
71e40fdb6e 85979: only show security tab on profile page when canChangePassword FeatureID is true 2021-12-15 14:04:38 +01:00
William Welling
b820794790 comment env-to-yaml script 2021-12-14 18:11:37 -06:00
William Welling
c7321f9a22 update script comment 2021-12-14 18:02:27 -06:00
William Welling
0afa7c5bab update readme examples to yaml 2021-12-14 18:01:34 -06:00
Tim Donohue
4ace07156f Merge pull request #1452 from tdonohue/minor_cleanup
Remove second unnecessary "relativeLinkResolution: 'legacy'" setting after Angular 11 upgrade
2021-12-14 10:52:02 -06:00
Tim Donohue
d407397775 Merge pull request #1419 from 4Science/CST-4882
[CST-4882] The search loads indefinitely if the written query is invalid
2021-12-14 10:39:01 -06:00
Tim Donohue
df46bcd16f Merge pull request #1449 from tdonohue/update_docker_deps
Update Docker to use latest Solr 8
2021-12-14 09:47:22 -06:00
William Welling
bbb8d708b9 Merge branch 'main' of github.com:wwelling/dspace-angular into 1422-deploy-time-config 2021-12-14 09:45:27 -06:00
Tim Donohue
f672e12433 Remove unnecessary relativeLinkResolution: 'legacy' 2021-12-14 09:40:00 -06:00
Tim Donohue
3e11162d0e Merge pull request #1451 from 4Science/CST-5033-submission-ssr-issue
Fix SSR issue with submission after migrate to angular 11
2021-12-14 09:29:17 -06:00
Giuseppe Digilio
d426f5f179 [DSC-287] fix test 2021-12-14 15:47:30 +01:00
Giuseppe Digilio
a952438247 [CST-5033] fix comments 2021-12-14 15:44:43 +01:00
Giuseppe Digilio
662f846caa [CST-5033] fix issue with cherry-pick 2021-12-14 15:37:44 +01:00
Giuseppe Digilio
7d0b9ec8a2 Merge remote-tracking branch 'origin/main' into CST-4633-search-refactoring 2021-12-14 15:32:05 +01:00
Giuseppe Digilio
34b73cc4f7 [DSC-370] Fix SSR issue with submission after migrate to angular 11 2021-12-14 15:26:23 +01:00
Giuseppe Digilio
44fc86c9fe [DSC-287] use CanActivateChild in order to check every time the rest server availability 2021-12-14 15:22:55 +01:00
Giuseppe Digilio
ddcb1ecdf2 [DSC-287] invalidate root endpoint cache when redirected to 500 page in order to check every time the rest server availability 2021-12-14 12:42:24 +01:00
Giuseppe Digilio
b6904a4df9 [DSC-287] add link button to home page 2021-12-14 12:40:51 +01:00
Tim Donohue
13cfd71686 Update Docker to use latest Solr 8 2021-12-13 16:41:34 -06:00
Michael Spalti
b1c3967a5b Added lockfile. 2021-12-13 11:32:37 -08:00
Michael Spalti
5acc29e498 Updated Mirador dependencies. 2021-12-13 11:08:10 -08:00
Nathan Buckingham
e2614b9dad w2p-85847 Add Authority to browse indexes 2021-12-13 13:48:09 -05:00
Davide Negretti
4c27a11747 [CST-4882] Tests improved 2021-12-11 01:59:38 +01:00
Davide Negretti
64231683b3 [CST-4882] Error 422 is now handled in home page too 2021-12-10 18:28:30 +01:00
Kristof De Langhe
549529c889 85262: Get submission object instead of sending empty patch + revert empty patch code 2021-12-10 14:18:51 +01:00
Rezart Vata
31fd89a9fc [CST-4878] Created component 2021-12-09 18:22:35 +01:00
Giuseppe Digilio
d3b5e09e2a [DSC-287] remove unused imports 2021-12-09 17:48:59 +01:00
Giuseppe Digilio
9be1733bc8 Merge remote-tracking branch 'origin/main' into DSC-287-Show-an-error-page-if-the-REST-API-is-not-available
# Conflicts:
#	src/app/app-routing.module.ts
2021-12-09 15:23:16 +01:00
Rezart Vata
a3892dc7e7 [CST-4875] Fixed response handling 2021-12-09 15:19:20 +01:00
Rezart Vata
01b200279b [CST-4875] improvements 2021-12-09 12:46:50 +01:00
Rezart Vata
f74716a459 [CST-4875] Created feedback route, created feedback form, created service & guard, utilzed when user is logged in, unit testing and lint check 2021-12-09 12:33:53 +01:00
Davide Negretti
b64b7c2607 [CST-4882] Error fixed - Tests improved 2021-12-09 12:17:20 +01:00
William Welling
2bf880b216 correct typo in comment 2021-12-08 19:31:05 -06:00
Tim Donohue
efe51aa340 Merge pull request #1442 from tdonohue/cleanup_license
Cleanup our LICENSE file so GitHub can detect our BSD license
2021-12-08 16:58:24 -06:00
Tim Donohue
ed806dc3bf Minor license formatting cleanup to allow GitHub to recognize our BSD 3-Clause License. Copy over NOTICE file from DSpace/DSpace 2021-12-08 16:55:38 -06:00
Tim Donohue
5b1c9286ed Merge pull request #1441 from tdonohue/disable_docker_action_on_forks
Disable Docker image build action on forked repos & on non-maintenance branches
2021-12-08 15:54:46 -06:00
Tim Donohue
a6eeceeb67 Ensure Docker GitHub action only runs for maintenance branches, official tags. Never run for forked repos 2021-12-08 15:08:44 -06:00
William Welling
10622008c4 refactor config filename and convert to yaml 2021-12-08 14:56:52 -06:00
Tim Donohue
d955fe7ca3 Merge pull request #1440 from tdonohue/docker_github_action
Add GitHub action to build Docker images and push to DockerHub
2021-12-08 10:22:04 -06:00
Tim Donohue
35584d44aa Minor cleanup. Disable 'latest' tag in Docker. 2021-12-08 09:42:48 -06:00
Tim Donohue
86c2f389d5 Create a Docker GitHub action to autobuild on each commit. Update Dockerfile and docker-compose.yml to support. 2021-12-08 09:10:43 -06:00
William Welling
bc999d0b5f minor refactoring and more config util assertions 2021-12-07 21:33:43 -06:00
Tim Donohue
0dba48be13 Update to latest version of all GitHub actions 2021-12-07 16:50:43 -06:00
William Welling
18dd2ad884 add simple config util test 2021-12-07 14:45:46 -06:00
William Welling
46bb3e109c cleanup and readme updates 2021-12-07 12:15:58 -06:00
William Welling
33488ccf40 extend environment and use injected app config 2021-12-07 10:12:27 -06:00
Tim Donohue
eb9d72ad72 Merge pull request #1425 from atmire/w2p-85192_pr-bugfix-specify-view-mode-in-ds-browse-by
BUGFIX: Load themed browse entry components
2021-12-06 14:14:10 -06:00
William Welling
71f5b46639 use standard environments 2021-12-06 12:25:37 -06:00
William Welling
c1555326fa build app config 2021-12-03 21:17:36 -06:00
Tim Donohue
46d340a5ce Merge pull request #1424 from ybnd/Fix-modal-open-issues
Fix minor modal UX issues
2021-12-03 14:20:04 -06:00
Nathan Buckingham
768de1a1e7 w2p-85346 Allow facets to be authority controlled and add test to verify 2021-12-03 11:49:39 -05:00
Tim Donohue
77f9b27fcf Merge pull request #1403 from tdonohue/angular_11
Upgrade to Angular 11
2021-12-03 09:34:47 -06:00
Giuseppe Digilio
11ecfd370c Merge remote-tracking branch 'origin/main' into DSC-287-Show-an-error-page-if-the-REST-API-is-not-available 2021-12-03 14:35:11 +01:00
Tim Donohue
ad5a76aedc Remove "relativeLinkResoluton: legacy" and use default instead 2021-12-02 10:36:06 -06:00
Bruno Roemers
03fd57e426 85194: Fix favicon switching in production mode 2021-12-02 14:25:16 +01:00
Bruno Roemers
47ed6bedb4 85123: BUGFIX: Use this.document instead of document
Typo caused ReferenceError in SSR
2021-12-02 12:47:38 +01:00
Kristof De Langhe
ed2c774d86 85262: Allow empty patch requests 2021-12-02 12:39:07 +01:00
Rezart Vata
b7b949b415 Merge branch 'DSC-287-Show-an-error-page-if-the-REST-API-is-not-available' of https://bitbucket.org/4Science/dspace-angular into DSC-287-Show-an-error-page-if-the-REST-API-is-not-available 2021-12-01 18:51:01 +01:00
Rezart Vata
c8de6ccb4c [DSC-287] Fixed for yarn start error 500 loading 2021-12-01 18:50:42 +01:00
Bruno Roemers
e99086c228 Fix bad merge 2021-12-01 17:16:21 +01:00
bruno-atmire
ddccae60b5 Merge branch 'main' into w2p-85192_pr-bugfix-specify-view-mode-in-ds-browse-by 2021-12-01 16:19:21 +01:00
Bruno Roemers
dcb80b7c9c 85192: Write test for themed browse entries 2021-12-01 15:56:49 +01:00
Bruno Roemers
ab3d53c19f 85192: BUGFIX: Ensure themed browse entries are picked up 2021-11-30 20:10:28 +01:00
Yura Bondarenko
8d8b24f00a Fix scrolling background when auto-focusing in modal 2021-11-30 15:51:52 +01:00
Yura
dbbb19e37f Fix modal backdrop animation 2021-11-30 15:51:41 +01:00
Kristof De Langhe
99af22b621 85262: Re-disable deposit button during save/deposit 2021-11-30 13:44:08 +01:00
Kristof De Langhe
5e17a4e958 85262: Always enable deposit button 2021-11-30 13:27:16 +01:00
Davide Negretti
7a567a47b9 [CST-4882] Show error message if the search query fails - Handle error 422 (invalid query) separately 2021-11-26 11:20:35 +01:00
Giuseppe Digilio
6df1ee64f2 [DSC-184] Fix issue with mydpsace page that hangs forever on error response 2021-11-25 11:22:15 +01:00
Davide Negretti
7218c450e6 [CST-4884] Code cleanup and test improvement 2021-11-24 23:39:59 +01:00
Davide Negretti
27bce0e5bb [CST-4879] After changing options in access-conditions.xml, "grant access" fields are displayed incorrectly 2021-11-24 20:17:16 +01:00
Davide Negretti
6752acbf12 [CST-4884] Test 2021-11-24 20:00:21 +01:00
Bruno Roemers
787358d1b0 85123: Fix tests - 3 2021-11-24 16:09:01 +01:00
Bruno Roemers
b6dc7af13e 85123: Fix tests #2 2021-11-24 15:13:50 +01:00
Bruno Roemers
7c23e2ef82 85123: Fix tests 2021-11-24 14:44:38 +01:00
Davide Negretti
5e8813f5b6 [CST-4884] Bitstream edit form moved inside modal (test WIP) 2021-11-24 13:12:01 +01:00
Bruno Roemers
893a306da0 85123: Fallback to favicon of default theme and src/assets/images/favicon.ico 2021-11-24 12:23:19 +01:00
Bruno Roemers
99a2cf926a 85123: WIP: Support for theme-specific head tags 2021-11-24 10:54:59 +01:00
Tim Donohue
75c0bf7b61 Merge pull request #1413 from 4Science/CST-4918
[CST-4918] Process status remains Running in detail page
2021-11-23 14:32:42 -06:00
Tim Donohue
55216ad5ed Merge pull request #1408 from 4Science/CST-4903
[CST-4903] The start time and end time of the export process are different
2021-11-23 14:15:49 -06:00
Bruno Roemers
a5a91d5139 85123: Add new favicon files 2021-11-23 19:27:33 +01:00
Bruno Roemers
ffff337aba 85123: Remove favicon 2021-11-23 16:43:53 +01:00
Davide Negretti
31442f36a3 [CST-4884] Bitstream edit form moved inside modal (test WIP) 2021-11-22 19:11:58 +01:00
Tim Donohue
597e5396f9 Update ngx-sortablejs to latest version 2021-11-22 11:30:25 -06:00
Tim Donohue
d2cc184763 Fix broken tests by fixing imports and providers 2021-11-22 11:27:10 -06:00
Tim Donohue
466aaaa0d5 Tell Visual Studio Code to use version of Typescript in project 2021-11-22 11:26:58 -06:00
Tim Donohue
d926a24088 Autoupdate to @ng-dynamic-forms/core@13 and @ng-dynamic-forms/ui-ng-bootstrap@13 2021-11-22 11:26:27 -06:00
Tim Donohue
10c342483a Required migration from old ngbTabSet to new ngbNav after ng-bootstrap update 2021-11-22 11:23:40 -06:00
Tim Donohue
ab3fa88913 Automated upgrade to @ng-bootstrap/ng-bootstrap@9 2021-11-22 11:22:13 -06:00
Davide Negretti
624f39df1e [CST-4884] Bitstream edit form moved inside modal (test TBD) 2021-11-22 18:20:41 +01:00
Tim Donohue
be289617e1 Automated upgrade to ng-mocks@11 2021-11-22 11:15:41 -06:00
Tim Donohue
2d633d79dc Automated upgrade to @nguniversal/express-engine@11 2021-11-22 11:13:04 -06:00
Tim Donohue
8fedb2c177 Automated upgrade to @ngrx/store@11 2021-11-22 11:10:35 -06:00
Tim Donohue
0d031d0b25 Automated upgrade to @angular/cdk@11 2021-11-22 11:07:53 -06:00
Tim Donohue
9f1a017b56 Automated upgrade to Angular 11.0 2021-11-22 11:01:54 -06:00
Tim Donohue
890731e3e2 Merge pull request #1412 from wwelling/1410-prod-build
[Issue 1410] Production build
2021-11-22 09:57:26 -06:00
Davide Negretti
5df2f6f8d5 [CST-4947] File description on bitstream can now be deleted 2021-11-22 11:16:17 +01:00
Davide Negretti
cefb73c11e Merge remote-tracking branch 'gh/CST-4878' into CST-4878 2021-11-22 10:56:44 +01:00
Davide Negretti
2579577225 [CST-4947] Test WIP 2021-11-22 10:56:27 +01:00
Tim Donohue
23586810b3 Merge pull request #1406 from 4Science/CSTPER-869_group_creation_validation
group creation validator
2021-11-19 14:51:57 -06:00
Davide Negretti
9363b0fb35 [CST-4947] File description on bitstream can now be deleted (test TBD) 2021-11-19 19:58:07 +01:00
Davide Negretti
df957fc31b [CST-4878] Remove start and end date when embargo policy is changed to 'open access' 2021-11-19 16:22:52 +01:00
William Welling
49a3a9a0f2 remove docker changes 2021-11-19 09:00:38 -06:00
Tim Donohue
8ce6a043bb Merge pull request #1411 from tdonohue/fix_1409
Add a config:dev:check:rest option for checking dev environment settings
2021-11-18 10:51:26 -06:00
Tim Donohue
3befdb9f48 Merge pull request #1400 from tdonohue/disable_cli_analytics
Disable CLI analytics by default
2021-11-18 10:29:10 -06:00
William Welling
f7bea3eaa9 update rxjs imports 2021-11-18 09:09:00 -06:00
William Welling
d049caa8c0 remove webpack node externals 2021-11-18 05:03:02 -06:00
William Welling
0b99ce3211 update uuid import in specs 2021-11-17 22:29:14 -06:00
William Welling
b0ee227918 update dockerfile 2021-11-17 22:26:21 -06:00
William Welling
8d66f68dfa remove bundle workaround, update dependencies and build 2021-11-17 22:11:06 -06:00
William Welling
600fbc6df7 update json5 import 2021-11-17 21:59:34 -06:00
William Welling
ebf900686b update uuid imports 2021-11-17 21:58:47 -06:00
William Welling
dc9e93a907 upgrade rxjs imports 2021-11-17 21:57:54 -06:00
Tim Donohue
4ed748381a Add a config:dev:check:rest option for checking dev environment settings 2021-11-17 11:36:38 -06:00
Davide Negretti
08b1025eb3 [CST-4903] Fix 2021-11-17 10:46:36 +01:00
Giuseppe Digilio
92e9f79f09 [DSC-287] optimize code and add typedoc 2021-11-17 09:37:49 +01:00
Corrado Lombardi
f9c8ac6568 [CSTPER-869] removed unused elements 2021-11-16 22:28:43 +01:00
Giuseppe Digilio
a323aefc22 [DSC-287] change app-routing.module.ts inn order to have ServerCheckGuard configured once 2021-11-16 19:13:57 +01:00
Rezart Vata
ce7a5b1499 [CSTPER-869] Fix on edit remove validator, unit testing , lint fixes & report 2021-11-16 18:14:53 +01:00
Rezart Vata
9aea3e0bbf [CSTPER-869] validator to check if a group already exists 2021-11-16 18:08:06 +01:00
Giuseppe Digilio
76ddce7239 [DSC-287] fix test 2021-11-16 17:38:20 +01:00
Davide Negretti
8e0fd14b4e [CST-4918] process-page.resolver.ts - don't use cached version 2021-11-16 17:33:11 +01:00
Davide Negretti
d3c3624816 [CST-4903] Test fixed 2021-11-16 12:53:51 +01:00
Davide Negretti
7d5493fcf4 [CST-4903] Button style fixed 2021-11-16 11:58:10 +01:00
Davide Negretti
cb88885870 [CST-4903] Timezone fixed in process detail page 2021-11-15 19:29:39 +01:00
Giuseppe Digilio
81c4403ee6 [DSC-287] reformat app-routing.module code 2021-11-15 19:02:10 +01:00
Giuseppe Digilio
25a51c9764 [DSC-287] Add test to guard 2021-11-15 18:52:33 +01:00
Giuseppe Digilio
2151d1af58 [DSC-287] Fix error message 2021-11-15 18:49:13 +01:00
Giuseppe Digilio
826875e207 Merge remote-tracking branch 'origin/main' into DSC-287-Show-an-error-page-if-the-REST-API-is-not-available 2021-11-15 17:02:50 +01:00
Tim Donohue
29f342380d Merge pull request #1401 from tdonohue/fixup_docker
Sync with DSpace/DSpace docker-compose setup
2021-11-12 08:20:37 -06:00
Tim Donohue
2503b39897 Sync with DSpace/DSpace docker-compose setup 2021-11-11 16:25:19 -06:00
Tim Donohue
d5c841253c Merge pull request #1397 from 4Science/CST-4873-request-copy-bug
Fix issue with request a copy functionality route
2021-11-11 16:11:17 -06:00
Tim Donohue
1e2f51ef3e Disable CLI analytics by default 2021-11-11 15:46:39 -06:00
Tim Donohue
9b2e533038 Merge pull request #1398 from atmire/fix-menu-icon-i18n-messages
Fix menu icon i18n messages
2021-11-11 15:42:02 -06:00
Art Lowel
dd6ec04801 Fix menu icon i18n messages 2021-11-10 11:47:39 +01:00
Giuseppe Digilio
9ea67b1b36 [CST-4873] Fix issue with request a copy functionality route 2021-11-10 09:37:11 +01:00
Rezart Vata
04548237fd [DSC-287] Fixes UI and changed the texts in i18n 2021-11-04 14:50:26 +01:00
Rezart Vata
fc6678515a [DSC-287] Created new page error 500, added guard to check for initial api request, redirect to page 500 2021-11-04 14:21:12 +01:00
Tim Donohue
2fe9fbd584 Merge pull request #1376 from atmire/remove-authorization-mocks
remove authorization mocks left over from PR #1105
2021-10-26 11:34:29 -05:00
Art Lowel
26a3ea4178 remove authorization mocks left over from PR #1105 2021-10-26 17:27:39 +02:00
Tim Donohue
30b9eae872 Merge pull request #1375 from 4Science/CST-4767
[CST-4767] Password are not properly url encoded at login
2021-10-26 08:41:20 -05:00
Davide Negretti
035a7826ba [CST-4767] encode-decode.util.ts removed 2021-10-26 11:11:21 +02:00
Tim Donohue
e8bebea543 Merge pull request #1368 from tdonohue/initial_rest_test_script
Add script to test connection to REST API (yarn config:check:rest)
2021-10-25 12:13:15 -05:00
Tim Donohue
f926b53848 Merge pull request #1374 from the-library-code/german-message-keys
Contribution to the German translation of DSpace 7
2021-10-25 11:44:34 -05:00
Davide Negretti
6ff065cd27 [CST-4767] Password are not properly url encoded at login 2021-10-25 18:34:28 +02:00
Tim Donohue
d0e4055bf0 Address feedback 2021-10-25 11:27:33 -05:00
Pascal-Nicolas Becker
b12bc4adc6 Small additional changes to the German message catalog 2021-10-25 18:13:38 +02:00
Tim Donohue
45933ba3d0 Add initial yarn test:rest-api script 2021-10-25 10:38:08 -05:00
Tim Donohue
3065720817 Merge pull request #1329 from 4Science/CST-4504-Adding-new-relationships-in-edit-item-is-difficult-for-entities-with-many-relationships
Fix issue with new relationships for entities with many relationships
2021-10-25 10:09:16 -05:00
YPaulsen-TLC
f58e0cd0c4 Contribution to the German translation of DSpace 7 2021-10-25 16:59:42 +02:00
Tim Donohue
043decf7e4 Merge pull request #1079 from mspalti/iiif-mirador
Angular support for IIIF and Mirador
2021-10-22 12:17:42 -05:00
Giuseppe Digilio
9382b16171 Merge remote-tracking branch 'origin/main' into CST-4504-Adding-new-relationships-in-edit-item-is-difficult-for-entities-with-many-relationships
# Conflicts:
#	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts
2021-10-21 17:20:04 +02:00
Rezart Vata
fe1c3417c7 [CST-4504] Bug fixing 2021-10-21 17:09:11 +02:00
Tim Donohue
936c5cabd3 Merge pull request #1332 from 4Science/CST-4510-entity-selection-porting
Assign an entity type to a collection and map external providers
2021-10-21 10:05:52 -05:00
Giuseppe Digilio
d1f16cdee3 Merge remote-tracking branch 'origin/main' into CST-4510-entity-selection-porting
# Conflicts:
#	src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.ts
2021-10-21 15:23:02 +02:00
Michael W Spalti
2c60cc4ca2 Updated versioned-item to provide route service in super constructor call. 2021-10-20 15:09:32 -07:00
Tim Donohue
07f20b1ad7 Merge pull request #1366 from atmire/w2p-84385_tabbed-view-breaks-on-tab-change
84385: Tabbed search view breaks if switch away/back between tabs
2021-10-20 17:09:31 -05:00
Tim Donohue
551404c08f Merge pull request #1363 from atmire/Search-results-LinkType-fix
linkType search-results bug fix
2021-10-20 16:31:34 -05:00
Michael W Spalti
2b19b1659c Merge branch 'main' into iiif-mirador 2021-10-20 14:24:59 -07:00
Tim Donohue
2568daedb4 Merge pull request #1318 from 4Science/CST-4499
Create new Item Version (basic Items only)
2021-10-20 11:17:57 -05:00
Marie Verdonck
cf0a526187 84385: Tabbed search view breaks if switch away/back between tabs 2021-10-20 16:50:02 +02:00
Davide Negretti
fd61ac0c41 [CST-4499] Version history - Test item-versions.component 2021-10-20 02:29:00 +02:00
Davide Negretti
3b0e1dbcc4 [CST-4499] Version history - Test item-versions.component 2021-10-20 02:28:02 +02:00
Tim Donohue
2650e1eb36 Merge pull request #1362 from atmire/issue-1294-fix-required-dropdown-initial-click-not-working
#1294 [Submission] - Fix for required dropdown initial select click not working
2021-10-19 16:37:33 -05:00
Davide Negretti
52baa819cf [CST-4499] Version history - Test versioned-item.component 2021-10-19 21:12:34 +02:00
Tim Donohue
238b47b2f9 Merge pull request #1364 from atmire/search-scope-small-fixes
Fixes to scope select in search
2021-10-19 14:12:12 -05:00
Davide Negretti
d12f932351 [CST-4499] Version history - Test version-history-data.service 2021-10-19 19:16:39 +02:00
Davide Negretti
75fffe2f15 [CST-4499] Version history - Test version-history-data.service 2021-10-19 17:54:11 +02:00
Davide Negretti
82f6a78511 Merge branch 'main' into CST-4499
# Conflicts:
#	src/app/item-page/item-page-routing.module.ts
2021-10-19 16:58:39 +02:00
Davide Negretti
3cc302bc42 [CST-4499] Version history - Test version-history-data.service 2021-10-19 16:49:13 +02:00
lotte
a4c957b8ef changed scope with to css variable and removed the search label alignment 2021-10-19 16:19:07 +02:00
Davide Negretti
6dac82989b Merge branch 'main' of github.com:4science/dspace-angular into CST-4499 2021-10-19 16:18:12 +02:00
Tim Donohue
a8900f7278 Merge pull request #1327 from atmire/w2p-83635_Request-a-copy
Request a copy
2021-10-19 09:09:45 -05:00
Kristof De Langhe
d7a5502d30 linkType search results bugfix 2021-10-19 16:03:38 +02:00
Giuseppe Digilio
9a30b8a9ae [CST-4504] fix issue with name variants 2021-10-19 15:16:10 +02:00
Marie Verdonck
0557750987 #1294 [Submission] - Fix for required dropdowns initial select click not working 2021-10-19 15:13:51 +02:00
Rezart Vata
5f05c1d7c0 [CST-4504] lint fixes 2021-10-19 14:12:59 +02:00
Rezart Vata
78403d9696 [CST-4504] Fixed discard issue and submit issue 2021-10-19 14:04:39 +02:00
Davide Negretti
376d803b96 [CST-4499] Version history - Test item-data.service and item-versions-shared.service 2021-10-19 13:34:58 +02:00
Kristof De Langhe
898548d399 Merge branch 'main' into w2p-83635_Request-a-copy 2021-10-19 10:04:24 +02:00
Giuseppe Digilio
e142a49479 [CST-4499] Add tests to version-data.service 2021-10-18 20:15:20 +02:00
Michael W Spalti
b0fcdf628f Updated test. 2021-10-18 11:15:06 -07:00
Michael W Spalti
8ac122b151 Updated viewport size check.
Updated test.

Mobile test added.

Fixed lint error.
2021-10-18 11:15:01 -07:00
Giuseppe Digilio
8f541c37a7 [CST-4499] Add tests to workspaceitem-data.service and workflowitem-data.service 2021-10-18 19:04:16 +02:00
Tim Donohue
03d9996dcc Merge pull request #1346 from 4Science/CST-4659
[Deque Re-Analysis] Submission "critical" accessibility issues
2021-10-18 11:01:21 -05:00
Michael W Spalti
a3511ab234 Merge branch 'iiif-mirador' of https://github.com/mspalti/dspace-angular into iiif-mirador 2021-10-18 08:54:07 -07:00
Davide Negretti
bee628921a [CST-4499] Version history - Test 2021-10-18 17:37:02 +02:00
Tim Donohue
7cc5bd0280 Merge pull request #1360 from tdonohue/enable_spanish
Add 'es' to languages. Order alphabetically by label
2021-10-18 09:54:28 -05:00
Kristof De Langhe
492a31dd10 83635: Remove f from fdescribe 2021-10-18 16:43:13 +02:00
Kristof De Langhe
0f7fc4907a Merge branch 'main' into w2p-83635_Request-a-copy 2021-10-18 16:01:19 +02:00
Davide Negretti
7c40c3ba68 [CST-4499] Version history - Pagination fixed 2021-10-18 13:20:03 +02:00
Davide Negretti
d264576a07 [CST-4659] Deque accessibility issues - fix 470001 2021-10-18 10:40:02 +02:00
Michael Spalti
6a2d856ecf Removed unused import. 2021-10-16 16:28:56 -07:00
Michael Spalti
073296eb07 Mirador component update and spec. 2021-10-16 14:28:34 -07:00
Tim Donohue
f4cdd6a9ab Merge pull request #1314 from tdonohue/add_a11y_tests
Add automated Accessibility testing for all public pages
2021-10-15 16:36:45 -05:00
Tim Donohue
8a1ff1ef70 Update to latest Cypress 2021-10-15 16:03:43 -05:00
Tim Donohue
305571bc25 Add accessibility tests for search/browse 2021-10-15 15:43:01 -05:00
Tim Donohue
4faa850fba Add logging for violations & testA11y() in utils.ts. Use that method everywhere else 2021-10-15 15:41:33 -05:00
Tim Donohue
fad74a4ca2 Upgrade Cypress 2021-10-15 15:41:33 -05:00
Tim Donohue
3c35c6c8ae Add basic accessibility scan for most public pages. Disable any a11y tests with known issues 2021-10-15 15:41:32 -05:00
Davide Negretti
dfeee7894a Merge branch 'main' into CST-4499
# Conflicts:
#	src/app/item-page/item-page.module.ts
#	src/app/shared/shared.module.ts
2021-10-15 22:35:27 +02:00
Tim Donohue
c3dbe00f0b Add 'es' to languages. Order alphabetically by label 2021-10-15 15:34:47 -05:00
Tim Donohue
ee70baafd9 Merge pull request #1351 from gsferreyro/spanish-translation
Complete Spanish translation
2021-10-15 15:24:10 -05:00
Tim Donohue
66b55bf910 Merge pull request #1336 from 4Science/CST-4634-Many-notifications-when-trying-to-create-an-eperson-with-already-existing-email
Added custom validator and mail check during eperson registration
2021-10-15 12:22:14 -05:00
Davide Negretti
e4d468b17c [CST-4499] Version history - Changes to version history table 2021-10-15 19:13:15 +02:00
Giuseppe Digilio
7b24e3bc8e [CST-4510] Fix issue with multiple selection in the collection-dropdown.component 2021-10-15 19:04:14 +02:00
Giuseppe Digilio
096a1d8427 [CST-4510] Close collection modal once entity is imported 2021-10-15 17:34:04 +02:00
Giuseppe Digilio
ded8a415cf Merge remote-tracking branch 'origin/main' into CST-4510-entity-selection-porting
# Conflicts:
#	src/assets/i18n/en.json5
2021-10-15 17:04:34 +02:00
Tim Donohue
d778f98b0d Merge pull request #1348 from atmire/search-scope-lookup
Replace search scope dropdown by modal
2021-10-15 09:52:37 -05:00
Giuseppe Digilio
05b288c8d0 [CST-4504] Fix LGTM issues 2021-10-15 14:58:34 +02:00
Davide Negretti
850970e204 [CST-4499] Version history - Code refactoring (WIP) and "Edit workspace item" button 2021-10-15 13:05:24 +02:00
Giuseppe Digilio
4d277991ef [CST-4510] Address feedback 2021-10-15 10:25:30 +02:00
Michael Spalti
80a9770936 More neutral primary color in mirador viewer configuration. 2021-10-14 16:13:36 -07:00
Michael Spalti
24a6a4c25a Checking for dev mode to prevent viewer embed. 2021-10-14 15:57:46 -07:00
Michael Spalti
3a1abe82a1 Removed unused import. 2021-10-14 09:29:02 -07:00
Michael Spalti
8c05c6d4df Merge branch 'main' into iiif-mirador 2021-10-14 08:38:13 -07:00
Tim Donohue
802a212b9b Merge pull request #1355 from the-library-code/PRs/dspace-angular/1354
Make 'FileSectionComponent' themeable
2021-10-14 10:17:17 -05:00
Giuseppe Digilio
bd02bcd0de [CST-4634] Remove impersonate button from eperson creation form 2021-10-14 16:02:20 +02:00
Rezart Vata
4c72fa7da1 [CST-4504] Fixes regarding code improvement & save spinner only 2021-10-14 15:55:20 +02:00
Kristof De Langhe
13dd4dfc05 83635: Remove fdescribe and unused imports 2021-10-14 15:48:50 +02:00
Kristof De Langhe
478c95f6d4 83635: Item request - processed message 2021-10-14 15:45:05 +02:00
Giuseppe Digilio
d08807544f [CST-4510] Fix LGTM issue 2021-10-14 15:44:59 +02:00
Giuseppe Digilio
f20776fb8f [CST-4510] Remove unused label 2021-10-14 15:44:42 +02:00
Rezart Vata
05261a91ea [CST-4504] Fixed multiple delete & multiple add in modal and changed unit testing 2021-10-14 13:06:55 +02:00
Kristof De Langhe
a745468b0c 83635: Keep bitstream param on link 2021-10-14 11:25:03 +02:00
Michael Spalti
b738065d88 Updated service mock for tests. 2021-10-13 17:58:34 -07:00
Giuseppe Digilio
9c47583a0a [CST-4634] Change email validator in order to show error also on focus 2021-10-13 23:13:39 +02:00
Tim Donohue
6356979994 Merge pull request #1323 from 4Science/DSC-227-myDspaceReloadIssue
Reload of My Dspace results is broken
2021-10-13 14:31:45 -05:00
Giuseppe Digilio
0fccf4c16a Merge remote-tracking branch 'origin/main' into CST-4510-entity-selection-porting
# Conflicts:
#	src/app/core/data/collection-data.service.ts
2021-10-13 19:24:25 +02:00
Vasilii Fedorov
7505a5a208 Make 'FileSectionComponent' themeable 2021-10-13 15:41:32 +02:00
Giuseppe Digilio
36be741eb3 [CST-4510] Remove check for entity type param in the import from external source page 2021-10-13 09:25:23 +02:00
Giuseppe Digilio
363e9b2dcb [CST-4510] Fix i18n labels 2021-10-13 09:25:09 +02:00
Giuseppe Digilio
b4a249245a [CST-4510] make entity type not mandatory in the collection form 2021-10-13 09:24:57 +02:00
Tim Donohue
ab9aed0143 Merge pull request #1328 from atmire/w2p-83707_Control-collection-harvest-from-the-UI
Control collection harvest from the UI
2021-10-12 16:18:34 -05:00
Michael W Spalti
a875f681a7 Merge branch 'iiif-mirador' of https://github.com/mspalti/dspace-angular into iiif-mirador 2021-10-12 14:00:27 -07:00
Michael Spalti
538e3cbd0f Mirador component update. 2021-10-12 07:56:23 -07:00
Giuseppe Digilio
93e0828135 [CST-4591] Hide none item type entry from available entities in the collection form 2021-10-12 16:23:47 +02:00
Yana De Pauw
72d1235b2c 83707: Add spinners to in progress buttons 2021-10-12 09:50:56 +02:00
Michael Spalti
2d1113626a Viewer updates. 2021-10-11 17:50:15 -07:00
Gustavo S. Ferreyro
82b88c85c2 Full Spanish translation
Full Spanish translation based on the English en.json5 file at 09 Oct, 2021.
2021-10-09 13:40:53 -03:00
Michael Spalti
681b10e070 Removed unused import. 2021-10-08 15:53:02 -07:00
Michael Spalti
baa94ca1cb Fixed proble with mirador iframe url for a single image. 2021-10-08 15:29:51 -07:00
Tim Donohue
bc89692acb Merge pull request #1344 from ybnd/Pause-notification-countdown-on-hover
Pause notification countdown on hover
2021-10-08 14:33:45 -05:00
lotte
b651f4e18f lgtm fixes 2021-10-08 14:37:57 +02:00
lotte
13bce1df60 Added missing typedoc 2021-10-08 14:08:04 +02:00
lotte
c28221623c Added search scope lookup to replace dropdown 2021-10-08 10:22:43 +02:00
Tim Donohue
a48074e5f1 Merge pull request #1341 from atmire/w2p-83783_show-all-collections-on-item-page-rebased
Show owning and mapped collections on item page
2021-10-07 11:38:33 -05:00
Tim Donohue
46c3ea2a7c Merge pull request #1326 from atmire/dynamic-theme-fixes
Dynamic theme improvements
2021-10-07 11:38:04 -05:00
Yura
1cc1674254 Add unit tests for notification countdown 2021-10-07 15:23:54 +02:00
Yura
26cfe7d9ea Remove old commented out code 2021-10-07 13:53:06 +02:00
Kristof De Langhe
881eb92fa1 83635: Feedback and test cases 2021-10-07 13:53:02 +02:00
Rezart Vata
ce2790a89b [CST-4504] Adding and removing in modal checkboxes, working on deleting paginated relationships 2021-10-06 18:35:52 +02:00
Corrado Lombardi
91218bb534 removed unnecessary new lines and commented out code 2021-10-06 18:00:19 +02:00
Davide Negretti
eaa3d96bc7 [CST-4659] Deque accessibility issues - 470010 and tests 2021-10-06 15:26:55 +02:00
Kristof De Langhe
03ddde9a97 83635: Button layout changes + LGTM fixes 2021-10-05 18:17:40 +02:00
Kristof De Langhe
120b9f5ce9 83635: Grant/Deny item requests 2021-10-05 18:17:40 +02:00
Kristof De Langhe
11bf10cbde 83635: Intermediate commit 2021-10-05 18:17:40 +02:00
Yana De Pauw
4feccb9989 intermittent commit 2021-10-05 18:17:40 +02:00
Yana De Pauw
90b706239e Fix page reload when requesting a copy 2021-10-05 18:17:40 +02:00
Yana De Pauw
416aa7adaf 83635: Update request a copy page and tests 2021-10-05 18:17:40 +02:00
Yana De Pauw
506883c960 83635: Request a copy - Request page 2021-10-05 18:17:40 +02:00
Davide Negretti
8173d7d805 [CST-4659] Deque accessibility issues - 470010 2021-10-05 17:51:31 +02:00
Davide Negretti
5c8448c36e [CST-4659] Deque accessibility issues - 469993 2021-10-05 16:22:46 +02:00
Davide Negretti
ad15c07a18 [CST-4659] Deque accessibility issues - 469984 2021-10-05 12:54:09 +02:00
Yura
08b79f0595 Fix undefined isPaused$ test failure (afterAll) 2021-10-05 10:51:37 +02:00
Yura
f4c50bc7a2 Pause all notifications when hovering over board 2021-10-05 10:06:30 +02:00
Yura
25ea75cf54 Pause notification countdown on hover 2021-10-05 09:52:31 +02:00
Giuseppe Digilio
e9bca1b51d [CST-4510] use alert component for info message 2021-10-05 09:19:10 +02:00
Tim Donohue
b29b87d0f6 Merge pull request #1315 from tdonohue/header_keyboard_fix
Header Accessibility Fix: Allow enter key or spacebar to expand or contract menu based on current active status
2021-10-04 10:59:34 -05:00
Tim Donohue
b4732f3c31 Move actions to keyup while having preventDefault on keydown 2021-10-04 10:18:01 -05:00
Davide Negretti
b7d6c8e557 [CST-4499] Version history - SSR bug fixed 2021-10-04 13:29:55 +02:00
Tim Donohue
1d0a5c0e87 Switch from keyup to keydown to fix spacebar scrolling issue. 2021-10-01 16:45:59 -05:00
Rezart Vata
74eac1f72c [CST-4504] code improvement and report fixes 2021-10-01 18:57:24 +02:00
Rezart Vata
78c88f212f [CST-4504] Merged conflicts 2021-10-01 18:16:46 +02:00
Rezart Vata
af09479203 [CST-4504] Added discard,reinstate & submit buttons , unit testing & lint fixes 2021-10-01 18:13:18 +02:00
Davide Negretti
69bd118001 [CST-4659] Deque accessibility issues - 469700 2021-10-01 17:22:03 +02:00
Davide Negretti
d59e6c630d [CST-4659] Deque accessibility issues - 470062 2021-10-01 17:10:54 +02:00
Yura
ed3bcaa574 83631: Reword & explain theme extension tests 2021-10-01 13:32:56 +02:00
Tim Donohue
7747a8c4e2 Attempt to stop scroll to bottom of page when clicking spacebar 2021-09-30 17:11:34 -05:00
Davide Negretti
a80d9694d8 [CST-4659] Deque accessibility issues - 470001 2021-09-30 18:11:24 +02:00
Davide Negretti
a2eb16d328 [CST-4659] Deque accessibility issues - 470065 2021-09-30 15:31:52 +02:00
Davide Negretti
ee9d54245c [CST-4659] Deque accessibility issues - 469979 2021-09-30 13:19:52 +02:00
Yana De Pauw
e434bb8952 83707: Implement feedback 2021-09-30 10:22:48 +02:00
Michael Spalti
d4a6ed6d08 Mirador component multi-view based on count of image files in the default bundle. 2021-09-29 22:03:23 -07:00
Michael Spalti
670a0b8a26 Completed work on angular tests. 2021-09-29 14:12:48 -07:00
Davide Negretti
e111f7c70b [CST-4499] Version history - Minor fixes 2021-09-29 20:21:42 +02:00
Bruno Roemers
578b5afa06 83783: Show owning and mapped collections on item page 2021-09-29 18:52:07 +02:00
Davide Negretti
8a38d06318 [CST-4499] Version history - Fixes and tests 2021-09-29 18:28:26 +02:00
Davide Negretti
ca9ca0105e [CST-4499] Version history - Redirect to Edit Item 2021-09-29 16:33:23 +02:00
Michael Spalti
ec0e8c7804 Completed the initial embed of mirador viewer. 2021-09-28 16:47:58 -07:00
Michael Spalti
abb733b9df Merge branch 'main' into iiif-mirador 2021-09-28 13:24:31 -07:00
Michael Spalti
3bf9c5f21c Starting update for iiif using non-entity metadata. 2021-09-28 13:22:09 -07:00
Tim Donohue
53cd1cfcb2 Merge pull request #1319 from 4Science/DSC-192
edit item metadata fix
2021-09-28 13:41:40 -05:00
Tim Donohue
e5e6e9c07a Also support using spacebar to open/close menu 2021-09-28 12:20:53 -05:00
Rezart Vata
7543af2a38 [CST-4634] Worked on unit testing formgroup input validation and custom validations 2021-09-27 16:06:29 +02:00
Davide Negretti
4f2697bf52 [CST-4499] Version history - New version refactored (with tests) 2021-09-27 12:26:20 +02:00
Yana De Pauw
4e9bd86012 83707: Implement tests 2021-09-27 11:11:54 +02:00
Davide Negretti
f60755b2b0 [CST-4499] Version history - New version refactored - Test TBD 2021-09-25 00:59:19 +02:00
Corrado Lombardi
eb14b6c5ad [DSC-192] lint fixes 2021-09-24 18:49:13 +02:00
Giuseppe Digilio
df8ff19550 Merge remote-tracking branch 'origin/main' into CST-4510-entity-selection-porting 2021-09-24 18:15:13 +02:00
Rezart Vata
d9237acb70 [CST-4634] Added custom validator and messages and show error message for not valid email, lint fixes & unit testing 2021-09-24 17:16:53 +02:00
Alba Aliu
010dee7a16 Merge branch 'DSC-192' of https://bitbucket.org/4Science/dspace-angular into DSC-192 2021-09-24 17:08:55 +02:00
Alba Aliu
b22d8358fb [DSC-112] unit testing 2021-09-24 17:07:38 +02:00
Giuseppe Digilio
93f2274c5d [CST-4591] add missing label 2021-09-24 14:33:30 +02:00
Giuseppe Digilio
d29c27b400 [CST-4591] Use search collection dropdown when importing from external source with lookup modal 2021-09-24 13:20:36 +02:00
Giuseppe Digilio
c6a73f2dcb [CST-4591] Fix issue with showing empty collection results 2021-09-24 13:18:50 +02:00
Giuseppe Digilio
a170f1f8a9 [CST-4591] Fix issue with navigate when entity type is empty 2021-09-24 13:17:35 +02:00
Tim Donohue
2b1e3c6b02 Merge pull request #1324 from atmire/upload-bitstream-bugfix
Fixed edit item bitstreams
2021-09-23 16:10:25 -05:00
lotte
50c2d918b0 fixed lgtm issue 2021-09-23 15:48:58 +02:00
Yana De Pauw
100166023a 83707: Control collection harvest from the UI 2021-09-23 15:47:43 +02:00
Giuseppe Digilio
2894045134 [CST-4504] fix lint error 2021-09-23 15:30:23 +02:00
Art Lowel
ac13b8b282 Merge branch 'w2p-83631_Add-the-ability-to-extend-a-theme' into w2p-83628_Dynamic-theme-fixes 2021-09-23 13:42:16 +02:00
Art Lowel
573a133815 fix ciruclar dependency 2021-09-23 13:30:40 +02:00
lotte
e41c66cdda 83681: fixed bundles issue on update bitstreams edit item page 2021-09-23 12:50:58 +02:00
Kristof De Langhe
e2c2423e53 83628: Dynamic theme fixes - test cases and JSDocs 2021-09-23 11:27:38 +02:00
Tim Donohue
4dd3b57539 Merge pull request #1298 from 4Science/CST-4058
Cannot easily tell similar named EPeople or Groups apart (usability issue)
2021-09-22 17:18:44 -05:00
Giuseppe Digilio
d10d0b039f [CST-4504] fix duplicated code 2021-09-22 18:16:32 +02:00
Giuseppe Digilio
6bf3b8e7cd [CST-4591] Change import from external source page in order to work with entity type 2021-09-22 18:02:52 +02:00
Kristof De Langhe
d9db65685b 83628: Dynamic theme fixes 2021-09-22 17:46:55 +02:00
Giuseppe Digilio
afdbf3541b [CST-4591] Add dropdown for selecting entity type when creating a new submission or importing from external source 2021-09-22 17:43:47 +02:00
Giuseppe Digilio
2e0095a587 [CST-4591] Create entity scrollable dropdown 2021-09-22 17:36:18 +02:00
Giuseppe Digilio
51ada1c933 [CST-4591] Change collection dropdown in order to accept entity type as input 2021-09-22 17:34:54 +02:00
Giuseppe Digilio
1f941acda4 [CST-4591] Add entity selection field to collection create/edit form 2021-09-22 17:32:41 +02:00
Giuseppe Digilio
b20b6d003f [CST-4591] Add methods to retrieve entity type related to collections 2021-09-22 17:29:47 +02:00
Davide Negretti
eaca1ac228 [CST-4058] Improvements applied in all places 2021-09-22 17:24:28 +02:00
Giuseppe Digilio
225a5640e5 [CST-4591] Add methods to retrieve collections by entity type 2021-09-22 17:20:04 +02:00
Rezart Vata
681ab1ff88 [CST-4504] Fixed issue for submission, removed tab when editing relationships, removed unused code & improved checking for remote data completed 2021-09-22 17:01:24 +02:00
Rezart Vata
f1135d8a96 [CST-4504] Finished Unit testing, ts lint, report changes and some fixes 2021-09-22 13:44:12 +02:00
Kristof De Langhe
2d638a738e 83628: Dynamic theme fixes 2021-09-22 11:51:05 +02:00
Alessandro Martelli
5a136f8865 [DSC-227] Reload of My Dspace results is broken 2021-09-22 11:35:59 +02:00
Davide Negretti
c816b97525 [CST-4499] Version history - Old tests fixed 2021-09-21 19:42:43 +02:00
Davide Negretti
468ad70751 [CST-4499] Version history - Old tests fixed 2021-09-21 18:21:38 +02:00
Davide Negretti
aee612e06d [CST-4499] Version history - Old tests fixed 2021-09-21 16:47:42 +02:00
Corrado Lombardi
8633b5207d Merge remote-tracking branch 'bb-cris/DSC-192' into DSC-192 2021-09-21 14:50:38 +02:00
Alba Aliu
7214f3fe6d [DSC-192] fix 2021-09-21 14:50:08 +02:00
Alba Aliu
a97f55c32d [DSC-192] disable edit metadata field name in edit mode 2021-09-21 14:50:08 +02:00
Davide Negretti
62fea1fa78 [CST-4499] Version history - Tests WIP 2021-09-21 12:11:23 +02:00
Davide Negretti
3255a29b30 [CST-4499] Version history - Tests WIP 2021-09-20 20:34:34 +02:00
Rezart Vata
3c26ecdcdf [CST-5404] Code refactoring, fixing issues , lint fixes and started unit testing 2021-09-20 19:43:11 +02:00
Davide Negretti
fbc69832d8 [CST-4499] Version history - Tests WIP 2021-09-20 17:38:32 +02:00
Yura
0b62144d97 83631: Add the ability to extend a theme 2021-09-20 17:03:34 +02:00
Alba Aliu
af12fc1a51 [DSC-192] fix 2021-09-20 11:12:45 +02:00
Alba Aliu
cbab3484e7 [DSC-94] reload tabs box after claim made 2021-09-17 23:07:48 +02:00
Michael Spalti
ded5e29f10 Merge branch 'main' into iiif-mirador 2021-09-17 10:38:57 -07:00
Davide Negretti
a547030ce0 [CST-4499] Version history - LGTM fixes - Test TBD 2021-09-17 18:22:48 +02:00
Tim Donohue
523fca2177 Minor updates to README to provide more helpful info on unit tests 2021-09-17 11:19:14 -05:00
Tim Donohue
8e2ab83d92 Fix existing tests. Add new specs for enter key presses 2021-09-17 11:19:14 -05:00
Davide Negretti
97ed08e5c8 [CST-4499] Version history - Test TBD 2021-09-17 18:04:33 +02:00
Davide Negretti
55a1a1c0eb [CST-4499] Version history (WIP) - Refactoring 2021-09-17 13:37:57 +02:00
Davide Negretti
025e7f5c38 [CST-4499] Version history (WIP) - Cache issue fixed 2021-09-17 12:19:18 +02:00
Davide Negretti
b1b2bd4562 [CST-4499] Version history (WIP) - Authorization features - Cache issue fixed 2021-09-16 18:53:45 +02:00
Davide Negretti
cf1c73bd32 [CST-4499] Version history (WIP) - Authorization features - Deleting 2021-09-16 15:49:11 +02:00
Davide Negretti
f858eeef46 [CST-4499] Version history (WIP) - Authorization features - Deleting not working 2021-09-16 00:28:45 +02:00
Tim Donohue
b86ae8dd14 Allow enter key to expand or contract menu based on current active status 2021-09-14 14:16:04 -05:00
Rezart Vata
a2605cdddd [CST-4504] Changed init api, disabled selected tab only for relationship edit page, fixed the related items checked, fixed the issue regarding the updated item control 2021-09-14 19:24:22 +02:00
Davide Negretti
77ff774c97 [CST-4499] Version history (WIP) - Minor fixes and code cleanup 2021-09-14 18:48:13 +02:00
Davide Negretti
60bbb9ace4 [CST-4499] Version history (WIP) - Redirect after deleting a version 2021-09-14 18:20:58 +02:00
Davide Negretti
5d8f625d01 [CST-4499] Version history (WIP) - Refactoring 2021-09-14 01:39:00 +02:00
Davide Negretti
f10f25d129 Merge remote-tracking branch 'bb/CST-4499' into CST-4499 2021-09-13 18:04:22 +02:00
Davide Negretti
b4111fe4b1 [CST-4499] Version history (WIP) - Version page added (redirecting to item's page) 2021-09-13 17:56:55 +02:00
Rezart Vata
ffee36607d [CST-5404] Started working on new feature,added services and started working on selection 2021-09-10 18:49:23 +02:00
Alessandro Martelli
ce399cb764 [CST-4499] Version history (WIP) - Missing tests and auth features 2021-09-10 18:22:55 +02:00
Davide Negretti
44d3558e87 [CST-4499] Version history (WIP) - 'Create version' button in item page and other fixes 2021-09-10 18:16:35 +02:00
Davide Negretti
5526cde869 [CST-4058] LGTM issues solved 2021-09-10 11:06:25 +02:00
Davide Negretti
8df8b1c574 [CST-4058] LGTM issues solved 2021-09-10 10:50:35 +02:00
Davide Negretti
ad5ace79fb Changes by alex 2021-09-10 10:36:37 +02:00
Davide Negretti
dd2df9106c [CST-4499] Version history (WIP) - Fixes to API calls 2021-09-10 10:36:33 +02:00
Davide Negretti
05385f3568 [CST-4499] Version history (WIP) - Fixes to API calls 2021-09-10 10:19:33 +02:00
Tim Donohue
706cc47197 Merge pull request #1300 from bbranan/issue-1299
Adds support for capturing i18n translation updates within a theme
2021-09-09 16:26:33 -05:00
Davide Negretti
d402ab7dcf [CST-4499] Version history (WIP) - New version modal and other changes 2021-09-09 00:57:44 +02:00
Tim Donohue
2f251a3a61 Merge pull request #1310 from DSpace/dependabot/npm_and_yarn/url-parse-1.5.3
Bump url-parse from 1.4.7 to 1.5.3
2021-09-08 16:39:39 -05:00
Tim Donohue
49773140c6 Merge pull request #1293 from DSpace/dependabot/npm_and_yarn/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7
2021-09-08 16:23:48 -05:00
Tim Donohue
1c3dcefcec Merge pull request #1165 from DSpace/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.20 to 4.17.21
2021-09-08 15:49:13 -05:00
Bill Branan
3be2e6f08b Merge branch 'main' into issue-1299 2021-09-08 15:28:02 -04:00
Tim Donohue
879c23e002 Merge pull request #1166 from DSpace/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.8 to 2.8.9
2021-09-08 13:33:04 -05:00
dependabot[bot]
c40958f450 Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-08 17:37:21 +00:00
dependabot[bot]
285551674d Bump url-parse from 1.4.7 to 1.5.3
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-08 17:11:31 +00:00
dependabot[bot]
c9ac591dc3 Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-08 17:11:13 +00:00
dependabot[bot]
17ed492a5f Bump lodash from 4.17.20 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-08 17:11:04 +00:00
Tim Donohue
5a82e1b60c Merge pull request #1307 from DSpace/dependabot/npm_and_yarn/tar-4.4.19
Bump tar from 4.4.13 to 4.4.19
2021-09-08 12:09:44 -05:00
Tim Donohue
fab1e3dbb0 Merge pull request #1311 from tdonohue/disable_a11y_checks
Temporarily disable a11y check until random failure for color contrast can be fixed
2021-09-08 12:09:30 -05:00
Tim Donohue
432fb4e3cc Temporarily disable a11y check until random failure for color contrast can be fixed 2021-09-08 11:14:24 -05:00
dependabot[bot]
173bf5460c Bump tar from 4.4.13 to 4.4.19
Bumps [tar](https://github.com/npm/node-tar) from 4.4.13 to 4.4.19.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.13...v4.4.19)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-08 14:51:55 +00:00
Tim Donohue
15e7f75e39 Merge pull request #1301 from tdonohue/switch_to_cypress
Switch to Cypress.io for all e2e tests
2021-09-08 09:50:46 -05:00
Davide Negretti
72bfab16df [CST-4499] Version history (WIP) - Changes to in-row editing, code cleanup, added modal for new versions 2021-09-08 12:08:54 +02:00
Davide Negretti
95ffc7a016 [CST-4499] Version history (WIP) - Added in-row editing in version history (call to REST service TBD) and other fixes 2021-09-07 20:33:47 +02:00
Tim Donohue
4d4aadd83f Merge pull request #1309 from atmire/fix-themed-profile-page-component
fix the profile page component in the custom theme
2021-09-07 11:40:25 -05:00
Davide Negretti
6f24b31b39 [CST-4499] Version history (WIP) - Removed summary page (with routing) and modal 2021-09-07 14:47:36 +02:00
Davide Negretti
a1e312440f [CST-4499] Version history (WIP) - Buttons added to history, form replaced with modal, minor fixes 2021-09-06 20:51:34 +02:00
Art Lowel
f35f671dc3 fix the profile page component in the custom theme 2021-09-06 11:23:46 +02:00
Alessandro Martelli
5b036e84e1 [CST-4499] Version history module (WIP) 2021-09-02 16:20:43 +02:00
Davide Negretti
d66cf881fb [CST-4058] 'colspan' removed from table header; code cleanup 2021-09-02 16:05:22 +02:00
Bill Branan
edb814c49a Updates formatting to follow code style rules 2021-08-31 15:59:09 -04:00
Bill Branan
81988179e9 Adds setting to maintain the use of double quotes 2021-08-31 15:47:46 -04:00
Tim Donohue
098779a82d Fix to Cypress tsconfig.json, don't override sourceMap settings 2021-08-27 13:09:33 -05:00
Tim Donohue
13d8d75cfa Upgrade to latest Cypress 2021-08-27 12:24:35 -05:00
Tim Donohue
fec71ebf99 Add link to Cypress docs on creating first test in our README 2021-08-27 12:02:23 -05:00
Tim Donohue
03a11aeda1 Minor cleanup to GitHub CI. No longer need chromedriver. Use latest version of Chrome. 2021-08-27 11:33:06 -05:00
Tim Donohue
9d118dc2fd Add docs on writing e2e tests. Minor cleanup to README elsewhere 2021-08-27 11:08:30 -05:00
Tim Donohue
3c3f2251bb Minor test cleanup. Ensure artifacts are available based on e2e search results 2021-08-27 10:07:07 -05:00
Tim Donohue
fbfd4a2769 Fixes to e2e CI process 2021-08-27 09:11:23 -05:00
Tim Donohue
c86b68a6e0 Replace Protrator e2e tests with Cypress. Move all existing tests to Cypress & add basic Deque Axe integration. 2021-08-26 17:14:08 -05:00
Bill Branan
95a2da6410 Adds script to merge in i18n translation files from themes
See: https://github.com/DSpace/dspace-angular/issues/1299
2021-08-26 09:37:53 -04:00
Michael Spalti
668a08be45 Updated the iiif endpoint that is passed to the viewer. 2021-08-25 11:09:47 -07:00
Davide Negretti
4b3e0e8d09 [CST-4058] lint errors fixed 2021-08-24 17:53:43 +02:00
Davide Negretti
cbbac01313 [CST-4058] bug fixed 2021-08-24 17:06:00 +02:00
Davide Negretti
dfae46d92e [DSC-198] commented lines removed 2021-08-24 15:16:02 +02:00
Davide Negretti
befc0d4c9e [CST-4058] lint errors fixed 2021-08-24 13:41:04 +02:00
Tim Donohue
adb40d8712 Merge pull request #1295 from atmire/w2p-81901_Fix-sidebar-a11y-issues
Fix sidebar a11y issues
2021-08-23 16:01:33 -05:00
Davide Negretti
2cb9345ed5 [CST-4058] tests 2021-08-23 18:09:03 +02:00
Yura Bondarenko
714ea5d8f9 81901: Add in forgotten translate pipe 2021-08-23 15:45:22 +02:00
Yura Bondarenko
9cb8a77bf8 81901: Fix OnClickMenuItemComponent unit test 2021-08-20 18:24:38 +02:00
Davide Negretti
8134e6bc17 [CST-4058] tests (WIP) 2021-08-20 15:13:10 +02:00
Yura Bondarenko
3c4f3e9104 81901: Fix navigation/onclick function ~ enter key 2021-08-20 10:53:01 +02:00
Yura Bondarenko
9d66bc5167 81901: Use sidebar section text for tooltip 2021-08-20 09:43:36 +02:00
Michael Spalti
fb0d51c574 Improved performance of mirador component by avoiding IIIF bundle bitstream lookup. 2021-08-19 13:00:58 -07:00
Davide Negretti
9e710f7093 [CST-4058] tests (WIP) 2021-08-18 18:58:16 +02:00
Davide Negretti
3d894d02d3 [CST-4058] Show EPerson's email address and netid; tests fixed 2021-08-17 18:38:35 +02:00
Davide Negretti
5c070428d3 [CST-4058] Show the name of the community/collection in "Edit group" page 2021-08-17 17:10:32 +02:00
Davide Negretti
1bb98119f5 [CST-4058] Show the name of the community/collection next to the name of the group 2021-08-17 09:33:54 +02:00
Yura Bondarenko
ab6e8be6b1 Remove unused import 2021-08-16 17:53:17 +02:00
Yura Bondarenko
2a10f6bf9e 81901: AdminSidebarSectionComponent navigate on spacebar 2021-08-16 17:36:04 +02:00
Yura Bondarenko
7ae26d3ebb 81901: Fix expandable section submenu spacing
* Selection outlines were cut off by the icon (which needs to be full height for the animation-
2021-08-16 17:36:04 +02:00
Yura Bondarenko
2fa06d28e3 81901: Make expandable section not a link 2021-08-16 17:36:04 +02:00
Davide Negretti
ed12770494 [CST-4058] Show EPerson's email address - Show netid as fallback value 2021-08-16 17:23:45 +02:00
Davide Negretti
8274594848 [CST-4058] Show EPerson's email address 2021-08-16 17:03:07 +02:00
Yura Bondarenko
214833af68 81901: Add aria-expanded attribute to expandable items 2021-08-16 16:50:36 +02:00
Yura Bondarenko
c63d049d55 81901: Make expanded submenu items slide in from under collapsed sidebar 2021-08-16 16:39:56 +02:00
Yura Bondarenko
303e69a6b9 81901: Make admin sidebar header not a link 2021-08-16 09:50:04 +02:00
Yura Bondarenko
129ea726e8 81901: Enable spacebar toggling for admin sidebar items 2021-08-16 09:50:04 +02:00
Yura Bondarenko
b32226c5ed 81901: Fix keyboard/hover expand/collapse interactions 2021-08-13 17:14:54 +02:00
Yura Bondarenko
b84e003f27 81901: Update unit tests 2021-08-06 19:03:31 +02:00
Yura Bondarenko
4ae526d6b2 81901: Expand/collapse admin sidebar preview on focusin/focusout 2021-08-06 18:32:14 +02:00
Yura Bondarenko
1bad7fae3f 81901: Set aria-disabled for menu links and sidebar sections 2021-08-06 18:14:44 +02:00
Yura Bondarenko
2265de8d44 81901: Single link in sidebar menu entries
+ improved focus ring styling
2021-08-06 18:14:44 +02:00
Yura Bondarenko
d095c98b13 81901: Menu item components as ul > li 2021-08-06 18:14:43 +02:00
Tim Donohue
5a12f34593 Merge pull request #1287 from atmire/language-attribute-html-tag
Language attribute on HTML tag
2021-08-05 16:53:33 -05:00
Tim Donohue
a45780566f Merge pull request #1283 from josekarvalho/patch-2
Update en.json5
2021-08-05 15:55:12 -05:00
lotte
43c03de0ad Language attribute on HTML tag 2021-08-04 17:38:27 +02:00
Michael Spalti
6019a21ebd Removed unused import. 2021-07-31 09:02:10 -07:00
Michael Spalti
9cc3351fcf Fixed item page component paths. 2021-07-30 16:52:33 -07:00
Michael Spalti
20477f0aaa Merge branch 'main' into iiif-mirador 2021-07-30 16:27:18 -07:00
Tim Donohue
9fc7b57157 Correct year in LICENSE 2021-07-29 12:55:59 -05:00
Tim Donohue
f0474ce2f2 Merge branch 'main' of github.com:DSpace/dspace-angular 2021-07-29 12:50:42 -05:00
Tim Donohue
3664a06d8b Update README for 7.0. Sync some sections with DSpace/DSpace 2021-07-29 12:50:15 -05:00
José Carvalho
85ae3da0c0 Update en.json5
removed strings not used
2021-07-29 18:46:28 +01:00
Tim Donohue
232b457eff Merge pull request #1264 from josekarvalho/patch-1
Update pt-PT.json5
2021-07-29 12:37:04 -05:00
José Carvalho
14f026f8c4 Update en.json5
Updated with missing strings (found by revising the portuguese translation), and added new strings to support relations between entities and the import of external funding from the OpenAIRE API. Removed one duplicate string.
2021-07-29 15:47:31 +01:00
José Carvalho
681fa3cbe9 Update pt-PT.json5
Update additional strings
2021-07-29 15:16:11 +01:00
Tim Donohue
47302acf66 Merge pull request #1282 from tdonohue/test_ssr_working
SEO + SSR fixes: Fix <meta> tag syntax and add a basic test that SSR is working
2021-07-26 15:49:47 -05:00
Tim Donohue
91bb5e2fd4 Add a basic SSR test to GitHub CI 2021-07-26 15:15:03 -05:00
Tim Donohue
7fcd055458 Meta tags should use "name" not "property" attribute, as "name" is HTML5 2021-07-26 15:14:36 -05:00
Tim Donohue
4292af4294 Merge pull request #1280 from atmire/fix-first-request-issue
Fix issue where the app wouldn't load for the first request in prod mode
2021-07-26 10:03:08 -05:00
Art Lowel
8ee12868aa deal with errors that aren't error responses 2021-07-26 13:38:40 +02:00
Art Lowel
8f43fbd399 check if correlationid exists before adding it as a header 2021-07-26 11:54:25 +02:00
Tim Donohue
e9a03994e2 Merge pull request #1278 from atmire/remove-plus-from-folders
Update folder structure based on style guide
2021-07-23 11:28:38 -05:00
Art Lowel
acf2b0ee57 switch scss imports back to relative paths 2021-07-23 17:59:57 +02:00
Art Lowel
1c5bfbac24 remove a missed plus sign 2021-07-23 17:41:42 +02:00
Tim Donohue
9483e3ff2c Merge pull request #1277 from atmire/test-date-timezone-issue
Fix timezone issue with test dates
2021-07-23 10:19:46 -05:00
Art Lowel
124845bee1 update folder structure based on style guide 2021-07-23 17:18:51 +02:00
Art Lowel
3c1263ada6 fix timezone issue with test dates 2021-07-23 16:30:25 +02:00
Tim Donohue
fa02d1efe6 Merge pull request #1276 from atmire/remove-unused-config-params
Remove unused config params
2021-07-22 14:57:01 -05:00
Art Lowel
d0771715b6 add prototcol to origin in ServerHardRedirectService 2021-07-22 18:48:06 +02:00
Art Lowel
03f6f75e49 remove unused config params and related methods 2021-07-22 17:59:10 +02:00
Art Lowel
146ec49a32 Merge pull request #1275 from 4Science/#1273_no_js_issue
#1273 no js issue
2021-07-22 10:14:46 +02:00
Tim Donohue
2f6501f1af Merge pull request #1242 from atmire/w2p-80141_Support-for-legacy-bitstream-download-urls
Add support for legacy bitstream download URLs
2021-07-21 09:10:15 -05:00
Giuseppe Digilio
85fa1c5a9c move effect for cleaning cache to auth.effects 2021-07-21 09:46:15 +02:00
Tim Donohue
b33c859d67 Merge pull request #1254 from 4Science/#1206
Improve error handling during submission
2021-07-20 13:39:17 -05:00
Tim Donohue
83d61a5929 Merge pull request #1255 from 4Science/#1248
Improve logging Angular implementation
2021-07-20 11:03:30 -05:00
Giuseppe Digilio
d3fe33a837 Address feedback 2021-07-20 11:54:25 +02:00
José Carvalho
580a67a18d Update pt-PT.json5
Update some strings and add new ones to support OpenAIRE 4.0 guidelines compatibility (by naming relationships)
2021-07-20 10:33:03 +01:00
Giuseppe Digilio
f7ebffec45 Merge remote-tracking branch 'origin/main' into #1206
# Conflicts:
#	src/app/submission/form/submission-upload-files/submission-upload-files.component.spec.ts
#	src/app/submission/form/submission-upload-files/submission-upload-files.component.ts
2021-07-20 11:26:06 +02:00
Giuseppe Digilio
b04c33a5fb Invalidate authorization requests cache on REHYDRATE 2021-07-20 11:02:02 +02:00
Tim Donohue
8b88e7f4cd Merge pull request #1252 from 4Science/#1171
Fix accessibility issues #1172 #1167  #1171
2021-07-19 14:13:35 -05:00
Giuseppe Digilio
6cadae4e7f Fix missing button title 2021-07-19 19:19:50 +02:00
Giuseppe Digilio
aaae62de5f remove unnecessary aria-label 2021-07-19 19:19:25 +02:00
Giuseppe Digilio
fbde0cbad9 Revert "[CSTPER-144] Fixed issue with authorization request encountered while logging-in with external idp"
This reverts commit 73a9fe16
2021-07-19 17:54:02 +02:00
Tim Donohue
88c591054f Merge pull request #1250 from 4Science/CST-4319
Cannot map new items with Collection Admin
2021-07-15 15:14:18 -05:00
Giuseppe Digilio
d6990b3cd1 Add keyup event for selecting a new language from lang dropdown 2021-07-15 11:02:33 +02:00
Tim Donohue
73e70e6546 Merge pull request #1269 from 4Science/submission-footer-improvement
improve positioning of buttons in the submission form
2021-07-13 11:18:06 -05:00
Tim Donohue
6fc8ef6b50 Merge pull request #1262 from tdonohue/date_fixes
Ensure we are always using UTC dates in the UI, as the backend expects/uses UTC-based dates
2021-07-13 09:06:08 -05:00
Michael Spalti
de352a839e Retrieve thumbnail from remote data object. 2021-07-12 09:53:17 -07:00
Tim Donohue
008e0cb66c Another small fix from @atarix83 2021-07-12 11:47:53 -05:00
Tim Donohue
9ee733ea80 Stop using localized Dates. Ensure we always use UTC dates, as the backend expects/uses UTC. 2021-07-12 10:11:55 -05:00
Tim Donohue
6d13ba42c6 Fix saving of dates to UTC 2021-07-12 10:11:54 -05:00
Giuseppe Digilio
9ef4a11771 fix test 2021-07-12 16:19:03 +02:00
Giuseppe Digilio
aac9f02447 fix test 2021-07-12 15:04:06 +02:00
Giuseppe Digilio
5185c90ad6 improve positioning of buttons in the submission form 2021-07-12 14:31:24 +02:00
Giuseppe Digilio
ff6f6fea33 fix issue with Hierarchical vocabulary onebox toggle 2021-07-12 11:54:36 +02:00
José Carvalho
ae1d462bec Update pt-PT.json5
Added additional corrections. The strings until line 44 where not in the file to be translated.  After checking our DSpace 7 instance they where missing so we added. It's fine by now to be included in DSpace 7.0.
2021-07-12 09:56:14 +01:00
Michael Spalti
9c41cd7f8f Merge branch 'main' into iiif-mirador 2021-07-11 07:37:03 -07:00
Art Lowel
98cecd3e84 Merge pull request #1249 from 4Science/CST-4320
No way to view an Item when in simple "Approve/Reject" workflow stage
2021-07-09 09:34:41 +02:00
Giuseppe Digilio
28707f9a4c fix issue with misaligned loading icon on tag field 2021-07-08 20:33:43 +02:00
Giuseppe Digilio
9875b61082 fix issue with wrong fontawesome icon that show odd char on firefox 2021-07-08 20:22:51 +02:00
Giuseppe Digilio
d30fdb1db7 fix issue with aria-expanded attribute that is invalid on input 2021-07-08 20:19:07 +02:00
Giuseppe Digilio
eae89e1be0 fix issue with missing aria label 2021-07-08 19:37:39 +02:00
Giuseppe Digilio
ab73bf87b0 fix issue with dropdowns key accessibility 2021-07-08 18:10:43 +02:00
Giuseppe Digilio
186e420db5 fix issue with not unique ids 2021-07-08 17:46:04 +02:00
Alessandro Martelli
de2ba413a1 [CSTPER-4320] fixed back button for accessibility 2021-07-08 17:16:13 +02:00
Giuseppe Digilio
3b264015cb Merge remote-tracking branch 'origin/main' into #1171
# Conflicts:
#	src/app/submission/sections/upload/file/section-upload-file.component.html
2021-07-08 17:09:01 +02:00
Giuseppe Digilio
2bd68b0585 fix issue with ssr 2021-07-08 17:06:02 +02:00
Alessandro Martelli
cf7d1ed108 Merge branch 'main' into CST-4320
# Conflicts:
#	src/assets/i18n/en.json5
2021-07-08 16:02:52 +02:00
Giuseppe Digilio
9607a5248b Merge remote-tracking branch 'origin/main' into #1248 2021-07-08 15:30:34 +02:00
Art Lowel
d55ae48e4a Merge pull request #1239 from atmire/Fix-hardcoded-submission-section-IDs
Fix hardcoded submission section IDs
2021-07-08 15:14:47 +02:00
Art Lowel
2c8d72b971 Merge pull request #1240 from atmire/w2p-79700_Improve-session-timeout-UX
Improve session timeout UX
2021-07-08 13:27:41 +02:00
Yura Bondarenko
bfcff12499 Fix hardcoded reference to 'upload' section 2021-07-07 18:05:26 +02:00
Alessandro Martelli
dbb4d08ca0 [CST-4320] back button standardized style 2021-07-07 16:28:27 +02:00
Alessandro Martelli
3d6cacadff [CST-4320] fixed item version component initialization 2021-07-07 16:09:19 +02:00
Alessandro Martelli
f5cd878096 [CST-4320] resolved merge conflicts 2021-07-05 16:01:32 +02:00
Alessandro Martelli
0212df5bd1 Merge branch 'main' into CST-4320
# Conflicts:
#	src/app/+item-page/full/full-item-page.component.ts
2021-07-05 15:56:40 +02:00
Alessandro Martelli
111170e7d4 [CST-4320] workflow item view resolved as full item page 2021-07-05 15:47:58 +02:00
Tim Donohue
873feb9cfe Merge pull request #1266 from 4Science/submission-bitstream-download
fix bitstream download during submission
2021-07-02 14:19:36 -05:00
Yura Bondarenko
8736c0b572 Add unit tests for SectionsService#isSectionType 2021-07-02 18:12:18 +02:00
Tim Donohue
1dba4c55f5 Merge pull request #1228 from atmire/w2p-79768_fix-issues-with-meta-tags
Fix issues with meta tags
2021-07-02 10:00:50 -05:00
Yura Bondarenko
7670ba8a43 Fix duplicate notifications 2021-07-02 14:26:58 +02:00
Yura Bondarenko
a3ba4e59b3 Fix lint issues 2021-07-02 14:26:58 +02:00
Yura Bondarenko
72e97ca6b4 Update unit tests 2021-07-02 14:26:58 +02:00
Yura Bondarenko
32003a72fd Fix hardcoded submission section IDs 2021-07-02 14:26:57 +02:00
Yana De Pauw
5b869cce46 80141: Add support for legacy bitstream download URLs 2021-07-02 14:12:07 +02:00
Giuseppe Digilio
c190cdc9bd fix comment 2021-07-02 13:53:11 +02:00
Giuseppe Digilio
badf901361 Use ds-file-download-link component to allow bitstream download during submission 2021-07-02 13:46:17 +02:00
José Carvalho
97144f74da Update pt-PT.json5
Big update of the translation to Portuguese
2021-07-02 12:14:17 +01:00
Giuseppe Digilio
193de508cd Merge remote-tracking branch 'origin/main' into #1206
# Conflicts:
#	src/app/submission/edit/submission-edit.component.ts
2021-07-02 13:12:04 +02:00
Giuseppe Digilio
5fd30e1be9 Merge remote-tracking branch 'origin/main' into #1171 2021-07-02 13:10:50 +02:00
Yura Bondarenko
a91f16ed62 79768: Fix followLink syntax 2021-07-01 23:11:57 +02:00
Yura Bondarenko
711abfca35 Merge branch 'main' into w2p-79768_fix-issues-with-meta-tags 2021-07-01 22:55:29 +02:00
Yura Bondarenko
5ed41b3f9b 79768: Fix unused imports & lint issue 2021-07-01 22:47:26 +02:00
Yura Bondarenko
8caa916316 79768: Fix typo 2021-07-01 22:37:55 +02:00
Yura Bondarenko
fb8f28f17d 79768: Update & add MetadataService unit tests 2021-07-01 22:37:07 +02:00
Yura Bondarenko
50400895de 79768: Add unit tests for metaTagReducer 2021-07-01 22:36:08 +02:00
Tim Donohue
0ee451f3d3 Merge pull request #1247 from atmire/w2p-80195_Fix-move-item-page
Fix move item page
2021-07-01 10:13:00 -05:00
Tim Donohue
8ad8824e3a Merge pull request #1233 from 4Science/#1129
Add possibility to edit embargo on bitstream of archived Item
2021-07-01 10:11:44 -05:00
Marie Verdonck
1721ba5ddf Icon changes & fix after rebase 2021-07-01 16:19:31 +02:00
Marie Verdonck
6c219e72d5 79700: Doc fixes, Spec tests authService & ariaLabelledBy for idle-modal 2021-07-01 15:52:12 +02:00
Marie Verdonck
829ce12710 lgtm alerts 2021-07-01 15:52:12 +02:00
Marie Verdonck
ddcb27da3f 79700: logout via store, automatic redirect 2021-07-01 15:52:12 +02:00
Marie Verdonck
c696b78393 79700: idle time and grace period testing times removed 2021-07-01 15:52:12 +02:00
Marie Verdonck
4b1f086469 79700: Feedback 2021-06-15 applied 2021-07-01 15:52:12 +02:00
Art Lowel
91b4c81986 run idle timer outside of angular zone 2021-07-01 15:52:12 +02:00
Marie Verdonck
e88baa1995 79700: specs for modal, auth check for idleness tracking & stop blocking at token success 2021-07-01 15:52:12 +02:00
Marie Verdonck
38387d1a0f 79700: Tracking idleness & idle modal 2021-07-01 15:52:12 +02:00
Marie Verdonck
b23522d39f 79700: Auto-refreshing the token & Needed config 2021-07-01 15:51:23 +02:00
Art Lowel
c86f163cb7 move tagstore to ngrx 2021-07-01 11:36:12 +02:00
Tim Donohue
de8e306d9f Merge pull request #1244 from 4Science/#1179
[CSTPER-144] Fixed issue with authorization request encountered while logging-in with shibboleth
2021-06-30 16:05:19 -05:00
Tim Donohue
c46abae264 Merge pull request #1261 from atmire/w2p-80369_Use-thumbnail-links-for-Items-and-Bitstreams
Use thumbnail links for items and bitstreams
2021-06-30 14:30:32 -05:00
Tim Donohue
a14230afcc Merge pull request #1251 from 4Science/1217
Delete pending json patch operations
2021-06-30 09:02:31 -05:00
Art Lowel
03e2e30510 fix issue where meta tags wouldn't be updated properly based on the route 2021-06-30 14:21:43 +02:00
Yura Bondarenko
fedf6aa847 80369: Fix unused imports 2021-06-29 21:18:06 +02:00
Yura Bondarenko
7bb32f31de Merge remote-tracking branch 'upstream/main' into w2p-80369_Use-thumbnail-links-for-Items-and-Bitstreams 2021-06-29 18:03:57 +02:00
Yura Bondarenko
abf6d26641 80369: Remove unneeded bundles followLink 2021-06-29 17:34:00 +02:00
Yura Bondarenko
b0599fa27c 80195: Fix ItemMoveComponent unit tests 2021-06-29 09:56:29 +02:00
Yura Bondarenko
72a6754245 80195: Fix breadcrumbs not updating 2021-06-29 09:14:17 +02:00
Tim Donohue
e6c2680d2f Merge pull request #1253 from 4Science/#1234
Fix issue when switching submission's collection between those with different submission definition
2021-06-28 16:28:23 -05:00
Tim Donohue
87e458bc0f Merge pull request #1246 from atmire/w2p-80233_add-pagination-to-edit-relationships-tab
Add pagination to edit relationships tab
2021-06-28 13:46:28 -05:00
Yura Bondarenko
eb0b3ae5f4 80369: Add optional thumbnail followLink in SearchComponent 2021-06-28 12:51:57 +02:00
Yura Bondarenko
c1b1cb2a27 80369: Remove deprecated front-end thumbnail methods 2021-06-28 12:42:53 +02:00
Yura Bondarenko
d21d0eae55 80369: Add followLinks for thumbnail 2021-06-28 12:42:51 +02:00
Yura Bondarenko
acff2186b4 80369: Add thumbnail link to Item & Bitstream models 2021-06-28 12:40:39 +02:00
Art Lowel
0d5fc8a1c0 refactor followlinks to use a single object for all params and add an isOptional param. Also add support for embedding links to search service 2021-06-28 12:28:59 +02:00
Tim Donohue
7714ef47c8 Merge pull request #1245 from 4Science/#1122
Disable community/collection delete button while the delete operation is being processed
2021-06-25 17:14:09 -05:00
Tim Donohue
ff0291d346 Merge pull request #1222 from atmire/w2p-79730_Fix-search-sidebar-a11y-issues
Fix search sidebar a11y issues
2021-06-25 16:56:09 -05:00
Tim Donohue
c33e3909b9 Merge pull request #1201 from 4Science/#1110
Fixes for submission forms bugs
2021-06-25 14:44:13 -05:00
Giuseppe Digilio
75d641dc82 Create a new log interceptor with the scope to attach new X-CORRELATION-ID and X-REFERRER headers 2021-06-25 16:06:07 +02:00
Giuseppe Digilio
ac7c038703 Fix tests 2021-06-25 15:31:23 +02:00
Giuseppe Digilio
4d12236930 Fix visualization of error in date field 2021-06-25 15:24:31 +02:00
Giuseppe Digilio
44d2310cdb Changes in order to keep server side validation errors into the submission form state 2021-06-25 15:23:56 +02:00
Giuseppe Digilio
0724692d40 Merge remote-tracking branch 'origin/main' into #1206 2021-06-25 14:18:26 +02:00
Giuseppe Digilio
a089e662fb fix issue with date picker that didn't save the date entered manually 2021-06-25 14:08:21 +02:00
Yura Bondarenko
98b2c75a3c 79730: Add unit tests for sequence service & ds-search-filter IDs 2021-06-25 10:00:21 +02:00
Yura Bondarenko
24ffa6c63a 79730: Replace component ID with unique number 2021-06-25 09:32:45 +02:00
Tim Donohue
980d6a6154 Merge pull request #1237 from atmire/w2p-bugfix-issue-1124-access-control-section-visible-to-non-admin-users
Access Control - Groups only editable by Com/Col admin if group related to com/col & Only site admin access to access control epeople
2021-06-24 13:47:20 -05:00
Bruno Roemers
511a2e18ab 80113: Display loading indicator after using pagination nav 2021-06-24 19:50:39 +02:00
Bruno Roemers
fc398c15f4 80113: Rename searching$ into loading$ 2021-06-24 19:44:06 +02:00
Giuseppe Digilio
434ef5628f [DSC-130] Fix issue when switching submission's collection between those with different submission definition 2021-06-24 18:52:00 +02:00
Giuseppe Digilio
714b713134 fix failed tests 2021-06-24 18:47:27 +02:00
Giuseppe Digilio
f8e4b770e8 fix a11y issue with drag and drop 2021-06-24 18:35:30 +02:00
Tim Donohue
1187edb486 Merge pull request #1219 from atmire/w2p-79597_Fix-thumbnail-a11y-issues
Fix thumbnail a11y issues
2021-06-24 10:24:44 -05:00
Giuseppe Digilio
b03c7fbe4d fix a11y issue with delete community/collection logo 2021-06-24 17:20:35 +02:00
Giuseppe Digilio
3bc5737f6d fix a11y issue with item edit metadata 2021-06-24 17:20:12 +02:00
Alessandro Martelli
da4be7b57f [DSC-76] Delete pending json patch operations 2021-06-24 17:13:58 +02:00
Tim Donohue
0dee03e0bc Merge pull request #1243 from DSpace/missing-i18n-key
Add missing i18n key for Sherpa Journals by ISSN
2021-06-24 09:58:53 -05:00
Alessandro Martelli
8be77017e9 [CST-4319] Corrected test assertion 2021-06-24 16:57:41 +02:00
Alessandro Martelli
4b11a2f1c1 [CST-4320] Added missing translations 2021-06-24 16:38:59 +02:00
Alessandro Martelli
3795ab0495 [CST-4319] Cannot map new items with Collection Admin 2021-06-24 16:24:18 +02:00
Giuseppe Digilio
71c36f59af fix issue with navbar issues 2021-06-24 15:38:27 +02:00
Alessandro Martelli
67ce3e6741 [CST-4320] No way to view an Item when in simple "Approve/Reject" workflow stage 2021-06-24 15:34:11 +02:00
Alessandro Martelli
a572b0acea [CST-4320] No way to view an Item when in simple "Approve/Reject" workflow stage 2021-06-24 15:28:26 +02:00
Giuseppe Digilio
dccf04d4c0 fix issue with wrong aria-labels 2021-06-24 14:53:06 +02:00
Giuseppe Digilio
b4cd7bdf26 fix issue with submission section missing elements 2021-06-24 14:47:35 +02:00
Giuseppe Digilio
2681a31e87 fix issue with comboboxes 2021-06-24 14:30:46 +02:00
Giuseppe Digilio
601bd5e922 fix issue with elements with missing/wrong role 2021-06-24 14:23:06 +02:00
Giuseppe Digilio
606915f39a fix issue with elements with missing name/label 2021-06-24 13:04:41 +02:00
Giuseppe Digilio
56487a44f3 fix issue with elements not accessible with Keyboard navigation 2021-06-24 12:49:41 +02:00
Giuseppe Digilio
4b6a0d8aa2 fix issue with missing labels in the mydspace page 2021-06-24 12:05:00 +02:00
Yura Bondarenko
a48e77810d 80195: Fix unused import 2021-06-24 12:01:05 +02:00
Giuseppe Digilio
3ca1e61a8c fix issue with missing labels in the submission form 2021-06-24 11:58:41 +02:00
Art Lowel
7dc4609a83 add getFirstCompletedRemoteData, remove force redownload of owningcollection 2021-06-24 11:16:38 +02:00
Giuseppe Digilio
396393e9b7 fix issue with multiple elements in the submission form that use the same ID 2021-06-24 11:09:25 +02:00
Giuseppe Digilio
217f7b5b21 fix issue with the aria-multiline attribute that is invalid on combobox role 2021-06-24 10:56:13 +02:00
Giuseppe Digilio
ea2030666c fix issue with aria-expanded attribute that is invalid on input 2021-06-24 10:55:46 +02:00
Tim Donohue
f6c48494b9 Merge pull request #1241 from atmire/w2p-80154_Fix-contrast-issues-with-grays
Fix contrast issues with grays
2021-06-23 14:05:31 -05:00
Yura Bondarenko
290abf7c43 80195: Fix unit tests 2021-06-23 18:39:15 +02:00
Yura Bondarenko
84274c3911 80195: Fix ItemMoveComponent#moveToCollection 2021-06-23 18:08:52 +02:00
Tim Donohue
c1ddf7f667 Add production warning 2021-06-23 10:55:22 -05:00
Art Lowel
04f4a25870 fix an issue where the results of a dso-selector wouldn't update until you clicked anywhere on the page 2021-06-23 17:28:36 +02:00
Art Lowel
2599068ccd add a focus style for truncatable parts 2021-06-23 17:27:23 +02:00
Art Lowel
b586a264ca ensure dynamic components are updated when their inputs change 2021-06-23 17:27:01 +02:00
Bruno Roemers
4c1a72fdb2 80233: Apply Art's feedback 2021-06-23 15:39:53 +02:00
Yura Bondarenko
c825f911f5 80195: Mimic back/save/discard buttons of other edit pages 2021-06-23 15:31:13 +02:00
Yura Bondarenko
86cd7ba03f 80195: Select original owningCollection on load 2021-06-23 15:29:24 +02:00
Art Lowel
f683d1219e make truncatable css global to ensure it adapts to the theme 2021-06-23 13:43:10 +02:00
Giuseppe Digilio
10aa2e14f1 Merge remote-tracking branch 'origin/#1110' into #1129 2021-06-23 12:54:44 +02:00
Giuseppe Digilio
fba5504dd9 fix issue while editing bitstream with an existing access condition 2021-06-23 12:42:32 +02:00
Yura Bondarenko
2c19d80a16 80195: Refresh moved Item's owningCollection before redirecting 2021-06-23 12:06:11 +02:00
Giuseppe Digilio
421c37f010 Disable community/collection delete button while the delete operation is being processed 2021-06-23 11:46:32 +02:00
Yura Bondarenko
0ac9d58194 80195: Update ItemMoveComponent unit tests 2021-06-23 11:35:37 +02:00
Yura Bondarenko
1407ea85d7 80195: Fix move request handling 2021-06-23 11:29:11 +02:00
Yura Bondarenko
b2c002057e 80195: Replace input suggestions with collection selector 2021-06-23 11:07:51 +02:00
Giuseppe Digilio
73a9fe16c5 [CSTPER-144] Fixed issue with authorization request encountered while logging-in with external idp 2021-06-23 10:41:54 +02:00
Tim Donohue
ddb7d5181f Merge pull request #1210 from DSpace/dependabot/npm_and_yarn/dns-packet-1.3.4
Bump dns-packet from 1.3.1 to 1.3.4
2021-06-22 14:46:29 -05:00
Tim Donohue
720126647c Add missing i18n key 2021-06-22 14:42:57 -05:00
Bruno Roemers
627b271d3b 80233: Write tests for pagination 2021-06-22 18:53:28 +02:00
Tim Donohue
3d4f493f9f Merge pull request #1221 from atmire/move-header-changes-to-dspace-theme
Move header changes to dspace theme
2021-06-22 09:15:22 -05:00
Bruno Roemers
c5689df73d 80233: Add required providers to test 2021-06-22 16:08:02 +02:00
Bruno Roemers
45ad6b6f0b 80233: Use correct relationship direction 2021-06-22 16:06:49 +02:00
Yura Bondarenko
a617e04290 80154: Change badge-light to badge-info 2021-06-22 09:09:39 +02:00
Art Lowel
d9a8b8f3fd add pagination to edit relationships tab 2021-06-21 16:18:12 +02:00
Yura Bondarenko
7c609820b1 80154: Fix semicolon placement 2021-06-18 15:42:07 +02:00
Yura Bondarenko
3a8e658d54 80154: Keep using Bootstrap variables 2021-06-18 15:24:16 +02:00
Tim Donohue
e546a4f0b5 Merge pull request #1225 from atmire/issue-1224-workflow-rejection-reason-not-properly-encoded
Workflow rejection reasons are not properly encoded
2021-06-17 15:58:04 -05:00
Tim Donohue
cfd6512856 Merge pull request #1230 from atmire/w2p-80103_Fix-admin-sidebar-link-a11y-issues
Fix admin sidebar link a11y issues
2021-06-17 15:48:54 -05:00
Tim Donohue
4b541a166f Merge pull request #1204 from DSpace/dependabot/npm_and_yarn/browserslist-4.16.6
Bump browserslist from 4.16.0 to 4.16.6
2021-06-17 15:02:38 -05:00
Yura Bondarenko
f3faa0df2c 80154: Revert to default Bootstrap grays 2021-06-17 16:58:00 +02:00
Yura Bondarenko
8085885da4 79730: Move aria-label from span to button 2021-06-17 14:05:57 +02:00
dependabot[bot]
aa5a395d91 Bump browserslist from 4.16.0 to 4.16.6
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.16.0 to 4.16.6.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.16.0...4.16.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-16 20:57:10 +00:00
dependabot[bot]
f20b139841 Bump dns-packet from 1.3.1 to 1.3.4
Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 1.3.1 to 1.3.4.
- [Release notes](https://github.com/mafintosh/dns-packet/releases)
- [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-16 20:56:35 +00:00
Tim Donohue
700afc2709 Create a SECURITY.md to document security policies 2021-06-16 12:03:30 -05:00
Marie Verdonck
cf515fe6f0 80113: Prevent anyone but site admin from accessing /access-control/epeople 2021-06-16 16:49:57 +02:00
Tim Donohue
166784b7f2 Merge pull request #1235 from tdonohue/fix_1231
Fix incorrect i18n tags in Collection Delete page
2021-06-16 09:15:40 -05:00
Art Lowel
b556234207 add aria and alt attributes to base header as well 2021-06-16 13:05:03 +02:00
Tim Donohue
98598a53d9 Fix incorrect i18n tags 2021-06-15 14:30:18 -05:00
Tim Donohue
f0ae00e7df Merge pull request #1211 from 4Science/CST-4223
Creating a new submission should redirect to workspaceitem edit page
2021-06-15 14:28:38 -05:00
Bruno Roemers
3fc44f6fc1 80113: Write tests for GroupsRegistryComponent 2021-06-15 19:38:33 +02:00
Bruno Roemers
3b07738d4d 80113: Write tests for GroupPageGuard 2021-06-15 18:43:50 +02:00
Bruno Roemers
3bc031ff00 80113: Create Group Page guard 2021-06-15 17:17:44 +02:00
Bruno Roemers
a69a4e9696 80113: Set ableToEdit on GroupDTOModel 2021-06-15 15:40:35 +02:00
Giuseppe Digilio
b85ebb2791 Merge remote-tracking branch 'origin/main' into #1129 2021-06-15 11:32:21 +02:00
Giuseppe Digilio
28c0c38d0d Merge remote-tracking branch 'origin/main' into #1110 2021-06-14 17:27:07 +02:00
Yana De Pauw
15e45c3dec 80103: Fix admin sidebar link a11y issues 2021-06-14 16:14:39 +02:00
Yura Bondarenko
34b117efe3 80084: Fix unit test & LGTM issues 2021-06-14 10:53:53 +02:00
Art Lowel
04b4f1cf58 Fix comment punctuation 2021-06-14 10:30:17 +02:00
Yura Bondarenko
64049fdcf7 79768: Make relative URLs absolute 2021-06-14 10:08:15 +02:00
Yura Bondarenko
2ed16aa66e 79768: Update typedocs 2021-06-14 10:08:15 +02:00
Yura Bondarenko
6a4e56322f 79768: Rename method 2021-06-14 10:08:15 +02:00
Yura Bondarenko
81b76dd327 79768: Fix tag: citation_publisher / citation_*_institution 2021-06-14 10:08:15 +02:00
Yura Bondarenko
304d8f7386 79768: Fix tag: citation_abstract_html_url 2021-06-14 10:08:15 +02:00
Yura Bondarenko
67f8ce7849 79768: Rename citation_date to citation_publication_date 2021-06-14 10:08:15 +02:00
Yura Bondarenko
6f7b76ec39 79768: Remove og:title & og:description 2021-06-14 10:08:15 +02:00
Yura Bondarenko
cb4446b79d 79768: Update & add unit tests 2021-06-14 10:08:15 +02:00
Yura Bondarenko
1caba78b4d 79768: Check against list of allowed mimetypes 2021-06-14 10:08:15 +02:00
Yura Bondarenko
9fe5a91bc2 79768: Extract download route method for Bundles with multiple Bitstreams 2021-06-14 10:08:15 +02:00
Art Lowel
dde57b9387 update citation_pdf_url logic 2021-06-14 10:06:18 +02:00
Yura Bondarenko
737728f603 79730: Remove label margins 2021-06-14 08:06:15 +02:00
Yura Bondarenko
d37d043531 79730: Show input labels when available 2021-06-14 08:06:15 +02:00
Yura Bondarenko
08878941ab 79730: Fix tslint issues 2021-06-14 08:06:15 +02:00
Yura Bondarenko
c60fa2c441 79730: Don't submit date slider changes until keyup 2021-06-14 08:06:15 +02:00
Yura Bondarenko
6e95990431 79730: Improve slider handles keyboard control 2021-06-14 08:06:15 +02:00
Yura Bondarenko
cb3f5ad259 79730: Add null href to more/collapse toggle links 2021-06-14 08:06:15 +02:00
Yura Bondarenko
abe26ce9f8 79730: Keyboard navigation for expandable filter facets 2021-06-14 08:06:15 +02:00
Yura Bondarenko
3e86efc66a 79730: Add labels around date range inputs 2021-06-14 08:06:15 +02:00
Yura Bondarenko
5b490203b2 79730: Add labels around FilterInputSuggestionsComponent inputs 2021-06-14 08:06:15 +02:00
Yura Bondarenko
ffb320373d 79730: Add labels around facet checkbox inputs 2021-06-14 08:06:15 +02:00
Yura Bondarenko
4683df431c 79730: Exclude search facet link from tablist 2021-06-14 08:06:15 +02:00
David Cavrenne [Atmire]
d253790c7d Updated version of the FR wordings (#1223)
Completed French message catalog.
2021-06-12 08:35:31 +02:00
Tim Donohue
22548c1e9d Merge pull request #1215 from atmire/remove-duplicate-author-field
Remove duplicate author field
2021-06-11 15:45:54 -05:00
Tim Donohue
79d5645f81 Merge pull request #1227 from tdonohue/demo_homepage
Remove references to Testathon & Beta 5 from Demo / Default theme
2021-06-11 14:59:15 -05:00
Tim Donohue
4c6d355376 Merge pull request #1212 from atmire/separate-startup-css
Fix theme switching issues
2021-06-11 14:57:55 -05:00
Tim Donohue
5edef6f942 Merge pull request #1209 from 4Science/issue-1208
Fix the rel name for the submissioncclicenseUrls-search link
2021-06-11 12:22:35 -05:00
Tim Donohue
9b80173b87 Merge pull request #1216 from atmire/w2p-79698_fix-browse-by-author-name-special-chars
Escape browse by author data requests
2021-06-11 11:21:46 -05:00
Tim Donohue
015f3b9607 Remove references to Testathon & Beta 5 2021-06-11 11:01:31 -05:00
Bruno Roemers
586de36835 Merge branch 'main' into issue-1224-workflow-rejection-reason-not-properly-encoded 2021-06-11 17:09:23 +02:00
Art Lowel
eead947352 put more useful example sass variable overrides in custom theme 2021-06-11 17:08:29 +02:00
Art Lowel
f2a29a6425 improve structure double footer 2021-06-11 17:08:29 +02:00
Art Lowel
2ddda1c766 enable e2e stacktrace 2021-06-11 17:08:29 +02:00
Art Lowel
74a17da5b8 fix issue where home page background image would wrap around on certain screen widths 2021-06-11 17:08:29 +02:00
Art Lowel
c756c68f28 move header changes to dspace theme 2021-06-11 17:08:29 +02:00
Bruno Roemers
412822db7c Merge branch 'main' into w2p-79698_fix-browse-by-author-name-special-chars 2021-06-11 17:06:24 +02:00
Tim Donohue
2cd78470ce Merge pull request #1226 from tdonohue/fix_ci_issues
Add option to pin to a specific version of Chrome/ChromeDriver in our CI process
2021-06-11 09:46:30 -05:00
Tim Donohue
e7282bdbd7 Minor cleanup, print chromedriver version after installation 2021-06-11 08:46:17 -05:00
Art Lowel
326bffae7f switch chromedriver to npm 2021-06-11 08:42:43 -05:00
Tim Donohue
b104958473 Add option to pin to a specific version of Chrome/ChromeDriver. Pin to v90 until v91 bugs are fixed 2021-06-10 12:56:40 -05:00
Bruno Roemers
a27a7a4083 Test requestService.uriEncodeBody 2021-06-10 15:00:03 +02:00
Bruno Roemers
bb2892edd8 BUGFIX: Encode special characters when sending workflow action 2021-06-10 14:45:30 +02:00
Giuseppe Digilio
4862a399c9 Merge remote-tracking branch 'origin/main' into #1110 2021-06-01 14:14:47 +02:00
Giuseppe Digilio
eaaad88443 [CST-4248] Remove embargo form field and add link to bitstream authorization page 2021-06-01 14:13:19 +02:00
Giuseppe Digilio
c150fb881e [CST-4248] bitstream authorizations page 2021-06-01 14:12:12 +02:00
Giuseppe Digilio
3e53b7c7b1 [CST-4248] Add possibility to add additional content to form.component 2021-06-01 14:09:17 +02:00
Giuseppe Digilio
2dfed863ed [DSC-75] Fix issue while deleting multiple qualdrop value 2021-05-31 12:20:42 +02:00
Yura Bondarenko
95b98d3f79 79597: Remove unused imports 2021-05-31 10:20:28 +02:00
Bruno Roemers
4ad089ef54 79698: Escape browse by author data requests 2021-05-28 15:40:20 +02:00
Samuel
bcfecc53a1 add support for multiple metadata fields to the MetadataRepresentationListComponent - fix bug when unauthorized for related item 2021-05-28 11:53:59 +02:00
Yura Bondarenko
4b238e1842 79597: Update ds-metadata-field-wrapper unit tests 2021-05-27 18:03:53 +02:00
Yura Bondarenko
120ecc6988 79597: Fix ds-metadata-field-wrapper for thumbnails 2021-05-27 17:10:42 +02:00
Yura Bondarenko
bcfb890e1a 79597: Update unit tests 2021-05-27 16:34:52 +02:00
Yura Bondarenko
c717fc5ec8 79597: Fix thumbnails ~ item page direct request 2021-05-27 16:00:06 +02:00
Art Lowel
899b30213e show full screen loader when switching themes 2021-05-27 15:06:26 +02:00
Art Lowel
772ac12329 create separate startup css to load before the theme is chosen 2021-05-27 11:51:59 +02:00
Yura Bondarenko
9b95fc5de9 79597: Add space between rows in FullFileSectionComponent 2021-05-27 11:18:40 +02:00
Yura Bondarenko
6cbd9dc920 79597: Remove GridThumbnailComponent 2021-05-27 11:06:08 +02:00
Yura Bondarenko
4f38821bb3 79597: Replace ds-grid-thumbnail with ds-thumbnail 2021-05-27 11:06:08 +02:00
Yura Bondarenko
41c07e74ca 79597: Add input to toggle thumbnail max-width 2021-05-27 11:05:48 +02:00
Alessandro Martelli
060d0dd556 [CST-4223] Creating a new submission should redirect to workspaceitem edit page 2021-05-27 09:43:29 +02:00
Andrea Bollini
fce77104d4 Fix the rel name for the submissioncclicenseUrls-search link 2021-05-26 22:39:06 +02:00
Samuel
21686c86df add support for multiple metadata fields to the MetadataRepresentationListComponent 2021-05-25 11:51:19 +02:00
Yura Bondarenko
ca7d45ff0c 79597: Fix tslint issue 2021-05-25 11:18:16 +02:00
Yura Bondarenko
363d1d74df 79597: Update unit tests 2021-05-25 11:03:51 +02:00
Yura Bondarenko
4567f8cc2c 79597: Limit thumbnail width & set to portrait 2021-05-25 10:20:46 +02:00
Yura Bondarenko
c9ff89a143 79597: Thumbnail placeholder style ~ CSS variables 2021-05-25 10:08:33 +02:00
Yura Bondarenko
4b6e02f773 79597: Specify i18n text for person, project & orgunit 2021-05-25 09:55:19 +02:00
Yura Bondarenko
7a69a23f0c 79597: Improve placeholder contrast 2021-05-25 09:46:54 +02:00
Yura Bondarenko
d80da3bbfe 79597: Add HTML placeholder for missing thumbnails 2021-05-25 09:44:39 +02:00
Yura Bondarenko
55affdebce 79597: Add alt text to ds-thumbnail 2021-05-25 09:28:02 +02:00
Tim Donohue
f85a5e65ad Merge pull request #1182 from atmire/w2p-79327_Fix-item-level-statistics
Fix item-level statistics pages
2021-05-24 11:47:22 -05:00
Tim Donohue
8daf52e8c2 Merge pull request #1200 from atmire/w2p-79219_update-metadata-import-export-script-params
Update metadata import export script params
2021-05-24 11:22:40 -05:00
Tim Donohue
fab567400d Merge pull request #1180 from atmire/w2p-79325_Fix-pagination-in-lookup
Fix pagination in author lookup window
2021-05-24 10:20:42 -05:00
Yana De Pauw
579f98d027 79327: Follow up fixes to test 2021-05-20 10:45:14 +02:00
Yana De Pauw
926dd46627 79327: Fix LGTM issues and add e2e tests 2021-05-20 09:45:48 +02:00
Giuseppe Digilio
3c0cb33bc7 fix failed build 2021-05-19 18:16:31 +02:00
Giuseppe Digilio
98dde58f9d [D4CRIS-1080] Fix issue where a replace patch operation was dispatched instead of an add one when field's previous value is empty 2021-05-19 16:28:49 +02:00
Giuseppe Digilio
d6dbbd1f1f Add tests for handleArrayGroupPatch method 2021-05-19 15:36:46 +02:00
Giuseppe Digilio
e18c66d688 Fix issue with patch operations related to repeatable fields 2021-05-19 15:36:43 +02:00
Giuseppe Digilio
e0edcd64d2 Fix wrong visualization of bitstream access condition form within submission form 2021-05-19 15:35:37 +02:00
Giuseppe Digilio
91137a216f Merge remote-tracking branch 'origin/main' into #1110 2021-05-19 15:08:02 +02:00
Giuseppe Digilio
d06b76af3f Fix issue with patching value with a date 2021-05-19 15:04:12 +02:00
Art Lowel
7e129f282f remove extra author field from item pages 2021-05-19 13:05:15 +02:00
Michael Spalti
da2bbcee09 Merge branch 'main' into iiif-mirador 2021-05-18 15:45:23 -07:00
Michael Spalti
3bd8e355f6 Added description field to iiif item view. 2021-05-18 15:42:46 -07:00
Tim Donohue
68bd8d40e8 Merge pull request #1181 from atmire/Fix-dso-selector-issues
Fix dso-selector issues
2021-05-17 12:33:36 -05:00
Michael Spalti
3dacbe51a1 Merge branch 'main' into iiif-mirador 2021-05-16 16:30:34 -07:00
Tim Donohue
5f87d69e9b Merge pull request #1145 from atmire/w2p-79218_remove-menu-options-for-disabled-features
Remove menu options for disabled features
2021-05-12 14:43:16 -05:00
Giuseppe Digilio
d3466c3e82 Fix issue where uploaded files disappear 2021-05-12 17:59:11 +02:00
Kristof De Langhe
43b8f45eee 79252: Remove unused import 2021-05-12 16:50:18 +02:00
Yana De Pauw
6631980ee6 79327: Fix item-level statistics pages 2021-05-12 16:31:48 +02:00
Yana De Pauw
4a8becf662 Fix ORCID tab loading 2021-05-12 14:47:16 +02:00
Yana De Pauw
a77ca2f126 79325: Fix pagination in the external metadata lookup 2021-05-11 11:39:46 +02:00
Tim Donohue
a87bf009ef Merge pull request #1146 from atmire/w2p-79220_fix-edit-group-navigation-bug
Fix edit group navigation bug
2021-05-07 09:42:35 -05:00
Kristof De Langhe
86bf7ff4f2 79252: Fix dso-selector issues 2021-05-06 18:03:46 +02:00
Tim Donohue
a69033917d Merge pull request #1086 from 4Science/CST-4009
[CST-4009] Discovery result sort options not reflecting what is configured
2021-05-05 10:52:07 -05:00
Tim Donohue
9dc9b5accf Merge pull request #1138 from atmire/w2p-78991_Issue-1112_Fix-date-filter-bugs
Fix date filter bugs
2021-05-04 14:19:04 -05:00
Tim Donohue
7dd2683fc3 Merge pull request #1139 from atmire/w2p-78994_Issue-1103_Fix-relationship-modal-on-item-page
Fix relationship modal on item page
2021-05-04 12:41:19 -05:00
Tim Donohue
abca095b9e Merge pull request #1105 from atmire/Edit-item-page-permission-checks
Edit item page permission checks
2021-05-04 09:24:16 -05:00
Bruno Roemers
f0fb8c1005 79219: Improve tests and wording 2021-05-04 13:43:51 +02:00
Bruno Roemers
042afd9bb8 79220: Fix edit group navigation bug 2021-05-04 11:46:04 +02:00
Yura Bondarenko
15ad31bd84 78991: Clean up SearchOptions.toRestUrl
* Extract "selective encoding" ops into separate methods
* Add comments to clarify regex
* Use hasValue() instead of just checking on 'match'
* Leave only the last comma of filter values unencoded
2021-05-04 11:26:19 +02:00
Bruno Roemers
f49a7746fb 79219: Remove -f from ExportMetadataSelectorComponent and pass uuid to -i 2021-05-04 11:19:01 +02:00
Bruno Roemers
93450e1dcf 79219: Remove -e option from MetadataImportPageComponent 2021-05-04 11:08:55 +02:00
Yura Bondarenko
b9a8bfb2bd 78991: Also test SearchOptions.fixedFilter 2021-05-04 10:44:06 +02:00
Yura Bondarenko
e682997195 78991: URI-encode SearchOptions query values 2021-05-04 10:34:37 +02:00
Yura Bondarenko
340f9518cd 78991: Fix SearchOptions typing 2021-05-04 10:34:37 +02:00
Bruno Roemers
fe4fe9e8d3 79218: Comment out all disabled menu options 2021-05-03 19:07:02 +02:00
Bruno Roemers
b5342e0fab 79218: Remove duplicate menu item 2021-05-03 18:41:56 +02:00
Tim Donohue
eb3cd85680 Merge pull request #1137 from atmire/w2p-78849_Issue-1113_Fix-forgot-password-page
Fix forgot password page
2021-04-30 16:57:49 -05:00
Tim Donohue
09a7685a3f Merge pull request #1109 from DSpace/dependabot/npm_and_yarn/ssri-6.0.2
Bump ssri from 6.0.1 to 6.0.2
2021-04-30 12:13:04 -05:00
Tim Donohue
6d00cad749 Merge pull request #1045 from DSpace/dependabot/npm_and_yarn/elliptic-6.5.4
Bump elliptic from 6.5.3 to 6.5.4
2021-04-29 17:19:46 -05:00
Yura Bondarenko
60009144a1 78994: Remove unused import 2021-04-29 14:28:37 +02:00
Yura Bondarenko
b2b077868e 78994: Disable no-shadowed-variable 2021-04-29 14:26:33 +02:00
Kristof De Langhe
a24cfe4cc7 78243: Feedback 2021-04-29 2021-04-29 14:15:03 +02:00
Yura Bondarenko
032231f10e 78849: Fix lint issues 2021-04-29 13:57:31 +02:00
Yura Bondarenko
781a88bc4c 78849: Fix double notification on submit 2021-04-29 13:42:57 +02:00
dependabot[bot]
d2b44318fa Bump elliptic from 6.5.3 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-28 21:57:44 +00:00
Alessandro Martelli
ad7824460b [CST-4009] update en.json5 2021-04-28 15:28:02 +02:00
Tim Donohue
8cade4fbf5 Merge pull request #1104 from atmire/Angular-10-upgrade-test-fixes
Angular 10 upgrade test fixes
2021-04-27 14:23:52 -05:00
Tim Donohue
fecf59e433 Merge pull request #1118 from 4Science/#1111
Fix visibility issue with collapsed navbar menu
2021-04-27 13:27:31 -05:00
Alessandro Martelli
bdc2dd5f9c [CST-4009] fixed search configuration stream 2021-04-27 09:53:38 +02:00
Yura Bondarenko
0fe199a97c 78849: Fix unit test 2021-04-26 16:49:42 +02:00
Yura Bondarenko
aca1c86455 78994: Provide Item's owning collection to relation modal 2021-04-26 15:13:41 +02:00
Yura Bondarenko
d62d9b0f48 78994: Update unit tests 2021-04-26 15:13:41 +02:00
Yura Bondarenko
5f45e93d12 78994: Remove setItem method 2021-04-26 13:24:26 +02:00
Yura Bondarenko
4634d2a4a8 78991: Don't initialize SearchFilterComponent with closed=true 2021-04-26 11:48:15 +02:00
Yura Bondarenko
6c2a3431c1 78991: Fix range handle lines
& remove duplicate CSS variable
2021-04-26 11:48:15 +02:00
Yura Bondarenko
4fa6a3e976 78991: Set fallback max date to the current year 2021-04-26 10:53:37 +02:00
Yura Bondarenko
eb9a7a15d6 78991: Specify filter operator for (date) ranges 2021-04-26 10:18:40 +02:00
Yura Bondarenko
8433f49ed9 78991: Initialize slider handle width 2021-04-26 09:09:51 +02:00
Alessandro Martelli
7c0d9acbf1 [CST-4009] default sort option configured with default sort order 2021-04-23 16:46:44 +02:00
Yura Bondarenko
7d0ea04b3e 78849: Add unit tests for EPerson registration caching 2021-04-23 15:45:46 +02:00
Yura Bondarenko
1aa659e6b7 78849: Fix cache/re-request issue & other improvements 2021-04-23 13:28:41 +02:00
Giuseppe Digilio
b6ab3d2067 [CST-4087] fix issue with mydspace result default order 2021-04-23 12:51:27 +02:00
Giuseppe Digilio
a205aa02b3 [CST-4009] Retrieve configuration by search config service 2021-04-23 12:47:53 +02:00
Alessandro Martelli
cba089081b Merge branch 'main' into CST-4009 2021-04-23 12:47:30 +02:00
Michael W Spalti
98571a496c Merge remote-tracking branch 'origin/iiif-mirador' into iiif-mirador 2021-04-20 14:46:44 -07:00
Giuseppe Digilio
ed7454ffc9 Fix visibility issue with collapsed navbar menu 2021-04-20 09:37:28 +02:00
dependabot[bot]
add2aac934 Bump ssri from 6.0.1 to 6.0.2
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-19 15:41:33 +00:00
Michael Spalti
4791cce928 Merge branch 'main' into iiif-mirador 2021-04-16 08:47:01 -07:00
Michael Spalti
2561d54b2d Added comments 2021-04-16 08:46:20 -07:00
reetagithub
a86f9444ce update fi.json5 (#1088)
* Update fi.json5

Part of the keys translated to Finnish

* Update fi.json5

The rest of the Finnish translations.

* Update fi.json5

Parent organization unit -> Ylemmän tason organisaatioyksikkö (was 'Ylätason')

* Update fi.json5
2021-04-16 17:28:21 +02:00
Kristof De Langhe
37be3530e6 Merge branch 'main' into w2p-78243_edit-item-page-permission-checks
Conflicts:
	src/app/core/data/feature-authorization/feature-id.ts
2021-04-16 12:35:30 +02:00
Kristof De Langhe
25f02b99d3 78243: message change 2021-04-16 12:31:22 +02:00
Kristof De Langhe
fd437eb7ee 78243: edit-item-page mocks, item-status operation refactoring 2021-04-16 11:36:33 +02:00
Kristof De Langhe
5fca681222 78001: RelationshipEffects test fixes 2021-04-15 13:19:27 +02:00
Kristof De Langhe
3504feedf3 78243: edit item page fine-grained permission checks - mocks + tests 2021-04-09 13:34:04 +02:00
Kristof De Langhe
a2e00bbd9f 78243: edit item page fine-grained permission checks 2021-04-08 17:54:27 +02:00
Alessandro Martelli
23fe338c5d [CST-4009] fix sort options on pagination change 2021-04-08 16:18:31 +02:00
Alessandro Martelli
1cbd41ef38 Merge branch 'main' into CST-4009
# Conflicts:
#	src/app/core/shared/search/search-configuration.service.ts
#	src/app/core/shared/search/search.service.ts
#	src/app/shared/search/search-settings/search-settings.component.ts
2021-04-08 15:51:05 +02:00
Alessandro Martelli
d54b7d9f7c [CST-4009] fix sort options on pagination change 2021-04-08 15:43:07 +02:00
Kristof De Langhe
9c85328b17 77998: xdescribe fixes 2021-04-07 15:45:22 +02:00
Giuseppe Digilio
b4686deb63 [CST-4009] Retrieve sort options also for search page 2021-04-06 17:49:06 +02:00
Alessandro Martelli
4d85c0270f [CST-4009] sorting options translations 2021-04-06 10:30:26 +02:00
Alessandro Martelli
9b8ada0326 [CST-4009] Discovery result sort options not reflecting what is configured 2021-04-06 10:06:15 +02:00
Michael Spalti
c37b31599c Merge remote-tracking branch 'upstream/main' into iiif-mirador 2021-04-02 16:35:54 -07:00
Michael Spalti
6f55225aee Removed unused variable. 2021-04-02 15:59:36 -07:00
Michael Spalti
247ae73c64 Merge branch 'main' into iiif-mirador 2021-04-02 14:41:50 -07:00
Michael Spalti
3bc7739098 Minor fix in module. 2021-04-01 16:02:28 -07:00
Michael Spalti
ce11ae2480 Merge branch 'main' into iiif-mirador 2021-04-01 16:01:08 -07:00
Michael Spalti
3744abb26f Allow canvas side panel on all views. 2021-04-01 15:04:40 -07:00
Michael Spalti
97e8c9b955 Added title to the mirador iframe. 2021-03-30 16:03:02 -07:00
Michael Spalti
0250b182b6 Changed property name 2021-03-30 15:42:51 -07:00
Michael Spalti
e4a51af46e Merge branch 'iiif-mirador' of https://github.com/mspalti/dspace-angular into iiif-mirador 2021-03-30 14:02:11 -07:00
Michael Spalti
c0aac8a5e9 Added mobile breakpoint for mirador viewer configuration. 2021-03-30 13:46:28 -07:00
Michael Spalti
f52ed2a218 Updated iiif component tests. 2021-03-30 13:41:11 -07:00
Michael Spalti
0330b3ea4c yarn.lock 2021-03-30 10:54:03 -07:00
Michael Spalti
5a8f38abdc Updates to iiif list elements. 2021-03-30 10:54:03 -07:00
Michael Spalti
45c6f4eb84 Added iiif labels to en.json5 2021-03-30 10:54:03 -07:00
Michael Spalti
187ae50d29 Added iiif entity module to parent item module. 2021-03-30 10:54:03 -07:00
Michael Spalti
2d694a864e Added mirador files for webpack build 2021-03-30 10:54:03 -07:00
Michael Spalti
71851fe141 Added FileSectionComponent to shared module. 2021-03-30 10:54:03 -07:00
Michael Spalti
23e7675171 Added iiif entity group. 2021-03-30 10:54:03 -07:00
Michael Spalti
42802bd543 Added mirador route to express server. 2021-03-30 10:54:03 -07:00
Michael Spalti
c02983c889 Added webpack configuration for mirador. 2021-03-30 10:54:03 -07:00
Michael Spalti
3b5df5d432 Added mirador deps and scripts to package.json 2021-03-30 10:54:03 -07:00
Michael Spalti
aa27ddad02 yarn.lock 2021-03-27 13:44:01 -07:00
Michael Spalti
f377347dcc Updates to iiif list elements. 2021-03-27 13:37:07 -07:00
Michael Spalti
2ec1096e21 Added iiif labels to en.json5 2021-03-27 13:35:11 -07:00
Michael Spalti
30ff10ea90 Added iiif entity module to parent item module. 2021-03-27 13:34:26 -07:00
Michael Spalti
6081dabe48 Added mirador files for webpack build 2021-03-27 10:18:15 -07:00
Michael Spalti
27afd4192f Added FileSectionComponent to shared module. 2021-03-27 10:12:18 -07:00
Michael Spalti
c6bc21f9db Added iiif entity group. 2021-03-27 10:09:22 -07:00
Michael Spalti
7e1c441ee8 Added mirador route to express server. 2021-03-27 10:03:20 -07:00
Michael Spalti
a56ebad133 Added webpack configuration for mirador. 2021-03-27 10:01:50 -07:00
Michael Spalti
156e9a08b0 Added mirador deps and scripts to package.json 2021-03-27 09:57:45 -07:00
1555 changed files with 66047 additions and 38999 deletions

View File

@@ -16,6 +16,9 @@ jobs:
DSPACE_REST_PORT: 8080 DSPACE_REST_PORT: 8080
DSPACE_REST_NAMESPACE: '/server' DSPACE_REST_NAMESPACE: '/server'
DSPACE_REST_SSL: false DSPACE_REST_SSL: false
# When Chrome version is specified, we pin to a specific version of Chrome
# Comment this out to use the latest release
#CHROME_VERSION: "90.0.4430.212-1"
strategy: strategy:
# Create a matrix of Node versions to test against (in parallel) # Create a matrix of Node versions to test against (in parallel)
matrix: matrix:
@@ -26,18 +29,28 @@ jobs:
steps: steps:
# https://github.com/actions/checkout # https://github.com/actions/checkout
- name: Checkout codebase - name: Checkout codebase
uses: actions/checkout@v1 uses: actions/checkout@v2
# https://github.com/actions/setup-node # https://github.com/actions/setup-node
- name: Install Node.js ${{ matrix.node-version }} - name: Install Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1 uses: actions/setup-node@v2
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Install latest Chrome (for e2e tests) # If CHROME_VERSION env variable specified above, then pin to that version.
# Otherwise, just install latest version of Chrome.
- name: Install Chrome (for e2e tests)
run: | run: |
sudo apt-get update if [[ -z "${CHROME_VERSION}" ]]
sudo apt-get --only-upgrade install google-chrome-stable -y then
echo "Installing latest stable version"
sudo apt-get update
sudo apt-get --only-upgrade install google-chrome-stable -y
else
echo "Installing version ${CHROME_VERSION}"
wget -q "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb"
sudo dpkg -i "google-chrome-stable_${CHROME_VERSION}_amd64.deb"
fi
google-chrome --version google-chrome --version
# https://github.com/actions/cache/blob/main/examples.md#node---yarn # https://github.com/actions/cache/blob/main/examples.md#node---yarn
@@ -53,9 +66,6 @@ jobs:
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn- restore-keys: ${{ runner.os }}-yarn-
- name: Install the latest chromedriver compatible with the installed chrome version
run: yarn global add chromedriver --detect_chromedriver_version
- name: Install Yarn dependencies - name: Install Yarn dependencies
run: yarn install --frozen-lockfile run: yarn install --frozen-lockfile
@@ -72,7 +82,7 @@ jobs:
# Upload coverage reports to Codecov (for Node v12 only) # Upload coverage reports to Codecov (for Node v12 only)
# https://github.com/codecov/codecov-action # https://github.com/codecov/codecov-action
- name: Upload coverage to Codecov.io - name: Upload coverage to Codecov.io
uses: codecov/codecov-action@v1 uses: codecov/codecov-action@v2
if: matrix.node-version == '12.x' if: matrix.node-version == '12.x'
# Using docker-compose start backend using CI configuration # Using docker-compose start backend using CI configuration
@@ -83,23 +93,63 @@ jobs:
docker-compose -f ./docker/cli.yml -f ./docker/cli.assetstore.yml run --rm dspace-cli docker-compose -f ./docker/cli.yml -f ./docker/cli.assetstore.yml run --rm dspace-cli
docker container ls docker container ls
# Wait until the REST API returns a 200 response (or for a max of 30 seconds) # Run integration tests via Cypress.io
# https://github.com/nev7n/wait_for_response # https://github.com/cypress-io/github-action
- name: Wait for DSpace REST Backend to be ready (for e2e tests) # (NOTE: to run these e2e tests locally, just use 'ng e2e')
uses: nev7n/wait_for_response@v1
with:
# We use the 'sites' endpoint to also ensure the database is ready
url: 'http://localhost:8080/server/api/core/sites'
responseCode: 200
timeout: 30000
- name: Get DSpace REST Backend info/properties
run: curl http://localhost:8080/server/api
- name: Run e2e tests (integration tests) - name: Run e2e tests (integration tests)
uses: cypress-io/github-action@v2
with:
# Run tests in Chrome, headless mode
browser: chrome
headless: true
# Start app before running tests (will be stopped automatically after tests finish)
start: yarn run serve:ssr
# Wait for backend & frontend to be available
# NOTE: We use the 'sites' REST endpoint to also ensure the database is ready
wait-on: http://localhost:8080/server/api/core/sites, http://localhost:4000
# Wait for 2 mins max for everything to respond
wait-on-timeout: 120
# Cypress always creates a video of all e2e tests (whether they succeeded or failed)
# Save those in an Artifact
- name: Upload e2e test videos to Artifacts
uses: actions/upload-artifact@v2
if: always()
with:
name: e2e-test-videos
path: cypress/videos
# If e2e tests fail, Cypress creates a screenshot of what happened
# Save those in an Artifact
- name: Upload e2e test failure screenshots to Artifacts
uses: actions/upload-artifact@v2
if: failure()
with:
name: e2e-test-screenshots
path: cypress/screenshots
# Start up the app with SSR enabled (run in background)
- name: Start app in SSR (server-side rendering) mode
run: | run: |
chromedriver --url-base='/wd/hub' --port=4444 & nohup yarn run serve:ssr &
yarn run e2e:ci printf 'Waiting for app to start'
until curl --output /dev/null --silent --head --fail http://localhost:4000/home; do
printf '.'
sleep 2
done
echo "App started successfully."
# Get homepage and verify that the <meta name="title"> tag includes "DSpace".
# If it does, then SSR is working, as this tag is created by our MetadataService.
# This step also prints entire HTML of homepage for easier debugging if grep fails.
- name: Verify SSR (server-side rendering)
run: |
result=$(wget -O- -q http://localhost:4000/home)
echo "$result"
echo "$result" | grep -oE "<meta name=\"title\" [^>]*>" | grep DSpace
- name: Stop running app
run: kill -9 $(lsof -t -i:4000)
- name: Shutdown Docker containers - name: Shutdown Docker containers
run: docker-compose -f ./docker/docker-compose-ci.yml down run: docker-compose -f ./docker/docker-compose-ci.yml down

78
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,78 @@
# DSpace Docker image build for hub.docker.com
name: Docker images
# Run this Build for all pushes to 'main' or maintenance branches, or tagged releases.
# Also run for PRs to ensure PR doesn't break Docker build process
on:
push:
branches:
- main
- 'dspace-**'
tags:
- 'dspace-**'
pull_request:
jobs:
docker:
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular'
if: github.repository == 'dspace/dspace-angular'
runs-on: ubuntu-latest
env:
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
# For a new commit on default branch (main), use the literal tag 'dspace-7_x' on Docker image.
# For a new commit on other branches, use the branch name as the tag for Docker image.
# For a new tag, copy that tag name as the tag for Docker image.
IMAGE_TAGS: |
type=raw,value=dspace-7_x,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=tag
# Define default tag "flavor" for docker/metadata-action per
# https://github.com/docker/metadata-action#flavor-input
# We turn off 'latest' tag by default.
TAGS_FLAVOR: |
latest=false
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v2
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
###############################################
# Build/Push the 'dspace/dspace-angular' image
###############################################
# https://github.com/docker/metadata-action
# Get Metadata for docker_build step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular' image
id: meta_build
uses: docker/metadata-action@v3
with:
images: dspace/dspace-angular
tags: ${{ env.IMAGE_TAGS }}
flavor: ${{ env.TAGS_FLAVOR }}
# https://github.com/docker/build-push-action
- name: Build and push 'dspace-angular' image
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
# but we ONLY do an image push to DockerHub if it's NOT a PR
push: ${{ github.event_name != 'pull_request' }}
# Use tags / labels provided by 'docker/metadata-action' above
tags: ${{ steps.meta_build.outputs.tags }}
labels: ${{ steps.meta_build.outputs.labels }}

4
.gitignore vendored
View File

@@ -7,10 +7,6 @@ npm-debug.log
/build/ /build/
/src/environments/environment.ts
/src/environments/environment.dev.ts
/src/environments/environment.prod.ts
/coverage /coverage
/dist/ /dist/

View File

@@ -3,5 +3,6 @@
"i18n-ally.localesPaths": [ "i18n-ally.localesPaths": [
"src/assets/i18n", "src/assets/i18n",
"src/app/core/locale" "src/app/core/locale"
] ],
"typescript.tsdk": "node_modules\\typescript\\lib"
} }

View File

@@ -1,7 +1,7 @@
# This image will be published as dspace/dspace-angular # This image will be published as dspace/dspace-angular
# See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details # See https://github.com/DSpace/dspace-angular/tree/main/docker for usage details
FROM node:12-alpine FROM node:14-alpine
WORKDIR /app WORKDIR /app
ADD . /app/ ADD . /app/
EXPOSE 4000 EXPOSE 4000

22
LICENSE
View File

@@ -1,6 +1,6 @@
DSpace source code BSD License: BSD 3-Clause License
Copyright (c) 2002-2020, LYRASIS. All rights reserved. Copyright (c) 2002-2021, LYRASIS. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
@@ -13,13 +13,12 @@ notice, this list of conditions and the following disclaimer.
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
- Neither the name DuraSpace nor the name of the DSpace Foundation - Neither the name of the copyright holder nor the names of its
nor the names of its contributors may be used to endorse or promote contributors may be used to endorse or promote products derived from
products derived from this software without specific prior written this software without specific prior written permission.
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
@@ -29,11 +28,4 @@ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. DAMAGE.
DSpace uses third-party libraries which may be distributed under
different licenses to the above. Information about these licenses
is detailed in the LICENSES_THIRD_PARTY file at the root of the source
tree. You must agree to the terms of these licenses, in addition to
the above DSpace source code license, in order to use this software.

28
NOTICE Normal file
View File

@@ -0,0 +1,28 @@
Licenses of Third-Party Libraries
=================================
DSpace uses third-party libraries which may be distributed under
different licenses than specified in our LICENSE file. Information
about these licenses is detailed in the LICENSES_THIRD_PARTY file at
the root of the source tree. You must agree to the terms of these
licenses, in addition to the DSpace source code license, in order to
use this software.
Licensing Notices
=================
[July 2019] DuraSpace joined with LYRASIS (another 501(c)3 organization) in July 2019.
LYRASIS holds the copyrights of DuraSpace.
[July 2009] Fedora Commons joined with the DSpace Foundation and began operating under
the new name DuraSpace in July 2009. DuraSpace holds the copyrights of
the DSpace Foundation, Inc.
[July 2007] The DSpace Foundation, Inc. is a 501(c)3 corporation established in July 2007
with a mission to promote and advance the dspace platform enabling management,
access and preservation of digital works. The Foundation was able to transfer
the legal copyright from Hewlett-Packard Company (HP) and Massachusetts
Institute of Technology (MIT) to the DSpace Foundation in October 2007. Many
of the files in the source code may contain a copyright statement stating HP
and MIT possess the copyright, in these instances please note that the copy
right has transferred to the DSpace foundation, and subsequently to DuraSpace.

370
README.md
View File

@@ -3,17 +3,39 @@
dspace-angular dspace-angular
============== ==============
> The next UI for DSpace 7, based on Angular Universal. > The DSpace User Interface built on [Angular](https://angular.io/), written in [TypeScript](https://www.typescriptlang.org/) and using [Angular Universal](https://angular.io/guide/universal).
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) Overview
--------
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). DSpace open source software is a turnkey repository application used by more than
2,000 organizations and institutions worldwide to provide durable access to digital resources.
For more information, visit http://www.dspace.org/
DSpace consists of both a Java-based backend and an Angular-based frontend.
* Backend (https://github.com/DSpace/DSpace/) provides a REST API, along with other machine-based interfaces (e.g. OAI-PMH, SWORD, etc)
* The REST Contract is at https://github.com/DSpace/RestContract
* Frontend (this codebase) is the User Interface built on the REST API
Downloads
---------
* Backend (REST API): https://github.com/DSpace/DSpace/releases
* Frontend (User Interface): https://github.com/DSpace/dspace-angular/releases
## Documentation / Installation
Documentation for each release may be viewed online or downloaded via our [Documentation Wiki](https://wiki.lyrasis.org/display/DSDOC/).
The latest DSpace Installation instructions are available at:
https://wiki.lyrasis.org/display/DSDOC7x/Installing+DSpace
Quick start Quick start
----------- -----------
**Ensure you're running [Node](https://nodejs.org) `v12.x` or `v14.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) >= `v1.x`** **Ensure you're running [Node](https://nodejs.org) `v12.x`, `v14.x` or `v16.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) == `v1.x`**
```bash ```bash
# clone the repo # clone the repo
@@ -39,14 +61,17 @@ 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) - [Deploy](#deploy)
- [Running the application with Docker](#running-the-application-with-docker) - [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) - [Test a Pull Request](#test-a-pull-request)
- [Unit Tests](#unit-tests)
- [E2E Tests](#e2e-tests)
- [Writing E2E Tests](#writing-e2e-tests)
- [Documentation](#documentation) - [Documentation](#documentation)
- [Other commands](#other-commands) - [Other commands](#other-commands)
- [Recommended Editors/IDEs](#recommended-editorsides) - [Recommended Editors/IDEs](#recommended-editorsides)
@@ -65,60 +90,98 @@ Requirements
------------ ------------
- [Node.js](https://nodejs.org) and [yarn](https://yarnpkg.com) - [Node.js](https://nodejs.org) and [yarn](https://yarnpkg.com)
- Ensure you're running node `v12.x` or `v14.x` and yarn >= `v1.x` - Ensure you're running node `v12.x`, `v14.x` or `v16.x` and yarn == `v1.x`
If you have [`nvm`](https://github.com/creationix/nvm#install-script) or [`nvm-windows`](https://github.com/coreybutler/nvm-windows) installed, which is highly recommended, you can run `nvm install --lts && nvm use` to install and start using the latest Node LTS. If you have [`nvm`](https://github.com/creationix/nvm#install-script) or [`nvm-windows`](https://github.com/coreybutler/nvm-windows) installed, which is highly recommended, you can run `nvm install --lts && nvm use` to install and start using the latest Node LTS.
Installing Installing
---------- ----------
- `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 `src/environments/` folder. Default configuration file is located in `config/` folder.
To change the default configuration values, create local files that override the parameters you need to change. You can use `environment.template.ts` as a starting point. To override the default configuration values, create local files that override the parameters you need to change. You can use `config.example.yml` as a starting point.
- Create a new `environment.dev.ts` file in `src/environments/` for a `development` environment; - Create a new `config.(dev or development).yml` file in `config/` for a `development` environment;
- Create a new `environment.prod.ts` file in `src/environments/` for a `production` environment; - Create a new `config.(prod or production).yml` file in `config/` for a `production` environment;
The server settings can also be overwritten using an environment file. The settings can also be overwritten using an environment file or environment variables.
This file should be called `.env` and be placed in the project root. This file should be called `.env` and be placed in the project root.
The following settings can be overwritten in this file: The following non-convention settings:
```bash ```bash
DSPACE_HOST # The host name of the angular application DSPACE_HOST # The host name of the angular application
DSPACE_PORT # The port number of the angular application DSPACE_PORT # The port number of the angular application
DSPACE_NAMESPACE # The namespace of the angular application DSPACE_NAMESPACE # The namespace of the angular application
DSPACE_SSL # Whether the angular application uses SSL [true/false] DSPACE_SSL # Whether the angular application uses SSL [true/false]
```
DSPACE_REST_HOST # The host name of the REST application All other settings can be set using the following convention for naming the environment variables:
DSPACE_REST_PORT # The port number of the REST application
DSPACE_REST_NAMESPACE # The namespace of the REST application 1. replace all `.` with `_`
DSPACE_REST_SSL # Whether the angular REST uses SSL [true/false] 2. convert all characters to upper case
3. prefix with `DSPACE_`
e.g.
```bash
# The host name of the REST application
rest.host => DSPACE_REST_HOST
# The port number of the REST application
rest.port => DSPACE_REST_PORT
# The namespace of the REST application
rest.nameSpace => DSPACE_REST_NAMESPACE
# Whether the angular REST uses SSL [true/false]
rest.ssl => DSPACE_REST_SSL
cache.msToLive.default => DSPACE_CACHE_MSTOLIVE_DEFAULT
auth.ui.timeUntilIdle => DSPACE_AUTH_UI_TIMEUNTILIDLE
```
The equavelant to the non-conventional legacy settings:
```bash
DSPACE_UI_HOST => DSPACE_HOST
DSPACE_UI_PORT => DSPACE_PORT
DSPACE_UI_NAMESPACE => DSPACE_NAMESPACE
DSPACE_UI_SSL => DSPACE_SSL
``` ```
The same settings can also be overwritten by setting system environment variables instead, E.g.: The same settings can also be overwritten by setting system environment variables instead, E.g.:
```bash ```bash
export DSPACE_HOST=api7.dspace.org export DSPACE_HOST=api7.dspace.org
export DSPACE_UI_PORT=4200
``` ```
The priority works as follows: **environment variable** overrides **variable in `.env` file** overrides **`environment.(prod, dev or test).ts`** overrides **`environment.common.ts`** The priority works as follows: **environment variable** overrides **variable in `.env` file** overrides external config set by `DSPACE_APP_CONFIG_PATH` overrides **`config.(prod or dev).yml`**
These configuration sources are collected **at build time**, and written to `src/environments/environment.ts`. At runtime the configuration is fixed, and neither `.env` nor the process' environment will be consulted. These configuration sources are collected **at run time**, and written to `dist/browser/assets/config.json` for production and `src/app/assets/config.json` for development.
The configuration file can be externalized by using environment variable `DSPACE_APP_CONFIG_PATH`.
#### Using environment variables in code #### Using environment variables in code
To use environment variables in a UI component, use: To use environment variables in a UI component, use:
```typescript ```typescript
import { environment } from '../environment.ts'; import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
...
constructor(@Inject(APP_CONFIG) private appConfig: AppConfig) {}
...
``` ```
This file is generated by the script located in `scripts/set-env.ts`. This script will run automatically before every build, or can be manually triggered using the appropriate `config` script in `package.json` or
```typescript
import { environment } from '../environment.ts';
```
Running the app Running the app
@@ -146,6 +209,9 @@ This will build the application and put the result in the `dist` folder. You ca
### Running the application with Docker ### Running the application with Docker
NOTE: At this time, we do not have production-ready Docker images for DSpace.
That said, we do have quick-start Docker Compose scripts for development or testing purposes.
See [Docker Runtime Options](docker/README.md) See [Docker Runtime Options](docker/README.md)
@@ -184,34 +250,68 @@ Once you have tested the Pull Request, please add a comment and/or approval to t
### Unit Tests ### Unit Tests
Unit tests use Karma. You can find the configuration file at the same level of this README file:`./karma.conf.js` If you are going to use a remote test environment you need to edit the `./karma.conf.js`. Follow the instructions you will find inside it. To executing tests whenever any file changes you can modify the 'autoWatch' option to 'true' and 'singleRun' option to 'false'. A coverage report is also available at: http://localhost:9876/ after you run: `yarn run coverage`. Unit tests use the [Jasmine test framework](https://jasmine.github.io/), and are run via [Karma](https://karma-runner.github.io/).
You can find the Karma configuration file at the same level of this README file:`./karma.conf.js` If you are going to use a remote test environment you need to edit the `./karma.conf.js`. Follow the instructions you will find inside it. To executing tests whenever any file changes you can modify the 'autoWatch' option to 'true' and 'singleRun' option to 'false'. A coverage report is also available at: http://localhost:9876/ after you run: `yarn run coverage`.
The default browser is Google Chrome. The default browser is Google Chrome.
Place your tests in the same location of the application source code files that they test. Place your tests in the same location of the application source code files that they test, e.g. ending with `*.component.spec.ts`
and run: `yarn run test` and run: `yarn test`
### E2E test If you run into odd test errors, see the Angular guide to debugging tests: https://angular.io/guide/test-debugging
E2E tests use Protractor + Selenium server + browsers. You can find the configuration file at the same level of this README file:`./protractor.conf.js` Protractor is installed as 'local' as a dev dependency. ### E2E Tests
If you are going to use a remote test enviroment you need to edit the './e2e//protractor.conf.js'. Follow the instructions you will find inside it. E2E tests (aka integration tests) use [Cypress.io](https://www.cypress.io/). Configuration for cypress can be found in the `cypress.json` file in the root directory.
The default browser is Google Chrome. The test files can be found in the `./cypress/integration/` folder.
Place your tests at the following path: `./e2e` Before you can run e2e tests, two things are required:
1. You MUST have a running backend (i.e. REST API). By default, the e2e tests look for this at http://localhost:8080/server/ or whatever `rest` backend is defined in your `config.prod.yml` or `config.yml`. You may override this using env variables, see [Configuring](#configuring).
2. Your backend MUST include our Entities Test Data set. Some tests run against a (currently hardcoded) Community/Collection/Item UUID. These UUIDs are all valid for our Entities Test Data set. The Entities Test Data set may be installed easily via Docker, see https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker-compose#ingest-option-2-ingest-entities-test-data
and run: `ng e2e` Run `ng e2e` to kick off the tests. This will start Cypress and allow you to select the browser you wish to use, as well as whether you wish to run all tests or an individual test file. Once you click run on test(s), this opens the [Cypress Test Runner](https://docs.cypress.io/guides/core-concepts/test-runner) to run your test(s) and show you the results.
### Continuous Integration (CI) Test #### Writing E2E Tests
To run all the tests (e.g.: to run tests with Continuous Integration software) you can execute:`yarn run ci` Keep in mind that this command prerequisites are the sum of unit test and E2E tests. All E2E tests must be created under the `./cypress/integration/` folder, and must end in `.spec.ts`. Subfolders are allowed.
* The easiest way to start creating new tests is by running `ng e2e`. This builds the app and brings up Cypress.
* From here, if you are editing an existing test file, you can either open it in your IDE or run it first to see what it already does.
* To create a new test file, click `+ New Spec File`. Choose a meaningful name ending in `spec.ts` (Please make sure it ends in `.ts` so that it's a Typescript file, and not plain Javascript)
* Start small. Add a basic `describe` and `it` which just [cy.visit](https://docs.cypress.io/api/commands/visit) the page you want to test. For example:
```
describe('Community/Collection Browse Page', () => {
it('should exist as a page', () => {
cy.visit('/community-list');
});
});
```
* Run your test file from the Cypress window. This starts the [Cypress Test Runner](https://docs.cypress.io/guides/core-concepts/test-runner) in a new browser window.
* In the [Cypress Test Runner](https://docs.cypress.io/guides/core-concepts/test-runner), you'll Cypress automatically visit the page. This first test will succeed, as all you are doing is making sure the _page exists_.
* From here, you can use the [Selector Playground](https://docs.cypress.io/guides/core-concepts/test-runner#Selector-Playground) in the Cypress Test Runner window to determine how to tell Cypress to interact with a specific HTML element on that page.
* Most commands start by telling Cypress to [get()](https://docs.cypress.io/api/commands/get) a specific element, using a CSS or jQuery style selector
* Cypress can then do actions like [click()](https://docs.cypress.io/api/commands/click) an element, or [type()](https://docs.cypress.io/api/commands/type) text in an input field, etc.
* Cypress can also validate that something occurs, using [should()](https://docs.cypress.io/api/commands/should) assertions.
* Any time you save your test file, the Cypress Test Runner will reload & rerun it. This allows you can see your results quickly as you write the tests & correct any broken tests rapidly.
* Cypress also has a great guide on [writing your first test](https://on.cypress.io/writing-first-test) with much more info. Keep in mind, while the examples in the Cypress docs often involve Javascript files (.js), the same examples will work in our Typescript (.ts) e2e tests.
_Hint: Creating e2e tests is easiest in an IDE (like Visual Studio), as it can help prompt/autocomplete your Cypress commands._
More Information: [docs.cypress.io](https://docs.cypress.io/) has great guides & documentation helping you learn more about writing/debugging e2e tests in Cypress.
### Learning how to build tests
See our [DSpace Code Testing Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Testing+Guide) for more hints/tips.
Documentation Documentation
-------------- --------------
See [`./docs`](docs) for further documentation. Official DSpace documentation is available in the DSpace wiki at https://wiki.lyrasis.org/display/DSDOC7x/
Some UI specific configuration documentation is also found in the [`./docs`](docs) folder of htis codebase.
### Building code documentation ### Building code documentation
@@ -234,8 +334,6 @@ To get the most out of TypeScript, you'll need a TypeScript-aware editor. We've
- Free - Free
- [Visual Studio Code](https://code.visualstudio.com/) - [Visual Studio Code](https://code.visualstudio.com/)
- [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) - [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)
- [Atom](https://atom.io/)
- [TypeScript plugin](https://atom.io/packages/atom-typescript)
- Paid - Paid
- [Webstorm](https://www.jetbrains.com/webstorm/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/) - [Webstorm](https://www.jetbrains.com/webstorm/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/)
- [Sublime Text](http://www.sublimetext.com/3) - [Sublime Text](http://www.sublimetext.com/3)
@@ -251,101 +349,85 @@ File Structure
``` ```
dspace-angular dspace-angular
├── README.md * This document ├── config *
├── app.yaml * Application manifest file │ └── config.yml * Default app config
├── config * Folder for configuration files ├── cypress * Folder for Cypress (https://cypress.io/) / e2e tests
   ├── environment.default.js * Default configuration files ├── downloads *
   └── environment.test.js * Test configuration files ├── fixtures * Folder for e2e/integration test files
│ ├── integration * Folder for any fixtures needed by e2e tests
│ ├── plugins * Folder for Cypress plugins (if any)
│ ├── support * Folder for global e2e test actions/commands (run for all tests)
│ └── tsconfig.json * TypeScript configuration file for e2e tests
├── docker * See docker/README.md for details
│ ├── cli.assetstore.yml *
│ ├── cli.ingest.yml *
│ ├── cli.yml *
│ ├── db.entities.yml *
│ ├── docker-compose-ci.yml *
│ ├── docker-compose-rest.yml *
│ ├── docker-compose.yml *
│ └── README.md *
├── docs * Folder for documentation ├── docs * Folder for documentation
├── e2e * Folder for e2e test files │ └── Configuration.md * Configuration documentation
│   ├── app.e2e-spec.ts * ├── scripts *
   ├── app.po.ts * ├── merge-i18n-files.ts *
   ├── pagenotfound * ├── serve.ts *
   │   ├── pagenotfound.e2e-spec.ts * ├── sync-i18n-files.ts *
   │   └── pagenotfound.po.ts * ├── test-rest.ts *
   └── tsconfig.json * TypeScript configuration file for e2e tests └── webpack.js *
├── src * The source of the application
│ ├── app * The source code of the application, subdivided by module/page.
│ ├── assets * Folder for static resources
│ │ ├── fonts * Folder for fonts
│ │ ├── i18n * Folder for i18n translations
│ │ └── images * Folder for images
│ ├── backend * Folder containing a mock of the REST API, hosted by the express server
│ ├── config *
│ ├── environments *
│ │ ├── environment.production.ts * Production configuration files
│ │ ├── environment.test.ts * Test configuration files
│ │ └── environment.ts * Default (development) configuration files
│ ├── mirador-viewer *
│ ├── modules *
│ ├── ngx-translate-loaders *
│ ├── styles * Folder containing global styles
│ ├── themes * Folder containing available themes
│ │ ├── custom * Template folder for creating a custom theme
│ │ └── dspace * Default 'dspace' theme
│ ├── index.csr.html * The index file for client side rendering fallback
│ ├── index.html * The index file
│ ├── main.browser.ts * The bootstrap file for the client
│ ├── main.server.ts * The express (http://expressjs.com/) config and bootstrap file for the server
│ ├── polyfills.ts *
│ ├── robots.txt * The robots.txt file
│ ├── test.ts *
│ └── typings.d.ts *
├── webpack *
│ ├── helpers.ts * Webpack helpers
│ ├── webpack.browser.ts * Webpack (https://webpack.github.io/) config for browser build
│ ├── webpack.common.ts * Webpack (https://webpack.github.io/) common build config
│ ├── webpack.mirador.config.ts * Webpack (https://webpack.github.io/) config for mirador config build
│ ├── webpack.prod.ts * Webpack (https://webpack.github.io/) config for prod build
│ └── webpack.test.ts * Webpack (https://webpack.github.io/) config for test build
├── angular.json * Angular CLI (https://angular.io/cli) configuration
├── cypress.json * Cypress Test (https://www.cypress.io/) configuration
├── Dockerfile *
├── karma.conf.js * Karma configuration file for Unit Test ├── karma.conf.js * Karma configuration file for Unit Test
├── LICENSE *
├── LICENSES_THIRD_PARTY *
├── nodemon.json * Nodemon (https://nodemon.io/) configuration ├── nodemon.json * Nodemon (https://nodemon.io/) configuration
├── package.json * This file describes the npm package for this project, its dependencies, scripts, etc. ├── package.json * This file describes the npm package for this project, its dependencies, scripts, etc.
├── postcss.config.js * PostCSS (http://postcss.org/) configuration file ├── postcss.config.js * PostCSS (http://postcss.org/) configuration
├── protractor.conf.js * ├── README.md * This document
├── resources * Folder for static resources ├── SECURITY.md *
│   ├── data * Folder for static data ├── server.ts * Angular Universal Node.js Express server
│   │   └── en * Folder for i18n English data ├── tsconfig.app.json * TypeScript config for browser (app)
│   ├── i18n * Folder for i18n translations ├── tsconfig.json * TypeScript common config
│   │   └── en.json * i18n translations for English ├── tsconfig.server.json * TypeScript config for server
│   └── images * Folder for images ├── tsconfig.spec.json * TypeScript config for tests
│   ├── dspace-logo-old.png * ├── tsconfig.ts-node.json * TypeScript config for using ts-node directly
│   ├── dspace-logo.png *
│   └── favicon.ico *
├── rollup.config.js * Rollup (http://rollupjs.org/) configuration
├── spec-bundle.js *
├── src * The source of the application
│   ├── app *
│   │   ├── app-routing.module.ts *
│   │   ├── app.component.html *
│   │   ├── app.component.scss *
│   │   ├── app.component.spec.ts *
│   │   ├── app.component.ts *
│   │   ├── app.effects.ts *
│   │   ├── app.module.ts *
│   │   ├── app.reducer.ts *
│   │   ├── browser-app.module.ts * The root module for the client
│   │   ├── +collection-page * Lazily loaded route for collection module
│   │   ├── +community-page * Lazily loaded route for community module
│   │   ├── core *
│   │   ├── header *
│   │   ├── +home * Lazily loaded route for home module
│   │   ├── +item-page * Lazily loaded route for item module
│   │   ├── object-list *
│   │   ├── pagenotfound *
│   │   ├── server-app.module.ts * The root module for the server
│   │   ├── shared *
│   │   ├── store.actions.ts *
│   │   ├── store.effects.ts *
│   │   ├── thumbnail *
│   │   └── typings.d.ts * File that allows you to add custom typings for libraries without TypeScript support
│   ├── backend * Folder containing a mock of the REST API, hosted by the express server
│   │   ├── api.ts *
│   │   ├── cache.ts *
│   │   ├── data *
│   │   └── db.ts *
│   ├── config *
│   │   ├── cache-config.interface.ts *
│   │   ├── config.interface.ts *
│   │   ├── global-config.interface.ts *
│   │   ├── server-config.interface.ts *
│   │   └── universal-config.interface.ts *
│   ├── config.ts * File that loads environmental and shareable settings and makes them available to app components
│   ├── index.csr.html * The index file for client side rendering fallback
│   ├── index.html * The index file
│   ├── main.browser.ts * The bootstrap file for the client
│   ├── main.server.ts * The express (http://expressjs.com/) config and bootstrap file for the server
│   ├── modules *
│   │   ├── cookies *
│   │   ├── data-loader *
│   │   ├── transfer-http *
│   │   ├── transfer-state *
│   │   ├── transfer-store *
│   │   └── translate-universal-loader.ts *
│   ├── routes.ts * The routes file for the server
│   ├── styles * Folder containing global styles
│   │   ├── _mixins.scss *
│   │   └── variables.scss * Global sass variables file
│   ├── tsconfig.browser.json * TypeScript config for the client build
│   ├── tsconfig.server.json * TypeScript config for the server build
│   └── tsconfig.test.json * TypeScript config for the test build
├── tsconfig.json * TypeScript config
├── tslint.json * TSLint (https://palantir.github.io/tslint/) configuration ├── tslint.json * TSLint (https://palantir.github.io/tslint/) configuration
├── typedoc.json * TYPEDOC configuration ├── typedoc.json * TYPEDOC configuration
├── webpack * Webpack (https://webpack.github.io/) config directory
│   ├── webpack.aot.js * Webpack (https://webpack.github.io/) config for AoT build
│   ├── webpack.client.js * Webpack (https://webpack.github.io/) config for client build
│   ├── webpack.common.js *
│   ├── webpack.prod.js * Webpack (https://webpack.github.io/) config for production build
│   ├── webpack.server.js * Webpack (https://webpack.github.io/) config for server build
│   └── webpack.test.js * Webpack (https://webpack.github.io/) config for test build
├── webpack.config.ts *
└── yarn.lock * Yarn lockfile (https://yarnpkg.com/en/docs/yarn-lock) └── yarn.lock * Yarn lockfile (https://yarnpkg.com/en/docs/yarn-lock)
``` ```
@@ -403,8 +485,8 @@ Frequently asked questions
- You can write your tests next to your component files. e.g. for `src/app/home/home.component.ts` call it `src/app/home/home.component.spec.ts` - You can write your tests next to your component files. e.g. for `src/app/home/home.component.ts` call it `src/app/home/home.component.spec.ts`
- How do I start the app when I get `EACCES` and `EADDRINUSE` errors? - How do I start the app when I get `EACCES` and `EADDRINUSE` errors?
- The `EADDRINUSE` error means the port `4000` is currently being used and `EACCES` is lack of permission to build files to `./dist/` - The `EADDRINUSE` error means the port `4000` is currently being used and `EACCES` is lack of permission to build files to `./dist/`
- What are the naming conventions for Angular 2? - What are the naming conventions for Angular?
- See [the official angular 2 style guide](https://angular.io/styleguide) - See [the official angular style guide](https://angular.io/styleguide)
- Why is the size of my app larger in development? - Why is the size of my app larger in development?
- The production build uses a whole host of techniques (ahead-of-time compilation, rollup to remove unreachable code, minification, etc.) to reduce the size, that aren't used during development in the intrest of build speed. - The production build uses a whole host of techniques (ahead-of-time compilation, rollup to remove unreachable code, minification, etc.) to reduce the size, that aren't used during development in the intrest of build speed.
- node-pre-gyp ERR in yarn install (Windows) - node-pre-gyp ERR in yarn install (Windows)
@@ -415,6 +497,36 @@ Frequently asked questions
- then run `git add yarn.lock` to stage the lockfile for commit - then run `git add yarn.lock` to stage the lockfile for commit
- and `git commit` to conclude the merge - and `git commit` to conclude the merge
Getting Help
------------
DSpace provides public mailing lists where you can post questions or raise topics for discussion.
We welcome everyone to participate in these lists:
* [dspace-community@googlegroups.com](https://groups.google.com/d/forum/dspace-community) : General discussion about DSpace platform, announcements, sharing of best practices
* [dspace-tech@googlegroups.com](https://groups.google.com/d/forum/dspace-tech) : Technical support mailing list. See also our guide for [How to troubleshoot an error](https://wiki.lyrasis.org/display/DSPACE/Troubleshoot+an+error).
* [dspace-devel@googlegroups.com](https://groups.google.com/d/forum/dspace-devel) : Developers / Development mailing list
Great Q&A is also available under the [DSpace tag on Stackoverflow](http://stackoverflow.com/questions/tagged/dspace)
Additional support options are at https://wiki.lyrasis.org/display/DSPACE/Support
DSpace also has an active service provider network. If you'd rather hire a service provider to
install, upgrade, customize or host DSpace, then we recommend getting in touch with one of our
[Registered Service Providers](http://www.dspace.org/service-providers).
Issue Tracker
-------------
DSpace uses GitHub to track issues:
* Backend (REST API) issues: https://github.com/DSpace/DSpace/issues
* Frontend (User Interface) issues: https://github.com/DSpace/dspace-angular/issues
License License
------- -------
This project's source code is made available under the DSpace BSD License: http://www.dspace.org/license DSpace source code is freely available under a standard [BSD 3-Clause license](https://opensource.org/licenses/BSD-3-Clause).
The full license is available in the [LICENSE](LICENSE) file or online at http://www.dspace.org/license/
DSpace uses third-party libraries which may be distributed under different licenses. Those licenses are listed
in the [LICENSES_THIRD_PARTY](LICENSES_THIRD_PARTY) file.

15
SECURITY.md Normal file
View File

@@ -0,0 +1,15 @@
# Security Policy
## Supported Versions
For information regarding which versions of DSpace are currently under support, please see our DSpace Software Support Policy:
https://wiki.lyrasis.org/display/DSPACE/DSpace+Software+Support+Policy
## Reporting a Vulnerability
If you believe you have found a security vulnerability in a supported version of DSpace, we encourage you to let us know right away.
We will investigate all legitimate reports and do our best to quickly fix the problem. Please see our DSpace Software Support Policy
for information on privately reporting vulnerabilities:
https://wiki.lyrasis.org/display/DSPACE/DSpace+Software+Support+Policy

View File

@@ -47,6 +47,7 @@
"src/robots.txt" "src/robots.txt"
], ],
"styles": [ "styles": [
"src/styles/startup.scss",
{ {
"input": "src/styles/base-theme.scss", "input": "src/styles/base-theme.scss",
"inject": false, "inject": false,
@@ -67,6 +68,12 @@
}, },
"configurations": { "configurations": {
"production": { "production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.production.ts"
}
],
"optimization": true, "optimization": true,
"outputHashing": "all", "outputHashing": "all",
"extractCss": true, "extractCss": true,
@@ -138,6 +145,16 @@
} }
], ],
"scripts": [] "scripts": []
},
"configurations": {
"test": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.test.ts"
}
]
}
} }
}, },
"lint": { "lint": {
@@ -146,7 +163,7 @@
"tsConfig": [ "tsConfig": [
"tsconfig.app.json", "tsconfig.app.json",
"tsconfig.spec.json", "tsconfig.spec.json",
"e2e/tsconfig.json" "cypress/tsconfig.json"
], ],
"exclude": [ "exclude": [
"**/node_modules/**" "**/node_modules/**"
@@ -154,10 +171,11 @@
} }
}, },
"e2e": { "e2e": {
"builder": "@angular-devkit/build-angular:protractor", "builder": "@cypress/schematic:cypress",
"options": { "options": {
"protractorConfig": "e2e/protractor.conf.js", "devServerTarget": "dspace-angular:serve",
"devServerTarget": "dspace-angular:serve" "watch": true,
"headless": false
}, },
"configurations": { "configurations": {
"production": { "production": {
@@ -175,16 +193,19 @@
} }
}, },
"outputPath": "dist/server", "outputPath": "dist/server",
"main": "src/main.server.ts", "main": "server.ts",
"tsConfig": "tsconfig.server.json" "tsConfig": "tsconfig.server.json"
}, },
"configurations": { "configurations": {
"production": { "production": {
"sourceMap": false, "sourceMap": false,
"optimization": { "optimization": true,
"scripts": false, "fileReplacements": [
"styles": true {
} "replace": "src/environments/environment.ts",
"with": "src/environments/environment.production.ts"
}
]
} }
} }
}, },
@@ -214,9 +235,30 @@
"configurations": { "configurations": {
"production": {} "production": {}
} }
},
"cypress-run": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "dspace-angular:serve"
},
"configurations": {
"production": {
"devServerTarget": "dspace-angular:serve:production"
}
}
},
"cypress-open": {
"builder": "@cypress/schematic:cypress",
"options": {
"watch": true,
"headless": false
}
} }
} }
} }
}, },
"defaultProject": "dspace-angular" "defaultProject": "dspace-angular",
} "cli": {
"analytics": false
}
}

2
config/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
config.*.yml
!config.example.yml

236
config/config.example.yml Normal file
View File

@@ -0,0 +1,236 @@
# NOTE: will log all redux actions and transfers in console
debug: false
# Angular Universal server settings
# NOTE: these must be 'synced' with the 'dspace.ui.url' setting in your backend's local.cfg.
ui:
ssl: false
host: localhost
port: 4000
# NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: /
# The rateLimiter settings limit each IP to a 'max' of 500 requests per 'windowMs' (1 minute).
rateLimiter:
windowMs: 60000 # 1 minute
max: 500 # limit each IP to 500 requests per windowMs
# The REST API server settings
# NOTE: these must be 'synced' with the 'dspace.server.url' setting in your backend's local.cfg.
rest:
ssl: true
host: api7.dspace.org
port: 443
# NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: /server
# Caching settings
cache:
# NOTE: how long should objects be cached for by default
msToLive:
default: 900000 # 15 minutes
control: max-age=60 # revalidate browser
autoSync:
defaultTime: 0
maxBufferSize: 100
timePerMethod:
PATCH: 3 # time in seconds
# Authentication settings
auth:
# Authentication UI settings
ui:
# the amount of time before the idle warning is shown
timeUntilIdle: 900000 # 15 minutes
# the amount of time the user has to react after the idle warning is shown before they are logged out.
idleGracePeriod: 300000 # 5 minutes
# Authentication REST settings
rest:
# If the rest token expires in less than this amount of time, it will be refreshed automatically.
# This is independent from the idle warning.
timeLeftBeforeTokenRefresh: 120000 # 2 minutes
# Form settings
form:
# NOTE: Map server-side validators to comparative Angular form validators
validatorMap:
required: required
regex: pattern
# Notification settings
notifications:
rtl: false
position:
- top
- right
maxStack: 8
# NOTE: after how many seconds notification is closed automatically. If set to zero notifications are not closed automatically
timeOut: 5000 # 5 second
clickToClose: true
# NOTE: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale'
animate: scale
# Submission settings
submission:
autosave:
# NOTE: which metadata trigger an autosave
metadata: []
# NOTE: after how many time (milliseconds) submission is saved automatically
# eg. timer: 5 * (1000 * 60); // 5 minutes
timer: 0
icons:
metadata:
# NOTE: example of configuration
# # NOTE: metadata name
# - name: dc.author
# # NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
# style: fas fa-user
- name: dc.author
style: fas fa-user
# default configuration
- name: default
style: ''
authority:
confidence:
# NOTE: example of configuration
# # NOTE: confidence value
# - name: dc.author
# # NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
# style: fa-user
- value: 600
style: text-success
- value: 500
style: text-info
- value: 400
style: text-warning
# default configuration
- value: default
style: text-muted
# Default Language in which the UI will be rendered if the user's browser language is not an active language
defaultLanguage: en
# Languages. DSpace Angular holds a message catalog for each of the following languages.
# When set to active, users will be able to switch to the use of this language in the user interface.
languages:
- code: en
label: English
active: true
- code: cs
label: Čeština
active: true
- code: de
label: Deutsch
active: true
- code: es
label: Español
active: true
- code: fr
label: Français
active: true
- code: gd
label: Gàidhlig
active: true
- code: lv
label: Latviešu
active: true
- code: hu
label: Magyar
active: true
- code: nl
label: Nederlands
active: true
- code: pt-PT
label: Português
active: true
- code: pt-BR
label: Português do Brasil
active: true
- code: fi
label: Suomi
active: true
# Browse-By Pages
browseBy:
# Amount of years to display using jumps of one year (current year - oneYearLimit)
oneYearLimit: 10
# Limit for years to display using jumps of five years (current year - fiveYearLimit)
fiveYearLimit: 30
# The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items)
defaultLowerLimit: 1900
# Item Page Config
item:
edit:
undoTimeout: 10000 # 10 seconds
# Collection Page Config
collection:
edit:
undoTimeout: 10000 # 10 seconds
# Theme Config
themes:
# Add additional themes here. In the case where multiple themes match a route, the first one
# in this list will get priority. It is advisable to always have a theme that matches
# every route as the last one
#
# # A theme with a handle property will match the community, collection or item with the given
# # handle, and all collections and/or items within it
# - name: 'custom',
# handle: '10673/1233'
#
# # A theme with a regex property will match the route using a regular expression. If it
# # matches the route for a community or collection it will also apply to all collections
# # and/or items within it
# - name: 'custom',
# regex: 'collections\/e8043bc2.*'
#
# # A theme with a uuid property will match the community, collection or item with the given
# # ID, and all collections and/or items within it
# - name: 'custom',
# uuid: '0958c910-2037-42a9-81c7-dca80e3892b4'
#
# # The extends property specifies an ancestor theme (by name). Whenever a themed component is not found
# # in the current theme, its ancestor theme(s) will be checked recursively before falling back to default.
# - name: 'custom-A',
# extends: 'custom-B',
# # Any of the matching properties above can be used
# handle: '10673/34'
#
# - name: 'custom-B',
# extends: 'custom',
# handle: '10673/12'
#
# # A theme with only a name will match every route
# name: 'custom'
#
# # This theme will use the default bootstrap styling for DSpace components
# - name: BASE_THEME_NAME
#
- name: dspace
headTags:
- tagName: link
attributes:
rel: icon
href: assets/dspace/images/favicons/favicon.ico
sizes: any
- tagName: link
attributes:
rel: icon
href: assets/dspace/images/favicons/favicon.svg
type: image/svg+xml
- tagName: link
attributes:
rel: apple-touch-icon
href: assets/dspace/images/favicons/apple-touch-icon.png
- tagName: link
attributes:
rel: manifest
href: assets/dspace/images/favicons/manifest.webmanifest
# Whether to enable media viewer for image and/or video Bitstreams (i.e. Bitstreams whose MIME type starts with 'image' or 'video').
# For images, this enables a gallery viewer where you can zoom or page through images.
# For videos, this enables embedded video streaming
mediaViewer:
image: false
video: false

5
config/config.yml Normal file
View File

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

10
cypress.json Normal file
View File

@@ -0,0 +1,10 @@
{
"integrationFolder": "cypress/integration",
"supportFile": "cypress/support/index.ts",
"videosFolder": "cypress/videos",
"screenshotsFolder": "cypress/screenshots",
"pluginsFile": "cypress/plugins/index.ts",
"fixturesFolder": "cypress/fixtures",
"baseUrl": "http://localhost:4000",
"retries": 2
}

2
cypress/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
screenshots/
videos/

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,15 @@
import { TEST_ENTITY_PUBLICATION } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Breadcrumbs', () => {
it('should pass accessibility tests', () => {
// Visit an Item, as those have more breadcrumbs
cy.visit('/entities/publication/' + TEST_ENTITY_PUBLICATION);
// Wait for breadcrumbs to be visible
cy.get('ds-breadcrumbs').should('be.visible');
// Analyze <ds-breadcrumbs> for accessibility
testA11y('ds-breadcrumbs');
});
});

View File

@@ -0,0 +1,13 @@
import { testA11y } from 'cypress/support/utils';
describe('Browse By Author', () => {
it('should pass accessibility tests', () => {
cy.visit('/browse/author');
// Wait for <ds-browse-by-metadata-page> to be visible
cy.get('ds-browse-by-metadata-page').should('be.visible');
// Analyze <ds-browse-by-metadata-page> for accessibility
testA11y('ds-browse-by-metadata-page');
});
});

View File

@@ -0,0 +1,13 @@
import { testA11y } from 'cypress/support/utils';
describe('Browse By Date Issued', () => {
it('should pass accessibility tests', () => {
cy.visit('/browse/dateissued');
// Wait for <ds-browse-by-date-page> to be visible
cy.get('ds-browse-by-date-page').should('be.visible');
// Analyze <ds-browse-by-date-page> for accessibility
testA11y('ds-browse-by-date-page');
});
});

View File

@@ -0,0 +1,13 @@
import { testA11y } from 'cypress/support/utils';
describe('Browse By Subject', () => {
it('should pass accessibility tests', () => {
cy.visit('/browse/subject');
// Wait for <ds-browse-by-metadata-page> to be visible
cy.get('ds-browse-by-metadata-page').should('be.visible');
// Analyze <ds-browse-by-metadata-page> for accessibility
testA11y('ds-browse-by-metadata-page');
});
});

View File

@@ -0,0 +1,13 @@
import { testA11y } from 'cypress/support/utils';
describe('Browse By Title', () => {
it('should pass accessibility tests', () => {
cy.visit('/browse/title');
// Wait for <ds-browse-by-title-page> to be visible
cy.get('ds-browse-by-title-page').should('be.visible');
// Analyze <ds-browse-by-title-page> for accessibility
testA11y('ds-browse-by-title-page');
});
});

View File

@@ -0,0 +1,15 @@
import { TEST_COLLECTION } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Collection Page', () => {
it('should pass accessibility tests', () => {
cy.visit('/collections/' + TEST_COLLECTION);
// <ds-collection-page> tag must be loaded
cy.get('ds-collection-page').should('exist');
// Analyze <ds-collection-page> for accessibility issues
testA11y('ds-collection-page');
});
});

View File

@@ -0,0 +1,32 @@
import { TEST_COLLECTION } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Collection Statistics Page', () => {
const COLLECTIONSTATISTICSPAGE = '/statistics/collections/' + TEST_COLLECTION;
it('should load if you click on "Statistics" from a Collection page', () => {
cy.visit('/collections/' + TEST_COLLECTION);
cy.get('ds-navbar ds-link-menu-item a[title="Statistics"]').click();
cy.location('pathname').should('eq', COLLECTIONSTATISTICSPAGE);
});
it('should contain a "Total visits" section', () => {
cy.visit(COLLECTIONSTATISTICSPAGE);
cy.get('.' + TEST_COLLECTION + '_TotalVisits').should('exist');
});
it('should contain a "Total visits per month" section', () => {
cy.visit(COLLECTIONSTATISTICSPAGE);
cy.get('.' + TEST_COLLECTION + '_TotalVisitsPerMonth').should('exist');
});
it('should pass accessibility tests', () => {
cy.visit(COLLECTIONSTATISTICSPAGE);
// <ds-collection-statistics-page> tag must be loaded
cy.get('ds-collection-statistics-page').should('exist');
// Analyze <ds-collection-statistics-page> for accessibility issues
testA11y('ds-collection-statistics-page');
});
});

View File

@@ -0,0 +1,25 @@
import { Options } from 'cypress-axe';
import { testA11y } from 'cypress/support/utils';
describe('Community List Page', () => {
it('should pass accessibility tests', () => {
cy.visit('/community-list');
// <ds-community-list-page> tag must be loaded
cy.get('ds-community-list-page').should('exist');
// Open first Community (to show Collections)...that way we scan sub-elements as well
cy.get('ds-community-list :nth-child(1) > .btn-group > .btn').click();
// Analyze <ds-community-list-page> for accessibility issues
// Disable heading-order checks until it is fixed
testA11y('ds-community-list-page',
{
rules: {
'heading-order': { enabled: false }
}
} as Options
);
});
});

View File

@@ -0,0 +1,15 @@
import { TEST_COMMUNITY } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Community Page', () => {
it('should pass accessibility tests', () => {
cy.visit('/communities/' + TEST_COMMUNITY);
// <ds-community-page> tag must be loaded
cy.get('ds-community-page').should('exist');
// Analyze <ds-community-page> for accessibility issues
testA11y('ds-community-page',);
});
});

View File

@@ -0,0 +1,32 @@
import { TEST_COMMUNITY } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Community Statistics Page', () => {
const COMMUNITYSTATISTICSPAGE = '/statistics/communities/' + TEST_COMMUNITY;
it('should load if you click on "Statistics" from a Community page', () => {
cy.visit('/communities/' + TEST_COMMUNITY);
cy.get('ds-navbar ds-link-menu-item a[title="Statistics"]').click();
cy.location('pathname').should('eq', COMMUNITYSTATISTICSPAGE);
});
it('should contain a "Total visits" section', () => {
cy.visit(COMMUNITYSTATISTICSPAGE);
cy.get('.' + TEST_COMMUNITY + '_TotalVisits').should('exist');
});
it('should contain a "Total visits per month" section', () => {
cy.visit(COMMUNITYSTATISTICSPAGE);
cy.get('.' + TEST_COMMUNITY + '_TotalVisitsPerMonth').should('exist');
});
it('should pass accessibility tests', () => {
cy.visit(COMMUNITYSTATISTICSPAGE);
// <ds-community-statistics-page> tag must be loaded
cy.get('ds-community-statistics-page').should('exist');
// Analyze <ds-community-statistics-page> for accessibility issues
testA11y('ds-community-statistics-page');
});
});

View File

@@ -0,0 +1,13 @@
import { testA11y } from 'cypress/support/utils';
describe('Footer', () => {
it('should pass accessibility tests', () => {
cy.visit('/');
// Footer must first be visible
cy.get('ds-footer').should('be.visible');
// Analyze <ds-footer> for accessibility
testA11y('ds-footer');
});
});

View File

@@ -0,0 +1,19 @@
import { testA11y } from 'cypress/support/utils';
describe('Header', () => {
it('should pass accessibility tests', () => {
cy.visit('/');
// Header must first be visible
cy.get('ds-header').should('be.visible');
// Analyze <ds-header> for accessibility
testA11y({
include: ['ds-header'],
exclude: [
['#search-navbar-container'], // search in navbar has duplicative ID. Will be fixed in #1174
['.dropdownLogin'] // "Log in" link has color contrast issues. Will be fixed in #1149
],
});
});
});

View File

@@ -0,0 +1,19 @@
import { testA11y } from 'cypress/support/utils';
describe('Site Statistics Page', () => {
it('should load if you click on "Statistics" from homepage', () => {
cy.visit('/');
cy.get('ds-navbar ds-link-menu-item a[title="Statistics"]').click();
cy.location('pathname').should('eq', '/statistics');
});
it('should pass accessibility tests', () => {
cy.visit('/statistics');
// <ds-site-statistics-page> tag must be loaded
cy.get('ds-site-statistics-page').should('exist');
// Analyze <ds-site-statistics-page> for accessibility issues
testA11y('ds-site-statistics-page');
});
});

View File

@@ -0,0 +1,32 @@
import { testA11y } from 'cypress/support/utils';
describe('Homepage', () => {
beforeEach(() => {
// All tests start with visiting homepage
cy.visit('/');
});
it('should display translated title "DSpace Angular :: Home"', () => {
cy.title().should('eq', 'DSpace Angular :: Home');
});
it('should contain a news section', () => {
cy.get('ds-home-news').should('be.visible');
});
it('should have a working search box', () => {
const queryString = 'test';
cy.get('ds-search-form input[name="query"]').type(queryString);
cy.get('ds-search-form button.search-button').click();
cy.url().should('include', '/search');
cy.url().should('include', 'query=' + encodeURI(queryString));
});
it('should pass accessibility tests', () => {
// Wait for homepage tag to appear
cy.get('ds-home-page').should('be.visible');
// Analyze <ds-home-page> for accessibility issues
testA11y('ds-home-page');
});
});

View File

@@ -0,0 +1,31 @@
import { Options } from 'cypress-axe';
import { TEST_ENTITY_PUBLICATION } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Item Page', () => {
const ITEMPAGE = '/items/' + TEST_ENTITY_PUBLICATION;
const ENTITYPAGE = '/entities/publication/' + TEST_ENTITY_PUBLICATION;
// Test that entities will redirect to /entities/[type]/[uuid] when accessed via /items/[uuid]
it('should redirect to the entity page when navigating to an item page', () => {
cy.visit(ITEMPAGE);
cy.location('pathname').should('eq', ENTITYPAGE);
});
it('should pass accessibility tests', () => {
cy.visit(ENTITYPAGE);
// <ds-item-page> tag must be loaded
cy.get('ds-item-page').should('exist');
// Analyze <ds-item-page> for accessibility issues
// Disable heading-order checks until it is fixed
testA11y('ds-item-page',
{
rules: {
'heading-order': { enabled: false }
}
} as Options
);
});
});

View File

@@ -0,0 +1,38 @@
import { TEST_ENTITY_PUBLICATION } from 'cypress/support';
import { testA11y } from 'cypress/support/utils';
describe('Item Statistics Page', () => {
const ITEMSTATISTICSPAGE = '/statistics/items/' + TEST_ENTITY_PUBLICATION;
it('should load if you click on "Statistics" from an Item/Entity page', () => {
cy.visit('/entities/publication/' + TEST_ENTITY_PUBLICATION);
cy.get('ds-navbar ds-link-menu-item a[title="Statistics"]').click();
cy.location('pathname').should('eq', ITEMSTATISTICSPAGE);
});
it('should contain element ds-item-statistics-page when navigating to an item statistics page', () => {
cy.visit(ITEMSTATISTICSPAGE);
cy.get('ds-item-statistics-page').should('exist');
cy.get('ds-item-page').should('not.exist');
});
it('should contain a "Total visits" section', () => {
cy.visit(ITEMSTATISTICSPAGE);
cy.get('.' + TEST_ENTITY_PUBLICATION + '_TotalVisits').should('exist');
});
it('should contain a "Total visits per month" section', () => {
cy.visit(ITEMSTATISTICSPAGE);
cy.get('.' + TEST_ENTITY_PUBLICATION + '_TotalVisitsPerMonth').should('exist');
});
it('should pass accessibility tests', () => {
cy.visit(ITEMSTATISTICSPAGE);
// <ds-item-statistics-page> tag must be loaded
cy.get('ds-item-statistics-page').should('exist');
// Analyze <ds-item-statistics-page> for accessibility issues
testA11y('ds-item-statistics-page');
});
});

View File

@@ -0,0 +1,13 @@
describe('PageNotFound', () => {
it('should contain element ds-pagenotfound when navigating to page that doesnt exist', () => {
// request an invalid page (UUIDs at root path aren't valid)
cy.visit('/e9019a69-d4f1-4773-b6a3-bd362caa46f2', { failOnStatusCode: false });
cy.get('ds-pagenotfound').should('exist');
});
it('should not contain element ds-pagenotfound when navigating to existing page', () => {
cy.visit('/home');
cy.get('ds-pagenotfound').should('not.exist');
});
});

View File

@@ -0,0 +1,49 @@
const page = {
fillOutQueryInNavBar(query) {
// Click the magnifying glass
cy.get('.navbar-container #search-navbar-container form a').click();
// Fill out a query in input that appears
cy.get('.navbar-container #search-navbar-container form input[name = "query"]').type(query);
},
submitQueryByPressingEnter() {
cy.get('.navbar-container #search-navbar-container form input[name = "query"]').type('{enter}');
},
submitQueryByPressingIcon() {
cy.get('.navbar-container #search-navbar-container form .submit-icon').click();
}
};
describe('Search from Navigation Bar', () => {
// NOTE: these tests currently assume this query will return results!
const query = 'test';
it('should go to search page with correct query if submitted (from home)', () => {
cy.visit('/');
page.fillOutQueryInNavBar(query);
page.submitQueryByPressingEnter();
// New URL should include query param
cy.url().should('include', 'query=' + query);
// At least one search result should be displayed
cy.get('ds-item-search-result-list-element').should('be.visible');
});
it('should go to search page with correct query if submitted (from search)', () => {
cy.visit('/search');
page.fillOutQueryInNavBar(query);
page.submitQueryByPressingEnter();
// New URL should include query param
cy.url().should('include', 'query=' + query);
// At least one search result should be displayed
cy.get('ds-item-search-result-list-element').should('be.visible');
});
it('should allow user to also submit query by clicking icon', () => {
cy.visit('/');
page.fillOutQueryInNavBar(query);
page.submitQueryByPressingIcon();
// New URL should include query param
cy.url().should('include', 'query=' + query);
// At least one search result should be displayed
cy.get('ds-item-search-result-list-element').should('be.visible');
});
});

View File

@@ -0,0 +1,72 @@
import { Options } from 'cypress-axe';
import { testA11y } from 'cypress/support/utils';
describe('Search Page', () => {
// unique ID of the search form (for selecting specific elements below)
const SEARCHFORM_ID = '#search-form';
it('should contain query value when navigating to page with query parameter', () => {
const queryString = 'test query';
cy.visit('/search?query=' + queryString);
cy.get(SEARCHFORM_ID + ' input[name="query"]').should('have.value', queryString);
});
it('should redirect to the correct url when query was set and submit button was triggered', () => {
const queryString = 'Another interesting query string';
cy.visit('/search');
// Type query in searchbox & click search button
cy.get(SEARCHFORM_ID + ' input[name="query"]').type(queryString);
cy.get(SEARCHFORM_ID + ' button.search-button').click();
cy.url().should('include', 'query=' + encodeURI(queryString));
});
it('should pass accessibility tests', () => {
cy.visit('/search');
// <ds-search-page> tag must be loaded
cy.get('ds-search-page').should('exist');
// Click each filter toggle to open *every* filter
// (As we want to scan filter section for accessibility issues as well)
cy.get('.filter-toggle').click({ multiple: true });
// Analyze <ds-search-page> for accessibility issues
testA11y(
{
include: ['ds-search-page'],
exclude: [
['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175
],
},
{
rules: {
// Search filters fail these two "moderate" impact rules
'heading-order': { enabled: false },
'landmark-unique': { enabled: false }
}
} as Options
);
});
it('should pass accessibility tests in Grid view', () => {
cy.visit('/search');
// Click to display grid view
// TODO: These buttons should likely have an easier way to uniquely select
cy.get('#search-sidebar-content > ds-view-mode-switch > .btn-group > [href="/search?view=grid"] > .fas').click();
// <ds-search-page> tag must be loaded
cy.get('ds-search-page').should('exist');
// Analyze <ds-search-page> for accessibility issues
testA11y('ds-search-page',
{
rules: {
// Search filters fail these two "moderate" impact rules
'heading-order': { enabled: false },
'landmark-unique': { enabled: false }
}
} as Options
);
});
});

16
cypress/plugins/index.ts Normal file
View File

@@ -0,0 +1,16 @@
// Plugins enable you to tap into, modify, or extend the internal behavior of Cypress
// For more info, visit https://on.cypress.io/plugins-api
module.exports = (on, config) => {
// Define "log" and "table" tasks, used for logging accessibility errors during CI
// Borrowed from https://github.com/component-driven/cypress-axe#in-cypress-plugins-file
on('task', {
log(message: string) {
console.log(message);
return null;
},
table(message: string) {
console.table(message);
return null;
}
});
};

View File

@@ -0,0 +1,43 @@
// ***********************************************
// This example namespace declaration will help
// with Intellisense and code completion in your
// IDE or Text Editor.
// ***********************************************
// declare namespace Cypress {
// interface Chainable<Subject = any> {
// customCommand(param: any): typeof customCommand;
// }
// }
//
// function customCommand(param: any): void {
// console.warn(param);
// }
//
// NOTE: You can use it like so:
// Cypress.Commands.add('customCommand', customCommand);
//
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

26
cypress/support/index.ts Normal file
View File

@@ -0,0 +1,26 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// When a command from ./commands is ready to use, import with `import './commands'` syntax
// import './commands';
// Import Cypress Axe tools for all tests
// https://github.com/component-driven/cypress-axe
import 'cypress-axe';
// Global constants used in tests
export const TEST_COLLECTION = '282164f5-d325-4740-8dd1-fa4d6d3e7200';
export const TEST_COMMUNITY = '0958c910-2037-42a9-81c7-dca80e3892b4';
export const TEST_ENTITY_PUBLICATION = 'e98b0f27-5c19-49a0-960d-eb6ad5287067';

44
cypress/support/utils.ts Normal file
View File

@@ -0,0 +1,44 @@
import { Result } from 'axe-core';
import { Options } from 'cypress-axe';
// Log violations to terminal/commandline in a table format.
// Uses 'log' and 'table' tasks defined in ../plugins/index.ts
// Borrowed from https://github.com/component-driven/cypress-axe#in-your-spec-file
function terminalLog(violations: Result[]) {
cy.task(
'log',
`${violations.length} accessibility violation${violations.length === 1 ? '' : 's'} ${violations.length === 1 ? 'was' : 'were'} detected`
);
// pluck specific keys to keep the table readable
const violationData = violations.map(
({ id, impact, description, helpUrl, nodes }) => ({
id,
impact,
description,
helpUrl,
nodes: nodes.length,
html: nodes.map(node => node.html)
})
);
// Print violations as an array, since 'node.html' above often breaks table alignment
cy.task('log', violationData);
// Optionally, uncomment to print as a table
// cy.task('table', violationData);
}
// Custom "testA11y()" method which checks accessibility using cypress-axe
// while also ensuring any violations are logged to the terminal (see terminalLog above)
// This method MUST be called after cy.visit(), as cy.injectAxe() must be called after page load
export const testA11y = (context?: any, options?: Options) => {
cy.injectAxe();
cy.configureAxe({
rules: [
// Disable color contrast checks as they are inaccurate / result in a lot of false positives
// See also open issues in axe-core: https://github.com/dequelabs/axe-core/labels/color%20contrast
{ id: 'color-contrast', enabled: false },
]
});
cy.checkA11y(context, options, terminalLog);
};

13
cypress/tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"include": [
"**/*.ts"
],
"compilerOptions": {
"types": [
"cypress",
"cypress-axe",
"node"
]
}
}

View File

@@ -1,5 +1,23 @@
# Docker Compose files # Docker Compose files
***
:warning: **NOT PRODUCTION READY** The below Docker Compose resources are not guaranteed "production ready" at this time. They have been built for development/testing only. Therefore, DSpace Docker images may not be fully secured or up-to-date. While you are welcome to base your own images on these DSpace images/resources, these should not be used "as is" in any production scenario.
***
## 'Dockerfile' in root directory
This Dockerfile is used to build a *development* DSpace 7 Angular UI image, published as 'dspace/dspace-angular'
```
docker build -t dspace/dspace-angular:dspace-7_x .
```
This image is built *automatically* after each commit is made to the `main` branch.
Admins to our DockerHub repo can manually publish with the following command.
```
docker push dspace/dspace-angular:dspace-7_x
```
## docker directory ## docker directory
- docker-compose.yml - docker-compose.yml
- Starts DSpace Angular with Docker Compose from the current branch. This file assumes that a DSpace 7 REST instance will also be started in Docker. - Starts DSpace Angular with Docker Compose from the current branch. This file assumes that a DSpace 7 REST instance will also be started in Docker.
@@ -11,10 +29,6 @@
- Docker compose file that provides a DSpace CLI container to work with a running DSpace REST container. - Docker compose file that provides a DSpace CLI container to work with a running DSpace REST container.
- cli.assetstore.yml - cli.assetstore.yml
- Docker compose file that will download and install data into a DSpace REST assetstore. This script points to a default dataset that will be utilized for CI testing. - Docker compose file that will download and install data into a DSpace REST assetstore. This script points to a default dataset that will be utilized for CI testing.
- environment.dev.ts
- Environment file for running DSpace Angular in Docker
- local.cfg
- Environment file for running the DSpace 7 REST API in Docker.
## To refresh / pull DSpace images from Dockerhub ## To refresh / pull DSpace images from Dockerhub

View File

@@ -18,10 +18,19 @@ services:
dspace-cli: dspace-cli:
image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}" image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}"
container_name: dspace-cli container_name: dspace-cli
#environment: environment:
# Below syntax may look odd, but it is how to override dspace.cfg settings via env variables.
# See https://github.com/DSpace/DSpace/blob/main/dspace/config/config-definition.xml
# __P__ => "." (e.g. dspace__P__dir => dspace.dir)
# __D__ => "-" (e.g. google__D__metadata => google-metadata)
# dspace.dir
dspace__P__dir: /dspace
# db.url: Ensure we are using the 'dspacedb' image for our database
db__P__url: 'jdbc:postgresql://dspacedb:5432/dspace'
# solr.server: Ensure we are using the 'dspacesolr' image for Solr
solr__P__server: http://dspacesolr:8983/solr
volumes: volumes:
- "assetstore:/dspace/assetstore" - "assetstore:/dspace/assetstore"
- "./local.cfg:/dspace/config/local.cfg"
entrypoint: /dspace/bin/dspace entrypoint: /dspace/bin/dspace
command: help command: help
networks: networks:

View File

@@ -17,6 +17,19 @@ services:
# DSpace (backend) webapp container # DSpace (backend) webapp container
dspace: dspace:
container_name: dspace container_name: dspace
environment:
# Below syntax may look odd, but it is how to override dspace.cfg settings via env variables.
# See https://github.com/DSpace/DSpace/blob/main/dspace/config/config-definition.xml
# __P__ => "." (e.g. dspace__P__dir => dspace.dir)
# __D__ => "-" (e.g. google__D__metadata => google-metadata)
# dspace.dir, dspace.server.url and dspace.ui.url
dspace__P__dir: /dspace
dspace__P__server__P__url: http://localhost:8080/server
dspace__P__ui__P__url: http://localhost:4000
# db.url: Ensure we are using the 'dspacedb' image for our database
db__P__url: 'jdbc:postgresql://dspacedb:5432/dspace'
# solr.server: Ensure we are using the 'dspacesolr' image for Solr
solr__P__server: http://dspacesolr:8983/solr
depends_on: depends_on:
- dspacedb - dspacedb
image: dspace/dspace:dspace-7_x-test image: dspace/dspace:dspace-7_x-test
@@ -29,7 +42,6 @@ services:
tty: true tty: true
volumes: volumes:
- assetstore:/dspace/assetstore - assetstore:/dspace/assetstore
- "./local.cfg:/dspace/config/local.cfg"
# Mount DSpace's solr configs to a volume, so that we can share to 'dspacesolr' container (see below) # Mount DSpace's solr configs to a volume, so that we can share to 'dspacesolr' container (see below)
- solr_configs:/dspace/solr - solr_configs:/dspace/solr
# Ensure that the database is ready BEFORE starting tomcat # Ensure that the database is ready BEFORE starting tomcat
@@ -64,7 +76,7 @@ services:
dspacesolr: dspacesolr:
container_name: dspacesolr container_name: dspacesolr
# Uses official Solr image at https://hub.docker.com/_/solr/ # Uses official Solr image at https://hub.docker.com/_/solr/
image: solr:8.8 image: solr:8.11-slim
# Needs main 'dspace' container to start first to guarantee access to solr_configs # Needs main 'dspace' container to start first to guarantee access to solr_configs
depends_on: depends_on:
- dspace - dspace

View File

@@ -13,10 +13,32 @@
version: '3.7' version: '3.7'
networks: networks:
dspacenet: dspacenet:
ipam:
config:
# Define a custom subnet for our DSpace network, so that we can easily trust requests from host to container.
# If you customize this value, be sure to customize the 'proxies.trusted.ipranges' env variable below.
- subnet: 172.23.0.0/16
services: services:
# DSpace (backend) webapp container # DSpace (backend) webapp container
dspace: dspace:
container_name: dspace container_name: dspace
environment:
# Below syntax may look odd, but it is how to override dspace.cfg settings via env variables.
# See https://github.com/DSpace/DSpace/blob/main/dspace/config/config-definition.xml
# __P__ => "." (e.g. dspace__P__dir => dspace.dir)
# __D__ => "-" (e.g. google__D__metadata => google-metadata)
# dspace.dir, dspace.server.url, dspace.ui.url and dspace.name
dspace__P__dir: /dspace
dspace__P__server__P__url: http://localhost:8080/server
dspace__P__ui__P__url: http://localhost:4000
dspace__P__name: 'DSpace Started with Docker Compose'
# db.url: Ensure we are using the 'dspacedb' image for our database
db__P__url: 'jdbc:postgresql://dspacedb:5432/dspace'
# solr.server: Ensure we are using the 'dspacesolr' image for Solr
solr__P__server: http://dspacesolr:8983/solr
# proxies.trusted.ipranges: This setting is required for a REST API running in Docker to trust requests
# from the host machine. This IP range MUST correspond to the 'dspacenet' subnet defined above.
proxies__P__trusted__P__ipranges: '172.23.0'
image: dspace/dspace:dspace-7_x-test image: dspace/dspace:dspace-7_x-test
depends_on: depends_on:
- dspacedb - dspacedb
@@ -29,7 +51,6 @@ services:
tty: true tty: true
volumes: volumes:
- assetstore:/dspace/assetstore - assetstore:/dspace/assetstore
- "./local.cfg:/dspace/config/local.cfg"
# Mount DSpace's solr configs to a volume, so that we can share to 'dspacesolr' container (see below) # Mount DSpace's solr configs to a volume, so that we can share to 'dspacesolr' container (see below)
- solr_configs:/dspace/solr - solr_configs:/dspace/solr
# Ensure that the database is ready BEFORE starting tomcat # Ensure that the database is ready BEFORE starting tomcat
@@ -62,7 +83,7 @@ services:
dspacesolr: dspacesolr:
container_name: dspacesolr container_name: dspacesolr
# Uses official Solr image at https://hub.docker.com/_/solr/ # Uses official Solr image at https://hub.docker.com/_/solr/
image: solr:8.8 image: solr:8.11-slim
# Needs main 'dspace' container to start first to guarantee access to solr_configs # Needs main 'dspace' container to start first to guarantee access to solr_configs
depends_on: depends_on:
- dspace - dspace
@@ -81,15 +102,22 @@ services:
# Keep Solr data directory between reboots # Keep Solr data directory between reboots
- solr_data:/var/solr/data - solr_data:/var/solr/data
# Initialize all DSpace Solr cores using the mounted local configsets (see above), then start Solr # Initialize all DSpace Solr cores using the mounted local configsets (see above), then start Solr
# * First, run precreate-core to create the core (if it doesn't yet exist). If exists already, this is a no-op
# * Second, copy updated configs from mounted configsets to this core. If it already existed, this updates core
# to the latest configs. If it's a newly created core, this is a no-op.
entrypoint: entrypoint:
- /bin/bash - /bin/bash
- '-c' - '-c'
- | - |
init-var-solr init-var-solr
precreate-core authority /opt/solr/server/solr/configsets/dspace/authority precreate-core authority /opt/solr/server/solr/configsets/dspace/authority
cp -r -u /opt/solr/server/solr/configsets/dspace/authority/* authority
precreate-core oai /opt/solr/server/solr/configsets/dspace/oai precreate-core oai /opt/solr/server/solr/configsets/dspace/oai
cp -r -u /opt/solr/server/solr/configsets/dspace/oai/* oai
precreate-core search /opt/solr/server/solr/configsets/dspace/search precreate-core search /opt/solr/server/solr/configsets/dspace/search
cp -r -u /opt/solr/server/solr/configsets/dspace/search/* search
precreate-core statistics /opt/solr/server/solr/configsets/dspace/statistics precreate-core statistics /opt/solr/server/solr/configsets/dspace/statistics
cp -r -u /opt/solr/server/solr/configsets/dspace/statistics/* statistics
exec solr -f exec solr -f
volumes: volumes:
assetstore: assetstore:

View File

@@ -16,11 +16,15 @@ services:
dspace-angular: dspace-angular:
container_name: dspace-angular container_name: dspace-angular
environment: environment:
DSPACE_HOST: dspace-angular DSPACE_UI_SSL: 'false'
DSPACE_NAMESPACE: / DSPACE_UI_HOST: dspace-angular
DSPACE_PORT: '4000' DSPACE_UI_PORT: '4000'
DSPACE_SSL: "false" DSPACE_UI_NAMESPACE: /
image: dspace/dspace-angular:latest DSPACE_REST_SSL: 'false'
DSPACE_REST_HOST: localhost
DSPACE_REST_PORT: 8080
DSPACE_REST_NAMESPACE: /server
image: dspace/dspace-angular:dspace-7_x
build: build:
context: .. context: ..
dockerfile: Dockerfile dockerfile: Dockerfile
@@ -33,5 +37,3 @@ services:
target: 9876 target: 9876
stdin_open: true stdin_open: true
tty: true tty: true
volumes:
- ./environment.dev.ts:/app/src/environments/environment.dev.ts

View File

@@ -1,18 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
// This file is based on environment.template.ts provided by Angular UI
export const environment = {
// Default to using the local REST API (running in Docker)
rest: {
ssl: false,
host: 'localhost',
port: 8080,
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: '/server'
}
};

View File

@@ -1,6 +0,0 @@
dspace.dir=/dspace
db.url=jdbc:postgresql://dspacedb:5432/dspace
dspace.server.url=http://localhost:8080/server
dspace.ui.url=http://localhost:4000
dspace.name=DSpace Started with Docker Compose
solr.server=http://dspacesolr:8983/solr

View File

@@ -1,26 +1,30 @@
# Configuration # Configuration
Default configuration file is located in `src/environments/` folder. All configuration options should be listed in the default configuration file `src/environments/environment.common.ts`. Please do not change this file directly! To change the default configuration values, create local files that override the parameters you need to change. You can use `environment.template.ts` as a starting point. Default configuration file is located at `config/config.yml`. All configuration options should be listed in the default typescript file `src/config/default-app-config.ts`. Please do not change this file directly! To override the default configuration values, create local files that override the parameters you need to change. You can use `config.example.yml` as a starting point.
- Create a new `environment.dev.ts` file in `src/environments/` for `development` environment; - Create a new `config.(dev or development).yml` file in `config/` for `development` environment;
- Create a new `environment.prod.ts` file in `src/environments/` for `production` environment; - Create a new `config.(prod or production).yml` file in `config/` for `production` environment;
Some few configuration options can be overridden by setting environment variables. These and the variable names are listed below. Alternatively, create a desired app config file at an external location and set the path as environment variable `DSPACE_APP_CONFIG_PATH`.
e.g.
```
DSPACE_APP_CONFIG_PATH=/usr/local/dspace/config/config.yml
```
Configuration options can be overridden by setting environment variables.
## Nodejs server ## Nodejs server
When you start dspace-angular on node, it spins up an http server on which it listens for incoming connections. You can define the ip address and port the server should bind itsself to, and if ssl should be enabled not. By default it listens on `localhost:4000`. If you want it to listen on all your network connections, configure it to bind itself to `0.0.0.0`. When you start dspace-angular on node, it spins up an http server on which it listens for incoming connections. You can define the ip address and port the server should bind itsself to, and if ssl should be enabled not. By default it listens on `localhost:4000`. If you want it to listen on all your network connections, configure it to bind itself to `0.0.0.0`.
To change this configuration, change the options `ui.host`, `ui.port` and `ui.ssl` in the appropriate configuration file (see above): To change this configuration, change the options `ui.host`, `ui.port` and `ui.ssl` in the appropriate configuration file (see above):
```
export const environment = { ```yaml
// Angular UI settings. ui:
ui: { ssl: false
ssl: false, host: localhost
host: 'localhost', port: 4000
port: 4000, nameSpace: /
nameSpace: '/'
}
};
``` ```
Alternately you can set the following environment variables. If any of these are set, it will override all configuration files: Alternately you can set the following environment variables. If any of these are set, it will override all configuration files:
@@ -30,21 +34,24 @@ Alternately you can set the following environment variables. If any of these are
DSPACE_PORT=4000 DSPACE_PORT=4000
DSPACE_NAMESPACE=/ DSPACE_NAMESPACE=/
``` ```
or
```
DSPACE_UI_SSL=true
DSPACE_UI_HOST=localhost
DSPACE_UI_PORT=4000
DSPACE_UI_NAMESPACE=/
```
## DSpace's REST endpoint ## DSpace's REST endpoint
dspace-angular connects to your DSpace installation by using its REST endpoint. To do so, you have to define the ip address, port and if ssl should be enabled. You can do this in a configuration file (see above) by adding the following options: dspace-angular connects to your DSpace installation by using its REST endpoint. To do so, you have to define the ip address, port and if ssl should be enabled. You can do this in a configuration file (see above) by adding the following options:
``` ```yaml
export const environment = { rest:
// The REST API server settings. ssl: true
rest: { host: api7.dspace.org
ssl: true, port: 443
host: 'api7.dspace.org', nameSpace: /server
port: 443, }
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: '/server'
}
};
``` ```
Alternately you can set the following environment variables. If any of these are set, it will override all configuration files: Alternately you can set the following environment variables. If any of these are set, it will override all configuration files:
@@ -55,6 +62,21 @@ Alternately you can set the following environment variables. If any of these are
DSPACE_REST_NAMESPACE=/server DSPACE_REST_NAMESPACE=/server
``` ```
## Environment variable naming convention
Settings can be set using the following convention for naming the environment variables:
1. replace all `.` with `_`
2. convert all characters to upper case
3. prefix with `DSPACE_`
e.g.
```
cache.msToLive.default => DSPACE_CACHE_MSTOLIVE_DEFAULT
auth.ui.timeUntilIdle => DSPACE_AUTH_UI_TIMEUNTILIDLE
```
## Supporting analytics services other than Google Analytics ## Supporting analytics services other than Google Analytics
This project makes use of [Angulartics](https://angulartics.github.io/angulartics2/) to track usage events and send them to Google Analytics. This project makes use of [Angulartics](https://angulartics.github.io/angulartics2/) to track usage events and send them to Google Analytics.

View File

@@ -1,14 +0,0 @@
const config = require('./protractor.conf').config;
config.capabilities = {
browserName: 'chrome',
chromeOptions: {
args: ['--headless', '--no-sandbox', '--disable-gpu']
}
};
// don't use protractor's webdriver, as it may be incompatible with the installed chrome version
config.directConnect = false;
config.seleniumAddress = 'http://localhost:4444/wd/hub';
exports.config = config;

View File

@@ -1,92 +0,0 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/docs/referenceConf.js
/*global jasmine */
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
exports.config = {
allScriptsTimeout: 600000,
// -----------------------------------------------------------------
// Uncomment to run tests using a remote Selenium server
//seleniumAddress: 'http://selenium.address:4444/wd/hub',
// Change to 'false' to run tests using a remote Selenium server
directConnect: true,
// Change if the website to test is not on the localhost
baseUrl: 'http://localhost:4000/',
// -----------------------------------------------------------------
specs: [
'./src/**/*.e2e-spec.ts'
],
// -----------------------------------------------------------------
// Browser and Capabilities: PhantomJS
// -----------------------------------------------------------------
// capabilities: {
// 'browserName': 'phantomjs',
// 'version': '',
// 'platform': 'ANY'
// },
// -----------------------------------------------------------------
// Browser and Capabilities: Chrome
// -----------------------------------------------------------------
capabilities: {
'browserName': 'chrome',
'version': '',
'platform': 'ANY',
'chromeOptions': {
'args': [ '--headless', '--disable-gpu' ]
}
},
// -----------------------------------------------------------------
// Browser and Capabilities: Firefox
// -----------------------------------------------------------------
// capabilities: {
// 'browserName': 'firefox',
// 'version': '',
// 'platform': 'ANY'
// },
// -----------------------------------------------------------------
// Browser and Capabilities: MultiCapabilities
// -----------------------------------------------------------------
//multiCapabilities: [
// {
// 'browserName': 'phantomjs',
// 'version': '',
// 'platform': 'ANY'
// },
// {
// 'browserName': 'chrome',
// 'version': '',
// 'platform': 'ANY'
// }
// {
// 'browserName': 'firefox',
// 'version': '',
// 'platform': 'ANY'
// }
//],
plugins: [{
path: '../node_modules/protractor-istanbul-plugin'
}],
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 600000,
print: function () {}
},
useAllAngular2AppRoots: true,
beforeLaunch: function () {
require('ts-node').register({
project: './e2e/tsconfig.json'
});
},
onPrepare: function () {
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: true
}
}));
}
};

View File

@@ -1,22 +0,0 @@
import { ProtractorPage } from './app.po';
describe('protractor App', () => {
let page: ProtractorPage;
beforeEach(() => {
page = new ProtractorPage();
});
it('should display translated title "DSpace Angular :: Home"', () => {
page.navigateTo();
page.waitUntilNotLoading();
expect<any>(page.getPageTitleText()).toEqual('DSpace Angular :: Home');
});
it('should contain a news section', () => {
page.navigateTo();
page.waitUntilNotLoading();
const text = page.getHomePageNewsText();
expect<any>(text).toBeDefined();
});
});

View File

@@ -1,23 +0,0 @@
import { browser, element, by, protractor, promise } from 'protractor';
export class ProtractorPage {
navigateTo() {
return browser.get('/')
.then(() => browser.waitForAngular());
}
getPageTitleText() {
return browser.getTitle();
}
getHomePageNewsText() {
return element(by.css('ds-home-news')).getText();
}
waitUntilNotLoading(): promise.Promise<unknown> {
const loading = element(by.css('.loader'));
const EC = protractor.ExpectedConditions;
const notLoading = EC.not(EC.presenceOf(loading));
return browser.wait(notLoading, 10000);
}
}

View File

@@ -1,19 +0,0 @@
import { ProtractorPage } from './pagenotfound.po';
describe('protractor PageNotFound', () => {
let page: ProtractorPage;
beforeEach(() => {
page = new ProtractorPage();
});
it('should contain element ds-pagenotfound when navigating to page that doesnt exist', () => {
page.navigateToNonExistingPage();
expect<any>(page.elementTagExists('ds-pagenotfound')).toEqual(true);
});
it('should not contain element ds-pagenotfound when navigating to existing page', () => {
page.navigateToExistingPage();
expect<any>(page.elementTagExists('ds-pagenotfound')).toEqual(false);
});
});

View File

@@ -1,18 +0,0 @@
import { browser, element, by } from 'protractor';
export class ProtractorPage {
HOMEPAGE = '/home';
NONEXISTINGPAGE = '/e9019a69-d4f1-4773-b6a3-bd362caa46f2';
navigateToNonExistingPage() {
return browser.get(this.NONEXISTINGPAGE);
}
navigateToExistingPage() {
return browser.get(this.HOMEPAGE);
}
elementTagExists(tag: string) {
return element(by.tagName(tag)).isPresent();
}
}

View File

@@ -1,46 +0,0 @@
import { ProtractorPage } from './search-navbar.po';
import { browser } from 'protractor';
describe('protractor SearchNavbar', () => {
let page: ProtractorPage;
let queryString: string;
beforeEach(() => {
page = new ProtractorPage();
queryString = 'the test query';
});
it('should go to search page with correct query if submitted (from home)', () => {
page.navigateToHome();
return checkIfSearchWorks();
});
it('should go to search page with correct query if submitted (from search)', () => {
page.navigateToSearch();
return checkIfSearchWorks();
});
it('check if can submit search box with pressing button', () => {
page.navigateToHome();
page.expandAndFocusSearchBox();
page.setCurrentQuery(queryString);
page.submitNavbarSearchForm();
browser.wait(() => {
return browser.getCurrentUrl().then((url: string) => {
return url.indexOf('query=' + encodeURI(queryString)) !== -1;
});
});
});
function checkIfSearchWorks(): boolean {
page.setCurrentQuery(queryString);
page.submitByPressingEnter();
browser.wait(() => {
return browser.getCurrentUrl().then((url: string) => {
return url.indexOf('query=' + encodeURI(queryString)) !== -1;
});
});
return false;
}
});

View File

@@ -1,35 +0,0 @@
import { browser, by, element, protractor } from 'protractor';
import { promise } from 'selenium-webdriver';
export class ProtractorPage {
HOME = '/home';
SEARCH = '/search';
navigateToHome() {
return browser.get(this.HOME);
}
navigateToSearch() {
return browser.get(this.SEARCH);
}
getCurrentQuery(): promise.Promise<string> {
return element(by.css('.navbar-container #search-navbar-container form input')).getAttribute('value');
}
expandAndFocusSearchBox() {
element(by.css('.navbar-container #search-navbar-container form a')).click();
}
setCurrentQuery(query: string) {
element(by.css('.navbar-container #search-navbar-container form input[name="query"]')).sendKeys(query);
}
submitNavbarSearchForm() {
element(by.css('.navbar-container #search-navbar-container form .submit-icon')).click();
}
submitByPressingEnter() {
element(by.css('.navbar-container #search-navbar-container form input[name="query"]')).sendKeys(protractor.Key.ENTER);
}
}

View File

@@ -1,60 +0,0 @@
import { ProtractorPage } from './search-page.po';
import { browser } from 'protractor';
describe('protractor SearchPage', () => {
let page: ProtractorPage;
beforeEach(() => {
page = new ProtractorPage();
});
it('should contain query value when navigating to page with query parameter', () => {
const queryString = 'Interesting query string';
page.navigateToSearchWithQueryParameter(queryString)
.then(() => page.getCurrentQuery())
.then((query: string) => {
expect<string>(query).toEqual(queryString);
});
});
it('should have right scope selected when navigating to page with scope parameter', () => {
page.navigateToSearch()
.then(() => page.getRandomScopeOption())
.then((scopeString: string) => {
page.navigateToSearchWithScopeParameter(scopeString);
page.waitUntilNotLoading();
page.getCurrentScope()
.then((s: string) => {
expect<string>(s).toEqual(scopeString);
});
});
});
it('should redirect to the correct url when scope was set and submit button was triggered', () => {
page.navigateToSearch()
.then(() => page.getRandomScopeOption())
.then((scopeString: string) => {
page.setCurrentScope(scopeString)
.then(() => page.submitSearchForm())
.then(() => page.waitUntilNotLoading())
.then(() => () => {
browser.wait(() => {
return browser.getCurrentUrl().then((url: string) => {
return url.indexOf('scope=' + encodeURI(scopeString)) !== -1;
});
});
});
});
});
it('should redirect to the correct url when query was set and submit button was triggered', () => {
const queryString = 'Another interesting query string';
page.setCurrentQuery(queryString);
page.submitSearchForm();
browser.wait(() => {
return browser.getCurrentUrl().then((url: string) => {
return url.indexOf('query=' + encodeURI(queryString)) !== -1;
});
});
});
});

View File

@@ -1,55 +0,0 @@
import { browser, by, element, protractor } from 'protractor';
import { promise } from 'selenium-webdriver';
export class ProtractorPage {
SEARCH = '/search';
navigateToSearch() {
return browser.get(this.SEARCH);
}
navigateToSearchWithQueryParameter(query: string) {
return browser.get(this.SEARCH + '?query=' + query);
}
navigateToSearchWithScopeParameter(scope: string) {
return browser.get(this.SEARCH + '?scope=' + scope);
}
getCurrentScope(): promise.Promise<string> {
const scopeSelect = element(by.css('#search-form select'));
browser.wait(protractor.ExpectedConditions.presenceOf(scopeSelect), 10000);
return scopeSelect.getAttribute('value');
}
getCurrentQuery(): promise.Promise<string> {
return element(by.css('#search-form input')).getAttribute('value');
}
setCurrentScope(scope: string) {
return element(by.css('#search-form option[value="' + scope + '"]')).click();
}
setCurrentQuery(query: string) {
element(by.css('#search-form input[name="query"]')).sendKeys(query);
}
submitSearchForm() {
return element(by.css('#search-form button.search-button')).click();
}
getRandomScopeOption(): promise.Promise<string> {
const options = element(by.css('select[name="scope"]')).all(by.tagName('option'));
return options.count().then((c: number) => {
const index: number = Math.floor(Math.random() * (c - 1));
return options.get(index + 1).getAttribute('value');
});
}
waitUntilNotLoading(): promise.Promise<unknown> {
const loading = element(by.css('.loader'));
const EC = protractor.ExpectedConditions;
const notLoading = EC.not(EC.presenceOf(loading));
return browser.wait(notLoading, 10000);
}
}

View File

@@ -1,16 +0,0 @@
{
"compileOnSave": false,
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../dist/out-tsc-e2e",
"sourceMap": true,
"target": "es2018",
"typeRoots": [
"../node_modules/@types"
]
}
}

View File

@@ -1,5 +0,0 @@
{
"watch": ["src/environments/mock-environment.ts"],
"ext": "ts",
"exec": "ts-node --project ./tsconfig.ts-node.json scripts/set-mock-env.ts"
}

View File

@@ -1,6 +1,6 @@
{ {
"watch": ["src/environments"], "watch": [
"ext": "ts", "config"
"ignore": ["src/environments/environment.ts", "src/environments/mock-environment.ts"], ],
"exec": "ts-node --project ./tsconfig.ts-node.json scripts/set-env.ts --dev" "ext": "json"
} }

View File

@@ -3,50 +3,40 @@
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"config:dev": "ts-node --project ./tsconfig.ts-node.json scripts/set-env.ts --dev", "config:watch": "nodemon",
"config:prod": "ts-node --project ./tsconfig.ts-node.json scripts/set-env.ts --prod", "test:rest": "ts-node --project ./tsconfig.ts-node.json scripts/test-rest.ts",
"config:test": "ts-node --project ./tsconfig.ts-node.json scripts/set-mock-env.ts",
"config:test:watch": "nodemon --config mock-nodemon.json",
"config:dev:watch": "nodemon",
"prestart:dev": "yarn run config:dev",
"prebuild": "yarn run config:dev",
"pretest": "yarn run config:test",
"pretest:watch": "yarn run config:test",
"pretest:headless": "yarn run config:test",
"prebuild:prod": "yarn run config:prod",
"pree2e": "yarn run config:prod",
"pree2e:ci": "yarn run config:prod",
"start": "yarn run start:prod", "start": "yarn run start:prod",
"start:dev": "nodemon --exec \"cross-env NODE_ENV=development yarn run serve\"",
"start:prod": "yarn run build:prod && cross-env NODE_ENV=production yarn run serve:ssr",
"start:mirador:prod": "yarn run build:mirador && yarn run start:prod",
"serve": "ts-node --project ./tsconfig.ts-node.json scripts/serve.ts", "serve": "ts-node --project ./tsconfig.ts-node.json scripts/serve.ts",
"start:dev": "npm-run-all --parallel config:dev:watch serve", "serve:ssr": "node dist/server/main",
"start:prod": "yarn run build:prod && yarn run serve:ssr",
"analyze": "webpack-bundle-analyzer dist/browser/stats.json", "analyze": "webpack-bundle-analyzer dist/browser/stats.json",
"build": "ng build", "build": "ng build",
"build:stats": "ng build --stats-json", "build:stats": "ng build --stats-json",
"build:prod": "yarn run build:ssr", "build:prod": "yarn run build:ssr",
"build:ssr": "yarn run build:client-and-server-bundles && yarn run compile:server", "build:ssr": "ng build --configuration production && ng run dspace-angular:server:production",
"build:client-and-server-bundles": "ng build --prod && ng run dspace-angular:server:production --bundleDependencies true", "test": "ng test --sourceMap=true --watch=false --configuration test",
"test:watch": "npm-run-all --parallel config:test:watch test", "test:watch": "nodemon --exec \"ng test --sourceMap=true --watch=true --configuration test\"",
"test": "ng test --sourceMap=true --watch=true", "test:headless": "ng test --sourceMap=true --watch=false --configuration test --browsers=ChromeHeadless --code-coverage",
"test:headless": "ng test --watch=false --sourceMap=true --browsers=ChromeHeadless --code-coverage",
"lint": "ng lint", "lint": "ng lint",
"lint-fix": "ng lint --fix=true", "lint-fix": "ng lint --fix=true",
"e2e": "ng e2e", "e2e": "ng e2e",
"e2e:ci": "ng e2e --webdriver-update=false --protractor-config=./e2e/protractor-ci.conf.js", "clean:dev:config": "rimraf src/assets/config.json",
"compile:server": "webpack --config webpack.server.config.js --progress --color",
"serve:ssr": "node dist/server",
"clean:coverage": "rimraf coverage", "clean:coverage": "rimraf coverage",
"clean:dist": "rimraf dist", "clean:dist": "rimraf dist",
"clean:doc": "rimraf doc", "clean:doc": "rimraf doc",
"clean:log": "rimraf *.log*", "clean:log": "rimraf *.log*",
"clean:json": "rimraf *.records.json", "clean:json": "rimraf *.records.json",
"clean:bld": "rimraf build",
"clean:node": "rimraf node_modules", "clean:node": "rimraf node_modules",
"clean:prod": "yarn run clean:coverage && yarn run clean:doc && yarn run clean:dist && yarn run clean:log && yarn run clean:json && yarn run clean:bld", "clean:prod": "yarn run clean:dist && yarn run clean:log && yarn run clean:doc && yarn run clean:coverage && yarn run clean:json",
"clean": "yarn run clean:prod && yarn run clean:env && yarn run clean:node", "clean": "yarn run clean:prod && yarn run clean:dev:config && yarn run clean:node",
"clean:env": "rimraf src/environments/environment.ts", "sync-i18n": "ts-node --project ./tsconfig.ts-node.json scripts/sync-i18n-files.ts",
"sync-i18n": "yarn run config:dev && ts-node --project ./tsconfig.ts-node.json scripts/sync-i18n-files.ts", "build:mirador": "webpack --config webpack/webpack.mirador.config.ts",
"postinstall": "ngcc" "merge-i18n": "ts-node --project ./tsconfig.ts-node.json scripts/merge-i18n-files.ts",
"cypress:open": "cypress open",
"cypress:run": "cypress run",
"env:yaml": "ts-node --project ./tsconfig.ts-node.json scripts/env-to-yaml.ts"
}, },
"browser": { "browser": {
"fs": false, "fs": false,
@@ -56,28 +46,29 @@
}, },
"private": true, "private": true,
"resolutions": { "resolutions": {
"minimist": "^1.2.5" "minimist": "^1.2.5",
"webdriver-manager": "^12.1.8"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "~10.2.3", "@angular/animations": "~11.2.14",
"@angular/cdk": "^10.2.6", "@angular/cdk": "^11.2.13",
"@angular/common": "~10.2.3", "@angular/common": "~11.2.14",
"@angular/compiler": "~10.2.3", "@angular/compiler": "~11.2.14",
"@angular/core": "~10.2.3", "@angular/core": "~11.2.14",
"@angular/forms": "~10.2.3", "@angular/forms": "~11.2.14",
"@angular/localize": "10.2.3", "@angular/localize": "11.2.14",
"@angular/platform-browser": "~10.2.3", "@angular/platform-browser": "~11.2.14",
"@angular/platform-browser-dynamic": "~10.2.3", "@angular/platform-browser-dynamic": "~11.2.14",
"@angular/platform-server": "~10.2.3", "@angular/platform-server": "~11.2.14",
"@angular/router": "~10.2.3", "@angular/router": "~11.2.14",
"@angularclass/bootloader": "1.0.1", "@kolkov/ngx-gallery": "^1.2.3",
"@ng-bootstrap/ng-bootstrap": "7.0.0", "@ng-bootstrap/ng-bootstrap": "9.1.3",
"@ng-dynamic-forms/core": "^12.0.0", "@ng-dynamic-forms/core": "^13.0.0",
"@ng-dynamic-forms/ui-ng-bootstrap": "^12.0.0", "@ng-dynamic-forms/ui-ng-bootstrap": "^13.0.0",
"@ngrx/effects": "^10.0.1", "@ngrx/effects": "^11.1.1",
"@ngrx/router-store": "^10.0.1", "@ngrx/router-store": "^11.1.1",
"@ngrx/store": "^10.0.1", "@ngrx/store": "^11.1.1",
"@nguniversal/express-engine": "10.1.0", "@nguniversal/express-engine": "11.2.1",
"@ngx-translate/core": "^13.0.0", "@ngx-translate/core": "^13.0.0",
"@nicky-lenaers/ngx-scroll-to": "^9.0.0", "@nicky-lenaers/ngx-scroll-to": "^9.0.0",
"angular-idle-preload": "3.0.0", "angular-idle-preload": "3.0.0",
@@ -87,9 +78,9 @@
"caniuse-lite": "^1.0.30001165", "caniuse-lite": "^1.0.30001165",
"cerialize": "0.1.18", "cerialize": "0.1.18",
"cli-progress": "^3.8.0", "cli-progress": "^3.8.0",
"compression": "^1.7.4",
"cookie-parser": "1.4.5", "cookie-parser": "1.4.5",
"core-js": "^3.7.0", "core-js": "^3.7.0",
"debug-loader": "^0.0.1",
"deepmerge": "^4.2.2", "deepmerge": "^4.2.2",
"express": "^4.17.1", "express": "^4.17.1",
"express-rate-limit": "^5.1.3", "express-rate-limit": "^5.1.3",
@@ -97,73 +88,83 @@
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"filesize": "^6.1.0", "filesize": "^6.1.0",
"font-awesome": "4.7.0", "font-awesome": "4.7.0",
"http-proxy-middleware": "^1.0.5",
"https": "1.0.0", "https": "1.0.0",
"js-cookie": "2.2.1", "js-cookie": "2.2.1",
"js-yaml": "^4.1.0",
"json5": "^2.1.3", "json5": "^2.1.3",
"jsonschema": "1.4.0", "jsonschema": "1.4.0",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"klaro": "^0.7.10", "klaro": "^0.7.10",
"lodash": "^4.17.21",
"mirador": "^3.3.0",
"mirador-dl-plugin": "^0.13.0",
"mirador-share-plugin": "^0.11.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"ng-mocks": "10.5.4", "ng-mocks": "11.11.2",
"ng2-file-upload": "1.4.0", "ng2-file-upload": "1.4.0",
"ng2-nouislider": "^1.8.2", "ng2-nouislider": "^1.8.3",
"ngx-infinite-scroll": "^10.0.1", "ngx-infinite-scroll": "^10.0.1",
"ngx-moment": "^5.0.0", "ngx-moment": "^5.0.0",
"ngx-pagination": "5.0.0", "ngx-pagination": "5.0.0",
"ngx-sortablejs": "^10.0.0", "ngx-sortablejs": "^11.1.0",
"nouislider": "^14.6.3", "nouislider": "^14.6.3",
"pem": "1.14.4", "pem": "1.14.4",
"postcss-cli": "^8.3.0", "postcss-cli": "^8.3.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rxjs": "^6.6.3", "rxjs": "^6.6.3",
"rxjs-spy": "^7.5.3",
"sass-resources-loader": "^2.1.1",
"sortablejs": "1.13.0", "sortablejs": "1.13.0",
"tslib": "^2.0.0", "tslib": "^2.0.0",
"url-parse": "^1.5.3",
"uuid": "^8.3.2",
"webfontloader": "1.6.28", "webfontloader": "1.6.28",
"zone.js": "^0.10.3", "zone.js": "^0.10.3"
"@kolkov/ngx-gallery": "^1.2.3"
}, },
"devDependencies": { "devDependencies": {
"@angular-builders/custom-webpack": "10.0.1", "@angular-builders/custom-webpack": "10.0.1",
"@angular-devkit/build-angular": "~0.1002.0", "@angular-devkit/build-angular": "~0.1102.15",
"@angular/cli": "~10.2.0", "@angular/cli": "~11.2.15",
"@angular/compiler-cli": "~10.2.3", "@angular/compiler-cli": "~11.2.14",
"@angular/language-service": "~10.2.3", "@angular/language-service": "~11.2.14",
"@cypress/schematic": "^1.5.0",
"@fortawesome/fontawesome-free": "^5.5.0", "@fortawesome/fontawesome-free": "^5.5.0",
"@ngrx/store-devtools": "^10.0.1", "@ngrx/store-devtools": "^11.1.1",
"@ngtools/webpack": "10.2.0", "@ngtools/webpack": "10.2.3",
"@nguniversal/builders": "~10.1.0", "@nguniversal/builders": "~11.2.1",
"@types/deep-freeze": "0.1.2", "@types/deep-freeze": "0.1.2",
"@types/express": "^4.17.9", "@types/express": "^4.17.9",
"@types/file-saver": "^2.0.1", "@types/file-saver": "^2.0.1",
"@types/jasmine": "^3.6.2", "@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.8", "@types/jasminewd2": "~2.0.8",
"@types/js-cookie": "2.2.6", "@types/js-cookie": "2.2.6",
"@types/lodash": "^4.14.165", "@types/lodash": "^4.14.165",
"@types/node": "^14.14.9", "@types/node": "^14.14.9",
"codelyzer": "^6.0.1", "axe-core": "^4.3.3",
"codelyzer": "^6.0.0",
"compression-webpack-plugin": "^3.0.1", "compression-webpack-plugin": "^3.0.1",
"copy-webpack-plugin": "^6.4.1", "copy-webpack-plugin": "^6.4.1",
"cross-env": "^7.0.3",
"css-loader": "3.4.0", "css-loader": "3.4.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"cypress": "8.6.0",
"cypress-axe": "^0.13.0",
"debug-loader": "^0.0.1",
"deep-freeze": "0.0.1", "deep-freeze": "0.0.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"fork-ts-checker-webpack-plugin": "^6.0.3", "fork-ts-checker-webpack-plugin": "^6.0.3",
"html-loader": "^1.3.2",
"html-webpack-plugin": "^4.5.0", "html-webpack-plugin": "^4.5.0",
"http-proxy-middleware": "^1.0.5", "jasmine-core": "~3.6.0",
"jasmine-core": "^3.6.0",
"jasmine-marbles": "0.6.0", "jasmine-marbles": "0.6.0",
"jasmine-spec-reporter": "^6.0.0", "jasmine-spec-reporter": "~5.0.0",
"karma": "^5.2.3", "karma": "^5.2.3",
"karma-chrome-launcher": "^3.1.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2", "karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "^4.0.1", "karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.4", "karma-jasmine-html-reporter": "^1.5.0",
"karma-mocha-reporter": "2.2.5", "karma-mocha-reporter": "2.2.5",
"nodemon": "^2.0.2", "nodemon": "^2.0.15",
"npm-run-all": "^4.1.5",
"optimize-css-assets-webpack-plugin": "^5.0.4", "optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-apply": "0.11.0", "postcss-apply": "0.11.0",
"postcss-import": "^12.0.1", "postcss-import": "^12.0.1",
@@ -173,17 +174,21 @@
"protractor": "^7.0.0", "protractor": "^7.0.0",
"protractor-istanbul-plugin": "2.0.0", "protractor-istanbul-plugin": "2.0.0",
"raw-loader": "0.5.1", "raw-loader": "0.5.1",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rxjs-spy": "^7.5.3",
"sass-resources-loader": "^2.1.1",
"script-ext-html-webpack-plugin": "2.1.5", "script-ext-html-webpack-plugin": "2.1.5",
"string-replace-loader": "^2.3.0", "string-replace-loader": "^2.3.0",
"terser-webpack-plugin": "^2.3.1", "terser-webpack-plugin": "^2.3.1",
"ts-loader": "^5.2.0", "ts-loader": "^5.2.0",
"ts-node": "^8.8.1", "ts-node": "^8.10.2",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"typescript": "~4.0.5", "typescript": "~4.0.5",
"webpack": "^4.44.2", "webpack": "^4.44.2",
"webpack-bundle-analyzer": "^4.4.0", "webpack-bundle-analyzer": "^4.4.0",
"webpack-cli": "^4.2.0", "webpack-cli": "^4.2.0",
"webpack-node-externals": "1.7.2" "webpack-dev-server": "^4.5.0"
} }
} }

39
scripts/env-to-yaml.ts Normal file
View File

@@ -0,0 +1,39 @@
import * as fs from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';
/**
* Script to help convert previous version environment.*.ts to yaml.
*
* Usage (see package.json):
*
* yarn env:yaml [relative path to environment.ts file] (optional relative path to write yaml file) *
*/
const args = process.argv.slice(2);
if (args[0] === undefined) {
console.log(`Usage:\n\tyarn env:yaml [relative path to environment.ts file] (optional relative path to write yaml file)\n`);
process.exit(0);
}
const envFullPath = join(process.cwd(), args[0]);
if (!fs.existsSync(envFullPath)) {
console.error(`Error:\n${envFullPath} does not exist\n`);
process.exit(1);
}
try {
const env = require(envFullPath);
const config = yaml.dump(env);
if (args[1]) {
const ymlFullPath = join(process.cwd(), args[1]);
fs.writeFileSync(ymlFullPath, config);
} else {
console.log(config);
}
} catch (e) {
console.error(e);
}

View File

@@ -0,0 +1,99 @@
import { projectRoot} from '../webpack/helpers';
const commander = require('commander');
const fs = require('fs');
const JSON5 = require('json5');
const _cliProgress = require('cli-progress');
const _ = require('lodash');
const program = new commander.Command();
program.version('1.0.0', '-v, --version');
const LANGUAGE_FILES_LOCATION = 'src/assets/i18n';
parseCliInput();
/**
* Purpose: Allows customization of i18n labels from within themes
* e.g. Customize the label "menu.section.browse_global" to display "Browse DSpace" rather than "All of DSpace"
*
* This script uses the i18n files found in a source directory to override settings in files with the same
* name in a destination directory. Only the i18n labels to be overridden need be in the source files.
*
* Execution (using custom theme):
* ```
* yarn merge-i18n -s src/themes/custom/assets/i18n
* ```
*
* Input parameters:
* * Output directory: The directory in which the original i18n files are stored
* - Defaults to src/assets/i18n (the default i18n file location)
* - This is where the final output files will be written
* * Source directory: The directory with override files
* - Required
* - Recommended to place override files in the theme directory under assets/i18n (but this is not required)
* - Files must have matching names in both source and destination directories, for example:
* en.json5 in the source directory will be merged with en.json5 in the destination directory
* fr.json5 in the source directory will be merged with fr.json5 in the destination directory
*/
function parseCliInput() {
program
.option('-d, --output-dir <output-dir>', 'output dir when running script on all language files', projectRoot(LANGUAGE_FILES_LOCATION))
.option('-s, --source-dir <source-dir>', 'source dir of transalations to be merged')
.usage('(-s <source-dir> [-d <output-dir>])')
.parse(process.argv);
if (program.outputDir && program.sourceDir) {
if (!fs.existsSync(program.outputDir) && !fs.lstatSync(program.outputDir).isDirectory() ) {
console.error('Output does not exist or is not a directory.');
console.log(program.outputHelp());
process.exit(1);
}
if (!fs.existsSync(program.sourceDir) && !fs.lstatSync(program.sourceDir).isDirectory() ) {
console.error('Source does not exist or is not a directory.');
console.log(program.outputHelp());
process.exit(1);
}
fs.readdirSync(projectRoot(program.sourceDir)).forEach(file => {
if (fs.existsSync(program.outputDir + '/' + file) ) {
console.log('Merging: ' + program.outputDir + '/' + file + ' with ' + program.sourceDir + '/' + file);
mergeFileWithSource(program.sourceDir + '/' + file, program.outputDir + '/' + file);
}
});
} else {
console.error('Source or Output parameter is missing.');
console.log(program.outputHelp());
process.exit(1);
}
}
/**
* Reads source file and output file to merge the contents
* > Iterates over the source file keys
* > Updates values for each key and adds new keys as needed
* > Updates the output file with the new merged json
* @param pathToSourceFile Valid path to source file to merge from
* @param pathToOutputFile Valid path to merge and write output
*/
function mergeFileWithSource(pathToSourceFile, pathToOutputFile) {
const progressBar = new _cliProgress.SingleBar({}, _cliProgress.Presets.shades_classic);
progressBar.start(100, 0);
const sourceFile = fs.readFileSync(pathToSourceFile, 'utf8');
progressBar.update(10);
const outputFile = fs.readFileSync(pathToOutputFile, 'utf8');
progressBar.update(20);
const parsedSource = JSON5.parse(sourceFile);
progressBar.update(30);
const parsedOutput = JSON5.parse(outputFile);
progressBar.update(40);
for (const key of Object.keys(parsedSource)) {
parsedOutput[key] = parsedSource[key];
}
progressBar.update(80);
fs.writeFileSync(pathToOutputFile,JSON5.stringify(parsedOutput,{ space:'\n ', quote: '"' }), { encoding:'utf8' });
progressBar.update(100);
progressBar.stop();
}

View File

@@ -1,11 +1,14 @@
import { environment } from '../src/environments/environment';
import * as child from 'child_process'; import * as child from 'child_process';
import { AppConfig } from '../src/config/app-config.interface';
import { buildAppConfig } from '../src/config/config.server';
const appConfig: AppConfig = buildAppConfig();
/** /**
* Calls `ng serve` with the following arguments configured for the UI in the environment file: host, port, nameSpace, ssl * Calls `ng serve` with the following arguments configured for the UI in the app config: host, port, nameSpace, ssl
*/ */
child.spawn( child.spawn(
`ng serve --host ${environment.ui.host} --port ${environment.ui.port} --servePath ${environment.ui.nameSpace} --ssl ${environment.ui.ssl}`, `ng serve --host ${appConfig.ui.host} --port ${appConfig.ui.port} --serve-path ${appConfig.ui.nameSpace} --ssl ${appConfig.ui.ssl}`,
{ stdio:'inherit', shell: true } { stdio: 'inherit', shell: true }
); );

View File

@@ -1,116 +0,0 @@
import { writeFile } from 'fs';
import { environment as commonEnv } from '../src/environments/environment.common';
import { GlobalConfig } from '../src/config/global-config.interface';
import { ServerConfig } from '../src/config/server-config.interface';
import { hasValue } from '../src/app/shared/empty.util';
// Configure Angular `environment.ts` file path
const targetPath = './src/environments/environment.ts';
// Load node modules
const colors = require('colors');
require('dotenv').config();
const merge = require('deepmerge');
const mergeOptions = { arrayMerge: (destinationArray, sourceArray, options) => sourceArray };
const environment = process.argv[2];
let environmentFilePath;
let production = false;
switch (environment) {
case '--prod':
case '--production':
production = true;
console.log(`Building ${colors.red.bold(`production`)} environment`);
environmentFilePath = '../src/environments/environment.prod.ts';
break;
case '--test':
console.log(`Building ${colors.blue.bold(`test`)} environment`);
environmentFilePath = '../src/environments/environment.test.ts';
break;
default:
console.log(`Building ${colors.green.bold(`development`)} environment`);
environmentFilePath = '../src/environments/environment.dev.ts';
}
const processEnv = {
ui: createServerConfig(
process.env.DSPACE_HOST,
process.env.DSPACE_PORT,
process.env.DSPACE_NAMESPACE,
process.env.DSPACE_SSL),
rest: createServerConfig(
process.env.DSPACE_REST_HOST,
process.env.DSPACE_REST_PORT,
process.env.DSPACE_REST_NAMESPACE,
process.env.DSPACE_REST_SSL)
} as GlobalConfig;
import(environmentFilePath)
.then((file) => generateEnvironmentFile(merge.all([commonEnv, file.environment, processEnv], mergeOptions)))
.catch(() => {
console.log(colors.yellow.bold(`No specific environment file found for ` + environment));
generateEnvironmentFile(merge(commonEnv, processEnv, mergeOptions))
});
function generateEnvironmentFile(file: GlobalConfig): void {
file.production = production;
buildBaseUrls(file);
const contents = `export const environment = ` + JSON.stringify(file);
writeFile(targetPath, contents, (err) => {
if (err) {
throw console.error(err);
} else {
console.log(`Angular ${colors.bold('environment.ts')} file generated correctly at ${colors.bold(targetPath)} \n`);
}
});
}
// allow to override a few important options by environment variables
function createServerConfig(host?: string, port?: string, nameSpace?: string, ssl?: string): ServerConfig {
const result = {} as any;
if (hasValue(host)) {
result.host = host;
}
if (hasValue(nameSpace)) {
result.nameSpace = nameSpace;
}
if (hasValue(port)) {
result.port = Number(port);
}
if (hasValue(ssl)) {
result.ssl = ssl.trim().match(/^(true|1|yes)$/i) ? true : false;
}
return result;
}
function buildBaseUrls(config: GlobalConfig): void {
for (const key in config) {
if (config.hasOwnProperty(key) && config[key].host) {
config[key].baseUrl = [
getProtocol(config[key].ssl),
getHost(config[key].host),
getPort(config[key].port),
getNameSpace(config[key].nameSpace)
].join('');
}
}
}
function getProtocol(ssl: boolean): string {
return ssl ? 'https://' : 'http://';
}
function getHost(host: string): string {
return host;
}
function getPort(port: number): string {
return port ? (port !== 80 && port !== 443) ? ':' + port : '' : '';
}
function getNameSpace(nameSpace: string): string {
return nameSpace ? nameSpace.charAt(0) === '/' ? nameSpace : '/' + nameSpace : '';
}

View File

@@ -1,11 +0,0 @@
import { copyFile } from 'fs';
// Configure Angular `environment.ts` file path
const sourcePath = './src/environments/mock-environment.ts';
const targetPath = './src/environments/environment.ts';
// destination.txt will be created or overwritten by default.
copyFile(sourcePath, targetPath, (err) => {
if (err) throw err;
console.log(sourcePath + ' was copied to ' + targetPath);
});

70
scripts/test-rest.ts Normal file
View File

@@ -0,0 +1,70 @@
import * as http from 'http';
import * as https from 'https';
import { AppConfig } from '../src/config/app-config.interface';
import { buildAppConfig } from '../src/config/config.server';
const appConfig: AppConfig = buildAppConfig();
/**
* Script to test the connection with the configured REST API (in the 'rest' settings of your config.*.yaml)
*
* This script is useful to test for any Node.js connection issues with your REST API.
*
* Usage (see package.json): yarn test:rest
*/
// Get root URL of configured REST API
const restUrl = appConfig.rest.baseUrl + '/api';
console.log(`...Testing connection to REST API at ${restUrl}...\n`);
// If SSL enabled, test via HTTPS, else via HTTP
if (appConfig.rest.ssl) {
const req = https.request(restUrl, (res) => {
console.log(`RESPONSE: ${res.statusCode} ${res.statusMessage} \n`);
res.on('data', (data) => {
checkJSONResponse(data);
});
});
req.on('error', error => {
console.error('ERROR connecting to REST API\n' + error);
});
req.end();
} else {
const req = http.request(restUrl, (res) => {
console.log(`RESPONSE: ${res.statusCode} ${res.statusMessage} \n`);
res.on('data', (data) => {
checkJSONResponse(data);
});
});
req.on('error', error => {
console.error('ERROR connecting to REST API\n' + error);
});
req.end();
}
/**
* Check JSON response from REST API to see if it looks valid. Log useful information
* @param responseData response data
*/
function checkJSONResponse(responseData: any): any {
let parsedData;
try {
parsedData = JSON.parse(responseData);
console.log('Checking JSON returned for validity...');
console.log(`\t"dspaceVersion" = ${parsedData.dspaceVersion}`);
console.log(`\t"dspaceUI" = ${parsedData.dspaceUI}`);
console.log(`\t"dspaceServer" = ${parsedData.dspaceServer}`);
console.log(`\t"dspaceServer" property matches UI's "rest" config? ${(parsedData.dspaceServer === appConfig.rest.baseUrl)}`);
// Check for "authn" and "sites" in "_links" section as they should always exist (even if no data)!
const linksFound: string[] = Object.keys(parsedData._links);
console.log(`\tDoes "/api" endpoint have HAL links ("_links" section)? ${linksFound.includes('authn') && linksFound.includes('sites')}`);
} catch (err) {
console.error('ERROR: INVALID DSPACE REST API! Response is not valid JSON!');
console.error(`Response returned:\n${responseData}`);
}
}

123
server.ts
View File

@@ -19,36 +19,50 @@ import 'zone.js/dist/zone-node';
import 'reflect-metadata'; import 'reflect-metadata';
import 'rxjs'; import 'rxjs';
import * as fs from 'fs';
import * as pem from 'pem'; import * as pem from 'pem';
import * as https from 'https'; import * as https from 'https';
import * as morgan from 'morgan'; import * as morgan from 'morgan';
import * as express from 'express'; import * as express from 'express';
import * as bodyParser from 'body-parser'; import * as bodyParser from 'body-parser';
import * as compression from 'compression'; import * as compression from 'compression';
import { existsSync, readFileSync } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { APP_BASE_HREF } from '@angular/common';
import { enableProdMode } from '@angular/core'; import { enableProdMode } from '@angular/core';
import { existsSync } from 'fs';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens'; import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
import { environment } from './src/environments/environment'; import { environment } from './src/environments/environment';
import { createProxyMiddleware } from 'http-proxy-middleware'; import { createProxyMiddleware } from 'http-proxy-middleware';
import { hasValue, hasNoValue } from './src/app/shared/empty.util'; import { hasValue, hasNoValue } from './src/app/shared/empty.util';
import { APP_BASE_HREF } from '@angular/common';
import { UIServerConfig } from './src/config/ui-server-config.interface'; import { UIServerConfig } from './src/config/ui-server-config.interface';
import { ServerAppModule } from './src/main.server';
import { buildAppConfig } from './src/config/config.server';
import { AppConfig, APP_CONFIG } from './src/config/app-config.interface';
import { extendEnvironmentWithAppConfig } from './src/config/config.util';
/* /*
* Set path for the browser application's dist folder * Set path for the browser application's dist folder
*/ */
const DIST_FOLDER = join(process.cwd(), 'dist/browser'); const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// Set path fir IIIF viewer.
const IIIF_VIEWER = join(process.cwd(), 'dist/iiif');
const indexHtml = existsSync(join(DIST_FOLDER, 'index.html')) ? 'index.html' : 'index'; const indexHtml = existsSync(join(DIST_FOLDER, 'index.html')) ? 'index.html' : 'index';
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { ServerAppModule, ngExpressEngine } = require('./dist/server/main');
const cookieParser = require('cookie-parser'); const cookieParser = require('cookie-parser');
const appConfig: AppConfig = buildAppConfig(join(DIST_FOLDER, 'assets/config.json'));
// extend environment with app config for server
extendEnvironmentWithAppConfig(environment, appConfig);
// The Express app is exported so that it can be used by serverless Functions. // The Express app is exported so that it can be used by serverless Functions.
export function app() { export function app() {
@@ -57,7 +71,6 @@ export function app() {
*/ */
const server = express(); const server = express();
/* /*
* If production mode is enabled in the environment file: * If production mode is enabled in the environment file:
* - Enable Angular's production mode * - Enable Angular's production mode
@@ -99,7 +112,11 @@ export function app() {
provide: RESPONSE, provide: RESPONSE,
useValue: (options as any).req.res, useValue: (options as any).req.res,
}, },
], {
provide: APP_CONFIG,
useValue: environment
}
]
})(_, (options as any), callback) })(_, (options as any), callback)
); );
@@ -135,6 +152,10 @@ export function app() {
* Serve static resources (images, i18n messages, …) * Serve static resources (images, i18n messages, …)
*/ */
server.get('*.*', cacheControl, express.static(DIST_FOLDER, { index: false })); server.get('*.*', cacheControl, express.static(DIST_FOLDER, { index: false }));
/*
* Fallthrough to the IIIF viewer (must be included in the build).
*/
server.use('/iiif', express.static(IIIF_VIEWER, {index:false}));
// Register the ngApp callback function to handle incoming requests // Register the ngApp callback function to handle incoming requests
server.get('*', ngApp); server.get('*', ngApp);
@@ -221,47 +242,59 @@ function run() {
}); });
} }
/* function start() {
* If SSL is enabled /*
* - Read credentials from configuration files * If SSL is enabled
* - Call script to start an HTTPS server with these credentials * - Read credentials from configuration files
* When SSL is disabled * - Call script to start an HTTPS server with these credentials
* - Start an HTTP server on the configured port and host * When SSL is disabled
*/ * - Start an HTTP server on the configured port and host
if (environment.ui.ssl) { */
let serviceKey; if (environment.ui.ssl) {
try { let serviceKey;
serviceKey = fs.readFileSync('./config/ssl/key.pem'); try {
} catch (e) { serviceKey = readFileSync('./config/ssl/key.pem');
console.warn('Service key not found at ./config/ssl/key.pem'); } catch (e) {
} console.warn('Service key not found at ./config/ssl/key.pem');
}
let certificate; let certificate;
try { try {
certificate = fs.readFileSync('./config/ssl/cert.pem'); certificate = readFileSync('./config/ssl/cert.pem');
} catch (e) { } catch (e) {
console.warn('Certificate not found at ./config/ssl/key.pem'); console.warn('Certificate not found at ./config/ssl/key.pem');
} }
if (serviceKey && certificate) { if (serviceKey && certificate) {
createHttpsServer({ createHttpsServer({
serviceKey: serviceKey, serviceKey: serviceKey,
certificate: certificate certificate: certificate
}); });
} else {
console.warn('Disabling certificate validation and proceeding with a self-signed certificate. If this is a production server, it is recommended that you configure a valid certificate instead.');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // lgtm[js/disabling-certificate-validation]
pem.createCertificate({
days: 1,
selfSigned: true
}, (error, keys) => {
createHttpsServer(keys);
});
}
} else { } else {
console.warn('Disabling certificate validation and proceeding with a self-signed certificate. If this is a production server, it is recommended that you configure a valid certificate instead.'); run();
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // lgtm[js/disabling-certificate-validation]
pem.createCertificate({
days: 1,
selfSigned: true
}, (error, keys) => {
createHttpsServer(keys);
});
} }
} else { }
run();
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
start();
} }
export * from './src/main.server'; export * from './src/main.server';

View File

@@ -1,11 +0,0 @@
<li class="sidebar-section">
<a class="nav-item nav-link shortcut-icon" attr.aria-labelledby="sidebarName-{{section.id}}" [title]="('menu.section.icon.' + section.id) | translate" [routerLink]="itemModel.link">
<i class="fas fa-{{section.icon}} fa-fw"></i>
</a>
<div class="sidebar-collapsible">
<span id="sidebarName-{{section.id}}" class="section-header-text">
<ng-container
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
</span>
</div>
</li>

View File

@@ -1,27 +0,0 @@
<li class="sidebar-section" [ngClass]="{'expanded': (expanded | async)}"
[@bgColor]="{
value: ((expanded | async) ? 'endBackground' : 'startBackground'),
params: {endColor: (sidebarActiveBg | async)}}">
<div class="icon-wrapper">
<a class="nav-item nav-link shortcut-icon" attr.aria.labelledby="sidebarName-{{section.id}}" [title]="('menu.section.icon.' + section.id) | translate" (click)="toggleSection($event)" href="#">
<i class="fas fa-{{section.icon}} fa-fw"></i>
</a>
</div>
<div class="sidebar-collapsible">
<a class="nav-item nav-link" href="#"
(click)="toggleSection($event)">
<span id="sidebarName-{{section.id}}" class="section-header-text">
<ng-container
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
</span>
<i class="fas fa-chevron-right fa-pull-right"
[@rotate]="(expanded | async) ? 'expanded' : 'collapsed'" [title]="('menu.section.toggle.' + section.id) | translate"></i>
</a>
<ul class="sidebar-sub-level-items list-unstyled" @slide *ngIf="(expanded | async)">
<li *ngFor="let subSection of (subSections$ | async)">
<ng-container
*ngComponentOutlet="(sectionMap$ | async).get(subSection.id).component; injector: (sectionMap$ | async).get(subSection.id).injector;"></ng-container>
</li>
</ul>
</div>
</li>

View File

@@ -1,38 +0,0 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { EditBitstreamPageComponent } from './edit-bitstream-page/edit-bitstream-page.component';
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
import { BitstreamPageResolver } from './bitstream-page.resolver';
import { BitstreamDownloadPageComponent } from '../shared/bitstream-download-page/bitstream-download-page.component';
const EDIT_BITSTREAM_PATH = ':id/edit';
/**
* Routing module to help navigate Bitstream pages
*/
@NgModule({
imports: [
RouterModule.forChild([
{
path:':id/download',
component: BitstreamDownloadPageComponent,
resolve: {
bitstream: BitstreamPageResolver
},
},
{
path: EDIT_BITSTREAM_PATH,
component: EditBitstreamPageComponent,
resolve: {
bitstream: BitstreamPageResolver
},
canActivate: [AuthenticatedGuard]
}
])
],
providers: [
BitstreamPageResolver,
]
})
export class BitstreamPageRoutingModule {
}

View File

@@ -1,254 +0,0 @@
import { EditBitstreamPageComponent } from './edit-bitstream-page.component';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRoute, Router } from '@angular/router';
import { of as observableOf } from 'rxjs';
import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
import { ChangeDetectorRef, NO_ERRORS_SCHEMA } from '@angular/core';
import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service';
import { Bitstream } from '../../core/shared/bitstream.model';
import { NotificationType } from '../../shared/notifications/models/notification-type';
import { INotification, Notification } from '../../shared/notifications/models/notification.model';
import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level';
import { hasValue } from '../../shared/empty.util';
import { FormControl, FormGroup } from '@angular/forms';
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
import { VarDirective } from '../../shared/utils/var.directive';
import {
createSuccessfulRemoteDataObject,
createSuccessfulRemoteDataObject$
} from '../../shared/remote-data.utils';
import { RouterStub } from '../../shared/testing/router.stub';
import { getEntityEditRoute, getItemEditRoute } from '../../+item-page/item-page-routing-paths';
import { createPaginatedList } from '../../shared/testing/utils.test';
import { Item } from '../../core/shared/item.model';
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
const successNotification: INotification = new Notification('id', NotificationType.Success, 'success');
let notificationsService: NotificationsService;
let formService: DynamicFormService;
let bitstreamService: BitstreamDataService;
let bitstreamFormatService: BitstreamFormatDataService;
let bitstream: Bitstream;
let selectedFormat: BitstreamFormat;
let allFormats: BitstreamFormat[];
let router: Router;
let routerStub;
describe('EditBitstreamPageComponent', () => {
let comp: EditBitstreamPageComponent;
let fixture: ComponentFixture<EditBitstreamPageComponent>;
beforeEach(waitForAsync(() => {
allFormats = [
Object.assign({
id: '1',
shortDescription: 'Unknown',
description: 'Unknown format',
supportLevel: BitstreamFormatSupportLevel.Unknown,
_links: {
self: { href: 'format-selflink-1' }
}
}),
Object.assign({
id: '2',
shortDescription: 'PNG',
description: 'Portable Network Graphics',
supportLevel: BitstreamFormatSupportLevel.Known,
_links: {
self: { href: 'format-selflink-2' }
}
}),
Object.assign({
id: '3',
shortDescription: 'GIF',
description: 'Graphics Interchange Format',
supportLevel: BitstreamFormatSupportLevel.Known,
_links: {
self: { href: 'format-selflink-3' }
}
})
] as BitstreamFormat[];
selectedFormat = allFormats[1];
notificationsService = jasmine.createSpyObj('notificationsService',
{
info: infoNotification,
warning: warningNotification,
success: successNotification
}
);
formService = Object.assign({
createFormGroup: (fModel: DynamicFormControlModel[]) => {
const controls = {};
if (hasValue(fModel)) {
fModel.forEach((controlModel) => {
controls[controlModel.id] = new FormControl((controlModel as any).value);
});
return new FormGroup(controls);
}
return undefined;
}
});
bitstream = Object.assign(new Bitstream(), {
metadata: {
'dc.description': [
{
value: 'Bitstream description'
}
],
'dc.title': [
{
value: 'Bitstream title'
}
]
},
format: createSuccessfulRemoteDataObject$(selectedFormat),
_links: {
self: 'bitstream-selflink'
},
bundle: createSuccessfulRemoteDataObject$({
item: createSuccessfulRemoteDataObject$(Object.assign(new Item(), {
uuid: 'some-uuid'
}))
})
});
bitstreamService = jasmine.createSpyObj('bitstreamService', {
findById: createSuccessfulRemoteDataObject$(bitstream),
update: createSuccessfulRemoteDataObject$(bitstream),
updateFormat: createSuccessfulRemoteDataObject$(bitstream),
commitUpdates: {},
patch: {}
});
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(allFormats))
});
const itemPageUrl = `fake-url/some-uuid`;
routerStub = Object.assign(new RouterStub(), {
url: `${itemPageUrl}`
});
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule],
declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective],
providers: [
{ provide: NotificationsService, useValue: notificationsService },
{ provide: DynamicFormService, useValue: formService },
{ provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: createSuccessfulRemoteDataObject(bitstream) }), snapshot: { queryParams: {} } } },
{ provide: BitstreamDataService, useValue: bitstreamService },
{ provide: BitstreamFormatDataService, useValue: bitstreamFormatService },
{ provide: Router, useValue: routerStub },
ChangeDetectorRef
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EditBitstreamPageComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
router = (comp as any).router;
});
describe('on startup', () => {
let rawForm;
beforeEach(() => {
rawForm = comp.formGroup.getRawValue();
});
it('should fill in the bitstream\'s title', () => {
expect(rawForm.fileNamePrimaryContainer.fileName).toEqual(bitstream.name);
});
it('should fill in the bitstream\'s description', () => {
expect(rawForm.descriptionContainer.description).toEqual(bitstream.firstMetadataValue('dc.description'));
});
it('should select the correct format', () => {
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.id);
});
it('should put the \"New Format\" input on invisible', () => {
expect(comp.formLayout.newFormat.grid.host).toContain('invisible');
});
});
describe('when an unknown format is selected', () => {
beforeEach(() => {
comp.updateNewFormatLayout(allFormats[0].id);
});
it('should remove the invisible class from the \"New Format\" input', () => {
expect(comp.formLayout.newFormat.grid.host).not.toContain('invisible');
});
});
describe('onSubmit', () => {
describe('when selected format hasn\'t changed', () => {
beforeEach(() => {
comp.onSubmit();
});
it('should call update', () => {
expect(bitstreamService.update).toHaveBeenCalled();
});
it('should commit the updates', () => {
expect(bitstreamService.commitUpdates).toHaveBeenCalled();
});
});
describe('when selected format has changed', () => {
beforeEach(() => {
comp.formGroup.patchValue({
formatContainer: {
selectedFormat: allFormats[2].id
}
});
fixture.detectChanges();
comp.onSubmit();
});
it('should call update', () => {
expect(bitstreamService.update).toHaveBeenCalled();
});
it('should call updateFormat', () => {
expect(bitstreamService.updateFormat).toHaveBeenCalled();
});
it('should commit the updates', () => {
expect(bitstreamService.commitUpdates).toHaveBeenCalled();
});
});
});
describe('when the cancel button is clicked', () => {
it('should call navigateToItemEditBitstreams method', () => {
spyOn(comp, 'navigateToItemEditBitstreams');
comp.onCancel();
expect(comp.navigateToItemEditBitstreams).toHaveBeenCalled();
});
});
describe('when navigateToItemEditBitstreams is called, and the component has an itemId', () => {
it('should redirect to the item edit page on the bitstreams tab with the itemId from the component', () => {
comp.itemId = 'some-uuid1';
comp.navigateToItemEditBitstreams();
expect(routerStub.navigate).toHaveBeenCalledWith([getEntityEditRoute(null, 'some-uuid1'), 'bitstreams']);
});
});
describe('when navigateToItemEditBitstreams is called, and the component does not have an itemId', () => {
it('should redirect to the item edit page on the bitstreams tab with the itemId from the bundle links ', () => {
comp.itemId = undefined;
comp.navigateToItemEditBitstreams();
expect(routerStub.navigate).toHaveBeenCalledWith([getEntityEditRoute(null, 'some-uuid'), 'bitstreams']);
});
});
});

View File

@@ -1,12 +0,0 @@
import { BrowseByType, rendersBrowseBy } from './browse-by-decorator';
describe('BrowseByDecorator', () => {
const titleDecorator = rendersBrowseBy(BrowseByType.Title);
const dateDecorator = rendersBrowseBy(BrowseByType.Date);
const metadataDecorator = rendersBrowseBy(BrowseByType.Metadata);
it('should have a decorator for all types', () => {
expect(titleDecorator.length).not.toEqual(0);
expect(dateDecorator.length).not.toEqual(0);
expect(metadataDecorator.length).not.toEqual(0);
});
});

View File

@@ -1,54 +0,0 @@
import { BrowseBySwitcherComponent } from './browse-by-switcher.component';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import * as decorator from './browse-by-decorator';
import { BehaviorSubject } from 'rxjs';
import { environment } from '../../../environments/environment';
import createSpy = jasmine.createSpy;
xdescribe('BrowseBySwitcherComponent', () => {
let comp: BrowseBySwitcherComponent;
let fixture: ComponentFixture<BrowseBySwitcherComponent>;
const types = environment.browseBy.types;
const params = new BehaviorSubject(createParamsWithId('initialValue'));
const activatedRouteStub = {
params: params
};
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [BrowseBySwitcherComponent],
providers: [
{ provide: ActivatedRoute, useValue: activatedRouteStub }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(BrowseBySwitcherComponent);
comp = fixture.componentInstance;
spyOnProperty(decorator, 'getComponentByBrowseByType').and.returnValue(createSpy('getComponentByItemType'));
}));
types.forEach((type) => {
describe(`when switching to a browse-by page for "${type.id}"`, () => {
beforeEach(() => {
params.next(createParamsWithId(type.id));
fixture.detectChanges();
});
it(`should call getComponentByBrowseByType with type "${type.type}"`, () => {
expect(decorator.getComponentByBrowseByType).toHaveBeenCalledWith(type.type);
});
});
});
});
export function createParamsWithId(id) {
return { id: id };
}

View File

@@ -1,39 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { BrowseByTypeConfig } from '../../../config/browse-by-type-config.interface';
import { map } from 'rxjs/operators';
import { getComponentByBrowseByType } from './browse-by-decorator';
import { environment } from '../../../environments/environment';
@Component({
selector: 'ds-browse-by-switcher',
templateUrl: './browse-by-switcher.component.html'
})
/**
* Component for determining what Browse-By component to use depending on the metadata (browse ID) provided
*/
export class BrowseBySwitcherComponent implements OnInit {
/**
* Resolved browse-by component
*/
browseByComponent: Observable<any>;
public constructor(protected route: ActivatedRoute) {
}
/**
* Fetch the correct browse-by component by using the relevant config from environment.js
*/
ngOnInit(): void {
this.browseByComponent = this.route.params.pipe(
map((params) => {
const id = params.id;
return environment.browseBy.types.find((config: BrowseByTypeConfig) => config.id === id);
}),
map((config: BrowseByTypeConfig) => getComponentByBrowseByType(config.type))
);
}
}

View File

@@ -1,59 +0,0 @@
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
import { DSpaceObjectDataService } from '../core/data/dspace-object-data.service';
import { hasNoValue, hasValue } from '../shared/empty.util';
import { map } from 'rxjs/operators';
import { getFirstSucceededRemoteData } from '../core/shared/operators';
import { TranslateService } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { environment } from '../../environments/environment';
@Injectable()
/**
* A guard taking care of the correct route.data being set for the Browse-By components
*/
export class BrowseByGuard implements CanActivate {
constructor(protected dsoService: DSpaceObjectDataService,
protected translate: TranslateService) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const title = route.data.title;
const id = route.params.id || route.queryParams.id || route.data.id;
let metadataField = route.data.metadataField;
if (hasNoValue(metadataField) && hasValue(id)) {
const config = environment.browseBy.types.find((conf) => conf.id === id);
if (hasValue(config) && hasValue(config.metadataField)) {
metadataField = config.metadataField;
}
}
const scope = route.queryParams.scope;
const value = route.queryParams.value;
const metadataTranslated = this.translate.instant('browse.metadata.' + id);
if (hasValue(scope)) {
const dsoAndMetadata$ = this.dsoService.findById(scope).pipe(getFirstSucceededRemoteData());
return dsoAndMetadata$.pipe(
map((dsoRD) => {
const name = dsoRD.payload.name;
route.data = this.createData(title, id, metadataField, name, metadataTranslated, value, route);
return true;
})
);
} else {
route.data = this.createData(title, id, metadataField, '', metadataTranslated, value, route);
return observableOf(true);
}
}
private createData(title, id, metadataField, collection, field, value, route) {
return Object.assign({}, route.data, {
title: title,
id: id,
metadataField: metadataField,
collection: collection,
field: field,
value: hasValue(value) ? `"${value}"` : ''
});
}
}

View File

@@ -1,87 +0,0 @@
import { Component, Input } from '@angular/core';
import {
DynamicFormControlModel,
DynamicFormService,
DynamicInputModel,
DynamicTextAreaModel
} from '@ng-dynamic-forms/core';
import { Collection } from '../../core/shared/collection.model';
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
import { TranslateService } from '@ngx-translate/core';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { CommunityDataService } from '../../core/data/community-data.service';
import { AuthService } from '../../core/auth/auth.service';
import { RequestService } from '../../core/data/request.service';
import { ObjectCacheService } from '../../core/cache/object-cache.service';
/**
* Form used for creating and editing collections
*/
@Component({
selector: 'ds-collection-form',
styleUrls: ['../../shared/comcol-forms/comcol-form/comcol-form.component.scss'],
templateUrl: '../../shared/comcol-forms/comcol-form/comcol-form.component.html'
})
export class CollectionFormComponent extends ComColFormComponent<Collection> {
/**
* @type {Collection} A new collection when a collection is being created, an existing Input collection when a collection is being edited
*/
@Input() dso: Collection = new Collection();
/**
* @type {Collection.type} This is a collection-type form
*/
type = Collection.type;
/**
* The dynamic form fields used for creating/editing a collection
* @type {(DynamicInputModel | DynamicTextAreaModel)[]}
*/
formModel: DynamicFormControlModel[] = [
new DynamicInputModel({
id: 'title',
name: 'dc.title',
required: true,
validators: {
required: null
},
errorMessages: {
required: 'Please enter a name for this title'
},
}),
new DynamicTextAreaModel({
id: 'description',
name: 'dc.description',
}),
new DynamicTextAreaModel({
id: 'abstract',
name: 'dc.description.abstract',
}),
new DynamicTextAreaModel({
id: 'rights',
name: 'dc.rights',
}),
new DynamicTextAreaModel({
id: 'tableofcontents',
name: 'dc.description.tableofcontents',
}),
new DynamicTextAreaModel({
id: 'license',
name: 'dc.rights.license',
}),
new DynamicTextAreaModel({
id: 'provenance',
name: 'dc.description.provenance',
}),
];
public constructor(protected formService: DynamicFormService,
protected translate: TranslateService,
protected notificationsService: NotificationsService,
protected authService: AuthService,
protected dsoService: CommunityDataService,
protected requestService: RequestService,
protected objectCache: ObjectCacheService) {
super(formService, translate, notificationsService, authService, requestService, objectCache);
}
}

View File

@@ -1,22 +0,0 @@
<div class="container">
<div class="row">
<ng-container *ngVar="(dsoRD$ | async)?.payload as dso">
<div class="col-12 pb-4">
<h2 id="header" class="border-bottom pb-2">{{ 'community.delete.head' | translate}}</h2>
<p class="pb-2">{{ 'community.delete.text' | translate:{ dso: dso.name } }}</p>
<div class="form-group row">
<div class="col text-right">
<button class="btn btn-outline-secondary" (click)="onCancel(dso)">
<i class="fas fa-times"></i> {{'community.delete.cancel' | translate}}
</button>
<button class="btn btn-danger mr-2" (click)="onConfirm(dso)">
<i class="fas fa-trash"></i> {{'community.delete.confirm' | translate}}
</button>
</div>
</div>
</div>
</ng-container>
</div>
</div>

View File

@@ -1,57 +0,0 @@
<div class="container-fluid">
<div class="d-inline-block float-right">
<button class=" btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
</div>
<h4>{{ 'collection.edit.tabs.source.head' | translate }}</h4>
<div *ngIf="contentSource" class="form-check mb-4">
<input type="checkbox" class="form-check-input" id="externalSourceCheck" [checked]="(contentSource?.harvestType !== harvestTypeNone)" (change)="changeExternalSource()">
<label class="form-check-label" for="externalSourceCheck">{{ 'collection.edit.tabs.source.external' | translate }}</label>
</div>
<ds-loading *ngIf="!contentSource" [message]="'loading.content-source' | translate"></ds-loading>
<h4 *ngIf="contentSource && (contentSource?.harvestType !== harvestTypeNone)">{{ 'collection.edit.tabs.source.form.head' | translate }}</h4>
</div>
<ds-form *ngIf="formGroup && contentSource && (contentSource?.harvestType !== harvestTypeNone)"
[formId]="'collection-source-form-id'"
[formGroup]="formGroup"
[formModel]="formModel"
[formLayout]="formLayout"
[displaySubmit]="false"
[displayCancel]="false"
(dfChange)="onChange($event)"
(submitForm)="onSubmit()"
(cancel)="onCancel()"></ds-form>
<div class="container-fluid" *ngIf="(contentSource?.harvestType !== harvestTypeNone)">
<div class="d-inline-block float-right">
<button class=" btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
</div>
</div>

View File

@@ -1,66 +0,0 @@
<div class="item-metadata">
<div class="button-row top d-flex mb-2">
<button class="mr-auto btn btn-success"
(click)="add()"><i
class="fas fa-plus"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.add-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !(isValid() | async)"
(click)="submit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
</div>
<table class="table table-responsive table-striped table-bordered" *ngIf="((updates$ | async)| dsObjectValues).length > 0">
<tbody>
<tr>
<th>{{'item.edit.metadata.headers.field' | translate}}</th>
<th>{{'item.edit.metadata.headers.value' | translate}}</th>
<th class="text-center">{{'item.edit.metadata.headers.language' | translate}}</th>
<th class="text-center">{{'item.edit.metadata.headers.edit' | translate}}</th>
</tr>
<tr *ngFor="let updateValue of ((updates$ | async)| dsObjectValues); trackBy: trackUpdate"
ds-edit-in-place-field
[fieldUpdate]="updateValue || {}"
[url]="url"
[ngClass]="{
'table-warning': updateValue.changeType === 0,
'table-danger': updateValue.changeType === 2,
'table-success': updateValue.changeType === 1
}">
</tr>
</tbody>
</table>
<div *ngIf="((updates$ | async)| dsObjectValues).length == 0">
<ds-alert [content]="'item.edit.metadata.empty'" [type]="AlertTypeEnum.Info"></ds-alert>
</div>
<div class="button-row bottom">
<div class="mt-2 float-right">
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i> {{"item.edit.metadata.reinstate-button" | translate}}
</button>
<button class="btn btn-primary mr-0" [disabled]="!(hasChanges() | async)"
(click)="submit()"><i
class="fas fa-save"></i> {{"item.edit.metadata.save-button" | translate}}
</button>
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i> {{"item.edit.metadata.discard-button" | translate}}
</button>
</div>
</div>
</div>

View File

@@ -1,48 +0,0 @@
<div class="container">
<div class="row">
<div class="col-12">
<h2>{{'item.edit.move.head' | translate: {id: (itemRD$ | async)?.payload?.handle} }}</h2>
<p>{{'item.edit.move.description' | translate}}</p>
<div class="row">
<div class="col-12">
<ds-dso-input-suggestions #f id="search-form"
[suggestions]="(collectionSearchResults | async)"
[placeholder]="'item.edit.move.search.placeholder'| translate"
[action]="getCurrentUrl()"
[name]="'item-move'"
[(ngModel)]="selectedCollectionName"
(clickSuggestion)="onClick($event)"
(typeSuggestion)="resetCollection($event)"
(findSuggestions)="findSuggestions($event)"
(click)="f.open()"
ngDefaultControl>
</ds-dso-input-suggestions>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
<input type="checkbox" name="tc" [(ngModel)]="inheritPolicies" id="inheritPoliciesCheckbox">
<label for="inheritPoliciesCheckbox">{{'item.edit.move.inheritpolicies.checkbox' |
translate}}</label>
</p>
<p>
{{'item.edit.move.inheritpolicies.description' | translate}}
</p>
</div>
</div>
<button (click)="moveCollection()" class="btn btn-primary" [disabled]=!canSubmit>
<span *ngIf="!processing"> {{'item.edit.move.move' | translate}}</span>
<span *ngIf="processing"><i class='fas fa-circle-notch fa-spin'></i>
{{'item.edit.move.processing' | translate}}
</span>
</button>
<button [routerLink]="[(itemPageRoute$ | async), 'edit']"
class="btn btn-outline-secondary">
{{'item.edit.move.cancel' | translate}}
</button>
</div>
</div>
</div>

View File

@@ -1,15 +0,0 @@
<div class="col-3 float-left d-flex h-100 action-label">
<span class="justify-content-center align-self-center">
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.label' | translate}}
</span>
</div>
<div *ngIf="!operation.disabled" class="col-9 float-left action-button">
<a class="btn btn-outline-primary" [routerLink]="operation.operationUrl">
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}}
</a>
</div>
<div *ngIf="operation.disabled" class="col-9 float-left action-button">
<span class="btn btn-danger">
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}}
</span>
</div>

View File

@@ -1,26 +0,0 @@
<h5>
{{getRelationshipMessageKey() | async | translate}}
<button class="ml-2 btn btn-success" (click)="openLookup()">
<i class="fas fa-plus"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.relationships.edit.buttons.add" | translate}}</span>
</button>
</h5>
<ng-container *ngVar="updates$ | async as updates">
<ng-container *ngIf="updates">
<ng-container *ngVar="updates | dsObjectValues as updateValues">
<ds-edit-relationship *ngFor="let updateValue of updateValues; trackBy: trackUpdate"
class="relationship-row d-block alert"
[fieldUpdate]="updateValue || {}"
[url]="url"
[editItem]="item"
[ngClass]="{
'alert-success': updateValue.changeType === 1,
'alert-warning': updateValue.changeType === 0,
'alert-danger': updateValue.changeType === 2
}">
</ds-edit-relationship>
<div *ngIf="updateValues.length === 0">{{"item.edit.relationships.no-relationships" | translate}}</div>
</ng-container>
</ng-container>
<ds-loading *ngIf="!updates"></ds-loading>
</ng-container>

View File

@@ -1,344 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { LinkService } from '../../../../core/cache/builders/link.service';
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
import { combineLatest as observableCombineLatest, Observable, of } from 'rxjs';
import {
FieldUpdate,
FieldUpdates,
RelationshipIdentifiable
} from '../../../../core/data/object-updates/object-updates.reducer';
import { RelationshipService } from '../../../../core/data/relationship.service';
import { Item } from '../../../../core/shared/item.model';
import { defaultIfEmpty, map, mergeMap, switchMap, take, startWith } from 'rxjs/operators';
import { hasValue, hasValueOperator } from '../../../../shared/empty.util';
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
import {
getAllSucceededRemoteData,
getRemoteDataPayload,
getFirstSucceededRemoteData,
} from '../../../../core/shared/operators';
import { ItemType } from '../../../../core/shared/item-relationships/item-type.model';
import { DsDynamicLookupRelationModalComponent } from '../../../../shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component';
import { RelationshipOptions } from '../../../../shared/form/builder/models/relationship-options.model';
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { SelectableListService } from '../../../../shared/object-list/selectable-list/selectable-list.service';
import { SearchResult } from '../../../../shared/search/search-result.model';
import { followLink } from '../../../../shared/utils/follow-link-config.model';
import { PaginatedList } from '../../../../core/data/paginated-list.model';
import { RemoteData } from '../../../../core/data/remote-data';
@Component({
selector: 'ds-edit-relationship-list',
styleUrls: ['./edit-relationship-list.component.scss'],
templateUrl: './edit-relationship-list.component.html',
})
/**
* A component creating a list of editable relationships of a certain type
* The relationships are rendered as a list of related items
*/
export class EditRelationshipListComponent implements OnInit {
/**
* The item to display related items for
*/
@Input() item: Item;
@Input() itemType: ItemType;
/**
* The URL to the current page
* Used to fetch updates for the current item from the store
*/
@Input() url: string;
/**
* The label of the relationship-type we're rendering a list for
*/
@Input() relationshipType: RelationshipType;
private relatedEntityType$: Observable<ItemType>;
/**
* The list ID to save selected entities under
*/
listId: string;
/**
* The FieldUpdates for the relationships in question
*/
updates$: Observable<FieldUpdates>;
/**
* A reference to the lookup window
*/
modalRef: NgbModalRef;
constructor(
protected objectUpdatesService: ObjectUpdatesService,
protected linkService: LinkService,
protected relationshipService: RelationshipService,
protected modalService: NgbModal,
protected selectableListService: SelectableListService,
) {
}
/**
* Get the i18n message key for this relationship type
*/
public getRelationshipMessageKey(): Observable<string> {
return observableCombineLatest(
this.getLabel(),
this.relatedEntityType$,
).pipe(
map(([label, relatedEntityType]) => {
if (hasValue(label) && label.indexOf('is') > -1 && label.indexOf('Of') > -1) {
const relationshipLabel = `${label.substring(2, label.indexOf('Of'))}`;
if (relationshipLabel !== relatedEntityType.label) {
return `relationships.is${relationshipLabel}Of.${relatedEntityType.label}`;
} else {
return `relationships.is${relationshipLabel}Of`;
}
} else {
return label;
}
}),
);
}
/**
* Get the relevant label for this relationship type
*/
private getLabel(): Observable<string> {
return observableCombineLatest([
this.relationshipType.leftType,
this.relationshipType.rightType,
].map((itemTypeRD) => itemTypeRD.pipe(
getFirstSucceededRemoteData(),
getRemoteDataPayload(),
))).pipe(
map((itemTypes: ItemType[]) => [
this.relationshipType.leftwardType,
this.relationshipType.rightwardType,
][itemTypes.findIndex((itemType) => itemType.id === this.itemType.id)]),
);
}
/**
* Prevent unnecessary rerendering so fields don't lose focus
*/
trackUpdate(index, update: FieldUpdate) {
return update && update.field ? update.field.uuid : undefined;
}
/**
* Open the dynamic lookup modal to search for items to add as relationships
*/
openLookup() {
this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, {
size: 'lg'
});
const modalComp: DsDynamicLookupRelationModalComponent = this.modalRef.componentInstance;
modalComp.repeatable = true;
modalComp.listId = this.listId;
modalComp.item = this.item;
modalComp.select = (...selectableObjects: SearchResult<Item>[]) => {
selectableObjects.forEach((searchResult) => {
const relatedItem: Item = searchResult.indexableObject;
this.getFieldUpdatesForRelatedItem(relatedItem)
.subscribe((identifiables) => {
identifiables.forEach((identifiable) =>
this.objectUpdatesService.removeSingleFieldUpdate(this.url, identifiable.uuid)
);
if (identifiables.length === 0) {
this.relationshipService.getNameVariant(this.listId, relatedItem.uuid)
.subscribe((nameVariant) => {
const update = {
uuid: this.relationshipType.id + '-' + relatedItem.uuid,
nameVariant,
type: this.relationshipType,
relatedItem,
} as RelationshipIdentifiable;
this.objectUpdatesService.saveAddFieldUpdate(this.url, update);
});
}
});
});
};
modalComp.deselect = (...selectableObjects: SearchResult<Item>[]) => {
selectableObjects.forEach((searchResult) => {
const relatedItem: Item = searchResult.indexableObject;
this.objectUpdatesService.removeSingleFieldUpdate(this.url, this.relationshipType.id + '-' + relatedItem.uuid);
this.getFieldUpdatesForRelatedItem(relatedItem)
.subscribe((identifiables) =>
identifiables.forEach((identifiable) =>
this.objectUpdatesService.saveRemoveFieldUpdate(this.url, identifiable)
)
);
});
};
this.relatedEntityType$
.pipe(take(1))
.subscribe((relatedEntityType) => {
modalComp.relationshipOptions = Object.assign(
new RelationshipOptions(), {
relationshipType: relatedEntityType.label,
// filter: this.getRelationshipMessageKey(),
searchConfiguration: relatedEntityType.label.toLowerCase(),
nameVariants: true,
}
);
});
this.selectableListService.deselectAll(this.listId);
this.updates$.pipe(
switchMap((updates) =>
Object.values(updates).length > 0 ?
observableCombineLatest(
Object.values(updates)
.filter((update) => update.changeType !== FieldChangeType.REMOVE)
.map((update) => {
const field = update.field as RelationshipIdentifiable;
if (field.relationship) {
return this.getRelatedItem(field.relationship);
} else {
return of(field.relatedItem);
}
})
) : of([])
),
take(1),
map((items) => items.map((item) => {
const searchResult = new ItemSearchResult();
searchResult.indexableObject = item;
searchResult.hitHighlights = {};
return searchResult;
})),
).subscribe((items) => {
this.selectableListService.select(this.listId, items);
});
}
/**
* Get the existing field updates regarding a relationship with a given item
* @param relatedItem The item for which to get the existing field updates
*/
private getFieldUpdatesForRelatedItem(relatedItem: Item): Observable<RelationshipIdentifiable[]> {
return this.updates$.pipe(
take(1),
map((updates) => Object.values(updates)
.map((update) => update.field as RelationshipIdentifiable)
.filter((field) => field.relationship)
),
mergeMap((identifiables) =>
observableCombineLatest(
identifiables.map((identifiable) => this.getRelatedItem(identifiable.relationship))
).pipe(
defaultIfEmpty([]),
map((relatedItems) =>
identifiables.filter((identifiable, index) => relatedItems[index].uuid === relatedItem.uuid)
),
)
),
);
}
/**
* Get the related item for a given relationship
* @param relationship The relationship for which to get the related item
*/
private getRelatedItem(relationship: Relationship): Observable<Item> {
return this.relationshipService.isLeftItem(relationship, this.item).pipe(
switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationship.leftItem),
getFirstSucceededRemoteData(),
getRemoteDataPayload(),
) as Observable<Item>;
}
ngOnInit(): void {
this.relatedEntityType$ =
observableCombineLatest([
this.relationshipType.leftType,
this.relationshipType.rightType,
].map((type) => type.pipe(
getFirstSucceededRemoteData(),
getRemoteDataPayload(),
))).pipe(
map((relatedTypes: ItemType[]) => relatedTypes.find((relatedType) => relatedType.uuid !== this.itemType.uuid)),
hasValueOperator()
);
this.relatedEntityType$.pipe(
take(1)
).subscribe(
(relatedEntityType) => this.listId = `edit-relationship-${this.itemType.id}-${relatedEntityType.id}`
);
this.updates$ = this.getItemRelationships().pipe(
switchMap((relationships) =>
observableCombineLatest(
relationships.map((relationship) => this.relationshipService.isLeftItem(relationship, this.item))
).pipe(
defaultIfEmpty([]),
map((isLeftItemArray) => isLeftItemArray.map((isLeftItem, index) => {
const relationship = relationships[index];
const nameVariant = isLeftItem ? relationship.rightwardValue : relationship.leftwardValue;
return {
uuid: relationship.id,
type: this.relationshipType,
relationship,
nameVariant,
} as RelationshipIdentifiable;
})),
)),
switchMap((initialFields) => this.objectUpdatesService.getFieldUpdates(this.url, initialFields).pipe(
map((fieldUpdates) => {
const fieldUpdatesFiltered: FieldUpdates = {};
Object.keys(fieldUpdates).forEach((uuid) => {
if (hasValue(fieldUpdates[uuid])) {
const field = fieldUpdates[uuid].field;
if ((field as RelationshipIdentifiable).type.id === this.relationshipType.id) {
fieldUpdatesFiltered[uuid] = fieldUpdates[uuid];
}
}
});
return fieldUpdatesFiltered;
}),
)),
startWith({}),
);
}
private getItemRelationships() {
this.linkService.resolveLink(this.item,
followLink('relationships', undefined, true, true, true,
followLink('relationshipType'),
followLink('leftItem'),
followLink('rightItem'),
));
return this.item.relationships.pipe(
getAllSucceededRemoteData(),
map((relationships: RemoteData<PaginatedList<Relationship>>) => relationships.payload.page.filter((relationship: Relationship) => hasValue(relationship))),
switchMap((itemRelationships: Relationship[]) =>
observableCombineLatest(
itemRelationships
.map((relationship) => relationship.relationshipType.pipe(
getFirstSucceededRemoteData(),
getRemoteDataPayload(),
))
).pipe(
defaultIfEmpty([]),
map((relationshipTypes) => itemRelationships.filter(
(relationship, index) => relationshipTypes[index].id === this.relationshipType.id)
),
)
),
);
}
}

View File

@@ -1,6 +0,0 @@
<div class="mt-4">
<ds-alert [content]="'item.edit.tabs.versionhistory.under-construction'" [type]="AlertTypeEnum.Warning"></ds-alert>
</div>
<div class="mt-2" *ngVar="(itemRD$ | async)?.payload as item">
<ds-item-versions *ngIf="item" [item]="item" [displayWhenEmpty]="true" [displayTitle]="false"></ds-item-versions>
</div>

View File

@@ -1,7 +0,0 @@
<ds-metadata-field-wrapper *ngIf="(this.collectionsRD$ | async)?.hasSucceeded" [label]="label | translate">
<div class="collections">
<a *ngFor="let collection of (this.collectionsRD$ | async)?.payload?.page; let last=last;" [routerLink]="['/collections', collection.id]">
<span>{{collection?.name}}</span><span *ngIf="!last" [innerHTML]="separator"></span>
</a>
</div>
</ds-metadata-field-wrapper>

View File

@@ -1,91 +0,0 @@
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { Collection } from '../../../core/shared/collection.model';
import { Item } from '../../../core/shared/item.model';
import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock';
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { CollectionsComponent } from './collections.component';
let collectionsComponent: CollectionsComponent;
let fixture: ComponentFixture<CollectionsComponent>;
let collectionDataServiceStub;
const mockCollection1: Collection = Object.assign(new Collection(), {
metadata: {
'dc.description.abstract': [
{
language: 'en_US',
value: 'Short description'
}
]
},
_links: {
self: { href: 'collection-selflink' }
}
});
const succeededMockItem: Item = Object.assign(new Item(), {owningCollection: createSuccessfulRemoteDataObject$(mockCollection1)});
const failedMockItem: Item = Object.assign(new Item(), {owningCollection: createFailedRemoteDataObject$('error', 500)});
describe('CollectionsComponent', () => {
collectionDataServiceStub = {
findOwningCollectionFor(item: Item) {
if (item === succeededMockItem) {
return createSuccessfulRemoteDataObject$(mockCollection1);
} else {
return createFailedRemoteDataObject$('error', 500);
}
}
};
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
declarations: [ CollectionsComponent ],
providers: [
{ provide: RemoteDataBuildService, useValue: getMockRemoteDataBuildService()},
{ provide: CollectionDataService, useValue: collectionDataServiceStub },
],
schemas: [ NO_ERRORS_SCHEMA ]
}).overrideComponent(CollectionsComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(CollectionsComponent);
collectionsComponent = fixture.componentInstance;
collectionsComponent.label = 'test.test';
collectionsComponent.separator = '<br/>';
}));
describe('When the requested item request has succeeded', () => {
beforeEach(() => {
collectionsComponent.item = succeededMockItem;
fixture.detectChanges();
});
it('should show the collection', () => {
const collectionField = fixture.debugElement.query(By.css('ds-metadata-field-wrapper div.collections'));
expect(collectionField).not.toBeNull();
});
});
describe('When the requested item request has failed', () => {
beforeEach(() => {
collectionsComponent.item = failedMockItem;
fixture.detectChanges();
});
it('should not show the collection', () => {
const collectionField = fixture.debugElement.query(By.css('ds-metadata-field-wrapper div.collections'));
expect(collectionField).toBeNull();
});
});
});

View File

@@ -1,68 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
import { RemoteData } from '../../../core/data/remote-data';
import { Collection } from '../../../core/shared/collection.model';
import { Item } from '../../../core/shared/item.model';
import { PageInfo } from '../../../core/shared/page-info.model';
import { hasValue } from '../../../shared/empty.util';
/**
* This component renders the parent collections section of the item
* inside a 'ds-metadata-field-wrapper' component.
*/
@Component({
selector: 'ds-item-page-collections',
templateUrl: './collections.component.html'
})
export class CollectionsComponent implements OnInit {
@Input() item: Item;
label = 'item.page.collections';
separator = '<br/>';
collectionsRD$: Observable<RemoteData<PaginatedList<Collection>>>;
constructor(private cds: CollectionDataService) {
}
ngOnInit(): void {
// this.collections = this.item.parents.payload;
// TODO: this should use parents, but the collections
// for an Item aren't returned by the REST API yet,
// only the owning collection
this.collectionsRD$ = this.cds.findOwningCollectionFor(this.item).pipe(
map((rd: RemoteData<Collection>) => {
if (hasValue(rd.payload)) {
return new RemoteData(
rd.timeCompleted,
rd.msToLive,
rd.lastUpdated,
rd.state,
rd.errorMessage,
buildPaginatedList({
elementsPerPage: 10,
totalPages: 1,
currentPage: 1,
totalElements: 1,
_links: {
self: rd.payload._links.self
}
} as PageInfo, [rd.payload]),
rd.statusCode
);
} else {
return rd as any;
}
})
);
}
}

View File

@@ -1,95 +0,0 @@
import { Component } from '@angular/core';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { MetadataFieldWrapperComponent } from './metadata-field-wrapper.component';
/* tslint:disable:max-classes-per-file */
@Component({
selector: 'ds-component-without-content',
template: '<ds-metadata-field-wrapper [label]="\'test label\'">\n' +
'</ds-metadata-field-wrapper>'
})
class NoContentComponent {}
@Component({
selector: 'ds-component-with-empty-spans',
template: '<ds-metadata-field-wrapper [label]="\'test label\'">\n' +
' <span></span>\n' +
' <span></span>\n' +
'</ds-metadata-field-wrapper>'
})
class SpanContentComponent {}
@Component({
selector: 'ds-component-with-text',
template: '<ds-metadata-field-wrapper [label]="\'test label\'">\n' +
' <span>The quick brown fox jumps over the lazy dog</span>\n' +
'</ds-metadata-field-wrapper>'
})
class TextContentComponent {}
@Component({
selector: 'ds-component-with-image',
template: '<ds-metadata-field-wrapper [label]="\'test label\'">\n' +
' <img src="https://some/image.png" alt="an alt text">\n' +
'</ds-metadata-field-wrapper>'
})
class ImgContentComponent {}
/* tslint:enable:max-classes-per-file */
describe('MetadataFieldWrapperComponent', () => {
let component: MetadataFieldWrapperComponent;
let fixture: ComponentFixture<MetadataFieldWrapperComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [MetadataFieldWrapperComponent, NoContentComponent, SpanContentComponent, TextContentComponent, ImgContentComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MetadataFieldWrapperComponent);
component = fixture.componentInstance;
});
const wrapperSelector = '.simple-view-element';
it('should create', () => {
expect(component).toBeDefined();
});
it('should not show the component when there is no content', () => {
const parentFixture = TestBed.createComponent(NoContentComponent);
parentFixture.detectChanges();
const parentNative = parentFixture.nativeElement;
const nativeWrapper = parentNative.querySelector(wrapperSelector);
expect(nativeWrapper.classList.contains('d-none')).toBe(true);
});
it('should not show the component when there is DOM content but not text or an image', () => {
const parentFixture = TestBed.createComponent(SpanContentComponent);
parentFixture.detectChanges();
const parentNative = parentFixture.nativeElement;
const nativeWrapper = parentNative.querySelector(wrapperSelector);
expect(nativeWrapper.classList.contains('d-none')).toBe(true);
});
it('should show the component when there is text content', () => {
const parentFixture = TestBed.createComponent(TextContentComponent);
parentFixture.detectChanges();
const parentNative = parentFixture.nativeElement;
const nativeWrapper = parentNative.querySelector(wrapperSelector);
parentFixture.detectChanges();
expect(nativeWrapper.classList.contains('d-none')).toBe(false);
});
it('should show the component when there is img content', () => {
const parentFixture = TestBed.createComponent(ImgContentComponent);
parentFixture.detectChanges();
const parentNative = parentFixture.nativeElement;
const nativeWrapper = parentNative.querySelector(wrapperSelector);
parentFixture.detectChanges();
expect(nativeWrapper.classList.contains('d-none')).toBe(false);
});
});

View File

@@ -1,39 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../../../environments/environment';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
import { Bitstream } from '../../../../core/shared/bitstream.model';
import { Item } from '../../../../core/shared/item.model';
import { getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators';
import { getItemPageRoute } from '../../../item-page-routing-paths';
@Component({
selector: 'ds-item',
template: ''
})
/**
* A generic component for displaying metadata and relations of an item
*/
export class ItemComponent implements OnInit {
@Input() object: Item;
/**
* Route to the item page
*/
itemPageRoute: string;
mediaViewer = environment.mediaViewer;
constructor(protected bitstreamDataService: BitstreamDataService) {
}
ngOnInit(): void {
this.itemPageRoute = getItemPageRoute(this.object);
}
// TODO refactor to return RemoteData, and thumbnail template to deal with loading
getThumbnail(): Observable<Bitstream> {
return this.bitstreamDataService.getThumbnailFor(this.object).pipe(
getFirstSucceededRemoteDataPayload()
);
}
}

View File

@@ -1,112 +0,0 @@
import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Store } from '@ngrx/store';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
import { CommunityDataService } from '../../../../core/data/community-data.service';
import { DefaultChangeAnalyzer } from '../../../../core/data/default-change-analyzer.service';
import { DSOChangeAnalyzer } from '../../../../core/data/dso-change-analyzer.service';
import { ItemDataService } from '../../../../core/data/item-data.service';
import { buildPaginatedList } from '../../../../core/data/paginated-list.model';
import { RelationshipService } from '../../../../core/data/relationship.service';
import { RemoteData } from '../../../../core/data/remote-data';
import { Bitstream } from '../../../../core/shared/bitstream.model';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { Item } from '../../../../core/shared/item.model';
import { MetadataMap } from '../../../../core/shared/metadata.models';
import { PageInfo } from '../../../../core/shared/page-info.model';
import { UUIDService } from '../../../../core/shared/uuid.service';
import { TranslateLoaderMock } from '../../../../shared/mocks/translate-loader.mock';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component';
import { createRelationshipsObservable } from '../shared/item.component.spec';
import { UntypedItemComponent } from './untyped-item.component';
const mockItem: Item = Object.assign(new Item(), {
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
metadata: new MetadataMap(),
relationships: createRelationshipsObservable()
});
describe('UntypedItemComponent', () => {
let comp: UntypedItemComponent;
let fixture: ComponentFixture<UntypedItemComponent>;
beforeEach(waitForAsync(() => {
const mockBitstreamDataService = {
getThumbnailFor(item: Item): Observable<RemoteData<Bitstream>> {
return createSuccessfulRemoteDataObject$(new Bitstream());
}
};
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock
}
})],
declarations: [UntypedItemComponent, GenericItemPageFieldComponent, TruncatePipe],
providers: [
{ provide: ItemDataService, useValue: {} },
{ provide: TruncatableService, useValue: {} },
{ provide: RelationshipService, useValue: {} },
{ provide: ObjectCacheService, useValue: {} },
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: NotificationsService, useValue: {} },
{ provide: HttpClient, useValue: {} },
{ provide: DSOChangeAnalyzer, useValue: {} },
{ provide: DefaultChangeAnalyzer, useValue: {} },
{ provide: BitstreamDataService, useValue: mockBitstreamDataService },
],
schemas: [NO_ERRORS_SCHEMA]
}).overrideComponent(UntypedItemComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(UntypedItemComponent);
comp = fixture.componentInstance;
comp.object = mockItem;
fixture.detectChanges();
}));
it('should contain a component to display the date', () => {
const fields = fixture.debugElement.queryAll(By.css('ds-item-page-date-field'));
expect(fields.length).toBeGreaterThanOrEqual(1);
});
it('should contain a component to display the author', () => {
const fields = fixture.debugElement.queryAll(By.css('ds-item-page-author-field'));
expect(fields.length).toBeGreaterThanOrEqual(1);
});
it('should contain a component to display the abstract', () => {
const fields = fixture.debugElement.queryAll(By.css('ds-item-page-abstract-field'));
expect(fields.length).toBeGreaterThanOrEqual(1);
});
it('should contain a component to display the uri', () => {
const fields = fixture.debugElement.queryAll(By.css('ds-item-page-uri-field'));
expect(fields.length).toBeGreaterThanOrEqual(1);
});
it('should contain a component to display the collections', () => {
const fields = fixture.debugElement.queryAll(By.css('ds-item-page-collections'));
expect(fields.length).toBeGreaterThanOrEqual(1);
});
});

View File

@@ -1,22 +0,0 @@
<ngb-tabset *ngIf="relationTypes.length > 1" [destroyOnHide]="true" #tabs="ngbTabset" [activeId]="activeTab$ | async" (tabChange)="onTabChange($event)">
<ngb-tab *ngFor="let relationType of relationTypes" title="{{'item.page.relationships.' + relationType.label | translate}}" [id]="relationType.filter">
<ng-template ngbTabContent>
<div class="mt-4">
<ds-related-entities-search [item]="item"
[relationType]="relationType.filter"
[configuration]="relationType.configuration"
[searchEnabled]="searchEnabled"
[sideBarWidth]="sideBarWidth">
</ds-related-entities-search>
</div>
</ng-template>
</ngb-tab>
</ngb-tabset>
<div *ngIf="relationTypes.length === 1" class="mt-4">
<ds-related-entities-search *ngVar="relationTypes[0] as relationType" [item]="item"
[relationType]="relationType.filter"
[configuration]="relationType.configuration"
[searchEnabled]="searchEnabled"
[sideBarWidth]="sideBarWidth">
</ds-related-entities-search>
</div>

View File

@@ -1 +0,0 @@
@import '../+login-page/login-page.component.scss';

View File

@@ -1,21 +0,0 @@
<div class="parent mb-3">
<div class="upload">
<ds-uploader *ngIf="uploadFilesOptions.url !== ''"
[uploadFilesOptions]="uploadFilesOptions"
(onCompleteItem)="onCompleteItem($event)"
(onUploadError)="onUploadError($event)"
(onFileSelected)="afterFileLoaded($event)"></ds-uploader>
</div>
<div class="add">
<button class="btn btn-lg btn-primary mt-1 ml-2" (click)="openDialog()" attr.aria-label="'mydspace.new-submission' | translate" title="{{'mydspace.new-submission' | translate}}">
<i class="fa fa-plus" aria-hidden="true"></i>
</button>
</div>
<div class="add">
<a class="btn btn-lg btn-outline-primary mt-1 ml-2" [routerLink]="['/import-external']" role="button" attr.aria-label="{{'mydspace.new-submission-external' | translate}}" title="{{'mydspace.new-submission-external' | translate}}">
<i class="fa fa-file-import" aria-hidden="true"></i>
</a>
</div>
</div>

View File

@@ -1,52 +0,0 @@
<div class="container">
<ds-my-dspace-new-submission *dsShowOnlyForRole="[roleTypeEnum.Submitter]"></ds-my-dspace-new-submission>
<div class="search-page row">
<ds-search-sidebar *ngIf="!(isXsOrSm$ | async)" class="col-3 sidebar-md-sticky"
id="search-sidebar"
[configurationList]="(configurationList$ | async)"
[resultCount]="(resultsRD$ | async)?.payload.totalElements"
[viewModeList]="viewModeList"
[refreshFilters]="refreshFilters.asObservable()"
[inPlaceSearch]="inPlaceSearch"></ds-search-sidebar>
<div class="col-12 col-md-9">
<ds-search-form id="search-form"
[query]="(searchOptions$ | async)?.query"
[scope]="(searchOptions$ | async)?.scope"
[currentUrl]="getSearchLink()"
[scopes]="(scopeListRD$ | async)"
[inPlaceSearch]="inPlaceSearch"
[searchPlaceholder]="'mydspace.search-form.placeholder' | translate">
</ds-search-form>
<ds-search-labels [inPlaceSearch]="inPlaceSearch"></ds-search-labels>
<div class="row">
<div id="search-body"
class="row-offcanvas row-offcanvas-left w-100"
[@pushInOut]="(isSidebarCollapsed() | async) ? 'collapsed' : 'expanded'">
<ds-search-sidebar *ngIf="(isXsOrSm$ | async)" class="col-12"
id="search-sidebar-sm"
[configurationList]="(configurationList$ | async)"
[resultCount]="(resultsRD$ | async)?.payload.totalElements"
(toggleSidebar)="closeSidebar()"
[ngClass]="{'active': !(isSidebarCollapsed() | async)}"
[refreshFilters]="refreshFilters.asObservable()"
[inPlaceSearch]="inPlaceSearch">
</ds-search-sidebar>
<div id="search-content" class="col-12">
<div class="d-block d-md-none search-controls clearfix">
<ds-view-mode-switch [viewModeList]="viewModeList" [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-my-dspace-results [searchResults]="resultsRD$ | async"
[searchConfig]="searchOptions$ | async"
[context]="context$ | async"
(contentChange)="onResultsContentChange()"></ds-my-dspace-results>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1 +0,0 @@
@import '../+search-page/search.component.scss';

View File

@@ -1,191 +0,0 @@
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ActivatedRoute } from '@angular/router';
import { By } from '@angular/platform-browser';
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Store } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { cold } from 'jasmine-marbles';
import { of as observableOf } from 'rxjs';
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
import { CommunityDataService } from '../core/data/community-data.service';
import { HostWindowService } from '../shared/host-window.service';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from './my-dspace-page.component';
import { RouteService } from '../core/services/route.service';
import { routeServiceStub } from '../shared/testing/route-service.stub';
import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service.stub';
import { SearchService } from '../core/shared/search/search.service';
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
import { SidebarService } from '../shared/sidebar/sidebar.service';
import { SearchFilterService } from '../core/shared/search/search-filter.service';
import { RoleDirective } from '../shared/roles/role.directive';
import { RoleService } from '../core/roles/role.service';
import { RoleServiceMock } from '../shared/mocks/role-service.mock';
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
import { SidebarServiceStub } from '../shared/testing/sidebar-service.stub';
describe('MyDSpacePageComponent', () => {
let comp: MyDSpacePageComponent;
let fixture: ComponentFixture<MyDSpacePageComponent>;
let searchServiceObject: SearchService;
let searchConfigurationServiceObject: SearchConfigurationService;
const store: Store<MyDSpacePageComponent> = jasmine.createSpyObj('store', {
/* tslint:disable:no-empty */
dispatch: {},
/* tslint:enable:no-empty */
select: observableOf(true)
});
const pagination: PaginationComponentOptions = new PaginationComponentOptions();
pagination.id = 'mydspace-results-pagination';
pagination.currentPage = 1;
pagination.pageSize = 10;
const sort: SortOptions = new SortOptions('score', SortDirection.DESC);
const mockResults = createSuccessfulRemoteDataObject$(['test', 'data']);
const searchServiceStub = jasmine.createSpyObj('SearchService', {
search: mockResults,
getEndpoint: observableOf('discover/search/objects'),
getSearchLink: '/mydspace',
getScopes: observableOf(['test-scope']),
setServiceOptions: {}
});
const configurationParam = 'default';
const queryParam = 'test query';
const scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f';
const paginatedSearchOptions = new PaginatedSearchOptions({
configuration: configurationParam,
query: queryParam,
scope: scopeParam,
pagination,
sort
});
const activatedRouteStub = {
snapshot: {
queryParamMap: new Map([
['query', queryParam],
['scope', scopeParam]
])
},
queryParams: observableOf({
query: queryParam,
scope: scopeParam
})
};
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule, NgbCollapseModule],
declarations: [MyDSpacePageComponent, RoleDirective],
providers: [
{ provide: SearchService, useValue: searchServiceStub },
{
provide: CommunityDataService,
useValue: jasmine.createSpyObj('communityService', ['findById', 'findAll'])
},
{ provide: ActivatedRoute, useValue: activatedRouteStub },
{ provide: RouteService, useValue: routeServiceStub },
{
provide: Store, useValue: store
},
{
provide: HostWindowService, useValue: jasmine.createSpyObj('hostWindowService',
{
isXs: observableOf(true),
isSm: observableOf(false),
isXsOrSm: observableOf(true)
})
},
{
provide: SidebarService,
useValue: SidebarServiceStub
},
{
provide: SearchFilterService,
useValue: {}
}, {
provide: SEARCH_CONFIG_SERVICE,
useValue: new SearchConfigurationServiceStub()
},
{
provide: RoleService,
useValue: new RoleServiceMock()
},
],
schemas: [NO_ERRORS_SCHEMA]
}).overrideComponent(MyDSpacePageComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyDSpacePageComponent);
comp = fixture.componentInstance; // SearchPageComponent test instance
fixture.detectChanges();
searchServiceObject = (comp as any).service;
searchConfigurationServiceObject = (comp as any).searchConfigService;
});
afterEach(() => {
comp = null;
searchServiceObject = null;
searchConfigurationServiceObject = null;
});
it('should get the scope and query from the route parameters', () => {
searchConfigurationServiceObject.paginatedSearchOptions.next(paginatedSearchOptions);
expect(comp.searchOptions$).toBeObservable(cold('b', {
b: paginatedSearchOptions
}));
});
describe('when the open sidebar button is clicked in mobile view', () => {
beforeEach(() => {
spyOn(comp, 'openSidebar');
const openSidebarButton = fixture.debugElement.query(By.css('.open-sidebar'));
openSidebarButton.triggerEventHandler('click', null);
});
it('should trigger the openSidebar function', () => {
expect(comp.openSidebar).toHaveBeenCalled();
});
});
describe('when sidebarCollapsed is true in mobile view', () => {
let menu: HTMLElement;
beforeEach(() => {
menu = fixture.debugElement.query(By.css('#search-sidebar-sm')).nativeElement;
comp.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.isSidebarCollapsed = () => observableOf(false);
fixture.detectChanges();
});
it('should open the menu', () => {
expect(menu.classList).toContain('active');
});
});
});

View File

@@ -1,202 +0,0 @@
import {
ChangeDetectionStrategy,
Component,
Inject,
InjectionToken,
Input,
OnInit
} from '@angular/core';
import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs';
import { map, switchMap, tap, } from 'rxjs/operators';
import { PaginatedList } from '../core/data/paginated-list.model';
import { RemoteData } from '../core/data/remote-data';
import { DSpaceObject } from '../core/shared/dspace-object.model';
import { pushInOut } from '../shared/animations/push';
import { HostWindowService } from '../shared/host-window.service';
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
import { SearchService } from '../core/shared/search/search.service';
import { SidebarService } from '../shared/sidebar/sidebar.service';
import { hasValue } from '../shared/empty.util';
import { getFirstSucceededRemoteData } from '../core/shared/operators';
import { MyDSpaceResponseParsingService } from '../core/data/mydspace-response-parsing.service';
import { SearchConfigurationOption } from '../shared/search/search-switch-configuration/search-configuration-option.model';
import { RoleType } from '../core/roles/role-types';
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
import { ViewMode } from '../core/shared/view-mode.model';
import { MyDSpaceRequest } from '../core/data/request.models';
import { SearchResult } from '../shared/search/search-result.model';
import { Context } from '../core/shared/context.model';
export const MYDSPACE_ROUTE = '/mydspace';
export const SEARCH_CONFIG_SERVICE: InjectionToken<SearchConfigurationService> = new InjectionToken<SearchConfigurationService>('searchConfigurationService');
/**
* This component represents the whole mydspace page
*/
@Component({
selector: 'ds-my-dspace-page',
styleUrls: ['./my-dspace-page.component.scss'],
templateUrl: './my-dspace-page.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [pushInOut],
providers: [
{
provide: SEARCH_CONFIG_SERVICE,
useClass: MyDSpaceConfigurationService
}
]
})
export class MyDSpacePageComponent implements OnInit {
/**
* True when the search component should show results on the current page
*/
@Input() inPlaceSearch = true;
/**
* The list of available configuration options
*/
configurationList$: Observable<SearchConfigurationOption[]>;
/**
* The current search results
*/
resultsRD$: BehaviorSubject<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>> = new BehaviorSubject(null);
/**
* The current paginated search options
*/
searchOptions$: Observable<PaginatedSearchOptions>;
/**
* The current relevant scopes
*/
scopeListRD$: Observable<DSpaceObject[]>;
/**
* Emits true if were on a small screen
*/
isXsOrSm$: Observable<boolean>;
/**
* Subscription to unsubscribe from
*/
sub: Subscription;
/**
* Variable for enumeration RoleType
*/
roleTypeEnum = RoleType;
/**
* List of available view mode
*/
viewModeList = [ViewMode.ListElement, ViewMode.DetailedListElement];
/**
* The current context of this page: workspace or workflow
*/
context$: Observable<Context>;
/**
* Emit an event every time search sidebars must refresh their contents.
*/
refreshFilters: Subject<any> = new Subject<any>();
constructor(private service: SearchService,
private sidebarService: SidebarService,
private windowService: HostWindowService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: MyDSpaceConfigurationService) {
this.isXsOrSm$ = this.windowService.isXsOrSm();
this.service.setServiceOptions(MyDSpaceResponseParsingService, MyDSpaceRequest);
}
/**
* Initialize available configuration list
*
* Listening to changes in the paginated search options
* If something changes, update the search results
*
* Listen to changes in the scope
* If something changes, update the list of scopes for the dropdown
*
* Listen to changes in the configuration
* If something changes, update the current context
*/
ngOnInit(): void {
this.configurationList$ = this.searchConfigService.getAvailableConfigurationOptions();
this.searchOptions$ = this.searchConfigService.paginatedSearchOptions;
this.sub = this.searchOptions$.pipe(
tap(() => this.resultsRD$.next(null)),
switchMap((options: PaginatedSearchOptions) => this.service.search(options).pipe(getFirstSucceededRemoteData())))
.subscribe((results) => {
this.resultsRD$.next(results);
});
this.scopeListRD$ = this.searchConfigService.getCurrentScope('').pipe(
switchMap((scopeId) => this.service.getScopes(scopeId))
);
this.context$ = this.searchConfigService.getCurrentConfiguration('workspace')
.pipe(
map((configuration: string) => {
if (configuration === 'workspace') {
return Context.Workspace;
} else {
return Context.Workflow;
}
})
);
}
/**
* Handle the contentChange event from within the my dspace content.
* Notify search sidebars to refresh their content.
*/
onResultsContentChange() {
this.refreshFilters.next();
}
/**
* Set the sidebar to a collapsed state
*/
public closeSidebar(): void {
this.sidebarService.collapse();
}
/**
* Set the sidebar to an expanded state
*/
public openSidebar(): void {
this.sidebarService.expand();
}
/**
* Check if the sidebar is collapsed
* @returns {Observable<boolean>} emits true if the sidebar is currently collapsed, false if it is expanded
*/
public isSidebarCollapsed(): Observable<boolean> {
return this.sidebarService.isCollapsed;
}
/**
* @returns {string} The base path to the search page
*/
public getSearchLink(): string {
return this.service.getSearchLink();
}
/**
* Unsubscribe from the subscription
*/
ngOnDestroy(): void {
if (hasValue(this.sub)) {
this.sub.unsubscribe();
}
this.refreshFilters.complete();
}
}

View File

@@ -1,14 +0,0 @@
<div *ngIf="searchResults?.hasSucceeded && !searchResults?.isLoading && searchResults?.payload?.page.length > 0" @fadeIn>
<ds-viewable-collection
[config]="searchConfig.pagination"
[hasBorder]="hasBorder"
[sortConfig]="searchConfig.sort"
[objects]="searchResults"
[hideGear]="true"
[context]="context"
(contentChange)="contentChange.emit()">
</ds-viewable-collection>
</div>
<ds-loading *ngIf="isLoading()" message="{{'loading.mydspace-results' | translate}}"></ds-loading>
<ds-error *ngIf="searchResults?.hasFailed && (!searchResults?.errorMessage || searchResults?.statusCode != 400)" message="{{'error.search-results' | translate}}"></ds-error>
<h3 *ngIf="searchResults?.payload?.page.length == 0" class="text-center text-muted" ><span>{{'mydspace.results.no-results' | translate}}</span></h3>

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