Compare commits

...

1679 Commits

Author SHA1 Message Date
Tim Donohue
b7a57035c4 Merge pull request #651 from bram-atmire/2020-04-09-New-Message-Keys
Extending catalogs with missing messages April 9th
2020-04-17 10:34:15 -05:00
Tim Donohue
c64760b0d3 Merge pull request #643 from atmire/Edit-Collection---Assign-Roles-Groups
Edit collection - assign roles groups
2020-04-16 11:37:46 -05:00
Tim Donohue
2fdb5a4ce2 Merge pull request #648 from atmire/request-by-uuid-issue
Request by UUID issue
2020-04-13 11:34:53 -05:00
Tim Donohue
fc35bdfe33 Merge pull request #632 from atmire/Edit-Community---Assign-Roles-Groups
Edit Community - Assign Roles/Groups
2020-04-13 10:49:33 -05:00
Samuel
b7b7e7ae24 Edit Collection - Assign Roles/Groups (Angular) - correct workflowgroup descriptions 2020-04-10 14:28:20 +02:00
Bram Luyten
d9ec9029ea Extending catalogs with missing messages April 9th 2020-04-09 16:58:01 +02:00
Bram Luyten
ac84b3f9c0 Merge pull request #649 from Denijsb/latvian-translations
Latvian translations for DSpace 7
2020-04-09 16:48:52 +02:00
Bram Luyten
44449e33cd Enabling Latvian in default environment 2020-04-09 16:41:45 +02:00
Denijsb
fc5395c1e5 Latvian translations for DSpace 7
Contribution to the Latvian translations of DSpace7
2020-04-09 16:40:01 +02:00
Bram Luyten
31c22d544e Merge pull request #617 from cjuergen/update-german-translation-001
Update German Translation
2020-04-09 16:33:00 +02:00
David Cavrenne [Atmire]
d2ec2c65fd French interface translation (#619)
Thanks to the original contribution of @davidatmire with reviewing by @mhvezina and @cjuergen
2020-04-09 16:23:10 +02:00
Samuel
36bd2169db Edit Collection - Assign Roles/Groups (Angular) - repair tests 2020-04-08 11:42:27 +02:00
Samuel
f35a5804fc Edit Collection - Assign Roles/Groups (Angular) 2020-04-08 10:59:10 +02:00
Samuel
ad71796507 Edit Community - Assign Roles/Groups (Angular) - feedback 2020-04-08 10:53:25 +02:00
Samuel
6a828f9286 Edit Community - Assign Roles/Groups (Angular) 2020-04-08 10:39:27 +02:00
Tim Donohue
9adafac6c7 Merge pull request #613 from atmire/manage-groups-page
Access Control - Group admin page
2020-04-07 16:08:33 -05:00
Art Lowel
15e44ff46c ensure getByUUID still returns undefined when there's no match 2020-04-07 18:26:13 +02:00
Bram Luyten
0e2f85ef77 Placeholder for the Latvian translation 2020-04-07 15:37:32 +02:00
Art Lowel
cea01d46f9 add test to prove the bug is fixed 2020-04-07 13:31:17 +02:00
Art Lowel
6351a951e7 fix test and lint 2020-04-07 11:32:45 +02:00
Art Lowel
f368da7a27 fix issue where requestservice.getByUUID wouldn't work for requests that were never sent because there was already a copy in the cache 2020-04-07 11:32:38 +02:00
Marie Verdonck
2ecc1ca7fd [groups/epeople admin pages] hide add epeople/groups on new group page, redirect after group creation to add them 2020-04-06 14:55:36 +02:00
Tim Donohue
49e7b4b4b4 Merge pull request #642 from atmire/Upload-bitstream-bugfix
Upload bitstream bug-fix
2020-04-03 15:01:38 -05:00
Tim Donohue
d932928a7f Merge pull request #608 from atmire/w2p-69305_Apply-new-MyDSpace-fix
Ensure workflow members can only perform actions assigned
2020-04-03 08:10:33 -05:00
Kristof De Langhe
e56d3f717f 68346: Upload bitstream bugfix - properly refresh uploader component 2020-04-03 11:52:09 +02:00
Kristof De Langhe
5e651881b5 Merge branch 'master' into w2p-69305_Apply-new-MyDSpace-fix
Conflicts:
	src/app/shared/shared.module.ts
2020-04-03 10:57:27 +02:00
Tim Donohue
926f8e5a2f Merge pull request #577 from atmire/Edit-item-bitstreams
Edit item bitstreams
2020-04-02 10:51:50 -05:00
Marie Verdonck
cc402a0a02 [groups/epeople admin pages] messages added, activeGroup reset after page refresh fix & clearcache/reload after add/delete member moved 2020-04-02 17:18:30 +02:00
Bram Luyten
ddc0ed6321 Spelling correction in a single en.json5 key 2020-04-02 10:14:32 +02:00
Tim Donohue
b493c9b0f2 Merge pull request #640 from atmire/broken-create-community
Broken create community
2020-04-01 10:03:56 -05:00
Kristof De Langhe
27f17b35f9 68346: Set upload url after bundle create 2020-04-01 14:51:24 +02:00
Kristof De Langhe
1f984c4c40 69920: Test fix 2020-04-01 13:29:25 +02:00
Tim Donohue
6850a47d70 Merge pull request #638 from tdonohue/add_license_terms
Add LICENSE info to this codebase
2020-03-31 13:45:39 -05:00
Tim Donohue
52d5beae1d Merge pull request #633 from DSpace/pull_request_template
Create an initial PR template for DSpace 7 UI
2020-03-31 13:44:16 -05:00
Tim Donohue
46a5a3eaca Link back to license-checker 2020-03-31 12:14:08 -05:00
Tim Donohue
59df043578 Add license terms to this codebase 2020-03-31 12:11:51 -05:00
Tim Donohue
ecf8e8915f Minor tweak based on feedback. 2020-03-31 12:00:11 -05:00
Kristof De Langhe
b1b8c05150 Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	src/app/app-routing.module.ts
	src/app/shared/shared.module.ts
2020-03-30 16:42:06 +02:00
Marie Verdonck
06c6ed18a6 [groups/epeople admin pages] No adding current active group itself as own subgroup:
* Added message if trying to add current group (that is being edited) as own subgroup
* Removed possible add/delete button from current group being edited in subgroups list, replace with message
2020-03-30 11:49:07 +02:00
Marie Verdonck
48d7f6987e [groups/epeople admin pages] Changes/Fixes:
* Added check with Group.permanent on whether or not to show delete button
* Disabled groupName input field if group that is being edited is permanent
* Cancel edit group button sends you back to group registry now
* In group edit, cache only gets cleared of that groups subgroups and epersons cache (at member delete/add) instead of cleared of all groups info
* Separated search groups result list and list of subgroups in edit group page and eperson members of edit group page
* Fixed pagination after search issues in groups registry, group edit page (groups search, subgroups, epeople search and members)
* Applied same fixes to epeople registry
* Browse All button added to all group/eperson searches to browse all groups/epeople
* Fixed immediately being able to add members after group creation in edit group page
* Fixed hover i18n tags on groups & epeople registry page => Missing tags
* Fixed tests after changes
2020-03-30 11:10:02 +02:00
Tim Donohue
0d38c75ea2 Initial draft PR template 2020-03-27 12:37:45 -05:00
Tim Donohue
b535d166e0 Merge pull request #568 from 4Science/shibboleth
Dspace 7 shibboleth (Angular)
2020-03-27 09:56:31 -05:00
Kristof De Langhe
7996555ec2 Merge branch 'master' into w2p-69305_Apply-new-MyDSpace-fix
Conflicts:
	src/app/core/core.module.ts
	src/app/shared/shared.module.ts
2020-03-27 09:59:33 +01:00
Art Lowel
521b0d3986 Merge pull request #629 from vitorsilverio/translation_typo
Fix pt tranlation typo
2020-03-25 17:05:18 +01:00
Kristof De Langhe
02526753e2 68346: Routing back to edit-bitstreams page 2020-03-25 16:15:58 +01:00
Kristof De Langhe
74af325e45 Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	src/app/shared/shared.module.ts
2020-03-25 14:01:44 +01:00
Tim Donohue
b384a9400b Merge pull request #595 from atmire/Notice-regarding-the-availability-of-new-version
Notice regarding the availability of new version on item pages
2020-03-23 11:40:51 -05:00
Giuseppe Digilio
7cf0480098 Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	src/app/app-routing.module.ts
#	src/app/core/auth/auth.service.ts
#	src/app/shared/shared.module.ts
2020-03-23 10:36:19 +01:00
Marie Verdonck
54b351c0d3 final tests (group-form & member&subgroup lists) & notification
for group creation fail, with specific notification for group name in use
2020-03-22 22:48:18 +01:00
vitorsilverio
240d2cc1a5 Fix typo 2020-03-20 19:40:46 -03:00
Kristof De Langhe
10cd6182ae 68948: Item null check 2020-03-20 17:49:07 +01:00
Kristof De Langhe
441d8a07b5 68948: New version notice 2020-03-20 17:47:19 +01:00
Kristof De Langhe
32546273e2 Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	src/app/core/core.module.ts
	src/app/shared/shared.module.ts
2020-03-20 17:22:58 +01:00
Tim Donohue
103605c36e Merge pull request #585 from atmire/List-version-history
List item version history
2020-03-20 10:41:39 -05:00
Marie Verdonck
173dcee427 fixes after rebase reinstated 2020-03-19 18:12:18 +01:00
Marie Verdonck
909158c30e group reducer and group registry tests 2020-03-19 17:46:58 +01:00
Marie Verdonck
e10a37e414 initialize all variables used in multiple tests inside a beforeEach 2020-03-19 17:46:58 +01:00
Marie Verdonck
87f53d613d start group tests - group data service 2020-03-19 17:46:58 +01:00
Marie Verdonck
78ab49c4a6 test fix after rebase and merge 2020-03-19 17:46:58 +01:00
Marie Verdonck
5b76ed6d52 69111: Links to edit EPerson page and edit Group page from members list in edit group page 2020-03-19 17:46:58 +01:00
Marie Verdonck
b9401b46b1 69111: Added list of groups that EPerson is member of in Edit EPerson form, linking to edit group page 2020-03-19 17:46:58 +01:00
Marie Verdonck
a8e0bd28fd 69110: EPeople admin page - CRUD & search on name, email, md 2020-03-19 17:44:36 +01:00
Marie Verdonck
2ba1106e0a Small notification message fix 2020-03-19 17:44:36 +01:00
Marie Verdonck
6f75ab6237 69111: bug fix isMemberOf, notifications add/delete member/group, group count added to member count, bug fix disappearing group table in registry after leaving edit 2020-03-19 17:44:36 +01:00
Marie Verdonck
8e3699f6a3 69111: Groups admin page, edit group add subgroups/members ok 2020-03-19 17:44:36 +01:00
Marie Verdonck
c7963e5126 69111: Groups admin page, WIP 2020-03-19 17:44:36 +01:00
Marie Verdonck
e0dc90ddd3 68930: add embed query param for followLinks in buildHref + tests
removed fdescribe
2020-03-19 17:43:18 +01:00
Marie Verdonck
6f4167c6cf log removed 2020-03-19 17:43:18 +01:00
Marie Verdonck
e6a454f863 69110: EPeople admin page - CRUD & search on name, email, md 2020-03-19 17:42:09 +01:00
Kristof De Langhe
1d09a6b050 68346: Bitstream description fix 2020-03-19 17:14:36 +01:00
Kristof De Langhe
08a6fa7c96 Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	src/app/core/cache/server-sync-buffer.effects.ts
	src/app/core/data/data.service.spec.ts
	src/app/core/data/data.service.ts
	src/app/shared/shared.module.ts
2020-03-19 17:12:04 +01:00
Kristof De Langhe
e8049aac04 Merge branch 'master' into w2p-68729_List-version-history
Conflicts:
	src/app/shared/shared.module.ts
2020-03-19 14:19:57 +01:00
Tim Donohue
c911ec902a Merge pull request #609 from atmire/manage-epersons-page
Access-control - EPeople admin page
2020-03-18 16:16:48 -05:00
Kristof De Langhe
f49007e2f6 69920: Move collection create route on top of ID + fix non-static ViewChild 2020-03-18 16:12:35 +01:00
Marie Verdonck
256ee0f6f4 Merge branch 'master' into manage-epersons-page 2020-03-18 15:58:57 +01:00
Tim Donohue
7c4a84bc2b Merge pull request #618 from atmire/Manage-account-profile
Manage account profile
2020-03-18 09:56:06 -05:00
Marie Verdonck
58f2a5bb2a fix tests after rebasing from master 2020-03-18 15:52:55 +01:00
Marie Verdonck
4e9afc9f67 fix after rebasing from master 2020-03-18 14:49:37 +01:00
Marie Verdonck
2e574ce0bf eperson form tests 2020-03-18 13:52:14 +01:00
Marie Verdonck
2f201a49f4 reducer tests, test fix & email in use notification fix 2020-03-18 13:52:14 +01:00
Marie Verdonck
32dfaa17b3 retrieve active eperson at component construct for checkboxes 2020-03-18 13:52:14 +01:00
Marie Verdonck
30d46bedf2 Fix test after changes for failure notification on updateEPerson 2020-03-18 13:52:14 +01:00
Marie Verdonck
2cb6ba98ce 69110: Failure notification on edit eperson 2020-03-18 13:52:14 +01:00
Marie Verdonck
1853d1bda2 69110: Failure notification on create and edit eperson 2020-03-18 13:52:14 +01:00
Marie Verdonck
a261034f9d 69110: EPerson Overview Page tests 2020-03-18 13:52:14 +01:00
Marie Verdonck
3fae13690f 69110: EPerson Service tests 2020-03-18 13:52:14 +01:00
Marie Verdonck
1549872cb8 removed logs 2020-03-18 13:52:14 +01:00
Marie Verdonck
a0b9ddcab7 [Manage epeeople page] EPerson search scope change & minor improvements/name changes 2020-03-18 13:52:14 +01:00
Marie Verdonck
4f4c2d25ed 69110: Add EPerson and EPerson form mutually exclusive & resend search after addEPerson 2020-03-18 13:52:14 +01:00
Marie Verdonck
48efc90531 69110: Prod build (AoT) permission issue 2020-03-18 13:52:14 +01:00
Marie Verdonck
c14f5bee55 69110: EPeople admin page - CRUD & search on name, email, md 2020-03-18 13:52:14 +01:00
Art Lowel
8f1df1921f Merge pull request #624 from atmire/cache-behavior-unknown-type
Cache behavior for unknown type
2020-03-18 13:41:09 +01:00
Kristof De Langhe
a8636b0e5c 69432: Fix being able to send invalid password form + 6 character password validator 2020-03-18 11:43:56 +01:00
Ben Bosman
5ec544ffea Moving create community to the top so "create" is not interpreted as an ID 2020-03-18 11:43:20 +01:00
Ben Bosman
18f50fb0c0 If the data is part of a type not yet known to Angular, the object is null
The null object causes an exception further down the road
2020-03-18 10:56:37 +01:00
Tim Donohue
41969ec3b1 Merge pull request #615 from atmire/administrative_search
Add Administrative search
2020-03-17 15:35:24 -05:00
Kristof De Langhe
0400b98e97 68729: Test fix 2020-03-17 16:06:07 +01:00
Kristof De Langhe
30c7e563f5 68729: Edit version history page as tab, removed sidebar link, added under-construction notice 2020-03-17 16:01:00 +01:00
Kristof De Langhe
1f02c2cd64 Merge branch 'master' into w2p-68729_List-version-history 2020-03-17 14:50:56 +01:00
Kristof De Langhe
f080a7568e Merge branch 'master' into w2p-69305_Apply-new-MyDSpace-fix
Conflicts:
	src/app/shared/object-detail/my-dspace-result-detail-element/claimed-task-search-result/claimed-task-search-result-detail-element.component.ts
	src/app/shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component.ts
	src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.ts
	src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.ts
2020-03-17 14:26:38 +01:00
Ben Bosman
c6de988486 If the data is part of a type not yet known to Angular, the object is null
The null object causes an exception further down the road
2020-03-17 12:00:17 +01:00
lotte
7390999010 force resolvers to rerun for community and collection sub-path changes too 2020-03-17 09:08:14 +01:00
lotte
92c5804af5 force resolvers to rerun on sub-path change 2020-03-17 09:01:03 +01:00
Art Lowel
9d3da6fdef fix issue where there was no redirect to the item status page after a withdraw/reinstate/make private/public 2020-03-16 18:27:28 +01:00
lotte
232b20689a remove discover requests from cache after changing state of items 2020-03-16 16:16:29 +01:00
Kristof De Langhe
4ee634144d 68346: Message change 2020-03-16 10:09:53 +01:00
lotte
930624fd19 added missing typedoc 2020-03-16 08:17:16 +01:00
Kristof De Langhe
5849499569 68346: Test fixes 2020-03-14 15:13:27 +01:00
Kristof De Langhe
ed2c935f7e 68346: Test cases 2020-03-14 15:00:19 +01:00
Kristof De Langhe
2b6072492e 68346: Create bundle button message 2020-03-14 03:20:16 +01:00
Kristof De Langhe
00db52494b 68346: Upload-bitstream automatically fill bundle name in combobox + create new bundle option 2020-03-14 03:13:30 +01:00
Kristof De Langhe
7fce3df3b4 68346: bitstream edit bugfix 2020-03-14 01:19:00 +01:00
Tim Donohue
e76c6e4dc3 Merge pull request #611 from atmire/testing-cache-behavior-unknown-type
Cache behavior for unknown type
2020-03-13 14:12:42 -05:00
Giuseppe Digilio
b2234e45e9 Set a max width to login div container 2020-03-13 18:28:57 +01:00
Giuseppe Digilio
580346c2f7 Fixed issue with no authentication methods displayed 2020-03-13 18:28:24 +01:00
Kristof De Langhe
0f55ee8adb 68346: Replace Bundle dropdown with combobox + edit-bistream cache fix 2020-03-13 17:52:46 +01:00
Kristof De Langhe
5db2906dea 68346: Fix 404 on bitstream download button 2020-03-13 16:57:07 +01:00
Kristof De Langhe
a72ef836f9 68346: edit-bitstream cache issues fixes 2020-03-13 16:39:43 +01:00
lotte
48b80c6a38 renamed discoverableAndUndiscoverableItems to administrativeView 2020-03-13 16:23:17 +01:00
Kristof De Langhe
1ea9623efc 68346: Review - TypeDocs and Test cases 2020-03-13 13:18:20 +01:00
cjuergen
ede9c3d397 Update German Translation 2020-03-12 18:04:32 +01:00
Kristof De Langhe
33e395a7f6 69432: refactor patch to return response 2020-03-12 17:59:12 +01:00
Kristof De Langhe
c932f41378 68346: immediatePatch to patch 2020-03-12 17:41:16 +01:00
Kristof De Langhe
d9e6d25da0 69432: Test fixes 2020-03-12 17:18:28 +01:00
Kristof De Langhe
5c096d5f66 69432: Fix for automatically updating authenticated user 2020-03-12 16:56:00 +01:00
Kristof De Langhe
c1bd6938a7 69432: Remove immediatePatch and replace usage with patch 2020-03-12 16:24:47 +01:00
Kristof De Langhe
6b8e134e45 68729: followLink embed fix 2020-03-12 15:54:09 +01:00
Kristof De Langhe
404b1053a7 Merge branch 'master' into w2p-68729_List-version-history 2020-03-12 15:47:08 +01:00
Kristof De Langhe
f469253fe4 Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	src/app/core/data/data.service.spec.ts
2020-03-12 15:39:31 +01:00
lotte
0175b50d48 applied feedback 2020-03-12 12:49:48 +01:00
Kristof De Langhe
20f8f913cf 69432: Tests 2020-03-12 10:18:49 +01:00
Tim Donohue
a9cd9f0366 Merge pull request #616 from atmire/disregard-embeds-when-checking-cache
Disregard embeds when checking request index
2020-03-11 15:04:32 -05:00
Art Lowel
c6c34b667a remove unused import 2020-03-11 16:53:43 +01:00
Art Lowel
795d638aa6 remove zone.runOutsideAngular from requestService.configure due to AoT
build issues
2020-03-11 16:51:53 +01:00
Art Lowel
383dff736c add comment to this.zone.runOutsideAngular 2020-03-11 16:22:09 +01:00
Kristof De Langhe
adfffac730 69432: Profile page - missing JSDocs 2020-03-11 15:53:48 +01:00
Art Lowel
a970aeaab8 disregard embed url params when indexing and checking indexed request urls 2020-03-11 15:34:04 +01:00
Kristof De Langhe
7d26fd478d 69432: Groups on profile page 2020-03-11 14:56:35 +01:00
Kristof De Langhe
892a985156 69432: Functional profile security form + notifications + metadata form refactoring 2020-03-11 14:32:38 +01:00
Kristof De Langhe
1f1846c487 69432: Immediate patch 2020-03-11 12:38:32 +01:00
Kristof De Langhe
004297fcfa 69432: Profile metadata form validation + notifications 2020-03-11 11:54:32 +01:00
Kristof De Langhe
53c457689c 69432: Object update metadata PUT to PATCH 2020-03-11 10:50:04 +01:00
Art Lowel
2922deff50 small UI tweaks, fix tests 2020-03-10 18:38:04 +01:00
Kristof De Langhe
ba25bd61cd Merge branch 'master' into w2p-68729_List-version-history 2020-03-10 17:16:50 +01:00
Kristof De Langhe
51e732e430 69432: Profile page intermediate commit 2020-03-10 17:06:59 +01:00
lotte
401393c8bd grid view for admin search results 2020-03-10 10:49:18 +01:00
Tim Donohue
8fd46d9c88 Merge pull request #588 from atmire/pass-followlinks-as-embed-params-to-requests
Pass followlinks as embed params to requests
2020-03-09 10:11:38 -05:00
lotte
6c7780ca56 fixed translation service issues 2020-03-09 11:15:48 +01:00
Marie Verdonck
7803c2a97b local java environment file removed, accidentally commited 2020-03-09 10:30:02 +01:00
lotte
f5a66c2266 added missing translation helper for facets 2020-03-06 16:22:04 +01:00
lotte
18eaf18108 updated admin menu 2020-03-06 14:19:31 +01:00
lotte
d5484e5c89 created admin search page 2020-03-06 13:54:46 +01:00
Kristof De Langhe
60d2f386df 69314: BaseResponseParsingService test cases for cache and process 2020-03-06 13:16:15 +01:00
Kristof De Langhe
4bbbc93f6c 68346: Tests fixes 2020-03-06 11:08:56 +01:00
Kristof De Langhe
cb21cd47bb 68346: Post-master-merge fixes & links 2020-03-05 17:47:09 +01:00
Kristof De Langhe
a054938d80 Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	package.json
	src/app/+item-page/item-page-routing.module.ts
	src/app/core/cache/builders/remote-data-build.service.ts
	src/app/core/cache/server-sync-buffer.effects.ts
	src/app/core/core.module.ts
	src/app/core/data/bitstream-data.service.ts
	src/app/core/data/bundle-data.service.ts
	src/app/core/data/data.service.ts
	src/app/core/data/dso-change-analyzer.service.ts
	src/app/core/data/item-data.service.ts
	src/app/core/data/object-updates/object-updates.actions.ts
	src/app/core/shared/bitstream.model.ts
	src/app/core/shared/dspace-object.model.ts
	src/app/shared/mocks/mock-request.service.ts
	src/app/shared/shared.module.ts
	yarn.lock
2020-03-05 17:21:38 +01:00
Ben Bosman
373acc6c82 Refusing to cache an object which can't be parsed 2020-03-05 11:01:19 +01:00
Kristof De Langhe
bae5c6652e Merge branch 'master' into w2p-68729_List-version-history
Conflicts:
	src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts
	src/app/+item-page/item-page-routing.module.ts
	src/app/+item-page/item-page.resolver.ts
	src/app/core/shared/item.model.ts
2020-03-04 17:06:48 +01:00
Kristof De Langhe
c087b8859f 69305: Refactor workflow-actions to be resolved as HAL links 2020-03-04 16:22:05 +01:00
Kristof De Langhe
496bedfe2e 69115: Moving enum options to components 2020-03-04 14:43:12 +01:00
Kristof De Langhe
b9c050c19c 69115: ClaimedTaskDataService and components refactoring 2020-03-04 14:43:03 +01:00
Kristof De Langhe
18b9a41fe0 69305: Remove normalized action 2020-03-04 14:40:24 +01:00
Kristof De Langhe
9e31b61d42 69115: post master merge changes to workflow-action 2020-03-04 14:38:51 +01:00
Kristof De Langhe
568b8ee1a7 68954: Tests + AoT build fixes 2020-03-04 14:38:38 +01:00
Kristof De Langhe
305c4ce882 68954: Display claimed task actions depending on config from REST API
Conflicts:
	src/app/core/core.module.ts
	src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.html
2020-03-04 14:38:20 +01:00
Marie Verdonck
677b3f63de Fixes after rebasing from upstream/master 2020-03-04 11:01:20 +01:00
Marie Verdonck
525c333e09 log removed 2020-03-04 10:03:13 +01:00
Marie Verdonck
781a558458 68930: getIDHref tests & removed undefined check, not needed because of spread array 2020-03-04 10:03:13 +01:00
Marie Verdonck
1f71274db6 68930: rename forwardToRest typo fix 2020-03-04 10:03:13 +01:00
Marie Verdonck
dffcd745af 68930: rename forwardToRest, embed query param added to getIDHref, tests wip 2020-03-04 10:03:13 +01:00
Marie Verdonck
32d0c8118b 68930: add embed query param for followLinks in buildHref + tests
removed fdescribe
2020-03-04 10:03:13 +01:00
Giuseppe Digilio
a6b2ed607a Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	src/app/core/auth/auth.actions.ts
#	src/app/core/auth/auth.effects.spec.ts
#	src/app/core/auth/auth.effects.ts
#	src/app/core/auth/auth.reducer.spec.ts
#	src/app/core/auth/auth.reducer.ts
#	src/app/core/auth/auth.service.spec.ts
#	src/app/core/auth/auth.service.ts
#	src/app/core/auth/server-auth.service.ts
#	src/app/shared/testing/auth-request-service-stub.ts
2020-03-03 20:04:02 +01:00
Tim Donohue
01231ef105 Merge pull request #606 from 4Science/#603_mydspace_fixes
#603 mydspace fixes
2020-03-03 11:14:06 -06:00
Giuseppe Digilio
98d44fd42e Fixed issue with workflowitem edit 2020-03-03 17:38:03 +01:00
Tim Donohue
000bfb85c0 Merge pull request #607 from atmire/allow-optional-links
Allow optional HALLinks
2020-03-03 10:30:04 -06:00
Kristof De Langhe
6606520c2f 68729: Resolve missing links to undefined 2020-03-03 16:36:35 +01:00
Giuseppe Digilio
5e95f1df1a Removed unintentional "this." from html template 2020-03-03 12:18:50 +01:00
Giuseppe Digilio
0e1d3e4048 Fixed following links for mydspace workflow results 2020-03-03 12:13:22 +01:00
Giuseppe Digilio
3cd8178f65 Reverted MyDSpacePageComponent 2020-03-03 12:11:25 +01:00
Giuseppe Digilio
2262a115fc Fixed issue with detailed visualization for mydspace results 2020-03-03 12:10:40 +01:00
Giuseppe Digilio
64c96c78f0 Fixed issue while retrieve undefined item's bitstreams on ItemDetailPreviewComponent 2020-03-03 12:09:33 +01:00
Giuseppe Digilio
401065dba2 Merge remote-tracking branch 'remotes/origin/master' into #603_mydspace_fixes 2020-03-03 09:29:09 +01:00
Tim Donohue
be4d4ec88d Merge pull request #605 from tdonohue/Increase_network_timeout_Docker
Increase network timeout for Docker builds to 5min
2020-03-02 14:00:06 -06:00
Tim Donohue
ccb3c98f81 Increase network timeout for Docker builds to 5min 2020-03-02 13:36:32 -06:00
Tim Donohue
dbca93e3aa Merge pull request #602 from 4Science/issues#599_and_issues#600_fixes
Issues#599 and issues#600 fixes
2020-03-02 12:56:30 -06:00
Giuseppe Digilio
18e17f0dad Added action to retrieve authenticated eperson object 2020-03-02 13:09:17 +01:00
Giuseppe Digilio
df8ef2b5c3 Fixed issue with field's required property during form filed initialization 2020-03-02 13:06:47 +01:00
Tim Donohue
b2f0e9f620 Merge pull request #591 from atmire/w2p-68921_breadcrumbs
Breadcrumbs
2020-02-28 10:36:43 -06:00
Tim Donohue
dbdc42fc73 Merge pull request #597 from 4Science/#592-miscellaneous-fixes
fix Submission cannot be completed #592
2020-02-27 15:20:48 -06:00
lotte
8b6b478df9 fixed other async 2020-02-27 16:59:34 +01:00
lotte
aa5383ca5a remove unnecessary async that causes test timeout 2020-02-27 16:58:44 +01:00
lotte
3d1e93f5ef feedback 2020-02-27 16:53:47 +01:00
Giuseppe Digilio
5d22ba7d36 Fixed Related Dynamic Form Controls functionality after Angular 8 upgrade 2020-02-27 13:08:09 +01:00
Giuseppe Digilio
653cf8e921 Temporary fix for Collection defaultAccessConditions issue 2020-02-27 11:20:00 +01:00
Giuseppe Digilio
355d9984b4 Fixed initialization of workspaceitem/workflowitem's selfUrl 2020-02-27 11:16:42 +01:00
Giuseppe Digilio
500f5c645f Fixed issue with DataService's delete method that used wrong uuid to make the request 2020-02-27 11:15:31 +01:00
Bram Luyten
3b89580caf Merge pull request #593 from bram-atmire/PR557-Partial-Dutch-Translation
Partial Dutch Translation by @muiltje
2020-02-27 10:11:26 +01:00
Bram Luyten
4814ed0c68 Rebase and enabling Dutch translation by default 2020-02-27 09:51:57 +01:00
muiltje
5acbf4f216 Second batch of Dutch translations 2020-02-27 08:54:59 +01:00
muiltje
423cf7569a First batch of Dutch translations 2020-02-27 08:54:59 +01:00
muiltje
9d988022c7 First batch of Dutch translations 2020-02-27 08:54:59 +01:00
muiltje
802498e27e First batch of Dutch translations 2020-02-27 08:54:59 +01:00
Kristof De Langhe
e1f940668a 69115: MyDSpace ClaimedTask proper link resolving 2020-02-26 17:50:44 +01:00
lotte
d2fe506299 fixed time out 2020-02-26 17:08:59 +01:00
lotte
b554d40e9c added tests and docs 2020-02-26 16:53:10 +01:00
lotte
4ae8997ada added tests for breadcrumbs service and component 2020-02-26 14:44:34 +01:00
Art Lowel
b4a63fccf4 rollback debug change 2020-02-26 14:17:27 +01:00
Art Lowel
5b326aea92 add DSONameService 2020-02-26 13:58:09 +01:00
Giuseppe Digilio
f92eb27c24 remove NormalizedAuthStatus 2020-02-26 10:01:43 +01:00
Giuseppe Digilio
1a192ecdc9 delete unintentional committed empty file 2020-02-25 17:53:20 +01:00
Giuseppe Digilio
d95d68dd7f Fixed deprecated /deep/ selector 2020-02-25 17:31:55 +01:00
Giuseppe Digilio
076ee8b26d Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	src/app/core/auth/auth.service.ts
#	src/app/core/auth/models/auth-status.model.ts
#	src/app/core/auth/models/normalized-auth-status.model.ts
#	src/app/core/auth/server-auth.service.ts
#	src/app/core/core.module.ts
#	src/app/shared/shared.module.ts
2020-02-25 17:31:07 +01:00
Kristof De Langhe
cbd36ce1f9 68729: Resolve missing links to undefined 2020-02-25 15:54:01 +01:00
Kristof De Langhe
56433d0776 68729: E-Person link on version list + test fixes 2020-02-25 14:55:26 +01:00
Kristof De Langhe
3f11ae9fa5 68729: Version(History) resource types 2020-02-25 14:35:25 +01:00
Kristof De Langhe
254305652d Merge branch 'master' into w2p-68729_List-version-history
Conflicts:
	src/app/core/cache/models/normalized-item.model.ts
	src/app/core/core.module.ts
	src/app/core/shared/item.model.ts
2020-02-25 14:34:56 +01:00
Tim Donohue
a6f1a6d1ec Merge pull request #584 from atmire/SubmissionUseFullProjection
Use full projection for submission REST requests
2020-02-24 16:29:50 -06:00
lotte
f67387ed65 first draft breadcrumbs 2020-02-24 16:27:19 +01:00
lotte
725f20a9d0 breadcrumbs for DSOs 2020-02-24 16:27:19 +01:00
lotte
4ea264dd7f dso + i18n breadcrumbs with providers + resolvers 2020-02-24 16:27:19 +01:00
lotte
413f798f71 initial simple breadcrumb implementation 2020-02-24 16:27:19 +01:00
Tim Donohue
e60688b85e Merge pull request #578 from atmire/followlink-refactor
Only resolve links when needed
2020-02-24 09:21:29 -06:00
Art Lowel
91e3775135 fix incorrect links in eperson and group dataservices 2020-02-24 15:15:41 +01:00
Art Lowel
a0d5cbc36a Merge remote-tracking branch 'upstream/master' into w2p-68405_Only-retrieve-related-objects-when-necessary 2020-02-24 15:08:31 +01:00
Art Lowel
92ee38c9ff Merge pull request #589 from atmire/node12fsevents
Lock fsevents version compatible with node 12
2020-02-24 09:37:55 +01:00
Chris Wilper
ab224cced5 Lock fsevents version compatible with node 12 2020-02-22 10:11:37 -05:00
Tim Donohue
3ded2b6973 Merge pull request #586 from tdonohue/bug_fix_dockerignore
[Docker] .dockerignore doesn't ignore "node_modules"
2020-02-21 09:24:17 -06:00
Tim Donohue
cda800f3be Bug fix: Correct name of "node_modules" folder. Also reorg entries into groups 2020-02-21 08:38:29 -06:00
Kristof De Langhe
0cb606877b Merge branch 'master' into w2p-68729_List-version-history
Conflicts:
	src/app/shared/shared.module.ts
2020-02-21 14:30:50 +01:00
Art Lowel
f52c1d0ba5 Merge branch 'master' into w2p-68405_Only-retrieve-related-objects-when-necessary 2020-02-21 12:16:40 +01:00
Tim Donohue
3298c4e6c6 Merge pull request #579 from atmire/angular8-update
Angular 8 update
2020-02-20 15:08:54 -06:00
Chris Wilper
775dfb5f87 Use full projection for submission REST requests 2020-02-20 14:35:21 -05:00
Tim Donohue
e614e9eca7 Merge pull request #580 from atmire/angulartics-ssr
Use Angulartics' Routerless module
2020-02-20 10:19:54 -06:00
Kristof De Langhe
ade2187492 68729: Version test cases 2020-02-20 12:56:32 +01:00
Art Lowel
dea6638c1f add docs, process PR feedback 2020-02-20 11:00:43 +01:00
Art Lowel
f7f6600806 remove event from errorHandler call 2020-02-20 09:28:46 +01:00
Art Lowel
2c12446128 add tests for build decorators 2020-02-19 19:16:42 +01:00
Kristof De Langhe
29ff18264c 68729: Edit Item Version History page + sidebar menu option - moving item-versions component to shared module 2020-02-19 17:58:23 +01:00
Art Lowel
df9e6b67f5 improve thumbnailcomponent test coverage 2020-02-19 17:51:25 +01:00
Kristof De Langhe
179fbd5276 68729: Item version history on full page 2020-02-19 15:43:20 +01:00
Kristof De Langhe
22ff110e9d 68729: disableRouteParameterUpdate for version list pagination 2020-02-19 12:43:06 +01:00
Kristof De Langhe
d7da83ad5a 68729: Pagination disableRouteParameterUpdate input 2020-02-19 12:41:08 +01:00
Kristof De Langhe
173f14c41f 68729: ItemVersionsComponent + changes to Version(History) model and services 2020-02-19 11:48:17 +01:00
Art Lowel
6824ccb307 fix AoT issues 2020-02-18 18:52:33 +01:00
Art Lowel
bc00c000a6 tests and documentation 2020-02-18 18:15:18 +01:00
Kristof De Langhe
d4ff4aab36 68729: Version and VersionHistory model, normalized and data-service classes 2020-02-18 16:05:38 +01:00
Art Lowel
08dedb2dc3 fix lint errors 2020-02-17 18:35:10 +01:00
Art Lowel
c5e8074040 remove fdescribe 2020-02-17 18:35:10 +01:00
Art Lowel
39f1766391 fixing tests 2020-02-17 18:35:10 +01:00
Marie Verdonck
4d3f85fafe 68405: test fixes search-facet 2020-02-17 18:35:10 +01:00
Art Lowel
dc73561575 fix SearchResultListElementComponent tests for workflow and workspace items 2020-02-17 18:35:10 +01:00
Art Lowel
025948e3a0 refactor all remaining self links in mocks 2020-02-17 18:35:10 +01:00
Art Lowel
8551d730d8 fix infinite thumbnail loop 2020-02-17 18:35:10 +01:00
Art Lowel
7f76769bff switch to typedObject decorator, which no longer needs explict type param 2020-02-17 18:35:10 +01:00
Marie Verdonck
10bb457897 68405: test fixes 2020-02-17 18:35:10 +01:00
Art Lowel
bc7c92f44c removed remaining normalized models and related services 2020-02-17 18:35:10 +01:00
Marie Verdonck
884e94a08b 68405: test fixes 2020-02-17 18:32:41 +01:00
Art Lowel
ab0f2c89e6 remove most uses of normalizedserializer 2020-02-17 18:22:42 +01:00
Art Lowel
b9432e7553 fix browse pages 2020-02-17 18:22:42 +01:00
Art Lowel
e6c1069e19 fix self links in mocks 2020-02-17 18:22:42 +01:00
Art Lowel
07998a8c08 remove normalized models part 1 2020-02-17 18:22:42 +01:00
Art Lowel
bffae34fcc Undo accidental commit 2020-02-17 18:19:27 +01:00
Art Lowel
89b3d2c40e fix findByHref test 2020-02-17 18:19:27 +01:00
Art Lowel
3331a72b02 clarify that this error is purposely thrown 2020-02-17 18:19:27 +01:00
Art Lowel
d5b2fbff0c fix RelationshipService tests 2020-02-17 18:19:27 +01:00
Marie Verdonck
6bffa68bbb 68405: javadoc, test, and cleanup 2020-02-17 18:19:27 +01:00
Marie Verdonck
42d6527ca9 68405: More test fixes 2020-02-17 18:18:00 +01:00
Marie Verdonck
be0158fc9c 68405: More test fixes 2020-02-17 18:17:23 +01:00
Marie Verdonck
fb153b7b13 68405: test fixes; tbc 2020-02-17 18:17:23 +01:00
Marie Verdonck
a52650e62a 68405: test fixes; tbc 2020-02-17 18:16:13 +01:00
Marie Verdonck
f17e204712 68405: separate resource types, missing @link paras/followLinks, start test fix 2020-02-17 18:16:13 +01:00
Art Lowel
b2f966eb83 fix links for relationships 2020-02-17 18:13:51 +01:00
Art Lowel
1d31cae970 switched to resource-types for annotations to get around circular dependency issues 2020-02-17 18:12:13 +01:00
Art Lowel
56c3d12497 itermediate commit 2020-02-17 18:12:13 +01:00
Art Lowel
44facb8dcb followlinks 2020-02-17 18:12:13 +01:00
Art Lowel
ad4e8eeb8c refactored items, bundles and bitstreams, test builders 2020-02-17 18:09:52 +01:00
Kristof De Langhe
8af72cb1d3 post performance improvement test fixes 2020-02-17 18:08:49 +01:00
Art Lowel
1102cda3b2 reduce number of unnecessary requests from HalEndpointService and RemoteDataBuildService 2020-02-17 18:08:49 +01:00
lotte
347d42246c updated node version in Dockerfile 2020-02-17 14:22:05 +01:00
Antoine Snyers
d571c174f0 Use Angulartics' Routerless module
https://github.com/DSpace/dspace-angular/issues/560
2020-02-14 13:03:06 +01:00
Giuseppe Digilio
516b23cfcc Merge remote-tracking branch 'remotes/origin/master' into shibboleth 2020-02-14 11:49:59 +01:00
lotte
3f48a5149b updated README and package.json to reflect correct node version 2020-02-14 09:21:15 +01:00
Tim Donohue
a04eb28815 Merge pull request #574 from tdonohue/DS-4380_and_DS-4257_minor_updates
DS-4380 and DS-4257: Minor updates to Docker configs for JDK11 and new URL configs
2020-02-13 16:16:51 -06:00
lotte
e3ce775aee removed unnecessary sass-node dep and fixed SCSS 2020-02-13 14:49:20 +01:00
Kristof De Langhe
c8be50614a Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/item-relationships/item-relationships.component.ts
	src/app/core/core.module.ts
	src/app/core/data/data.service.ts
	src/app/core/data/object-updates/object-updates.actions.ts
	src/app/core/data/object-updates/object-updates.reducer.spec.ts
	src/app/core/data/object-updates/object-updates.reducer.ts
	src/app/core/data/object-updates/object-updates.service.spec.ts
	src/app/core/data/object-updates/object-updates.service.ts
2020-02-13 14:34:45 +01:00
lotte
a18120d497 bumped travis 2020-02-13 11:29:04 +01:00
lotte
04cb75e786 upgraded to angular 8 2020-02-13 11:09:20 +01:00
Kristof De Langhe
78c6144f71 68346: edit-bitstream-page onCancel 2020-02-11 13:16:00 +01:00
Kristof De Langhe
87d7bc1a20 68346: Cleanup of bootstrap col classes in item-bitstream components 2020-02-11 13:06:31 +01:00
Kristof De Langhe
c38bf3fd0c 68346: page-hover fix + pageSize reverted to 10 2020-02-11 10:48:14 +01:00
Kristof De Langhe
3dd433a5da 68346: Tests and JSDocs 2020-02-10 17:51:37 +01:00
Kristof De Langhe
a638055d12 68346: Bitstreams Drag-and-drop cross-page support 2020-02-10 14:38:34 +01:00
Tim Donohue
421b45b9ec Minor updates to Docker configs for JDK11 and new URL configs 2020-02-07 12:30:48 -06:00
Giuseppe Digilio
c1db19ee03 Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	src/app/shared/shared.module.ts
2020-02-07 15:04:12 +01:00
Giuseppe Digilio
573a9b8de3 Set password as default authentication method on error 2020-02-07 14:12:14 +01:00
Giuseppe Digilio
03c1b689f8 Fixed LogInComponent test 2020-02-07 13:18:53 +01:00
Giuseppe Digilio
1e67131902 Fixed LogInShibbolethComponent test 2020-02-07 13:10:43 +01:00
Giuseppe Digilio
0452a9a8cd Change the redirect url using the current page url on shibboleth authentication 2020-02-07 13:09:55 +01:00
Giuseppe Digilio
cc4b7b215e Prevent that RouteService is instantiated two times on both SSR and CSR 2020-02-07 13:08:19 +01:00
Tim Donohue
3bbd05f588 Merge pull request #533 from atmire/Virtual-metadata-on-item-delete
Virtual metadata on item delete
2020-02-06 16:58:16 -06:00
Tim Donohue
618ac070e8 Merge pull request #565 from atmire/generic-uri-metadata
Generic uri metadata
2020-02-06 16:21:21 -06:00
Kristof De Langhe
5e93a89678 68346: PaginatedDragAndDropBitstreamList component and refactoring item-edit-bitstream-bundle using this new component ; removed pagination-drag-and-drop 2020-02-06 16:57:17 +01:00
Samuel
cddd345fcc Merge branch 'master' into Virtual-metadata-on-item-delete 2020-02-06 14:04:58 +01:00
Kristof De Langhe
90f8bf42a1 68346: Drag handle outside drag component 2020-02-06 14:02:26 +01:00
Kristof De Langhe
210db7fac8 68346: Fixed loading multiple pages with unloaded inbetween 2020-02-06 11:43:45 +01:00
Kristof De Langhe
b987a3d762 68346: Fixed moving objects within paginated list 2020-02-06 11:19:20 +01:00
Tim Donohue
bda3a30889 Merge pull request #572 from atmire/travis-auto-update-chrome
Auto-update chrome on travis
2020-02-05 11:40:43 -06:00
Kristof De Langhe
2795c1ecc7 68346: initial Drag-And-Drop pagination component + paginated custom-order support in field-updates store - Intermediate commit 2020-02-05 18:04:10 +01:00
Art Lowel
de17f099ce fix sudo command 2020-02-05 17:51:10 +01:00
Art Lowel
e891d65526 sudo chrome update 2020-02-05 17:40:58 +01:00
Art Lowel
b16607e597 auto update chrome on travis 2020-02-05 17:30:44 +01:00
Samuel
ddbc0e097a Merge branch 'master' into Virtual-metadata-on-item-delete 2020-02-05 17:05:23 +01:00
Samuel
db7ecb0f53 safety check 2020-02-05 16:28:43 +01:00
Tim Donohue
6f4f0eab11 Merge pull request #552 from atmire/submission-upload.required
verify whether file uploads are mandatory
2020-02-05 09:12:14 -06:00
Kristof De Langhe
ce5547db4b 68346: Hover drag-handle + alignment fix 2020-02-05 11:45:17 +01:00
Ben Bosman
4a46780d85 support uri field which is not dc.identifier.uri
Replacing item-page-uri-field instead of introducing item-page-generic-uri-field
2020-02-04 15:10:10 +01:00
Kristof De Langhe
246343d175 68346: Further alignment fixes and separate drag handle component 2020-02-03 17:59:35 +01:00
Kristof De Langhe
19c788f126 68346: Aligning content 2020-02-03 16:51:13 +01:00
Ben Bosman
5585bcbc9b updated tests 2020-01-31 15:14:01 +01:00
Ben Bosman
a45273048d verify whether file uploads are mandatory => observe changes to both filelist and required status 2020-01-31 09:47:40 +01:00
Samuel
d0680e2aa8 delete codestyle 2020-01-30 15:33:01 +01:00
Samuel
58bfb9b1a7 Merge branch 'master' into Virtual-metadata-on-item-delete 2020-01-29 12:28:18 +01:00
Samuel
0387c5f15b Virtual metadata on item delete - filter relationship types without relationships - fix tests 2020-01-29 12:27:41 +01:00
Tim Donohue
3a9277c415 Merge pull request #569 from paulo-graca/patch-2
adding relationships.isContributorOf i18n support
2020-01-28 11:00:21 -06:00
Tim Donohue
eba6bf505f Merge pull request #530 from atmire/Keep-virtual-metadata-on-relationship-delete
Keep virtual metadata on relationship delete
2020-01-28 10:34:07 -06:00
Samuel
b352690cca Virtual metadata on item delete - filter relationship types without relationships 2020-01-28 15:35:55 +01:00
Samuel
cff3a6f010 Merge branch 'Keep-virtual-metadata-on-relationship-delete' into Virtual-metadata-on-item-delete 2020-01-28 14:22:43 +01:00
Art Lowel
1903ad0440 remove debug output 2020-01-27 18:16:12 +01:00
Art Lowel
cab971211f attempt to diagnose travis-only e2e issues 2020-01-27 17:33:54 +01:00
Art Lowel
ed11cb9f01 Merge branch 'master' into Keep-virtual-metadata-on-relationship-delete 2020-01-27 11:26:15 +01:00
Paulo Graça
34f79f1667 adding relationships.isContributorOf support 2020-01-24 16:12:31 +00:00
Kristof De Langhe
cf15fbcca2 68346: Drag-handle in front of row 2020-01-24 15:08:16 +01:00
Kristof De Langhe
14ea71f536 68346: Test fixes 2020-01-24 14:34:11 +01:00
Kristof De Langhe
b2ef5ee2fa Merge branch 'master' into w2p-68346_Bundles-in-edit-item-Updates
Conflicts:
	package.json
	resources/i18n/en.json5
	src/app/+item-page/item-page.module.ts
	src/app/core/core.module.ts
	src/app/core/data/bundle-data.service.ts
	src/app/core/data/data.service.spec.ts
	src/app/core/data/data.service.ts
	src/app/core/data/item-data.service.ts
	src/app/core/data/object-updates/object-updates.service.ts
	src/app/core/shared/hal-endpoint.service.ts
	src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
	src/app/shared/mocks/mock-request.service.ts
	src/app/shared/shared.module.ts
	src/app/shared/trackable/abstract-trackable.component.ts
	yarn.lock
2020-01-24 14:21:20 +01:00
Tim Donohue
1472bd7df9 Merge pull request #506 from atmire/Collection-content-source-tab
Collection content source tab
2020-01-23 10:18:23 -06:00
Tim Donohue
31aff062eb Merge pull request #540 from atmire/Convert-external-source-to-entity
Convert external source to entity
2020-01-23 08:35:02 -06:00
benbosman
e6ffec0129 Merge pull request #564 from atmire/mydspace-display-entity-type
Display the entity type in MyDSpace
2020-01-23 14:44:41 +01:00
Giuseppe Digilio
68d3144bec Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	src/app/app.module.ts
2020-01-23 14:10:58 +01:00
Giuseppe Digilio
b768043bcc Add withCredentials param to ServerAuthService's checkAuthenticationCookie method 2020-01-23 09:57:49 +01:00
Giuseppe Digilio
b19aa64052 Add withCredentials param to request options instead of using http interceptor 2020-01-22 17:06:54 +01:00
Tim Donohue
fe3eea6079 Merge pull request #559 from atmire/header-search-box
Header search box
2020-01-21 11:17:30 -06:00
Tim Donohue
cc27ad5965 Merge pull request #566 from atmire/submit-this-collection
Submit this collection
2020-01-21 11:16:41 -06:00
Tim Donohue
3bc903f812 Merge pull request #567 from atmire/w2p-68276_Tabbed-display-fixedFilterQuery-fix
Fixed configuration-search-page fixedFilterQuery parameter
2020-01-21 10:36:12 -06:00
Kristof De Langhe
a403732d45 68276: Fixed configuration-search-page fixedFilterQuery parameter 2020-01-20 16:52:53 +01:00
Giuseppe Digilio
c8d516598a Fixed failed test 2020-01-17 15:15:32 +01:00
Giuseppe Digilio
2a4f8aaad8 Merge remote-tracking branch 'remotes/origin/master' into shibboleth 2020-01-17 14:39:40 +01:00
Art Lowel
f531bdd976 Merge pull request #563 from 4Science/fix_store_selectors
Fix history and bitstreamFormats store selector after moved in CoreState
2020-01-17 13:59:24 +01:00
Giuseppe Digilio
ddb787277b Fix failed test 2020-01-17 13:08:26 +01:00
Giuseppe Digilio
eb866d85ef Fixed merge 2020-01-17 12:12:03 +01:00
Giuseppe Digilio
29b2e89625 Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	src/app/core/auth/auth.interceptor.ts
#	src/app/shared/auth-nav-menu/auth-nav-menu.component.html
#	src/app/shared/shared.module.ts
2020-01-17 12:11:46 +01:00
Giuseppe Digilio
1e99071907 Added auth action that allows to retrieve token once check on authentication cooke is successful 2020-01-17 11:51:55 +01:00
Giuseppe Digilio
0eac9c6369 check Authentication Token both on SSR and CSR 2020-01-17 11:50:07 +01:00
Giuseppe Digilio
afe70bc546 added refresh token when check on authorization cookie is successful 2020-01-17 11:09:41 +01:00
Giuseppe Digilio
49e59c44e1 fixed test 2020-01-17 11:08:09 +01:00
Kristof De Langhe
7b3a2e9dc8 Merge branch 'master' into w2p-67611_Convert-external-source-to-entity
Conflicts:
	src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
	src/app/shared/shared.module.ts
2020-01-16 17:54:12 +01:00
Giuseppe Digilio
57b007ffe2 fix referer url used for X-Requested-With header 2020-01-16 17:43:10 +01:00
Giuseppe Digilio
f630898eab Merge remote-tracking branch 'remotes/origin/master' into fix_store_selectors 2020-01-16 16:14:19 +01:00
Tim Donohue
1ca1fe746a Merge pull request #534 from atmire/reorder-name-variants
Reordering related entities in the submission
2020-01-16 08:49:29 -06:00
Giuseppe Digilio
4f8f4de241 Added X-Requested-With header when retrieving auth methods on SSR 2020-01-16 15:17:59 +01:00
Ben Bosman
323ac03e54 Merge remote-tracking branch 'community/master' into mydspace-display-entity-type 2020-01-16 14:50:58 +01:00
Kristof De Langhe
3fd4ecbfc4 67611: ExpressionChangedAfterItHasBeenCheckedError fix 2020-01-16 14:47:37 +01:00
Giuseppe Digilio
6560d1d112 Use status request to check an existing token and to retrieve auth methods available 2020-01-16 14:36:20 +01:00
Ben Bosman
17989667aa Merge remote-tracking branch 'community/master' into submission-upload.required 2020-01-16 14:32:43 +01:00
Ben Bosman
cc1cc08d8e Merge remote-tracking branch 'community/master' into generic-uri-metadata 2020-01-16 14:16:25 +01:00
Kristof De Langhe
010da52476 Merge branch 'master' into w2p-67611_Convert-external-source-to-entity 2020-01-16 13:59:38 +01:00
Ben Bosman
4a2e7741b7 Merge remote-tracking branch 'community/master' into submit-this-collection
# Conflicts:
#	src/app/submission/submission.service.ts
2020-01-16 12:53:59 +01:00
Ben Bosman
6010316d91 Merge remote-tracking branch 'community/master' into submit-this-collection 2020-01-16 12:51:46 +01:00
lotte
4c23d01567 Merge branch 'master' into reorder-name-variants 2020-01-16 09:30:31 +01:00
Tim Donohue
16831decca Merge pull request #551 from 4Science/pagination-on-community-page
Pagination on community page
2020-01-15 11:48:32 -06:00
Tim Donohue
fd3eea99b8 Merge pull request #539 from atmire/Search-external-sources
Lookup relations - Search external sources
2020-01-15 11:22:40 -06:00
Kristof De Langhe
32a7dcd787 Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2 2020-01-15 17:01:39 +01:00
Tim Donohue
cd39d47214 Merge pull request #562 from atmire/travis-dist-upgrade
Upgrade Travis image to 'bionic'
2020-01-15 09:55:36 -06:00
Giuseppe Digilio
4e8ec5f4a2 Fix history and bitstreamFormats store selector after moved in CoreState 2020-01-15 12:14:53 +01:00
Art Lowel
94a71b69d1 remove chrome source, doesn't work anyway and doesn't seem to be needed. Remove chromium to try to solve the issue where travis can't find chrome 2020-01-15 11:56:04 +01:00
Art Lowel
1d6e9d5b96 add xvfb service for headless chrome 2020-01-15 11:32:29 +01:00
Art Lowel
2e06357291 upgrade to bionic 2020-01-15 11:12:49 +01:00
Kristof De Langhe
813fcfbd30 Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2 2020-01-15 10:02:30 +01:00
Tim Donohue
db4408274e Merge pull request #561 from atmire/tslint-rule-renaming
Fixed renamed TSLint rules
2020-01-14 09:11:47 -06:00
lotte
0271821305 updated tslint rules that have been renamed 2020-01-14 14:50:46 +01:00
lotte
78f9d62e00 fixed linting error 2020-01-14 14:42:14 +01:00
lotte
1bc7182372 fixes after merge 2020-01-14 14:04:42 +01:00
Kristof De Langhe
9d71f0348b 67611: fix test 2020-01-14 13:38:01 +01:00
Kristof De Langhe
d8bdd768ca Merge branch 'w2p-67478_Search-external-sources-in-submission' into w2p-67611_Convert-external-source-to-entity 2020-01-14 13:07:24 +01:00
Kristof De Langhe
617bbbb90c 67478: Remove redundant test 2020-01-14 12:52:50 +01:00
Samuel
9563ceb348 Merge branch 'master' into Virtual-metadata-on-item-delete 2020-01-14 12:51:54 +01:00
Kristof De Langhe
4ba3b01997 Merge branch 'master' into w2p-67478_Search-external-sources-in-submission
Conflicts:
	src/app/core/data/data.service.ts
	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts
2020-01-14 12:46:55 +01:00
lotte
02802c0de1 Merge branch 'master' into reorder-name-variants 2020-01-14 12:40:39 +01:00
Samuel
2c1337031d Merge branch 'master' into Keep-virtual-metadata-on-relationship-delete 2020-01-14 12:01:30 +01:00
Art Lowel
6e928eeb89 Merge pull request #547 from 4Science/upgrade-angular-7
Upgrade angular 7
2020-01-14 11:41:18 +01:00
Giuseppe Digilio
a3b349b6a3 Added test for SidebarFilterService 2020-01-13 13:04:09 +01:00
Giuseppe Digilio
0730c68654 use test for undefined Menu Section 2020-01-13 12:48:42 +01:00
Giuseppe Digilio
24015b2f95 use MockStore to provide test for menuKeySelector function 2020-01-13 11:58:12 +01:00
Giuseppe Digilio
d47a8fc572 commit yarn.lock 2020-01-13 11:14:49 +01:00
Giuseppe Digilio
ec9e0407df Merge branch 'dependabot/npm_and_yarn/handlebars-4.5.3' into upgrade-angular-7 2020-01-13 10:45:43 +01:00
Giuseppe Digilio
ff80afb839 Moved history state from AppState to CoreState 2020-01-13 10:25:16 +01:00
Giuseppe Digilio
11e4f02946 Moved BitstreamFormatRegistryState from AppState to CoreState 2020-01-13 09:50:01 +01:00
Ben Bosman
70b2c8c6e1 go back to the setup where mockUploadConfigResponseNotRequired starts from a clone 2020-01-10 18:30:23 +01:00
Ben Bosman
3a37f9be12 submit to this collection 2020-01-10 18:15:28 +01:00
Samuel
de0992bf85 PR-533 Virtual metadata on item delete 2020-01-10 17:00:32 +01:00
lotte
3e51fd8598 fixed test issue 2020-01-10 16:36:47 +01:00
Giuseppe Digilio
6f8f4b31bf Renamed retrieveAuthMethods to retrieveAuthMethodsFromAuthStatus 2020-01-10 15:30:26 +01:00
Marie Verdonck
d3d2bb20d4 id css selector added to remove ambiguity in search-page e2e tests 2020-01-10 15:28:57 +01:00
Marie Verdonck
c57810f00d Timeout time for e2e tests 2020-01-10 15:04:52 +01:00
Marie Verdonck
34fb8612f8 Expandable search form in header with tests (& e2e tests)
Squashed:
66021: Expandable search form in header
66021: Adjustment small screens
66021: search icon now pressable and css partially moved to bootstrap classes
66021: start testing of header search box; TODO fix e2e
66021: E2E Tests
66021: Header search box now with angular animation and bootstrap > css; e2e fix
66021: feedback 2019-12-19 style changes
66021: Fix navbar search tests
Patch: add opacity to header search animation  Change the input style
66021: expandable search navbar - tests
66021: Expandable search form in header
Small fix after rebasing upstream/master
2020-01-10 14:58:13 +01:00
Samuel
7b337acc1c PR-530 repair tests 2020-01-10 11:59:33 +01:00
Samuel
4f57d7ae83 Merge branch 'master' into Keep-virtual-metadata-on-relationship-delete 2020-01-09 17:55:18 +01:00
Giuseppe Digilio
3132da9b3d Use withCredentials only with request to authn endpoint 2020-01-09 17:44:10 +01:00
Samuel
4e679ec6db PR-530 Keep virtual metadata on relationship delete - community feedback 2020-01-09 13:53:42 +01:00
Giuseppe Digilio
f594fc9088 Use withCredentials only with request to authn/login endpoint 2020-01-09 12:58:00 +01:00
Giuseppe Digilio
cd2e640886 Use withCredentials only with request to authn/login endpoint 2020-01-09 12:45:11 +01:00
Kristof De Langhe
894888fc8f Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2
Conflicts:
	resources/i18n/en.json5
	src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts
	src/app/+community-page/edit-community-page/edit-community-page.component.ts
	src/app/shared/shared.module.ts
2020-01-09 10:34:08 +01:00
Giuseppe Digilio
6801194cbb if check of Authentication Cookie succeed store token 2020-01-08 18:25:15 +01:00
Ben Bosman
feced9f893 submit to this collection 2020-01-08 17:41:29 +01:00
Giuseppe Digilio
34a4f211f1 Resolved AOT build errors 2020-01-08 17:19:02 +01:00
Giuseppe Digilio
5aca8cc87d Merge remote-tracking branch 'remotes/origin/master' into upgrade-angular-7
# Conflicts:
#	src/app/+collection-page/collection-form/collection-form.component.ts
#	src/app/+community-page/community-form/community-form.component.ts
#	src/app/shared/comcol-forms/comcol-form/comcol-form.component.ts
2020-01-08 17:18:43 +01:00
lotte
f9fa8f0347 added typedoc 2020-01-08 10:34:24 +01:00
Tim Donohue
ad77640f7d Merge pull request #512 from atmire/Community-and-Collection-logos
Community and collection logos
2020-01-07 16:37:45 -06:00
Ben Bosman
bb87bf5a0e display the entity type in myDSpace 2020-01-07 18:26:26 +01:00
Kristof De Langhe
42d12a83ce Merge branch 'master' into w2p-65240_Community-and-collection-logos
Conflicts:
	src/app/shared/shared.module.ts
2020-01-07 16:11:24 +01:00
dependabot[bot]
ebe64c2dcc Bump handlebars from 4.1.2 to 4.5.3
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.5.3.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-01-06 16:18:15 +00:00
Kristof De Langhe
b1575b3336 67611: Remove redundant test 2020-01-06 16:08:43 +01:00
Kristof De Langhe
5de567b8b0 Merge branch 'master' into w2p-67611_Convert-external-source-to-entity
Conflicts:
	src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
2020-01-06 13:24:20 +01:00
Kristof De Langhe
dee06c69a6 64503: Collection harvester settings refresh cache after submitting changes 2020-01-06 12:57:00 +01:00
Kristof De Langhe
d2c2431c6c Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2
Conflicts:
	resources/i18n/en.json5
	src/app/core/core.module.ts
	src/app/core/data/collection-data.service.ts
	src/app/shared/shared.module.ts
2020-01-06 11:48:44 +01:00
Ben Bosman
347c9ca785 support uri field which is not dc.identifier.uri 2020-01-06 11:07:53 +01:00
Ben Bosman
d6e19254e6 support uri field which is not dc.identifier.uri 2020-01-06 11:04:09 +01:00
Ben Bosman
f7d4d89db2 verify whether file uploads are mandatory 2020-01-06 10:24:19 +01:00
Ben Bosman
a4d9ce2ec9 verify whether file uploads are mandatory 2020-01-06 09:55:47 +01:00
Ben Bosman
1ca4b95bef support uri field which is not dc.identifier.uri 2020-01-03 18:20:34 +01:00
Ben Bosman
015a0c76f8 verify whether file uploads are mandatory 2020-01-03 11:14:57 +01:00
Ben Bosman
1a22f147fb verify whether file uploads are mandatory 2020-01-03 10:44:01 +01:00
Ben Bosman
fb10c7764b case sensitive for Linux compatibility 2020-01-03 10:04:31 +01:00
Ben Bosman
9ed2d4321e verify whether file uploads are mandatory 2020-01-03 09:32:14 +01:00
Ben Bosman
375b51d0d4 verify whether file uploads are mandatory 2020-01-02 18:45:09 +01:00
Giuseppe Digilio
fdd05d2fec Refactored components' name and added missing tests 2020-01-02 18:21:47 +01:00
Giuseppe Digilio
972f0dfd60 Merge remote-tracking branch 'remotes/origin/master' into shibboleth
# Conflicts:
#	resources/i18n/de.json5
#	resources/i18n/en.json5
#	src/app/shared/shared.module.ts
2020-01-02 11:43:19 +01:00
Giuseppe Digilio
daeb475eb6 upgrade angulartics lib version 2020-01-02 10:47:27 +01:00
Giuseppe Digilio
75b4291789 Resolved type errors after merge 2019-12-24 16:35:20 +01:00
Giuseppe Digilio
ee8293978f Merge remote-tracking branch 'remotes/origin/master' into upgrade-angular-7
# Conflicts:
#	src/app/core/services/route.service.ts
#	src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
#	src/app/shared/form/builder/form-builder.service.ts
#	src/app/shared/object-list/object-list.component.spec.ts
#	src/app/submission/submission.service.ts
2019-12-24 15:57:06 +01:00
Giuseppe Digilio
c09010e151 Added test for TopLevelCommunityList Component 2019-12-23 17:23:43 +01:00
Giuseppe Digilio
b18cfcbd25 fixed issue with type of object emitted onPaginationChange event 2019-12-23 17:23:17 +01:00
Giuseppe Digilio
fcbb690b29 Added pagination to community's sub-community list in the community page 2019-12-23 15:55:03 +01:00
Giuseppe Digilio
e004098016 Added pagination to community's collection list in the community page 2019-12-23 15:54:25 +01:00
Giuseppe Digilio
ce004c2e58 Resolve conflict occurred when two or more pagination components are present in the same page 2019-12-23 15:54:05 +01:00
lotte
4dd66073fc added tests for new component 2019-12-23 11:19:23 +01:00
Tim Donohue
4b67dbf10f Merge pull request #544 from atmire/stop-parsing-stat-event-responses
Disregard the response body for statistic event calls
2019-12-20 13:56:05 -06:00
Tim Donohue
6b5303faa5 Merge pull request #531 from atmire/clean-relationships-in-submission
Create relationships during the submission
2019-12-20 13:34:32 -06:00
lotte
b510894f6f fixed edit submission bug 2019-12-20 17:01:39 +01:00
lotte
65b648b000 fixed existing tests 2019-12-20 16:48:40 +01:00
lotte
4f1dd88923 Merge branch 'clean-relationships-in-submission' into reorder-name-variants 2019-12-20 15:26:46 +01:00
lotte
01ba97af7a applied feedback 2019-12-20 14:13:31 +01:00
lotte
7c39bf4b5f fixed bug where removing a filter in the submission relationship modal redirects to the homepage 2019-12-20 10:15:24 +01:00
lotte
9d185e8a15 fixing tests 2019-12-20 08:55:23 +01:00
Giuseppe Digilio
83fabb007a fixed issue with refresh page when user is already authenticated 2019-12-19 19:01:22 +01:00
Giuseppe Digilio
62b555beee fixed vulnerabilty with serialize-javascript 2019-12-19 18:22:35 +01:00
Kristof De Langhe
ea05af74bd 67611: Import external source entry window layout changes 2019-12-19 17:34:13 +01:00
Kristof De Langhe
e2c4e6d27b Merge branch 'w2p-67478_Search-external-sources-in-submission' into w2p-67611_Convert-external-source-to-entity
Conflicts:
	src/app/entity-groups/research-entities/submission/item-list-elements/external-source-entry/external-source-entry-list-submission-element.component.html
	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts
	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts
2019-12-19 17:00:44 +01:00
lotte
d352443848 reverted server change 2019-12-19 15:36:04 +01:00
Giuseppe Digilio
8ecb215105 Updated yarn.lock 2019-12-19 14:41:13 +01:00
Giuseppe Digilio
850f474c28 updated @ngx-translate 2019-12-19 14:40:08 +01:00
lotte
a5ed837180 Merge branch 'clean-relationships-in-submission' into reorder-name-variants 2019-12-19 14:11:23 +01:00
Giuseppe Digilio
2a26159af6 added eslint to dev dependencies 2019-12-19 13:58:55 +01:00
Giuseppe Digilio
be445a7bde Fixed error with UglifyJsPlugin during AOT build after upgrade to angular 7 2019-12-19 13:58:24 +01:00
Giuseppe Digilio
66834bb279 remove resolve-url-loader after upgrade to angular 7 2019-12-19 13:57:51 +01:00
lotte
00039436b6 more tests 2019-12-19 13:57:44 +01:00
Giuseppe Digilio
bc72b1c2ae Fixed webpack loaders version 2019-12-19 13:56:54 +01:00
Giuseppe Digilio
6b123ad0a7 Fixed dropdown login menu after upgrade to angular 7 2019-12-19 13:55:34 +01:00
Giuseppe Digilio
2022268ab0 Fixed AOT build after upgrade to angular 7 2019-12-19 13:55:02 +01:00
Kristof De Langhe
890d60aa9c 67478: External source link + pagination fix 2019-12-19 13:13:46 +01:00
Kristof De Langhe
904228127e Merge remote-tracking branch 'atmire/clean-relationships-in-submission' into w2p-67478_Search-external-sources-in-submission
Conflicts:
	src/app/+item-page/simple/related-items/related-items-component.ts
	src/app/+search-page/configuration-search-page.component.ts
	src/app/+search-page/search-page.module.ts
	src/app/+search-page/search-tracker.component.ts
	src/app/+search-page/search.component.ts
	src/app/app.reducer.ts
	src/app/core/data/data.service.ts
	src/app/core/data/relationship.service.ts
	src/app/core/services/route.service.ts
	src/app/core/utilities/equatable.ts
	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts
	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts
	src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/selection-tab/dynamic-lookup-relation-selection-tab.component.ts
	src/app/shared/form/builder/models/relationship-options.model.ts
2019-12-19 11:55:28 +01:00
Kristof De Langhe
64eb5db05b 67478: JSDocs intermediate commit 2019-12-19 11:36:39 +01:00
lotte
20b4da5c33 fixed import issue 2019-12-19 11:27:10 +01:00
lotte
b98cec011b added documentation for endpoint mock service 2019-12-19 11:15:44 +01:00
lotte
0dbea31b0d added typedoc 2019-12-19 09:23:13 +01:00
lotte
38f3f583f6 Merge branch 'master' into clean-relationships-in-submission 2019-12-18 14:48:48 +01:00
lotte
c480e96043 more tests 2019-12-18 14:38:17 +01:00
Giuseppe Digilio
c9987e3451 Fixed test after upgrade to angular 7 2019-12-18 09:47:02 +01:00
Tim Donohue
a4988d580e Merge pull request #542 from paulo-graca/rcaap-openaire4-translations
OpenAIRE4 funding agency missing translation
2019-12-17 11:52:36 -06:00
Paulo Graça
9ad78e1ff1 Merge branch 'master' of github.com:DSpace/dspace-angular into rcaap-openaire4-translations 2019-12-17 17:22:01 +00:00
Tim Donohue
e94c1adfb8 Merge pull request #532 from atmire/Item-page-entities-improvements
Item page entities improvements
2019-12-17 09:12:49 -06:00
lotte
2db42d0677 added tests 2019-12-17 13:47:09 +01:00
Giuseppe Digilio
ea4e9f8797 Fixed errors after upgrade to angular 7 2019-12-17 13:10:53 +01:00
Giuseppe Digilio
8df0591272 upgrade library dependencies to angular 7 2019-12-17 13:05:24 +01:00
Art Lowel
907358edc5 add test to prove the response body isn't part of the output 2019-12-17 09:58:05 +01:00
Art Lowel
de6abb7ce6 add a responseparser that only looks at the status code, and use it for statistic event responses 2019-12-16 18:43:09 +01:00
lotte
149f59039e fixed import issues 2019-12-16 11:19:08 +01:00
lotte
c54faf69b1 Merge branch 'master' into clean-relationships-in-submission 2019-12-16 10:45:21 +01:00
Philip Vissenaekens
9df5a508f1 65240: Community and Collection logo layout 2019-12-12 13:11:54 +01:00
Philip Vissenaekens
9a921e9311 Merge remote-tracking branch 'dspace/master' into w2p-65240_Community-and-collection-logos-2
# Conflicts:
#	src/app/+collection-page/collection-page.component.html
#	src/app/core/data/comcol-data.service.ts
2019-12-12 13:08:38 +01:00
Paulo Graça
23352412ce Merge branch 'master' of github.com:DSpace/dspace-angular into configurable_entities 2019-12-10 18:05:54 +00:00
Paulo Graça
46c9a77cd9 adding default translations for funding lookup interface 2019-12-10 18:05:48 +00:00
Kristof De Langhe
c31b1725a8 66155: Fixed test cases and AoT build 2019-12-09 15:25:43 +01:00
Kristof De Langhe
9e5508f9e5 66155: Refactoring metadata-representation and related-item lists with abstract incremental list and loading by pages 2019-12-09 14:48:55 +01:00
Kristof De Langhe
64944ebb71 Merge branch 'master' into w2p-66155_Item-page-entities-improvement
Conflicts:
	src/app/+item-page/simple/related-items/related-items-component.ts
2019-12-09 12:46:07 +01:00
Kristof De Langhe
6914000e19 67611: Remaining test cases 2019-12-09 11:59:55 +01:00
Kristof De Langhe
9246cce7de 67611: Test cases 2019-12-06 17:54:52 +01:00
Kristof De Langhe
1402dd9129 67611: Import new external entity and add to selection + message changes/refactoring 2019-12-06 16:52:30 +01:00
Kristof De Langhe
3a7fa8dbaf Merge branch 'w2p-67478_Search-external-sources-in-submission' into w2p-67611_Convert-external-source-to-entity
Conflicts:
	src/app/core/data/item-data.service.ts
2019-12-06 13:23:47 +01:00
Kristof De Langhe
cdbb9b6203 67478: External source entries loading on search-option change 2019-12-06 12:59:01 +01:00
Kristof De Langhe
b51218ad5f Merge branch 'master' into w2p-67478_Search-external-sources-in-submission
Conflicts:
	src/app/+collection-page/collection-page.module.ts
	src/app/+item-page/simple/related-entities/related-entities-search/related-entities-search.component.html
	src/app/+item-page/simple/related-items/related-items-component.ts
	src/app/+search-page/configuration-search-page.component.spec.ts
	src/app/+search-page/configuration-search-page.component.ts
	src/app/+search-page/filtered-search-page.component.spec.ts
	src/app/+search-page/filtered-search-page.component.ts
	src/app/+search-page/search-page.component.html
	src/app/+search-page/search-page.component.ts
	src/app/+search-page/search-page.module.ts
	src/app/+search-page/search.component.spec.ts
	src/app/app.reducer.ts
	src/app/core/data/data.service.spec.ts
	src/app/core/data/data.service.ts
	src/app/core/data/relationship.service.ts
	src/app/core/shared/search/search-configuration.service.ts
	src/app/core/shared/search/search.service.ts
2019-12-06 11:56:28 +01:00
Tim Donohue
a78e0512cb Merge pull request #517 from atmire/Tabbed-display-of-relations
Tabbed display of relations
2019-12-05 14:28:33 -06:00
Tim Donohue
393b2e0029 Merge pull request #537 from atmire/w2p-67625-minor-bug-in-edit-metadata
[DS-4400] Fix for minor edit metadata bug
2019-12-05 10:37:32 -06:00
Kristof De Langhe
f0e38e9e8c 67611: Console error fix, notification on adding local entity and JSDocs 2019-12-05 17:31:13 +01:00
Art Lowel
dfb3c076d7 Merge pull request #505 from atmire/ComCol-CDK-Tree
Community and Collection Tree
2019-12-05 17:22:41 +01:00
Samuel
a434b5706e taskid 66074 Keep virtual metadata on relationship delete - fix lint issues 2019-12-05 17:09:56 +01:00
Kristof De Langhe
e13801ce81 Merge branch 'master' into w2p-66156_Display-of-relations
Conflicts:
	src/app/+item-page/item-page.module.ts
	src/app/+search-page/filtered-search-page.component.spec.ts
	src/app/+search-page/filtered-search-page.component.ts
	src/app/+search-page/search-page.module.ts
2019-12-05 16:23:33 +01:00
Kristof De Langhe
fda083137a 67611: Import external entry as new entity pt1 2019-12-05 15:48:54 +01:00
Samuel
038483c8b8 taskid 66074 Keep virtual metadata on relationship delete - fix tests 2019-12-05 15:29:32 +01:00
Kristof De Langhe
7a904f9bf7 67611: Refactored import button to separate component within object-collection + moved calling of import modal to external-source tab 2019-12-05 14:06:29 +01:00
Kristof De Langhe
6ada3fae5b 67611: Fixed radio button bug + hide pagintion details 2019-12-05 10:58:38 +01:00
Kristof De Langhe
0210be1a53 67611: External-Source-Entry import window 2019-12-04 17:54:01 +01:00
Marie Verdonck
7b31ad0345 [DS-4400] Fix for minor edit metadata bug 2019-12-04 17:48:42 +01:00
Marie Verdonck
4368015567 e2e tests for community-list removed 2019-12-04 15:03:55 +01:00
Marie Verdonck
e77866a0d2 Merged Dspace/dspace-angular/master and changed all new FindAllOptions references to FindListOptions 2019-12-04 14:19:31 +01:00
Marie Verdonck
0b368e8c25 Merge remote-tracking branch 'upstream/master' into w2p-66391_ComCol-Tree---PR-Feedback 2019-12-04 14:09:04 +01:00
Marie Verdonck
8cacad3264 e2e test fix, so it waits for the loading element to disappear (tree is rendered) 2019-12-04 11:09:00 +01:00
Tim Donohue
a0347d263f Merge pull request #528 from atmire/add-fonts
Add support for locally hosted fonts
2019-12-03 15:55:59 -06:00
Tim Donohue
33972cbaf7 Merge pull request #508 from atmire/refactor-submission-parsers
Refactor Submission Parsers
2019-12-03 15:32:01 -06:00
Samuel
891415daae taskid 66076 Keep virtual metadata on item delete - tests & docs & small fixes 2019-12-03 16:54:55 +01:00
Samuel
2eac2a20bb Merge branch 'master' into w2p-66074_Keep-virtual-metadata-on-relationship-delete 2019-12-03 16:54:48 +01:00
lotte
69d58c0881 removed console logs and reinstated thumbnails 2019-12-03 16:37:58 +01:00
Kristof De Langhe
e9a8a25116 67478: AoT build fixes 2019-12-03 15:40:10 +01:00
Art Lowel
5234a7b015 fix loop for name variants as well 2019-12-03 15:09:29 +01:00
Kristof De Langhe
558285da85 67478: Automatically fill query in search form 2019-12-03 14:56:05 +01:00
Kristof De Langhe
b3e2041cdb 67478: External source tabs test cases 2019-12-03 14:47:47 +01:00
Art Lowel
71a3a22a7c fix infinite loop 2019-12-03 14:46:33 +01:00
lotte
ef1ed04fd2 manual change detection for preview list in submission 2019-12-03 13:57:56 +01:00
lotte
c48932431f fixes after merge + tslint changes 2019-12-03 11:43:19 +01:00
lotte
dc316dc6cb Merge branch 'master' into reorder-name-variants 2019-12-03 10:20:52 +01:00
lotte
c3ef2f8dee fixed reordering request 2019-12-03 10:10:46 +01:00
Art Lowel
78d1c5ee2b use reorderables instead of relationships 2019-12-02 18:30:35 +01:00
Tim Donohue
6e0bd0c146 Merge pull request #495 from atmire/dspace-angulartics-provider
Track page views and searches in DSpace with a custom Angulartics2 provider
2019-12-02 10:13:37 -06:00
Kristof De Langhe
edbc32604d 67478: LookupRelationService, external source tabs, list implementation 2019-12-02 17:07:28 +01:00
lotte
bc8e7d8fe6 reordering authors 2019-12-02 15:37:59 +01:00
Art Lowel
4896c98f9a apply fix to test webpack config as well 2019-12-02 13:46:34 +01:00
Kristof De Langhe
de4b32dcad 67478: Intermediate commit - Basic components 2019-11-29 17:51:27 +01:00
Art Lowel
0048a97181 fix issue where submission requests would time out before they could be used once 2019-11-29 15:15:06 +01:00
lotte
afa61b11c8 added item to submission 2019-11-29 10:52:25 +01:00
Kristof De Langhe
380e02a92d 66155: Fixed 'hide last x' algorithm 2019-11-29 10:17:11 +01:00
lotte
820280f901 fixed bug in results per page 2019-11-29 09:10:26 +01:00
lotte
06667e448f Merge branch 'clean-relationships-in-submission' of https://git.atmire.com/contributions/dspace-angular into clean-relationships-in-submission 2019-11-29 08:52:30 +01:00
lotte
d1ba3d9936 Merge branch 'master' into clean-relationships-in-submission 2019-11-29 08:52:10 +01:00
Art Lowel
82fcd47ac3 Fix issue with update frequency 2019-11-28 18:20:35 +01:00
lotte
16a16bedfe fixed lint error 2019-11-28 15:47:16 +01:00
lotte
9147a6b18f Merge branch 'clean-relationships-in-submission' of https://git.atmire.com/contributions/dspace-angular into clean-relationships-in-submission 2019-11-28 15:12:45 +01:00
lotte
23cbc98208 small fixes + test fix 2019-11-28 15:10:48 +01:00
Art Lowel
25c3e53b63 fix an issue where relationships wouldn't show up in the submission view 2019-11-28 14:33:00 +01:00
Kristof De Langhe
7755228b59 65240: Refresh object cache after removing com/col logo 2019-11-28 11:51:07 +01:00
Kristof De Langhe
424089312b Merge branch 'master' into w2p-65240_Community-and-collection-logos 2019-11-28 11:39:26 +01:00
Kristof De Langhe
6b3a395e4a Merge branch 'master' into w2p-66155_Item-page-entities-improvement
Conflicts:
	resources/i18n/en.json5
	src/app/+item-page/simple/metadata-representation-list/metadata-representation-list.component.html
	src/app/+item-page/simple/related-items/related-items.component.html
2019-11-28 11:02:37 +01:00
Art Lowel
f72343bd8e Fix searchParams readonly error in the subission 2019-11-28 10:41:06 +01:00
Antoine Snyers
870c98f368 Update TypeDoc 2019-11-28 09:54:42 +01:00
Antoine Snyers
93b465c3b2 Use waitForAngular() so e2e tests don't run while data is still loading 2019-11-28 09:54:42 +01:00
Antoine Snyers
dfa846a98e Track page views and searches in DSpace with a custom Angulartics2 provider 2019-11-28 09:54:39 +01:00
Kristof De Langhe
9b711cc460 Merge branch 'master' into w2p-66156_Display-of-relations
Conflicts:
	src/app/+search-page/filtered-search-page.component.ts
	src/app/+search-page/search-page.module.ts
2019-11-27 18:03:03 +01:00
Kristof De Langhe
1b978124d1 66156: Removal of redundant fields, message update and aciveTab as observable 2019-11-27 18:01:31 +01:00
Tim Donohue
7f44c7751b Merge pull request #513 from atmire/sidebar-refactoring
Sidebar refactoring
2019-11-27 10:46:40 -06:00
Art Lowel
8c2e63c2a7 fix issue where font urls in scss slow down the build 2019-11-27 14:55:18 +01:00
Kristof De Langhe
2ef02864f2 Merge branch 'master' into w2p-66156_Display-of-relations 2019-11-27 14:47:29 +01:00
Antoine Snyers
c83c861e85 Update TypeDocs 2019-11-27 14:11:43 +01:00
Art Lowel
d127e5f27c remove version number 2019-11-27 13:48:06 +01:00
Marie Verdonck
afcf897bbe Reducer test and e2e test for persisting tree state through store 2019-11-27 13:37:37 +01:00
Art Lowel
c0962cb966 add supported fonts README 2019-11-27 13:32:30 +01:00
Art Lowel
36e80e3624 Add support for OTF fonts 2019-11-27 13:30:26 +01:00
Marie Verdonck
db7ebfb16e Existing community list test fixes 2019-11-27 10:37:38 +01:00
Tim Donohue
fcae21e944 Merge pull request #529 from DSpace/tdonohue-README
Update README
2019-11-26 11:42:17 -06:00
Marie Verdonck
5ff634a26f Last bit of doc 2019-11-26 18:06:07 +01:00
Marie Verdonck
69a99e9381 Fix after master rebase and tests updated for chevron rendering changes (AoT ok) 2019-11-26 18:02:45 +01:00
Art Lowel
77f6294bde fix linting issues 2019-11-26 17:42:27 +01:00
Samuel
b1f4a90a58 taskid 66074 Keep virtual metadata on relationship delete - fix lint issues 2019-11-26 17:31:47 +01:00
Marie Verdonck
9bd1933548 66391: expandedNodes (&loadingNode) is now retrieved/sent to the store
at component initialisation/destruction so the state of the tree persists
& documentation
2019-11-26 17:23:49 +01:00
Marie Verdonck
eaf0911e2e 66391: Fixed the valse positive chevron indicating node is expandable 2019-11-26 17:23:49 +01:00
Marie Verdonck
84326ef564 Pagination for collections & Process feedback 2019-11-26 17:23:49 +01:00
Art Lowel
adfe881a81 add findByParent method to ComColDataService 2019-11-26 17:23:03 +01:00
Kristof De Langhe
aed4db6289 64387: HAL endpoint refactoring 2019-11-26 17:18:04 +01:00
Marie Verdonck
ee140e623a 65600: Cleanup & indentation of shortDescription 2019-11-26 17:18:04 +01:00
Marie Verdonck
98c8eb558a 65600: Renamed FindAllOptions to FindListOptions 2019-11-26 17:18:04 +01:00
Marie Verdonck
a4bf1a64c7 65600: Pagination for subcommunities works; not yet for collections since it needs authorisation 2019-11-26 17:18:04 +01:00
Marie Verdonck
48d893e975 65600: Pagination on top level communities by combineFlatten list of consecutive page payloads 2019-11-26 17:18:03 +01:00
Marie Verdonck
1400af3a5e 65600: Indentation description more than one line 2019-11-26 17:18:03 +01:00
Marie Verdonck
e950c23f40 65600: Theme changes&improvements and route calculation moved to tree creation 2019-11-26 17:18:03 +01:00
Marie Verdonck
c99b6adb31 65600: ComCol-Tree load more links message, not yet functional 2019-11-26 17:18:03 +01:00
Marie Verdonck
f4686ea6cf 65528: styleLint 2019-11-26 17:18:03 +01:00
Marie Verdonck
3997ed2c99 65528: ComCol routing via routing modules instead of literal 2019-11-26 17:18:03 +01:00
Marie Verdonck
3daf35e4a4 65528: Renaming/Moving according to feedback; style and links added; chevrons fixed 2019-11-26 17:18:03 +01:00
Art Lowel
79424ac108 refactor community list datasource 2019-11-26 17:18:03 +01:00
Marie Verdonck
8e0280cb5a 65528: last coll/subcom undefined fix (wait for remoteData.succeeded) 2019-11-26 17:18:03 +01:00
Marie Verdonck
514e9a98ed 65528: Removed unused css files 2019-11-26 17:18:03 +01:00
Marie Verdonck
2ece89db62 65528: ComCol flat tree with actual backend comm/coll
> TODO FIX: Last subcom and coll are undefined
2019-11-26 17:18:03 +01:00
Marie Verdonck
69e8221867 65528: ComCol Tree with flatlist that gets generated at every (un)collapse
> Only creates flatlist with expanded nodes
2019-11-26 17:18:03 +01:00
Marie Verdonck
4feba32157 65528: ComCol Tree with full FlatList that gets generated at page-load 2019-11-26 17:18:03 +01:00
Samuel
ae476baa62 taskid 66074 Keep virtual metadata on relationship delete 2019-11-26 16:44:31 +01:00
lotte
8522c35186 fixes 2019-11-26 16:43:46 +01:00
lotte
835ce735cb added some tests 2019-11-25 18:04:05 +01:00
Tim Donohue
b73799d28b Update README
Update wiki links. Reorg docs/links in README
2019-11-25 10:57:06 -06:00
Tim Donohue
2d50598177 Merge pull request #525 from vitorsilverio/translation-pt
Portuguese Translation
2019-11-25 09:53:12 -06:00
Tim Donohue
c5d271b647 Merge pull request #526 from vitorsilverio/fix-translation-typo
fix translation typo
2019-11-25 09:51:42 -06:00
Kristof De Langhe
757b9f9dcd 66156: Persons and Projects search tabs on OrgUnit pages + mantis fix 2019-11-25 14:18:21 +01:00
lotte
7c88616ba8 name variant reducer tests 2019-11-25 12:36:22 +01:00
lotte
23a378bd26 fixes after merge with master 2019-11-25 12:11:40 +01:00
lotte
168e74d1fa Merge branch 'master' into clean-relationships-in-submission 2019-11-25 11:18:57 +01:00
lotte
cbfc396b29 fixed some tests 2019-11-25 11:09:44 +01:00
Art Lowel
29c9682508 Fix variable name 2019-11-22 18:14:36 +01:00
Art Lowel
b34e636379 Add support for locally hosted fonts 2019-11-22 18:14:02 +01:00
Kristof De Langhe
8c3416ce29 Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2
Conflicts:
	resources/i18n/en.json5
	src/app/core/data/collection-data.service.spec.ts
	src/app/core/data/collection-data.service.ts
2019-11-22 18:08:00 +01:00
Vitor S Rodrigues
745ac6eaad added portuguese as active language 2019-11-22 10:37:12 -03:00
Vitor S Rodrigues
eca4931c7b fix translation typo 2019-11-22 10:22:45 -03:00
Vitor S Rodrigues
599f66b57f translation pt-br 2019-11-22 10:14:26 -03:00
Art Lowel
3c0adf9b12 Merge pull request #521 from bram-atmire/placeholder-catalogs
i18n: Placeholder catalogs as a starting point for translators
2019-11-22 08:54:43 +01:00
Tim Donohue
536ecbb6ed Merge pull request #509 from atmire/w2p-65572_Add-support-for-bundles
Add support for bundles
2019-11-21 14:53:10 -06:00
Bram Luyten
1267b7fc2d Deleting placeholder catalogs from languages that weren't updated in XMLUI in the last 3 years 2019-11-21 17:05:00 +01:00
Tim Donohue
0f4c905628 Merge pull request #515 from fernandaruizm/master
spanish translation
2019-11-21 08:50:13 -06:00
Art Lowel
7bbb90cbfd Merge pull request #523 from vitorsilverio/fix-translations
Fix translation
2019-11-21 15:14:23 +01:00
Kristof De Langhe
6097d089fd Merge branch 'master' into w2p-65240_Community-and-collection-logos 2019-11-21 15:09:08 +01:00
Art Lowel
d416437895 Merge pull request #522 from DSpace/dutch-message-keys
Contribution to the Dutch translation of DSpace 7
2019-11-21 14:35:31 +01:00
Vitor S Rodrigues
33156547ea Fix translation 2019-11-21 10:26:25 -03:00
Kristof De Langhe
ed3f7dfc7b Merge branch 'master' into w2p-65572_Add-support-for-bundles
Conflicts:
	src/app/core/shared/item.model.ts
	src/app/entity-groups/journal-entities/item-grid-elements/journal-issue/journal-issue-grid-element.component.spec.ts
	src/app/entity-groups/journal-entities/item-grid-elements/journal-volume/journal-volume-grid-element.component.spec.ts
	src/app/entity-groups/journal-entities/item-grid-elements/journal/journal-grid-element.component.spec.ts
	src/app/entity-groups/journal-entities/item-list-elements/journal-issue/journal-issue-list-element.component.spec.ts
	src/app/entity-groups/journal-entities/item-list-elements/journal-volume/journal-volume-list-element.component.spec.ts
	src/app/entity-groups/journal-entities/item-list-elements/journal/journal-list-element.component.spec.ts
	src/app/entity-groups/research-entities/item-grid-elements/person/person-grid-element.component.spec.ts
	src/app/entity-groups/research-entities/item-grid-elements/project/project-grid-element.component.spec.ts
	src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-list-element.component.spec.ts
	src/app/entity-groups/research-entities/item-list-elements/person/person-list-element.component.spec.ts
	src/app/entity-groups/research-entities/item-list-elements/project/project-list-element.component.spec.ts
	src/app/shared/object-grid/item-grid-element/item-grid-element.component.spec.ts
	src/app/shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec.ts
	src/app/shared/object-list/item-list-element/item-types/publication/publication-list-element.component.spec.ts
	src/app/shared/testing/utils.ts
2019-11-21 14:14:39 +01:00
Bram Luyten
a825699af8 Contribution to the Dutch translation of DSpace 7 2019-11-21 13:50:05 +01:00
fernandaruizm
55fe66676a Update resources/i18n/es.json5
Co-Authored-By: Bram Luyten <bram@atmire.com>
2019-11-21 09:28:44 -03:00
Kristof De Langhe
64c9d009a9 66156: Active tab in URL for tabbed related entities search 2019-11-21 13:28:33 +01:00
Bram Luyten
87eb733d8b i18n: Placeholder catalogs as a starting point for translators 2019-11-21 13:17:48 +01:00
Kristof De Langhe
63257eac3d 66156: AoT build error fix 2019-11-21 12:45:38 +01:00
Bram Luyten
981c915975 Translations: German: missing key (breaking) 2019-11-21 10:02:29 +01:00
Bram Luyten
4ff887035e missing " in german translation (breaking) 2019-11-21 09:14:27 +01:00
Bram Luyten
9d124c1546 Merge pull request #519 from cjuergen/german-translation
German translation
2019-11-21 08:55:35 +01:00
lotte
3487231af1 fixed name variants in previews 2019-11-20 15:59:23 +01:00
Kristof De Langhe
87d468f9b9 66156: Hide tabbox on single tab, merged filtered- and configuration-search-page into one component and added configuration option to tabs 2019-11-19 14:42:58 +01:00
Kristof De Langhe
52e6d5ca29 Merge branch 'master' into w2p-66156_Display-of-relations 2019-11-19 14:01:22 +01:00
fernandaruizm
da577756fe Spanish translation finished
Spanish translation finished to review
2019-11-18 15:33:21 -03:00
cjuergen
3a84dc1800 Merge branch 'master' into german-translation 2019-11-18 17:47:33 +01:00
Kristof De Langhe
c7b3766399 65240: fdescribe to describe 2019-11-18 17:36:56 +01:00
cjuergen
485a496938 Updated German Translation after transition to json5 2019-11-18 17:27:13 +01:00
Kristof De Langhe
64978f2cfe 65240: Marking logo for deletion and request on form submit 2019-11-18 16:28:51 +01:00
lotte
0c4a1bc610 added thumbnails 2019-11-18 15:45:24 +01:00
Kristof De Langhe
4887353450 Merge branch 'master' into w2p-65240_Community-and-collection-logos
Conflicts:
	resources/i18n/en.json5
2019-11-18 14:42:58 +01:00
lotte
94329b0b52 fixed aot issues 2019-11-18 11:40:10 +01:00
lotte
efc2c9933a autoselect + small fixes 2019-11-18 11:24:01 +01:00
Tim Donohue
e2a2cad91b Merge pull request #518 from DSpace/tdonohue-patch-1
Remove bad characters from en.json5
2019-11-15 13:17:47 -06:00
Tim Donohue
86af0368b8 Remove bad characters from en.json5 2019-11-15 12:29:52 -06:00
Kristof De Langhe
558ff27d31 Merge branch 'master' into w2p-66156_Display-of-relations
Conflicts:
	resources/i18n/en.json5
2019-11-15 17:46:18 +01:00
Tim Donohue
a7ad6885e3 Merge pull request #516 from atmire/AoT-build-errorfix
AoT build error fix
2019-11-15 09:52:01 -06:00
lotte
3b4d8598d5 implementing auto select 2019-11-15 16:28:41 +01:00
Tim Donohue
2c4bbe874d Merge pull request #504 from atmire/i18n-sync-files-script
I18n sync script
2019-11-15 09:18:40 -06:00
Kristof De Langhe
4debb54352 AoT build errorfix - moving url matcher to exported function 2019-11-15 16:00:33 +01:00
Kristof De Langhe
4c8f9f82a4 Merge branch 'master' into w2p-66156_Display-of-relations
Conflicts:
	resources/i18n/en.json5
	src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html
	src/app/entity-groups/research-entities/item-pages/person/person.component.html
	themes/mantis/app/entity-groups/journal-entities/item-pages/journal/journal.component.html
	themes/mantis/app/entity-groups/research-entities/item-pages/person/person.component.html
2019-11-15 15:39:45 +01:00
Antoine Snyers
56d6965233 Update the search-settings component specs 2019-11-15 12:00:55 +01:00
Marie Verdonck
1ba07c4683 Merged new message keys from dspace/master and ran script again 2019-11-15 10:02:00 +01:00
Marie Verdonck
699c86c201 Merged new message keys from dspace/master and ran script again 2019-11-15 10:00:27 +01:00
Marie Verdonck
5ba7cd2c2d If on windows OS, all LF get replaced with CRLF 2019-11-15 10:00:06 +01:00
Marie Verdonck
1c3f2e73e1 Added missing documentation for larger functions 2019-11-15 10:00:06 +01:00
Marie Verdonck
f5234bab52 ran i18n script on all files for initial & regex $ > \n in en.json5 2019-11-15 10:00:06 +01:00
Marie Verdonck
3550cb9073 i18n-sync-files script 2019-11-15 09:59:32 +01:00
Tim Donohue
d8dd045a10 Merge pull request #514 from tdonohue/fix_broken_build
Fix broken tests on master
2019-11-14 14:13:38 -06:00
fernandaruizm
fe680150bd Merge pull request #1 from fernandaruizm/fernandaruizm-es
Add files via upload
2019-11-14 16:52:49 -03:00
fernandaruizm
94b99b9bb5 Add files via upload 2019-11-14 16:51:12 -03:00
Tim Donohue
eb4f7d557c Fix code from PR#490 to align with PR#468 2019-11-14 13:34:17 -06:00
Tim Donohue
c2f13548ed Merge pull request #490 from mspalti/routing_by_id_2
Lookup and redirect by uuid and handle
2019-11-14 10:00:12 -06:00
Tim Donohue
3381d5e8df Merge pull request #468 from mspalti/forceBypassCache_remove
forceBypassCache param removed
2019-11-14 09:59:35 -06:00
Tim Donohue
68d186ae8d Merge pull request #497 from atmire/w2p-65195_dynamic-component-refactoring
Dynamic component loading refactoring
2019-11-14 09:58:49 -06:00
Art Lowel
ce31ef0d0f Merge pull request #511 from mspalti/login_redirect_encoding_fix
Prevent encoding of query after login redirect.
2019-11-14 16:51:06 +01:00
lotte
c2ae71b1b8 Added name variant dialog 2019-11-14 16:00:48 +01:00
Antoine Snyers
78a29a8770 Replace double quotes by single quotes 2019-11-14 14:05:52 +01:00
Kristof De Langhe
4bddbb6c62 66155: Test fixes 2019-11-14 14:02:40 +01:00
Kristof De Langhe
aedd4b99ee 66155: Show more/less incremental on item pages + loading component for entities 2019-11-14 13:29:39 +01:00
Antoine Snyers
771041a3cf Implement sidebar filter and dropdown components 2019-11-14 13:14:47 +01:00
Antoine Snyers
4f7b7637cb Refactor search sidebar 2019-11-14 13:14:47 +01:00
lotte
4a7c7a61f1 implemented debounce for name variant updates 2019-11-14 09:56:53 +01:00
Kristof De Langhe
ac58297cbf 66156: Tabbed related entities search 2019-11-13 17:23:28 +01:00
Michael W Spalti
3bea8f5a17 Redirect after login changed to use Router navigateByUrl() to prevent encoding of query parameters in redirect. 2019-11-12 12:01:16 -08:00
Kristof De Langhe
840ed6acb7 65717: Item edit tabs label changes 2019-11-12 17:34:46 +01:00
lotte
190203cb48 add/remove subscriptions for name variants on init/destroy 2019-11-12 16:34:26 +01:00
Kristof De Langhe
166aab606d 65240: logo under browse 2019-11-12 14:54:16 +01:00
Kristof De Langhe
bb5103518e Merge branch 'master' into w2p-65240_Community-and-collection-logos
Conflicts:
	resources/i18n/en.json5
	src/app/shared/shared.module.ts
2019-11-12 14:39:10 +01:00
lotte
40d740640d fixes after merge 2019-11-12 14:36:29 +01:00
Kristof De Langhe
792455f007 65240: Uploader alignment fix 2019-11-12 14:21:33 +01:00
lotte
0cdafacf22 Merge branch 'master' into w2p-65195_dynamic-component-refactoring 2019-11-12 13:37:37 +01:00
Kristof De Langhe
857f796287 64503: Metadata Format resetting to initial state fix 2019-11-12 13:16:41 +01:00
Kristof De Langhe
2d3d7ae71e 64503: Prevent submit when harvest type is NONE and not changed 2019-11-12 11:59:44 +01:00
benbosman
576b5328c3 Merge pull request #475 from atmire/Item-Page-Entities
Item page entities changes/refactoring
2019-11-12 11:26:29 +01:00
Kristof De Langhe
449f66076b Merge branch 'master' into w2p-64574_Item-page-entities
Conflicts:
	src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts
	src/app/+item-page/simple/item-types/shared/item.component.spec.ts
	src/app/+item-page/simple/item-types/shared/item.component.ts
	src/app/+item-page/simple/metadata-representation-list/metadata-representation-list.component.spec.ts
2019-11-12 10:53:21 +01:00
Michael W Spalti
85509e2159 Removed unused import. 2019-11-08 12:12:53 -08:00
Michael W Spalti
e7302bd8af Clear cache in mydspace redirect and reload methods. 2019-11-08 12:04:54 -08:00
lotte
f289c1353e fixed issues with sending name variant update requests to the server 2019-11-08 16:05:37 +01:00
lotte
d8a049c550 Merge branch 'w2p-65195_dynamic-component-refactoring' into clean-relationships-in-submission 2019-11-08 13:55:08 +01:00
lotte
5b37d90444 fixed bug where going to the mydspace page broke 2019-11-08 13:42:20 +01:00
lotte
6d3a52d2f9 fix issue with wsi in field container 2019-11-08 12:45:10 +01:00
lotte
19510a88ef fixed functionality after merge 2019-11-08 10:59:52 +01:00
lotte
7e62ce80c2 Merge branch 'refactor-submission-parsers' into clean-relationships-in-submission 2019-11-08 08:49:12 +01:00
lotte
1e94a02da0 added missing typedoc 2019-11-08 07:44:10 +01:00
lotte
e04d13402b trying to get request handling in the right order 2019-11-07 17:04:32 +01:00
lotte
575a142022 split up submission context 2019-11-07 16:58:05 +01:00
lotte
b1ff5765a6 Fixes after merge 2019-11-07 16:41:28 +01:00
lotte
36ec68fd33 Merge branch 'master' into w2p-65195_dynamic-component-refactoring 2019-11-07 14:23:36 +01:00
Art Lowel
77826beb2a Merge remote-tracking branch 'upstream/master' into w2p-65572_Add-support-for-bundles 2019-11-07 13:37:56 +01:00
Art Lowel
7474c0a514 fix lint issue 2019-11-07 13:27:23 +01:00
Michael W Spalti
7565507f69 Merge remote-tracking branch 'upstream/master' into forceBypassCache_remove 2019-11-06 10:36:10 -08:00
lotte
836492d2af sending name variant update requests to the server 2019-11-06 16:43:25 +01:00
Art Lowel
60f9692c29 update mockobject signature 2019-11-06 10:17:43 +01:00
Art Lowel
bf086db969 add a service to retrieve a submission object without knowing its type 2019-11-06 10:08:31 +01:00
Tim Donohue
959134fc89 Merge pull request #496 from atmire/Name-variants-on-item-pages
Name variants on item pages
2019-11-05 09:55:13 -06:00
lotte
5a6a0eac6f trying to clean up namevariant code 2019-11-05 16:33:39 +01:00
Art Lowel
d255838265 add submissionId to fieldparser, and refactor to create fieldparsers using DI 2019-11-05 15:53:41 +01:00
Michael W Spalti
dc43e23301 Added not found for identifier message to i18n. 2019-11-01 13:40:19 -07:00
Kristof De Langhe
b62af58502 65717: Fix reloading lists on viewing more while still preventing unwanted initializes 2019-10-31 14:20:50 +01:00
Kristof De Langhe
e762ed4d9e 65717: Edit-bitstreams move + delete request fix 2019-10-31 14:07:03 +01:00
Kristof De Langhe
404729faa3 64503: Feedback 2019-10-24 ; loading, message fix, notification clearing 2019-10-31 12:41:03 +01:00
Michael W Spalti
0dd765d84a Reverted object cache method names back to the original UUID convention. 2019-10-30 14:23:50 -07:00
Michael W Spalti
d309b2081c Removed the handle index (not needed because the uuid index will always be used internally) and all associated code. 2019-10-30 13:59:10 -07:00
Michael W Spalti
9a0a1645fb Removed the success filter from DSO data response so that all responses are returned, including 404. 2019-10-30 11:53:46 -07:00
Michael W Spalti
d3a84c7e7f Updated matcher in lookup-by-id routing module.
Converted id to const.
2019-10-30 09:28:17 -07:00
Michael W Spalti
c3095e37bf Merge branch 'routing_by_id_2' of https://github.com/mspalti/dspace-angular into routing_by_id_2 2019-10-30 09:22:36 -07:00
Art Lowel
18cf2a8aca Merge pull request #503 from atmire/update-webdriver
Update webdriver-manager library
2019-10-30 14:45:08 +01:00
Antoine Snyers
bbb2570f87 Update webdriver-manager library 2019-10-30 14:13:47 +01:00
Michael W Spalti
3694c557e1 Tracking multiple subscriptions and unsubscribing in ondestroy. 2019-10-29 16:08:54 -07:00
Kristof De Langhe
dc9520a832 Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2
Conflicts:
	resources/i18n/en.json5
	src/app/core/core.module.ts
	src/app/core/data/collection-data.service.spec.ts
	src/app/core/data/collection-data.service.ts
	src/app/core/data/request.models.ts
	src/app/shared/shared.module.ts
2019-10-29 17:36:42 +01:00
Kristof De Langhe
dd5f40858d 65717: Additional tests and fixes 2019-10-29 13:50:15 +01:00
Kristof De Langhe
468fc097c0 Merge branch 'performance-improvements-fall-2019' into w2p-65717_Bundles-in-edit-item
Conflicts:
	src/app/shared/mocks/mock-request.service.ts
2019-10-29 13:19:35 +01:00
Kristof De Langhe
ca38af3772 post performance improvement test fixes 2019-10-29 13:14:07 +01:00
Kristof De Langhe
0b2daf8cbf 65717: Immediate patch request + delete in order; refresh cache and show notifications after submit 2019-10-29 12:04:08 +01:00
Kristof De Langhe
9cad39ff36 Merge remote-tracking branch 'origin/performance-improvements-fall-2019' into w2p-65717_Bundles-in-edit-item
Conflicts:
	src/app/core/shared/hal-endpoint.service.ts
2019-10-29 10:08:28 +01:00
Art Lowel
e26961322f reduce number of unnecessary requests from HalEndpointService and RemoteDataBuildService 2019-10-28 18:01:05 +01:00
Kristof De Langhe
90436f3b2c 65717: ObjectValuesPipe pure 2019-10-28 17:48:08 +01:00
Kristof De Langhe
756134f773 65717: Small margin fix 2019-10-28 17:00:48 +01:00
Kristof De Langhe
4efbbf1c99 65717: Test cases 2019-10-28 16:35:18 +01:00
Kristof De Langhe
8059301906 65717: Move operations from custom order + sending bundle patch 2019-10-28 14:27:12 +01:00
lotte
2e50d99fc4 working on sending name variants to the server on patch 2019-10-25 16:35:10 +02:00
Kristof De Langhe
89f4d66012 65240: Switch to POST requests after logo has been deleted 2019-10-25 11:37:43 +02:00
Giuseppe Digilio
eea76746b1 remove test AuthMethodModel 2019-10-24 22:48:51 +02:00
Giuseppe Digilio
1896b14520 Added CHECK_AUTHENTICATION_TOKEN_COOKIE action 2019-10-24 22:46:01 +02:00
Giuseppe Digilio
24b308ace6 change i18n shibboleth label 2019-10-24 22:45:15 +02:00
Giuseppe Digilio
61eccb2973 Move out new-user and forgot-password items menu from LogInPasswordComponent 2019-10-24 22:44:36 +02:00
Giuseppe Digilio
ab117105b3 Remove shibboleth target page 2019-10-24 21:47:11 +02:00
lotte
5925b50141 65711: implemented retrieval and initial saving of name variants 2019-10-24 16:41:11 +02:00
Antoine Snyers
95b2feb868 Update webdriver-manager library 2019-10-24 15:38:08 +02:00
Giuseppe Digilio
e4bcf3d4b0 Added X-Requested-With header on SSR 2019-10-24 15:35:41 +02:00
Giuseppe Digilio
103425d7ee Added withCredentials request param 2019-10-24 15:35:15 +02:00
Kristof De Langhe
d5198283ff 65529: Remove line-break from imports 2019-10-24 12:00:20 +02:00
Kristof De Langhe
b550667bc9 65717: submit intermediate commit 2019-10-24 11:58:48 +02:00
Kristof De Langhe
7e3ba86ccc 65717: Edit-bitstreams fetch all bundles and expandable bitstream list 2019-10-23 17:04:23 +02:00
lotte
f53ebba096 65711: name variants in store 2019-10-23 16:25:01 +02:00
Kristof De Langhe
cbbc776922 65717: AoT build error fixes 2019-10-23 14:49:14 +02:00
Kristof De Langhe
7adb50a9b8 65717: Remove object updates on page url (only bundles now) and added support for tracking custom order changes, discard and reinstate 2019-10-23 14:28:19 +02:00
Kristof De Langhe
896e19990b 65240: Removed old test cases 2019-10-23 13:37:13 +02:00
Kristof De Langhe
19a2ae6ecc 65240: ComCol logo caching issue fix 2019-10-23 10:59:14 +02:00
Kristof De Langhe
9113a08796 65717: Custom order within bundles stored + danger class fix 2019-10-22 17:54:45 +02:00
lotte
9d5f1b09bc name variants combobox 2019-10-22 16:24:06 +02:00
Kristof De Langhe
5e6082c1c7 65717: cdk install, table layout to divs, dragging support (no implementation yet) 2019-10-22 15:58:41 +02:00
Julius Gruber
a851a71f22 Removed building of target param from auth-method.model2 2019-10-22 11:02:13 +02:00
Michael W Spalti
9ae869936b Added proposed change to force clearing the object cache in workspace component onInit. 2019-10-21 16:51:25 -07:00
Tim Donohue
82367ea778 Merge pull request #500 from DSpace/tdonohue-fix-e2e-tests
Correct baseUrl in local.cfg used by e2e tests
2019-10-21 14:23:31 -05:00
Tim Donohue
227943b112 Correct baseUrl in local.cfg used by e2e tests 2019-10-21 13:45:14 -05:00
Michael W Spalti
83e7b662e3 Merge branch 'forceBypassCache_remove' of https://github.com/mspalti/dspace-angular into forceBypassCache_remove 2019-10-21 11:17:36 -07:00
Kristof De Langhe
a30529e091 65717: Additional upload-bitstream component fixes 2019-10-21 13:49:44 +02:00
Kristof De Langhe
9abc48960f 65717: Edit-bitstreams bundle upload button + bitstream-upload component changes to include bundles 2019-10-21 13:29:46 +02:00
Julius Gruber
0df7bb57a6 Removed log from auth.interceptor 2019-10-21 11:32:39 +02:00
Kristof De Langhe
b9754764b3 65717: Ability to discard all field-updates at once (fixes discard and reinstate issues) 2019-10-21 10:43:46 +02:00
Julius Gruber
2e236cc98b Shibboleth location error fixed 2019-10-21 09:17:01 +02:00
Michael W Spalti
03c36ab233 Updated unit test. 2019-10-18 11:18:21 -07:00
Michael W Spalti
dfd1881f89 Added support for using the dso (uuid) endpoint. 2019-10-18 10:59:24 -07:00
Kristof De Langhe
6dca421256 65717: Edit Item bitstreams - Bundles part 1 2019-10-18 17:57:25 +02:00
Julius Gruber
5088ec0628 Code clean up 2019-10-18 12:55:34 +02:00
Julius Gruber
0b57dd738b Code clean up 2019-10-18 12:50:11 +02:00
Julius Gruber
6231495444 Code clean up 2019-10-18 12:45:48 +02:00
Julius Gruber
4805dd5abf Code clean up 2019-10-18 12:45:19 +02:00
Julius Gruber
d894056d44 Code clean up 2019-10-18 12:44:49 +02:00
Julius Gruber
eb96359d9e Code clean up 2019-10-18 12:43:55 +02:00
Julius Gruber
41daaa34ad Code clean up 2019-10-18 12:43:02 +02:00
Kristof De Langhe
ef3d4fb154 Merge branch 'w2p-65572_Add-support-for-bundles' into w2p-65717_Bundles-in-edit-item 2019-10-18 12:42:34 +02:00
Kristof De Langhe
5fa2827d1b Merge branch 'master' into w2p-65717_Bundles-in-edit-item
Conflicts:
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/core/core.module.ts
	src/app/core/data/item-data.service.ts
	src/app/shared/shared.module.ts
2019-10-18 12:42:11 +02:00
Julius Gruber
764546e4d5 Code clean up 2019-10-18 12:41:42 +02:00
Julius Gruber
e9abafb141 Code clean up 2019-10-18 12:41:03 +02:00
Julius Gruber
64a396a00f Code clean up 2019-10-18 12:40:19 +02:00
Julius Gruber
9741fbe9f6 Code clean up 2019-10-18 12:38:14 +02:00
Julius Gruber
eb099e588c Removed dev stub from config environment.default.js 2019-10-18 12:33:29 +02:00
Julius Gruber
0aac997238 Removed dev console logs 2019-10-18 11:40:08 +02:00
Julius Gruber
94539cd61d Code clean up 2019-10-18 11:37:38 +02:00
Kristof De Langhe
1fafc3a5d5 65240: Additional tests 2019-10-18 10:35:25 +02:00
Julius Gruber
ac32d2de11 Added storage of redirectUrl in a cookie 2019-10-18 10:20:18 +02:00
Julius Gruber
8ea2b79edf Testing local storage of redirectURL 2019-10-18 09:50:37 +02:00
Julius Gruber
8d939cd35c Shared module import fixed 2019-10-18 09:12:15 +02:00
Julius Gruber
8fbe6ade81 Merge conflicts resolved 2019-10-18 09:11:22 +02:00
Julius Gruber
792f7bf74d Removed isStandAlone from store 2019-10-18 08:58:36 +02:00
Michael W Spalti
6b26506d88 Added matcher function to router that supports handle paths (eliminates the need to encode the forward slash).
Fixed comment.
2019-10-17 15:08:35 -07:00
Kristof De Langhe
c7bb6ab17c 65240: ComCol logo delete on bitstreams endpoint + caching issue fixes when editing logos 2019-10-17 17:59:18 +02:00
lotte
ae6a6f28f7 added new submission list component for persons 2019-10-17 16:37:55 +02:00
Julius Gruber
392b539036 Removed model InjectedAuthMethods 2019-10-17 15:46:55 +02:00
Julius Gruber
6a2b9dad26 Added Action to set isStandAlonePage in store 2019-10-17 15:39:33 +02:00
lotte
99517c084c fixed issues after merge 2019-10-17 13:57:10 +02:00
lotte
bc358ec954 Merge branch 'master' into w2p-65195_dynamic-component-refactoring 2019-10-17 12:49:50 +02:00
lotte
f79e210959 Merge branch 'w2p-65195_dynamic-component-refactoring' into clean-relationships-in-submission 2019-10-17 12:49:22 +02:00
Art Lowel
bf5fb417e1 Merge pull request #472 from lhenze/460-coll-pages
Collections pages: add collection header and footer to all "browse by..." views
2019-10-17 12:38:01 +02:00
lotte
6d253be878 Fix for search parameters 2019-10-17 10:19:12 +02:00
lotte
44228c3839 fixed tests for demo 2019-10-17 10:18:33 +02:00
Michael W Spalti
e38556e821 Updated unit test. 2019-10-16 23:42:36 -07:00
Michael W Spalti
b695da8487 Encoding removed. 2019-10-16 23:39:47 -07:00
Michael W Spalti
85d179e27f Bugfix for request by handle (removed unnecessary encoding) 2019-10-16 13:18:03 -07:00
Michael W Spalti
2d49f3e765 Added unit test for isCachedOrPending lookup by id (FindByIdRequest). 2019-10-16 13:18:03 -07:00
Michael W Spalti
5e40d7a4c1 Fixed lint errors. 2019-10-16 13:18:03 -07:00
Michael W Spalti
2aaab83427 Added unit tests. 2019-10-16 13:18:03 -07:00
Michael W Spalti
a1d21cd6af Minor change to comment. 2019-10-16 13:18:03 -07:00
Michael W Spalti
5ec9b7c29f Added new unit tests. 2019-10-16 13:18:03 -07:00
Michael W Spalti
efc91a4591 Updated work on routing by id.
Fixed unit tests.

Updated to use pid REST endpoint.

Minor change in data.service and unit test update.

Updated the objectnotfound page with new text and go home button.
2019-10-16 13:18:03 -07:00
lotte
ddbe0c825a fixed test issue 2019-10-16 16:32:22 +02:00
lotte
437dce9b15 Merge branch 'master' into w2p-65195_dynamic-component-refactoring 2019-10-16 15:48:39 +02:00
Julius Gruber
8fde909915 Changed log-in.comonent to use observables again 2019-10-16 15:33:18 +02:00
lotte
ac851f3812 renaming fixes, new tests 2019-10-16 14:48:17 +02:00
Julius Gruber
94377487b7 Another testserver log 2019-10-16 13:41:51 +02:00
Julius Gruber
a59aafb1f4 Commit for server test 2019-10-16 13:14:24 +02:00
lotte
d962e40c58 added TypeDoc 2019-10-16 11:21:25 +02:00
Julius Gruber
331596968b Added log for injectedAuthMethods on testserver 2019-10-16 10:41:19 +02:00
Julius Gruber
26fd261d17 Added more debug logs for testserver 2019-10-16 10:08:49 +02:00
Michael W Spalti
ef4ae44898 Added forceBypassCache property to request model. 2019-10-15 14:42:38 -07:00
Michael W Spalti
4b03f76db2 Setting responseMsToLive to zero for SubmissionRequest. 2019-10-15 14:42:38 -07:00
Art Lowel
040692455e increased responseMsToLive from 0 to 10s, to prevent infinite loops 2019-10-15 14:42:38 -07:00
Art Lowel
70a5e271f4 ensure object cache uses responseMsToLive from request 2019-10-15 14:40:39 -07:00
Michael W Spalti
2475de726f Tentative fix for the mydspace submission requests. 2019-10-15 14:40:39 -07:00
Michael W Spalti
255e17b1a9 Removed a missed forcedBypassCache property. 2019-10-15 14:40:39 -07:00
Michael W Spalti
5c2b7767ed Renamed cache property and replaced conditional with hasValue. 2019-10-15 14:40:39 -07:00
Michael W Spalti
2d9fdef974 Explicitly checking for undefined in dataService (since I think 0 is not truthy for number). 2019-10-15 14:40:11 -07:00
Michael W Spalti
934f5a1bd0 Sets responseMsToLive to zero in some dataService methods and adds ability to reset the responseMsToLive value in subclasses. 2019-10-15 14:38:52 -07:00
Michael W Spalti
fbcffd8097 Fixes unit test and problem in map fuction. 2019-10-15 14:38:00 -07:00
Michael W Spalti
34defdc5cd Setting cache period to zero for all instances where forceBypassCache was previously true. 2019-10-15 14:36:41 -07:00
Michael W Spalti
121e564e12 Refactored to remove forceBypassCache param from requestService and from data service classes. 2019-10-15 14:33:33 -07:00
Michael W Spalti
7bda63bc5a Renamed cache property and replaced conditional with hasValue. 2019-10-15 14:26:50 -07:00
Michael W Spalti
8ae5e415db Explicitly checking for undefined in dataService (since I think 0 is not truthy for number). 2019-10-15 14:26:49 -07:00
Michael W Spalti
2a1c85937c Fixed unit test that was missing from project before rebase. 2019-10-15 14:26:49 -07:00
Michael W Spalti
a50e568899 Sets responseMsToLive to zero in some dataService methods and adds ability to reset the responseMsToLive value in subclasses. 2019-10-15 14:26:49 -07:00
Michael W Spalti
d449bd70a0 Fixes unit test and problem in map fuction. 2019-10-15 14:26:49 -07:00
Michael W Spalti
6e3127c3a6 Setting cache period to zero for all instances where forceBypassCache was previously true. 2019-10-15 14:26:49 -07:00
Michael W Spalti
d2897cec3f Removed final reference to forceBypassCache param. 2019-10-15 14:26:49 -07:00
Michael W Spalti
96f8e905dd Refactored to remove forceBypassCache param from requestService and from data service classes. 2019-10-15 14:26:49 -07:00
L. Henze
150aace38e Page title - only show if there is no parent 2019-10-15 13:47:51 -04:00
L. Henze
b7b8eed6db *ngIf broken into two parts 2019-10-15 12:38:22 -04:00
L. Henze
8f2a942536 Merge branch 'master' into 460-coll-pages 2019-10-15 10:57:35 -04:00
lotte
7ca88021c9 added tests, aot fixes, lint fixes 2019-10-15 15:58:40 +02:00
Julius Gruber
6718bfdcfe Code clean up 2019-10-15 15:14:36 +02:00
Kristof De Langhe
f1b4b57cdb 65529: AoT build error fixes 2019-10-15 13:58:03 +02:00
Julius Gruber
909b47425f Added logs for testserver 2019-10-14 16:29:06 +02:00
lotte
bafb2f3490 fixed existing tests and added linkType 2019-10-14 16:27:08 +02:00
Julius Gruber
c9f92ee7a8 Moved isAuthenticated and isLoading to container 2019-10-14 16:21:35 +02:00
Kristof De Langhe
61d757493a 65572: Support for bundles on items 2019-10-14 13:39:29 +02:00
Michael W Spalti
a7f48865ea Added forceBypassCache property to request model. 2019-10-10 16:25:00 -07:00
Michael W Spalti
03a91adfab Setting responseMsToLive to zero for SubmissionRequest. 2019-10-10 15:53:52 -07:00
Tim Donohue
896462ff10 Merge pull request #348 from atmire/Item-Collection_Mapper
Item-Collection mapper
2019-10-10 11:38:24 -05:00
lotte
dfe1143184 metadata representation 2019-10-10 16:18:14 +02:00
Kristof De Langhe
f7bd30cf12 62589: Item-Mapper Requests responseMsToLive to 10s 2019-10-10 13:39:59 +02:00
Kristof De Langhe
98cd2aa84c 65529: Revert OrgUnit list changes on publication 2019-10-10 10:12:28 +02:00
Kristof De Langhe
7f50d7b23d 65529: ItemMetadataRepresentation using the virtual metadata value to display names 2019-10-09 17:08:59 +02:00
L. Henze
46b86ec6c7 Desktop view: also using allOptions array, and tidying 2019-10-08 12:52:10 -04:00
L. Henze
c46480c97f from @art-lowel: update onSelectChange to work with ngModel
Because we're working with ngModel, we're no longer getting a generic JS event in the onSelectChange, but simply the id of the selected option. I use that Id to find the option in the allOptions array that matches, and then use the data inside that matching option to navigate to the correct page.
2019-10-08 12:40:57 -04:00
L. Henze
be19a2a961 from @art-lowel: set ngModel for select, and also selected attribute for options
That currentOptionId$ observable is then used in the template to set the ngModel for the select, which, as mentioned above, should have been enough to select the correct option, but as it wasn't I also use it to set the selected attribute on the options
2019-10-08 12:38:01 -04:00
L. Henze
c957031317 from @art-lowel: Observable for currentOptionId
Next in order to know what page we're on, I use the route.url observable angular provides us that contains the current url, pipe that through a filter to ensure it has a value for the map below, which will just get the last part of the current url, so the community or collection id, or the type of the browse page.
2019-10-08 12:32:40 -04:00
L. Henze
3d8ffd6fe3 from @art-lowel: create array and map all options to it
I created a list in the component that contains all the possible values a button or an option in the select can have, that way we can get rid of those *ngIfs in the template, and render everything with an *ngFor
Instead of putting all the data needed to select an option and to redirect to the correct option in the template, I created an interface to represent all the info we need: ComColPageNavOption
During ngOnInit, I first take the browseBy types in the config, and perform a map operation on them, that basically means, turn every element of this array in to something else using the function inside the map operator.
So inside the map function I each BrowseByTypeConfig object in to a ComColPageNavOption object
Afterwards I check whether we're dealing with a collection or a community, and in each case I create a ComColPageNavOption object, and add it to the front of the allOptions array
...this.allOptions means enumerate everything that's currently in the allOptions array, so I put my new object first, then enumerate everything that was already there, and assign the result again to this.allOptions
2019-10-08 12:15:25 -04:00
Julius Gruber
a6ae487ebe Changed log-in-password.component to use injectedAuthModel 2019-10-08 17:17:57 +02:00
Julius Gruber
cc8a3c2dc1 Removed isStandalonePage property from AuthMethodModel class 2019-10-08 16:58:55 +02:00
L. Henze
61edfea1de Merge branch 'master' into 460-coll-pages 2019-10-08 10:47:30 -04:00
Julius Gruber
593018021d Code clean up 2019-10-08 16:39:19 +02:00
Julius Gruber
f9d9ca6191 Removed some failing tests 2019-10-08 16:12:17 +02:00
Julius Gruber
71fbf28984 Boolean isStandalonePage injected 2019-10-08 16:00:24 +02:00
lotte
0fb12c4274 refactored mydspace/listelements etc 2019-10-08 15:51:31 +02:00
Kristof De Langhe
e7b72d6df7 Merge branch 'master' into w2p-64574_Item-page-entities
Conflicts:
	src/app/core/data/relationship.service.spec.ts
2019-10-08 13:40:28 +02:00
Kristof De Langhe
5b776b605a 62589: Review 03-10-2019 Changes and fixes 2019-10-08 13:06:31 +02:00
Julius Gruber
43933771c0 Added english translation for Shibboleth login button 2019-10-08 10:42:37 +02:00
Julius Gruber
da7b7f92a0 Changed selector of ds-auth-methods 2019-10-08 10:33:21 +02:00
Julius Gruber
95239e0590 upToDate - ready to be worked on 2019-10-08 10:13:46 +02:00
Julius Gruber
46878a7875 Branch update merge 2019-10-08 09:44:37 +02:00
Art Lowel
254b7d1633 increased responseMsToLive from 0 to 10s, to prevent infinite loops 2019-10-07 15:35:19 +02:00
Art Lowel
4836fd9ec8 ensure object cache uses responseMsToLive from request 2019-10-07 15:27:45 +02:00
Kristof De Langhe
bfb2ef021a 65240: AoT build error fixes 2019-10-07 14:05:54 +02:00
Kristof De Langhe
d45b4eedfd Merge branch 'w2p-63669_Edit-Col/Com-Tabs' into w2p-65240_Community-and-collection-logos 2019-10-07 13:43:39 +02:00
Kristof De Langhe
c9ea990483 63669: Hide return button on community metadata edit 2019-10-07 13:43:26 +02:00
Kristof De Langhe
0cd8a4ebcd Merge branch 'w2p-63669_Edit-Col/Com-Tabs' into w2p-65240_Community-and-collection-logos
Conflicts:
	resources/i18n/en.json5
	src/app/+collection-page/edit-collection-page/edit-collection-page.component.html
	src/app/+collection-page/edit-collection-page/edit-collection-page.component.spec.ts
	src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts
	src/app/+community-page/edit-community-page/edit-community-page.component.html
	src/app/+community-page/edit-community-page/edit-community-page.component.spec.ts
	src/app/+community-page/edit-community-page/edit-community-page.component.ts
	src/app/shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.spec.ts
	src/app/shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.ts
2019-10-07 13:39:53 +02:00
Tim Donohue
1508d6133d Merge pull request #493 from terrywbrady/ds4346V2
[DS-4346] V2: create docker compose files in code base
2019-10-04 19:37:43 +02:00
Tim Donohue
f114897661 Minor updates/corrections to README 2019-10-04 12:08:30 -05:00
lotte
a1f144aa0b replaced type input by getRenderType method 2019-10-04 16:06:59 +02:00
Kristof De Langhe
ac68893f6e 63669: Test fix 2019-10-04 15:47:52 +02:00
Kristof De Langhe
03db2a084b Merge branch 'master' into w2p-63669_Edit-Col/Com-Tabs 2019-10-04 14:51:23 +02:00
Michael W Spalti
604e99eee4 Tentative fix for the mydspace submission requests. 2019-10-03 16:37:52 -07:00
Michael W Spalti
0e75ef8c12 Removed a missed forcedBypassCache property. 2019-10-03 11:50:50 -07:00
Michael W Spalti
c1f7d39290 Renamed cache property and replaced conditional with hasValue. 2019-10-03 11:50:50 -07:00
Michael W Spalti
dc4becee0c Explicitly checking for undefined in dataService (since I think 0 is not truthy for number). 2019-10-03 11:50:50 -07:00
Michael W Spalti
e6e9530b3f Fixed unit test that was missing from project before rebase. 2019-10-03 11:50:50 -07:00
Michael W Spalti
0b6963aea1 Sets responseMsToLive to zero in some dataService methods and adds ability to reset the responseMsToLive value in subclasses. 2019-10-03 11:50:50 -07:00
Michael W Spalti
ac95a8b8d6 Fixes unit test and problem in map fuction. 2019-10-03 11:50:50 -07:00
Michael W Spalti
2988146d59 Setting cache period to zero for all instances where forceBypassCache was previously true. 2019-10-03 11:50:50 -07:00
Michael W Spalti
6cf8cc5fbe Removed final reference to forceBypassCache param. 2019-10-03 11:50:50 -07:00
Michael W Spalti
1b48d3d1f6 Refactored to remove forceBypassCache param from requestService and from data service classes. 2019-10-03 11:50:50 -07:00
Tim Donohue
262b33261e Merge pull request #494 from atmire/Changes-to-relationship-type-fix
Small bug-fix due to changes to relationship-type
2019-10-03 19:18:29 +02:00
lotte
9badabade6 Split typed list/grid elements into normal and search result 2019-10-03 16:26:58 +02:00
Kristof De Langhe
556475318d Fixed remaining left/right-labels 2019-10-03 15:22:45 +02:00
Kristof De Langhe
a1fea1d6a2 leftLabel/rightLabel renaming to leftwardType/rightwardType in test case 2019-10-03 14:53:00 +02:00
Kristof De Langhe
e10a5bb8f8 63669: Hide return button for metadata edit on com/col 2019-10-03 14:39:46 +02:00
Kristof De Langhe
36d3ddd691 leftLabel/rightLabel renaming to leftwardType/rightwardType 2019-10-03 13:55:57 +02:00
Kristof De Langhe
97de2b8ef3 Merge branch 'master' into w2p-63669_Edit-Col/Com-Tabs
Conflicts:
	resources/i18n/en.json
	src/app/shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.spec.ts
	src/app/shared/shared.module.ts
2019-10-03 13:46:11 +02:00
benbosman
b85c76f40e Merge pull request #461 from atmire/changes-to-relationship-type
Rename relationship type properties
2019-10-02 18:23:04 +02:00
lotte
5b6aa951ad continued refactoring listable objects 2019-10-02 15:43:19 +02:00
Kristof De Langhe
37a18fdaa7 65240: Success notification on submitting comcol form 2019-10-02 13:40:06 +02:00
Kristof De Langhe
8a475f2523 65240: comcol form logo tests 2019-10-02 13:04:15 +02:00
Kristof De Langhe
f3a032470d 65240: Fixed current tests 2019-10-02 10:19:21 +02:00
Terry Brady
e4bab45f3c correct path in README 2019-10-01 23:47:01 -07:00
Terry Brady
f8961d7647 readme update 2019-10-01 23:32:45 -07:00
Terry Brady
dc47d191ec move all compose files to one dir 2019-10-01 23:30:26 -07:00
Terry Brady
a74f256cea refine startup instructions 2019-10-01 22:52:44 -07:00
Terry Brady
292f7ddd25 Add pull vs build instructions to README 2019-10-01 15:38:19 -07:00
Michael W Spalti
b89e57a1a6 Added unit test for isCachedOrPending lookup by id (FindByIdRequest). 2019-10-01 12:25:41 -07:00
Terry Brady
f85d4fa033 Add README for Docker 2019-10-01 10:31:07 -07:00
lhenze
d4d4a6121e Mobile view: adding select element for navigation 2019-10-01 12:12:50 -04:00
lhenze
39aa284310 Merge branch 'master' into 460-coll-pages 2019-10-01 12:09:15 -04:00
Kristof De Langhe
eade3e7d37 65240: Set uploader method to PUT if object already contains a logo 2019-10-01 16:53:21 +02:00
Kristof De Langhe
ecef1b35d1 65240: Delete logo button and service method 2019-10-01 16:12:08 +02:00
Kristof De Langhe
ed91e96d42 65240: Message cleanup 2019-10-01 15:26:09 +02:00
Kristof De Langhe
a2695edbac 65240: Add community/collection logo on create/edit pages 2019-10-01 14:42:25 +02:00
Michael W Spalti
dd817c9159 Fixed lint errors. 2019-10-01 03:38:56 -07:00
Michael W Spalti
24be6c1544 Added unit tests. 2019-10-01 03:03:08 -07:00
Michael W Spalti
8fe37eeaf7 Minor change to comment. 2019-10-01 01:06:12 -07:00
Michael W Spalti
e41b3083aa Added new unit tests. 2019-09-30 16:57:06 -07:00
Terry Brady
c6d2cb66c7 refactor docker compse names 2019-09-30 10:45:45 -07:00
Kristof De Langhe
8652c4bce8 62589: Fixed test imports 2019-09-30 16:37:44 +02:00
Kristof De Langhe
b8a466d12b 62589: Loading components for item and collection select lists 2019-09-30 16:17:18 +02:00
Kristof De Langhe
3c8e35e4d2 Merge branch 'master' into w2p-62589_Item-mapper-update 2019-09-30 10:37:02 +02:00
Kristof De Langhe
a2fb8a316b 62589: Added tests for more coverage 2019-09-30 10:35:52 +02:00
Terry Brady
eca35851d3 match network name 2019-09-29 11:58:50 -07:00
Terry Brady
824289cde1 fix compose file 2019-09-29 11:19:56 -07:00
Terry Brady
c060099ff8 run angular on its own 2019-09-29 10:44:42 -07:00
Michael W Spalti
6bf086b707 Updated work on routing by id.
Fixed unit tests.

Updated to use pid REST endpoint.

Minor change in data.service and unit test update.

Updated the objectnotfound page with new text and go home button.
2019-09-27 11:26:19 -07:00
Tim Donohue
2789996000 Merge pull request #486 from atmire/add-header-icon-color-variable
Add header icon color variable
2019-09-27 20:20:24 +02:00
lotte
5353e889a3 added new decorator for metadata representations 2019-09-27 16:58:24 +02:00
Kristof De Langhe
145ed346c8 62589: Feedback improvements and fixes 2019-09-27 16:40:47 +02:00
Kristof De Langhe
f83e31a1a2 Merge remote-tracking branch 'dspace/master' into w2p-62589_Item-mapper-update
Conflicts:
	src/app/core/data/collection-data.service.ts
2019-09-27 15:33:02 +02:00
Art Lowel
e68cbcd28c add header icon color variable and add !default to all themeable
variables
2019-09-27 14:57:07 +02:00
lotte
20274bd4af refactored ItemViewMode to be part of ViewMode and added the Context enum 2019-09-27 13:19:26 +02:00
lotte
e584489eaf 65195: removed duplicate view mode, renamed existing modes from SetViewMode 2019-09-27 11:22:55 +02:00
Tim Donohue
eea250664d Merge pull request #432 from 4Science/submission-miscellaneous-fixes
Submission miscellaneous fixes
2019-09-26 23:22:42 +02:00
Art Lowel
69a0ae8722 Merge pull request #491 from paulo-graca/patch-1
Remove duplicated "SearchFilterService"
2019-09-26 11:36:40 +02:00
Paulo Graça
ef832d34dc Remove duplicated "SearchFilterService" 2019-09-26 10:04:21 +01:00
Terry Brady
5dfc2fffca fix compose file 2019-09-25 15:09:36 -07:00
Terry Brady
71287b6b41 travis troubleshooting 2019-09-25 15:03:46 -07:00
Terry Brady
dfcb5abd49 change path to component compose files 2019-09-25 14:56:57 -07:00
Kristof De Langhe
1bb3bb6626 64961: Test and naming fixes 2019-09-25 17:44:15 +02:00
Kristof De Langhe
f81de8ad0e 64961: Proper loading of edit-bitstream page 2019-09-25 17:02:38 +02:00
Kristof De Langhe
16223dfedc 64961: Edit bitstream observable fixes 2019-09-25 16:12:44 +02:00
Terry Brady
314c33b011 reference compose files in travis.yml 2019-09-23 16:56:07 -07:00
Terry Brady
05d85c2d18 create docker compose files in code base 2019-09-23 14:32:57 -07:00
L. Henze
e992dde287 Handle component: UIURLCombiner 2019-09-23 15:50:47 -04:00
L. Henze
4f6b81ea9f CSS update: In mobile, long URL breaks layout 2019-09-23 13:17:54 -04:00
L. Henze
2aaa0cf726 Comcol Handle component 2019-09-23 12:43:00 -04:00
L. Henze
948fa5cfee Moving margins to a bootstrap class attribute 2019-09-23 12:40:05 -04:00
Kristof De Langhe
f152cad1fa 64961: server-sync-buffer bugfix, data-service update revert changes + edit-bitstream onSubmit refactoring 2019-09-20 15:24:24 +02:00
Julius Gruber
8936b96a25 Code clean up 2019-09-20 14:19:09 +02:00
Julius Gruber
1a703af9cb Code cleanup 2019-09-20 13:36:58 +02:00
Julius Gruber
9844e9eff7 Prototype ready 2019-09-20 11:41:01 +02:00
L. Henze
cf980dfb47 Building handle using GLOBAL_CONFIG 2019-09-19 15:57:00 -04:00
L. Henze
2c904f7e39 Merge branch 'master' into 460-coll-pages 2019-09-19 15:15:42 -04:00
Tim Donohue
d85cc0a0f2 Merge pull request #467 from mspalti/login_redirect_url
Redirecting user to same page after login.
2019-09-19 17:30:00 +02:00
Kristof De Langhe
a87dc89ff1 Merge branch 'master' into w2p-62589_Item-mapper-update
Conflicts:
	resources/i18n/en.json5
2019-09-19 17:29:32 +02:00
Kristof De Langhe
4357c19cad 64961: Update format before sending out patch requests 2019-09-19 17:25:54 +02:00
Kristof De Langhe
0798701019 64961: Return to last page on cancel, description 10 rows, renaming Other Format and Submit 2019-09-19 17:00:12 +02:00
Julius Gruber
52ef2acb08 Requested changes implemented - basic functionality working 2019-09-19 13:43:36 +02:00
L. Henze
300aeb435e Some visual / layout improvements 2019-09-18 17:42:20 -04:00
L. Henze
b91220368c Alternate default text 2019-09-18 16:37:58 -04:00
Michael W Spalti
ca048736b5 Removed unnecessary import in unit test. 2019-09-18 12:13:41 -07:00
L. Henze
7f3152b21a Copyright is already in the footer 2019-09-18 14:53:54 -04:00
L. Henze
6525516538 Whitespace only 2019-09-18 14:53:36 -04:00
L. Henze
ba133084c8 Section wrapper fix 2019-09-18 14:53:08 -04:00
L. Henze
6aee498d29 Only one set of wrappers needed to define parentContext 2019-09-18 14:49:13 -04:00
L. Henze
f4a1d5eb8a Header, section, and footer consistently 2019-09-18 14:42:44 -04:00
L. Henze
3d82a47e0b Nesting error 2019-09-18 14:28:26 -04:00
L. Henze
3c03ec8ede License not used 2019-09-18 14:20:46 -04:00
L. Henze
ea55e7333e Browse nav out of header 2019-09-18 14:13:56 -04:00
L. Henze
471ec25a58 Margins not needed here 2019-09-18 14:13:42 -04:00
L. Henze
e56def92fd h3 is not visible, so width not needed 2019-09-18 14:13:13 -04:00
L. Henze
d87f1777f9 Reducing unnecessary wrapper divs 2019-09-18 14:12:25 -04:00
L. Henze
4d6e57337b Browse pages' browse sections' header hidden visually
Remains for screenreaders
2019-09-18 13:50:30 -04:00
L. Henze
8cec08b29f 118n keys 2019-09-18 13:41:32 -04:00
Michael W Spalti
73dd0147bc Minor update of the imports in unit test. 2019-09-18 10:37:12 -07:00
L. Henze
5341beae1e Merge branch '460-coll-pages-revisions' into 460-coll-pages 2019-09-18 13:20:07 -04:00
L. Henze
e854fb85e5 Merge branch 'master' into 460-coll-pages 2019-09-18 13:09:14 -04:00
L. Henze
4a77dec870 Fixing some work that was rolled back 2019-09-17 17:38:46 -04:00
L. Henze
6b55f94405 Update comcol-page-browse-by.component.ts 2019-09-17 17:29:37 -04:00
L. Henze
af3005c863 wip 2019-09-17 17:19:34 -04:00
L. Henze
01212750bf handle component 2019-09-17 17:08:09 -04:00
Michael W Spalti
e70b9c5994 Added new auth redirect code for ssr. 2019-09-17 12:44:02 -07:00
Kristof De Langhe
e76579ee00 Merge branch 'master' into w2p-64961_Edit-bitstream-page
Conflicts:
	resources/i18n/en.json5
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/core/data/item-data.service.ts
	src/app/shared/shared.module.ts
2019-09-17 15:38:02 +02:00
Kristof De Langhe
a56d551ef1 94961: Edit-bitstream loading message, error notifications and AoT fixes 2019-09-17 15:31:54 +02:00
Kristof De Langhe
fa1b1ad886 64961: edit-bitstream tests 2019-09-17 13:48:39 +02:00
Kristof De Langhe
3c3cff4398 64961: UUID filtering on compare + formToBitstream refactoring 2019-09-17 11:10:07 +02:00
Art Lowel
5917d92a07 Merge pull request #484 from atmire/fix-CVE-2019-10747
Update set-value to fix CVE-2019-10747
2019-09-17 10:33:06 +02:00
L. Henze
65ae16b70b Merge branch 'master' into 460-coll-pages 2019-09-16 16:39:28 -04:00
Michael W Spalti
8fe617bd74 Changed method name. 2019-09-16 13:14:45 -07:00
Tim Donohue
6ae9efde59 Merge pull request #477 from atmire/64644-Removal-of-filtered-discovery-page
Removal of filtered-discovery-page in Angular
2019-09-16 19:08:21 +02:00
Tim Donohue
f429483c93 Merge pull request #479 from terrywbrady/compose-v2
Use the improved DSpace Docker Compose files to create the ci image
2019-09-16 19:06:52 +02:00
Art Lowel
d088f0a504 update set-value to fix CVE-2019-10747 2019-09-16 18:35:17 +02:00
Art Lowel
b4d5bff1e6 update set-value to fix CVE-2019-10747 2019-09-16 18:28:40 +02:00
L. Henze
afc38dbff5 Merge branch 'master' into 460-coll-pages 2019-09-16 12:11:27 -04:00
Art Lowel
f45bc3124a Merge pull request #483 from DSpace/dependabot/npm_and_yarn/mixin-deep-1.3.2
Bump mixin-deep from 1.3.1 to 1.3.2
2019-09-16 18:06:51 +02:00
Kristof De Langhe
4157844178 64961: Fixed jumping of layout on hiding other-format 2019-09-16 17:45:36 +02:00
dependabot[bot]
95005ef110 Bump mixin-deep from 1.3.1 to 1.3.2
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-09-16 15:36:17 +00:00
Kristof De Langhe
43c329988a 64961: Add Other Format as dc.format 2019-09-16 17:33:46 +02:00
Art Lowel
5fd8a12489 Merge pull request #439 from atmire/improve-i18n-files
Convert i18n files to JSON5 format
2019-09-16 17:28:41 +02:00
Kristof De Langhe
358a6522c0 64961: Update bitstream format 2019-09-16 17:01:03 +02:00
Art Lowel
ed958c1232 Merge branch 'master' into improve-i18n-files 2019-09-16 16:57:17 +02:00
Giuseppe Digilio
95d1495397 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes 2019-09-16 16:36:52 +02:00
Tim Donohue
8ffd44f1ed Merge pull request #480 from atmire/upgrade-travis-image
Fix travis chrome install issue
2019-09-16 16:16:07 +02:00
Kristof De Langhe
647bfb4e0d 62589: Import fix 2019-09-16 14:06:54 +02:00
Kristof De Langhe
4f6c3c0a9b Merge branch 'master' into w2p-62589_Item-mapper-update
Conflicts:
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts
	src/app/+item-page/item-page.module.ts
	src/app/core/data/item-data.service.ts
	src/app/shared/shared.module.ts
2019-09-16 13:36:42 +02:00
Kristof De Langhe
683c19bfbe Merge remote-tracking branch 'atmire/upgrade-travis-image' into w2p-62589_Item-mapper-update 2019-09-16 11:30:39 +02:00
Kristof De Langhe
6230fef6b9 64961: Intermediate commit 2019-09-16 11:29:44 +02:00
Art Lowel
7d947291e4 add dpkg to prevent chrome install issues 2019-09-16 11:04:35 +02:00
Giuseppe Digilio
25c6491962 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes 2019-09-16 10:02:00 +02:00
helix84
6c0aaa7bee Update cs.json5 2019-09-16 08:28:56 +02:00
Tim Donohue
ef8f857fe8 Merge pull request #335 from atmire/Move-item-component
Move item component
2019-09-13 18:14:17 +02:00
Giuseppe Digilio
0b878af92a Fix issue with find operator on SSR 2019-09-13 17:38:12 +02:00
Giuseppe Digilio
4cc7432e91 Print error message when error occurred on SSR 2019-09-13 17:37:08 +02:00
Giuseppe Digilio
aea83ed662 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes 2019-09-13 17:26:16 +02:00
Kristof De Langhe
a00ceb3da5 64961: Edit bitstream - format inputs 2019-09-13 17:09:08 +02:00
Kristof De Langhe
1d3ada20f9 64961: Edit bitstream metadata PATCH requests 2019-09-13 14:39:40 +02:00
Kristof De Langhe
91c6b76230 64961: Edit bitstream page foundations 2019-09-12 17:49:45 +02:00
Art Lowel
154fc83930 fix typo 2019-09-12 17:14:19 +02:00
Art Lowel
b186ec635e Merge branch 'master' into improve-i18n-files 2019-09-12 17:13:43 +02:00
Kristof De Langhe
a1ac80e53a Merge branch 'master' into w2p-64961_Edit-bitstream-page
Conflicts:
	src/app/+item-page/edit-item-page/abstract-item-update/abstract-item-update.component.ts
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.ts
	src/app/app-routing.module.ts
	src/app/shared/shared.module.ts
2019-09-12 13:21:08 +02:00
Julius Gruber
62cbba5982 Added config to shibboleth component 2019-09-11 17:42:38 +02:00
Kristof De Langhe
1b0b1d7797 62589: Fixed import 2019-09-11 10:44:03 +02:00
Kristof De Langhe
8b5a3ac9b3 Merge branch 'master' of https://git.atmire.com/contributions/dspace-angular into w2p-62589_Item-mapper-update 2019-09-11 10:09:35 +02:00
Kristof De Langhe
02b007a0f6 62589: Exclude owning collection + redirect to first tab after mapping + page reload fix 2019-09-10 16:29:15 +02:00
Ben Bosman
da0b70faa4 Merge remote-tracking branch 'atmire-git/w2p-64644_Removal-of-filtered-discovery-page' into 64644-Removal-of-filtered-discovery-page 2019-09-10 12:38:24 +02:00
Ben Bosman
4c5d4427dc Merge remote-tracking branch 'atmire-git/64644-Removal-of-filtered-discovery-page' into 64644-Removal-of-filtered-discovery-page 2019-09-10 09:24:44 +02:00
Michael W Spalti
6425f6e7d1 Removed the router injection that slipped into auth service during rebase, test now passes. 2019-09-09 13:33:51 -07:00
Michael W Spalti
c3102b9d43 A little cleanup in unit tests. 2019-09-09 12:58:55 -07:00
Michael W Spalti
d9fb68dce9 Modified redirectToPreviousUrl to use the standalone page parameter if no redirect url is found in the store.
Removed unused import that was causing merge conflict.

Once again try to fix merge conflict.

Added routeService to server module providers.

Changed order of providers.

Minor change to ServerAuthService to make method signature consistent with AuthService.

Try adding RouteService to browser-app module to see if that fixes travis build.

One more try at getting the CI build to work.

Removed change to browser module.
2019-09-09 12:58:55 -07:00
Michael W Spalti
0935bd4afd Proposed authentication service method that sets redirect url and dispatches auth request. 2019-09-09 12:55:31 -07:00
Michael W Spalti
f0813fcbc1 Added @Input to the log-in component that indicates whether the component is being used in the standalone login page or the drop-down. 2019-09-09 12:39:04 -07:00
Michael W Spalti
54fc57d1f3 Modified mobile log-in to use history as provided by the store.
Minor typedoc and import updates.
2019-09-09 12:39:04 -07:00
Michael W Spalti
fcaf01807c Modifed log-in component to use LOGIN_ROUTE when setting the redirect url.
Also added check for mobile layout that forces setting of the redirect url.
2019-09-09 12:39:04 -07:00
Michael W Spalti
c6156c5cbe Modified log-in component to set the redirect url only if one has not been set already. 2019-09-09 12:39:04 -07:00
Michael W Spalti
db326a706c Fixed the unit test (and added a typedoc) 2019-09-09 12:39:04 -07:00
Michael W Spalti
6360d5a88c Modified the log-in component to set the redirectUrl in AuthState (so the user is returned to the same page after login). 2019-09-09 12:39:04 -07:00
Yana De Pauw
ee760908c5 Merge branch 'master' into w2p-64644_Removal-of-filtered-discovery-page 2019-09-09 18:26:01 +02:00
Yana De Pauw
5553d046ce 64644: Remove empty line to fix lint error 2019-09-09 17:37:14 +02:00
Yana De Pauw
ee76c256f8 Merge branch 'master' into Move-item-component 2019-09-09 11:06:16 +02:00
lhenze
9e8dd6f349 Adding Var Directive to tests as needed 2019-09-08 21:38:08 -04:00
Terry Brady
754abdd2ec correct data load script 2019-09-06 20:32:11 -07:00
Terry Brady
0b1bc9fe65 Use v2 compose files 2019-09-06 20:27:44 -07:00
lhenze
1099c42eb1 Merge branch 'master' into 460-coll-pages 2019-09-06 16:10:23 -04:00
Art Lowel
80706b9f61 Merge pull request #437 from atmire/w2p-62355_optimize-search-performance
Search performance optimisations #2
2019-09-06 16:35:45 +02:00
Tim Donohue
3c9fdec8dd Merge pull request #466 from terrywbrady/travis-docker
Start Docker Compose for end-to-end (e2e) Testing
2019-09-06 16:12:48 +02:00
lotte
e518380025 fixed import issues 2019-09-06 16:07:37 +02:00
Tim Donohue
ddd1bb42cf Spelling fixes 2019-09-06 08:38:48 -05:00
Tim Donohue
56c479f73d Merge pull request #476 from Flusspferd123/spellingMistake
Typo in dropdown-field-parser.ts fixed
2019-09-06 15:36:31 +02:00
Art Lowel
af3cc28f43 Merge pull request #478 from atmire/Clean-build-folder-pretest
Clean build folder pre-tests
2019-09-06 15:36:08 +02:00
lotte
2b24caba34 Merge branch 'master' into w2p-62355_optimize-search-performance 2019-09-06 15:22:44 +02:00
Kristof De Langhe
bf039978be 62589: test environment comment 2019-09-06 14:30:57 +02:00
Kristof De Langhe
431d7e12b1 62589: Clean build folder pre-tests 2019-09-06 14:09:21 +02:00
Julius Gruber
92f8a5d522 Typo in dropdown-field-parser.ts fixed 2019-09-06 13:22:43 +02:00
Kristof De Langhe
7fe0db7d7c Merge branch 'master' into w2p-62589_Item-mapper-update
Conflicts:
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts
	src/app/+search-page/search-service/search.service.ts
2019-09-06 12:52:36 +02:00
Kristof De Langhe
e90e550f8f Merge branch 'master' into w2p-64574_Item-page-entities 2019-09-06 11:38:12 +02:00
Kristof De Langhe
6ffd791f12 64574: Further mantis template fixes 2019-09-06 11:35:20 +02:00
Tim Donohue
3a68b6dd7b Merge pull request #474 from atmire/master-travis-test-fixes
master travis test fixes
2019-09-05 18:50:53 +02:00
Kristof De Langhe
6c4d461ade master travis test fixes 2019-09-05 18:24:03 +02:00
Kristof De Langhe
adcefbae17 64574: Update mantis item pages with new template 2019-09-05 17:34:13 +02:00
Art Lowel
f9c5768ee3 Merge pull request #443 from atmire/UI-language-cookie
UI language cookie
2019-09-05 17:22:16 +02:00
L. Henze
f443a2bcce Excess whitespace removed 2019-09-05 10:52:05 -04:00
Giuseppe Digilio
5a3eb8c9df Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes
# Conflicts:
#	src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
2019-09-05 16:35:32 +02:00
benbosman
c4c6de66de Merge pull request #402 from atmire/Item-Relations-Edit-Delete
Item relations edit delete
2019-09-05 15:59:41 +02:00
Kristof De Langhe
e6a051e9c6 Merge branch 'master' into w2p-64574_Item-page-entities 2019-09-05 15:43:59 +02:00
Giuseppe Digilio
67b09e3794 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes
# Conflicts:
#	src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
2019-09-05 14:54:27 +02:00
Kristof De Langhe
04f57b753e Merge branch 'master' into w2p-62589_Item-mapper-update
Conflicts:
	src/app/app.reducer.ts
	src/app/shared/shared.module.ts
2019-09-05 14:16:13 +02:00
lotte
9723d929e1 resolved issues after merge with master 2019-09-05 10:44:37 +02:00
lotte
b634799ef9 Merge branch 'master' into w2p-62355_optimize-search-performance 2019-09-05 10:16:51 +02:00
Julius Gruber
917783e34b Branch change commit 2019-09-05 08:00:54 +02:00
lhenze
20bc4d1c2d tidying - whitespace only 2019-09-04 17:12:52 -04:00
Tim Donohue
36f134f1c6 Merge pull request #433 from atmire/Entities-grid-templates
Entities grid templates
2019-09-04 22:15:55 +02:00
lhenze
2845578d07 Tidying 2019-09-04 16:13:39 -04:00
lhenze
d6bcdda8a0 Adding i18n keys for the labels for handles 2019-09-04 14:57:26 -04:00
lhenze
50c3c4133f Merge branch 'master' into 460-coll-pages 2019-09-04 14:34:04 -04:00
Art Lowel
94eecffa88 Merge pull request #465 from lhenze/464-collpages-emptymessage
Collection pages, recent submissions: Added "empty" message
2019-09-04 17:56:29 +02:00
Julius Gruber
6167012e32 Basic implmentation of the dynamic rendering of Authentication Methods 2019-09-04 16:19:59 +02:00
lotte
11ad52c120 finished second selection tab 2019-09-04 15:45:08 +02:00
Julius Gruber
c428b1deef Test if reopening PR works 2019-09-04 14:14:12 +02:00
lotte
77e2fde15a added selected results to lookup tab 2019-09-04 08:47:32 +02:00
lhenze
f609476270 New key 2019-09-03 17:19:13 -04:00
lhenze
ba89698509 Merge branch 'master' into 460-coll-pages 2019-09-03 17:03:21 -04:00
lhenze
64db1c242e New key created for *no recent items in this collection* 2019-09-03 17:02:09 -04:00
lhenze
79ccf2e2be Merge branch 'master' into 464-collpages-emptymessage 2019-09-03 16:24:32 -04:00
Julius Gruber
093ad47a3d Added spaces on import {} 2019-09-03 16:34:26 +02:00
Kristof De Langhe
e59b0929ed 64503: Default metadataConfigID 2019-09-03 16:11:31 +02:00
lotte
3018845d0a created new tab for lookup 2019-09-03 15:42:42 +02:00
lotte
4ace067265 changed labels for input groups 2019-09-03 14:15:36 +02:00
Julius Gruber
526fab8008 Branch change 2019-09-03 14:07:59 +02:00
Julius Gruber
e72e02773d Mege conflict resolved 2019-09-03 11:50:45 +02:00
Julius Gruber
e27aadc432 Branch merge commit 2019-09-03 11:48:46 +02:00
Kristof De Langhe
7432297dce 64503: Fetch harvester endpoint using halService + small unsubscribe fix 2019-09-03 11:19:23 +02:00
Julius Gruber
3375086c6f Commit for PR 2019-09-02 17:13:06 +02:00
Julius Gruber
7e292cdde4 Branch change commit 2019-09-02 16:23:30 +02:00
Julius Gruber
901951eaa8 Removed switch statement, changed AuthMethod parsing in authInterceptor to be more generic 2019-09-02 15:01:03 +02:00
Terry Brady
b68c59b835 Updating comments per review 2019-09-01 16:25:26 -07:00
lotte
5142915e83 created tabs, working on concat field lookups 2019-08-30 16:17:43 +02:00
Yana De Pauw
343a1498ac Prevent navigation by link from collection-list component 2019-08-30 15:41:50 +02:00
Art Lowel
ee56de9e55 Merge pull request #455 from atmire/Bitstream-format-registries
Bitstream format registries
2019-08-30 09:55:01 +02:00
Tim Donohue
c80542c280 Merge pull request #459 from atmire/edit-com-col-labels
Fix the labels on edit collection and community pages
2019-08-29 19:44:12 +02:00
Terry Brady
c8fafd067e run e2e tests in docker using docker-compose 2019-08-29 09:15:12 -07:00
Julius Gruber
beb0f2d410 Dynamic rendering of auth methods via decorator 2019-08-29 17:58:07 +02:00
Yana De Pauw
22df3ec7f2 64644: Removal of filtered discovery page 2019-08-29 16:33:38 +02:00
lotte
addc6618ba solved issues with radiobuttons 2019-08-29 16:29:55 +02:00
Yana De Pauw
f955998d8b 64644: Removal of filtered discovery page 2019-08-29 16:03:37 +02:00
lotte
fa86601f55 applied feedback 2019-08-29 13:36:24 +02:00
lotte
3f0e5865f9 solved bug where equal objects were't compared by their properties 2019-08-29 13:15:52 +02:00
Julius Gruber
466d01ce09 Changed AuthMethods enum2 2019-08-29 10:44:15 +02:00
lotte
c117af34c3 Merge branch 'w2p-64574_Item-page-entities' into w2p-62849_relationships-in-submission 2019-08-29 10:32:57 +02:00
Kristof De Langhe
7233482fe7 64574: Fix AoT error 2019-08-29 10:32:28 +02:00
Julius Gruber
3517e9bee9 Changed type of payload in class RetrieveAuthMethodsSuccessAction 2019-08-29 10:25:52 +02:00
Julius Gruber
3ee20ad17a Changed folder structure in shared/login folder 2019-08-29 09:59:49 +02:00
Julius Gruber
ca1710c548 Deleted the IP-login component 2019-08-29 09:14:59 +02:00
Julius Gruber
c9142b604a Deleted IP-Login, X509-Login and LDAP-login comoponent 2019-08-29 09:11:09 +02:00
Julius Gruber
bde1d33b6f Resolved merge conflict 2019-08-29 08:47:45 +02:00
lotte
85279c5601 solved tests 2019-08-28 16:58:21 +02:00
lotte
dc3302e73b Merge branch 'w2p-64574_Item-page-entities' into w2p-62849_relationships-in-submission 2019-08-28 14:28:06 +02:00
lotte
35056959bb test fixes 2019-08-28 13:05:46 +02:00
Kristof De Langhe
76636933e4 64574: Test fixes 2019-08-28 12:01:24 +02:00
Kristof De Langhe
713c40451f 64574: Mantis publication template fix 2019-08-28 11:32:04 +02:00
Kristof De Langhe
f4f099995e 64574: Tests and small bugfix 2019-08-28 11:13:54 +02:00
Terry Brady
7b65270a0f add docker startup 2019-08-27 13:06:13 -07:00
Kristof De Langhe
8a1fd78811 64574: Tests intermediate commit 2019-08-27 17:38:53 +02:00
lotte
89be29ad7f solved issues after merge 2019-08-27 16:48:18 +02:00
lotte
4d67c98f04 Merge branch 'master' into w2p-62849_relationships-in-submission 2019-08-27 16:41:37 +02:00
lotte
fc6f5fd331 fixed server configuration read issues 2019-08-27 16:08:27 +02:00
Kristof De Langhe
a641b20db7 64574: View more/less for metadata-representations + refactoring item pages 2019-08-27 15:58:23 +02:00
Kristof De Langhe
4afb35c53e 64574: View-more/less for related-items + refactoring item pages 2019-08-27 14:12:39 +02:00
Kristof De Langhe
bd54d47037 64574: Further refactoring of item-component, mantis publication and JSDocs 2019-08-27 11:36:32 +02:00
Kristof De Langhe
4b55d7507c 64574: Refactor item-pages to use paginated-lists and relationship-service 2019-08-27 11:18:12 +02:00
Tim Donohue
7903a93042 Merge pull request #463 from lhenze/440-pagination-messaging
Pagination messaging:  Hiding "Now Showing"
2019-08-26 17:54:54 +02:00
Kristof De Langhe
02cf98c759 64574: relationship-service's getRelatedItemsByLabel returns paginated list using new REST API search endpoint + test cases on publication pages 2019-08-26 17:51:42 +02:00
lhenze
ba3778acae Ally improvements 2019-08-26 10:36:08 -04:00
lotte
56c93ff27e solved final caching/debounce issues, working on getting the submission to work with the rest endpoint again 2019-08-26 16:25:26 +02:00
lhenze
94050b655b Fixing typo 2019-08-26 09:40:17 -04:00
lhenze
f49fab3599 Added "empty" message
Modeled on browse-by.component.html
2019-08-26 08:56:13 -04:00
lhenze
ba97ca9f3a Exploring using same approach on Community pages 2019-08-26 08:46:32 -04:00
lhenze
5d7a36e1e3 formatting only 2019-08-26 08:08:40 -04:00
lhenze
047f9e75c3 Merge branch '440-pagination-messaging' into 460-coll-pages
* 440-pagination-messaging:
  More compact approach h/t @artlowel
  Moving the ngIf directive to wrap both parts of the statement
2019-08-26 07:52:49 -04:00
lhenze
316ced7fef More compact approach h/t @artlowel 2019-08-26 07:47:11 -04:00
lhenze
064552188e Moving the ngIf directive to wrap both parts of the statement 2019-08-24 13:47:20 -04:00
lhenze
a35523f78d Pagination -- Hide "Now Showing" when there are no results 2019-08-24 13:36:29 -04:00
lhenze
5963c6cd95 Handle added to header and copyright added to footer 2019-08-24 13:35:59 -04:00
lhenze
6f3a5448c5 Formatting only 2019-08-24 11:08:22 -04:00
lhenze
72c382d5c3 Using "type" value to determine path & innerHTML of first button 2019-08-23 17:59:08 -04:00
lhenze
86d3389438 One approach 2019-08-23 17:52:29 -04:00
lotte
74c26c17ba debounce for relationships in submission 2019-08-23 16:19:56 +02:00
lhenze
b73ad7a8f0 Managed to pass URL value and not have it be sanitized 2019-08-22 12:47:33 -04:00
lotte
0bf4c57a43 Resolved more caching issues for relationships 2019-08-22 16:04:08 +02:00
Giuseppe Digilio
c47ed59c96 Merge branch 'master' into submission-miscellaneous-fixes 2019-08-22 15:40:56 +02:00
Giuseppe Digilio
c1b241dc29 Fixed issue with lookup field which updated model on input event 2019-08-22 15:22:24 +02:00
Giuseppe Digilio
5bcb361c6e Fixed issue with model value update within scrollable fields 2019-08-22 15:16:13 +02:00
Giuseppe Digilio
3651b16b2c Fixed issue with form value init within relation fields 2019-08-22 15:10:32 +02:00
Giuseppe Digilio
0cc130a8b9 Fixed bitstream download in mydspace page 2019-08-22 14:51:19 +02:00
lotte
37072dc01e solved issue where the items werent reloaded after updating the relationship 2019-08-22 09:05:44 +02:00
lhenze
8f93d723a5 Problem: Attempt to extend comcol-page-browse-by
Cannot pass a URL.  it is getting sanitized
2019-08-21 16:07:34 -04:00
lhenze
1c2203804a If no items, show error 2019-08-21 14:26:43 -04:00
lhenze
edb6577d06 Tidying (2 spaces as tab) 2019-08-21 14:13:36 -04:00
lhenze
165dc2ccda Browse by pages: Adding Parent's Title and Description 2019-08-21 14:03:34 -04:00
lhenze
2a6e3c08cc HTML Structure: Header and Footer tags 2019-08-21 14:00:45 -04:00
lhenze
16b3e8af35 Comcol component - adding styles 2019-08-21 13:59:54 -04:00
lhenze
b9baecd573 Bootstrap -- list group for links
https://getbootstrap.com/docs/4.3/components/list-group/
2019-08-21 13:27:52 -04:00
lhenze
78638e77da Label need not be an H3 2019-08-21 12:51:27 -04:00
Kristof De Langhe
8659182795 64387: Small refactoring change 2019-08-21 17:49:34 +02:00
Kristof De Langhe
0eb47fd804 Merge branch 'w2p-63945_Edit-bitstream-tab' into w2p-64387_Edit+Upload-bitstreams
Conflicts:
	resources/i18n/en.json
	src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.ts
	src/app/core/core.module.ts
	src/app/core/data/bitstream-data.service.ts
	src/app/core/data/item-data.service.ts
2019-08-21 17:47:53 +02:00
Yana De Pauw
1008bd16e2 64424: Angular impact of changes to relationship type changes 2019-08-21 17:35:16 +02:00
Kristof De Langhe
3912860f98 64387: HAL endpoint refactoring 2019-08-21 17:31:24 +02:00
lhenze
897e303035 Moving Logo 2019-08-21 11:00:56 -04:00
lotte
4b59780117 fixed issue with combinelatest 2019-08-21 16:27:43 +02:00
Kristof De Langhe
ff2083941a 64503: Removal of unnecessary messages 2019-08-21 14:42:35 +02:00
Kristof De Langhe
a3116a3c5a 64503: AoT build error fixes 2019-08-21 14:37:14 +02:00
Kristof De Langhe
86555b936d 64503: Small bugfix on login 2019-08-21 14:22:54 +02:00
Kristof De Langhe
9fab40d7e9 64503: CollectionSourceComponent and CollectionDataService tests 2019-08-21 14:14:01 +02:00
Kristof De Langhe
a3b6917aba 64503: Remembering previously selected harvest type + small dropdown fix 2019-08-21 11:24:52 +02:00
Kristof De Langhe
bf8e2078bc 64503: Metadata Format dropdown filled in by metadataConfig from REST response 2019-08-21 10:40:58 +02:00
Kristof De Langhe
8103321245 64503: MetadataConfig in ContentSource + JSDocs 2019-08-20 17:54:58 +02:00
lotte
90a9570e7d bug with deleting after adding 2019-08-20 17:44:40 +02:00
Kristof De Langhe
1b9bc2f7a3 64503: Content Source PUT request on form submit 2019-08-20 17:28:28 +02:00
Kristof De Langhe
764f532b99 64503: Content Source fetched from API 2019-08-20 16:25:40 +02:00
Kristof De Langhe
2d3dfde6bb Merge branch 'master' into w2p-64503_Edit-collection-Content-Source-2
Conflicts:
	config/environment.default.js
	resources/i18n/en.json
	src/app/shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.spec.ts
	src/config/global-config.interface.ts
2019-08-20 12:43:16 +02:00
Yana De Pauw
88c8fddbce Fix to message, margin and deletion page reset 2019-08-19 17:25:41 +02:00
lotte
40b30b7aea fixed issue with adding/selecting relation 2019-08-19 16:03:52 +02:00
Kristof De Langhe
c95fa8fb96 62589: Refactoring mapping endpoint and methods to mapped + collection-list sorting bugfix 2019-08-19 14:18:10 +02:00
Art Lowel
70503e1fd7 Merge branch 'master' into improve-i18n-files 2019-08-19 13:02:05 +02:00
lotte
34b165b7d2 intermediate commit 2019-08-19 11:37:49 +02:00
Kristof De Langhe
03ef13fd76 64387: UploadBitstreamComponent tests 2019-08-16 16:24:12 +02:00
Kristof De Langhe
7bd6c9acab 64387: Upload bitstream component + Edit bitstream placeholder 2019-08-16 13:35:04 +02:00
Yana De Pauw
1d05680126 Implement feedback
Change padding into margin
Change 'Create link' to a button
Add placeholder to extension field
Fix pagination
2019-08-16 13:00:04 +02:00
Kristof De Langhe
d1dbe49333 64387: UploadBitstreamComponent intermediate commit 2019-08-14 17:53:07 +02:00
lotte
1b6c0a9e42 fixed AoT errors 2019-08-14 16:20:10 +02:00
Kristof De Langhe
7d0439b006 64225: Fixed AoT build errors 2019-08-14 16:00:26 +02:00
Kristof De Langhe
737792a1df 62741: Moved entity mantis files to correct location 2019-08-14 15:05:25 +02:00
lotte
d1dbd891b4 62355: solved lint error 2019-08-14 13:05:20 +02:00
lotte
62880336d9 Merge branch 'master' into w2p-62355_optimize-search-performance 2019-08-14 12:31:07 +02:00
Yana De Pauw
863189b2e5 fix missing , in messages file 2019-08-14 11:48:51 +02:00
Yana De Pauw
67feaf3178 Merge branch 'master' into Bitstream-format-registries
Conflicts:
	resources/i18n/en.json
2019-08-14 11:24:45 +02:00
Yana De Pauw
295bbc5c40 flatten en.json 2019-08-14 11:22:36 +02:00
lotte
46614f4562 fixed issue with deleting items linked to relationship from the cache 2019-08-14 10:47:57 +02:00
Yana De Pauw
228a61e7ed Fix margin and amount of returned results 2019-08-13 17:44:26 +02:00
Art Lowel
930da6dde3 fix the labels on edit collection and community pages 2019-08-13 15:13:51 +02:00
Kristof De Langhe
fc21dc2019 64225: Search results reloading correctly after object deletion 2019-08-13 14:46:10 +02:00
Kristof De Langhe
e05f44d079 64225: Import fix 2019-08-13 12:30:47 +02:00
Kristof De Langhe
9afcd48f12 Merge branch 'master' into w2p-64225_Relations-delete-feedback-3
Conflicts:
	resources/i18n/en.json
	src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.ts
	src/app/+search-page/search-service/search.service.ts
	src/app/core/core.module.ts
	src/app/core/shared/item.model.ts
2019-08-13 12:03:29 +02:00
Kristof De Langhe
26e25069ad 62589: PR Feedback 2019-08-12 16:41:56 +02:00
Yana De Pauw
1bf9693952 63838: Add typedoc comments and fix unused method 2019-08-12 15:53:10 +02:00
Yana De Pauw
7d4987da5c Merge branch 'master' into Move-item-component
Conflicts:
	resources/i18n/en.json
	src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts
	src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts
2019-08-12 15:30:04 +02:00
Kristof De Langhe
2f0a5a4065 Merge branch 'master' into w2p-62589_Item-mapper-update
Conflicts:
	resources/i18n/en.json
	src/app/+search-page/search-service/search.service.ts
	src/app/core/core.module.ts
2019-08-12 15:23:43 +02:00
Kristof De Langhe
1be7f4e550 62741: Grid template field changes 2019-08-12 11:05:45 +02:00
Art Lowel
0ad505ba30 Merge pull request #442 from atmire/ConfigurationSearchPageComponent
Configuration search page component
2019-08-12 10:40:35 +02:00
Kristof De Langhe
2db0bf44f3 62741: PR Feedback changes 2019-08-12 10:22:49 +02:00
Tim Donohue
64b657507c Merge pull request #440 from atmire/Edit-current-item-query
Edit current item query
2019-08-09 22:48:09 +02:00
Tim Donohue
2fc6f9ea77 Merge pull request #457 from atmire/flatten-i18n-files
Flatten i18n files
2019-08-09 17:32:50 +02:00
lotte
7406ab5d47 62849: fixed delete/add relationships 2019-08-09 16:57:06 +02:00
lotte
827ffc2d79 fixed relationship service finished 2019-08-09 12:54:01 +02:00
Julius Gruber
e846aa801f authService startShibAuth() changed 2019-08-09 08:10:32 +02:00
Tim Donohue
3a7926eebe Merge pull request #454 from atmire/remove-e2e-from-ci
Remove e2e tests from the ci task
2019-08-08 22:14:04 +02:00
lotte
9907087dc3 62849: progress refactoring relationships 2019-08-08 16:02:58 +02:00
Yana De Pauw
ad863b62a7 63838: Fix feedback
Add a title to the move page
Disable submit button when no target is selected
Add operation in progress indicator
Use updated inputSuggestion to fix bug with value selection
2019-08-08 15:44:54 +02:00
Yana De Pauw
5c101d116a 63838: Refactor input suggestions to support DSpaceObjects as suggestions 2019-08-08 15:43:29 +02:00
lotte
719d0e791c intermediate commit to see whats wrong 2019-08-08 15:33:13 +02:00
Art Lowel
44aabe19d7 Merge branch 'master' into improve-i18n-files 2019-08-08 13:50:10 +02:00
Art Lowel
746567ab52 Merge branch 'master' into flatten-i18n-files 2019-08-08 13:49:13 +02:00
Julius Gruber
ad2b98e780 Merge branch 'master' into shibbolethDev4 2019-08-08 12:26:54 +02:00
Julius Gruber
8883793b06 Changed modifier of dynamicLoginMethods 2019-08-08 12:24:02 +02:00
Julius Gruber
aca60642a9 Removed dev log statemnet from lon-in-container 2019-08-08 11:30:31 +02:00
Julius Gruber
d3e93fed24 Removed hardcoded shibbolethUrl 2019-08-08 11:17:18 +02:00
Julius Gruber
3b6a20bf67 Added further dynamic authentication methods 2019-08-08 11:05:12 +02:00
Julius Gruber
bcc6daa39f Added mock components for dynamic login components 2019-08-08 09:29:00 +02:00
Julius Gruber
68968ca70a First functional prototype 2019-08-07 17:57:31 +02:00
lotte
b6e9c5b840 refactorting relationship service functions 2019-08-07 16:21:49 +02:00
Art Lowel
c81f589338 Update the Quick Start docs to include node 10 2019-08-06 17:41:22 +02:00
Yana De Pauw
c325e6d61b Merge branch 'master' into w2p-62769_Bitstream-format-registry
Conflicts:
	src/app/+admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts
	src/app/core/core.module.ts
	src/app/core/registry/registry-bitstreamformats-response.model.ts
	src/app/core/registry/registry.service.ts
	src/app/core/shared/bitstream-format.model.ts
2019-08-06 17:22:03 +02:00
Art Lowel
d1ba6ab610 restore protractor timeouts to their default values 2019-08-06 17:19:49 +02:00
Art Lowel
588fc484a4 remove e2e tests from the ci task 2019-08-06 17:08:43 +02:00
lotte
848b700f84 refactoring relationship service code 2019-08-06 16:59:27 +02:00
Tim Donohue
5221615c42 Merge pull request #452 from atmire/security-fixes
Upgrade dependencies to prevent vulnerabilities
2019-08-06 15:37:17 +02:00
lotte
28b450498f 62849: intermediate commit, fixed issue with retrieving relationship type id 2019-08-06 15:30:44 +02:00
Art Lowel
004f4ce38c increase protractor timeouts again 2019-08-06 14:40:53 +02:00
Art Lowel
1fb38fe56d increase protractor allScriptsTimeout 2019-08-06 13:31:32 +02:00
Art Lowel
dc868853a8 remove node 9, add node 10 2019-08-06 11:17:17 +02:00
Art Lowel
73f67827f3 upgrade dependencies to prevent CVE-2019-10744, CVE-2019-13173, CVE-2018-14732, CVE-2018-16469, CVE-2018-1000620, CVE-2019-10744 and WS-2018-0236 2019-08-05 18:23:27 +02:00
Julius Gruber
92989a618a Added null/undefined check for authMethodModels 2019-08-05 17:16:15 +02:00
lotte
07d876348e submitting relationships to the REST server 2019-08-05 16:30:56 +02:00
Julius Gruber
9234f8bc46 Removed unused methods from auth.interceptor 2019-08-05 15:42:07 +02:00
Julius Gruber
12941640a4 Removed old shibboleth code 2019-08-05 15:32:41 +02:00
Julius Gruber
de8bcce8be Removed ssoLoginUrl from initial auth state 2019-08-05 15:17:53 +02:00
Julius Gruber
c8f4db618e Store available authentication methods in ngrx/store 2019-08-05 14:45:57 +02:00
Yana De Pauw
279b80b4de 62769: Bitstream format registry 2019-08-05 13:14:03 +02:00
Julius Gruber
7a3155f2b4 Merge branch 'master' into shibbolethDev4 2019-08-05 09:06:02 +02:00
Julius Gruber
d25f12590d Branch upadate 2019-08-05 09:00:13 +02:00
Art Lowel
0b4379abad Merge pull request #431 from DSpace/dependabot/npm_and_yarn/lodash.mergewith-4.6.2
Bump lodash.mergewith from 4.6.1 to 4.6.2
2019-08-02 17:23:59 +02:00
Art Lowel
2e4b9d7811 Merge pull request #422 from DSpace/dependabot/npm_and_yarn/ecstatic-3.3.2
Bump ecstatic from 3.2.2 to 3.3.2
2019-08-02 17:23:26 +02:00
Art Lowel
00858ae013 Merge pull request #415 from DSpace/dependabot/npm_and_yarn/handlebars-4.1.2
Bump handlebars from 4.0.11 to 4.1.2
2019-08-02 17:23:05 +02:00
Art Lowel
aed3e5ae46 Merge pull request #414 from DSpace/dependabot/npm_and_yarn/js-yaml-3.13.1
Bump js-yaml from 3.12.0 to 3.13.1
2019-08-02 17:22:44 +02:00
Art Lowel
3e8b12cb91 Merge pull request #412 from DSpace/dependabot/npm_and_yarn/pem-1.13.2
Bump pem from 1.12.3 to 1.13.2
2019-08-02 17:21:57 +02:00
Art Lowel
8148a67e40 double e2e jasmine timeout 2019-08-02 16:52:15 +02:00
lotte
8ece6bf79f creating relationship type service 2019-08-02 16:43:25 +02:00
Julius Gruber
f086ee79a5 Removed double ssoLoginUrl from auth.state 2019-08-02 13:05:57 +02:00
Julius Gruber
fb44c02437 Changed home-news.component.html to original state 2019-08-02 10:41:30 +02:00
Julius Gruber
8af15d06bc Moved Shibboleth route to DECLARATIONS array 2019-08-02 10:41:30 +02:00
Julius Gruber
8beece2f73 Revert "Changed auth-status model: ssoLoginUrl: string"
This reverts commit 35554b57
2019-08-02 10:41:30 +02:00
Julius Gruber
71f281516a Added logs for server debug 2019-08-02 10:40:46 +02:00
Julius Gruber
7c243623c8 Added hardcoded shibboleth button 2019-08-02 10:40:46 +02:00
Julius Gruber
39fd025252 Added spinner to shibboleth landing page 2019-08-02 10:40:46 +02:00
Julius Gruber
5d5f9c4046 Added debug logs for server 2019-08-02 10:40:46 +02:00
Julius Gruber
318c736083 Added translation for Shibboleth button 2019-08-02 10:40:46 +02:00
Julius Gruber
159ce66050 Removed logs from auth.interceptor 2019-08-02 10:40:46 +02:00
Julius Gruber
26f01d6f8f Added backend lookup if shibboleth is enabled 2019-08-02 10:40:46 +02:00
Julius Gruber
14419ca567 Removed dispatchShibAction button 2019-08-02 10:40:46 +02:00
Julius Gruber
a504d96897 post to login endpoint without credentials 2019-08-02 10:40:46 +02:00
Julius Gruber
0b56b0d8dc Changed css file of shib component to scss 2019-08-02 10:40:46 +02:00
Julius Gruber
3d5b3ea9a1 Shbboleth workflow new 2019-08-02 10:40:46 +02:00
Julius Gruber
c4ab1c5180 Removed import of deleted shibb component 2019-08-02 10:39:59 +02:00
Julius Gruber
b9c10813ce Deleted component that causes build failure 2019-08-02 10:39:59 +02:00
Julius Gruber
17e2918721 AuthInterceptor changed 2019-08-02 10:39:58 +02:00
Julius Gruber
4bcc54befd Added log to interceptor 2019-08-02 10:39:58 +02:00
Julius Gruber
70c9050fad Test dispatch of action delivering bearer token 2019-08-02 10:39:58 +02:00
Julius Gruber
0355ff3e47 Get tokoen from backend 2019-08-02 10:39:58 +02:00
Julius Gruber
4504fa1818 Test CORS policy' 2019-08-02 10:39:58 +02:00
Julius Gruber
8ed359cc7e postLoginCall() refactored 2019-08-02 10:39:58 +02:00
Julius Gruber
a36aa50d16 Added button for empty post login call 2019-08-02 10:39:58 +02:00
Julius Gruber
9a2b22943e Hardcoded button without target 2019-08-02 10:39:58 +02:00
Julius Gruber
2e9eb1d387 Changed shibb target to ..../submit 2019-08-02 10:39:58 +02:00
Julius Gruber
99ffd43d95 Changed target url to fis.tiss.tuwien.ac.at 2019-08-02 10:39:58 +02:00
Julius Gruber
e8f7aa6201 Changed log-in.component 2019-08-02 10:39:58 +02:00
Julius Gruber
1cbbcaa800 Changed href in hardcoded login button 2019-08-02 10:39:58 +02:00
Julius Gruber
1186f24cea Added success response log to auth interceptor 2019-08-02 10:39:58 +02:00
Julius Gruber
0a4df44315 Changed heading of welcome screen 2019-08-02 10:39:58 +02:00
Julius Gruber
3f13031ea3 Added hardcoded ssoLogin button 2019-08-02 10:39:58 +02:00
Julius Gruber
99576dc64a Hardcoded ssoLoginUrl in auth.service retrieveAuthMethods 2019-08-02 10:39:58 +02:00
Julius Gruber
ecdf585216 null check for auth interceptor 2019-08-02 10:39:58 +02:00
Julius Gruber
41e238bad7 Added method getLocationFromHeaders() to auth.interceptor 2019-08-02 10:39:58 +02:00
Julius Gruber
20794381f1 Refactoring of auth.interceptor 2019-08-02 10:39:58 +02:00
Julius Gruber
994d96bc95 Removed parseSSOlocation() from auth.service 2019-08-02 10:39:58 +02:00
Julius Gruber
ef9447cb54 Removed global config from auth.service 2019-08-02 10:39:57 +02:00
Julius Gruber
3dfdc9bdc5 Added 405 error response check to interceptor 2019-08-02 10:39:57 +02:00
Julius Gruber
73c046974b Branch change commit 2019-08-02 10:39:57 +02:00
Julius Gruber
086579b7f7 Added effect: checkTokenError 2019-08-02 10:39:57 +02:00
Julius Gruber
ffc724bfbc Added auth to environment.default.js 2019-08-02 10:39:57 +02:00
Julius Gruber
b4f3bf71ad Added shibboleth button to log-in.component 2019-08-02 10:39:57 +02:00
Julius Gruber
d6eab441a4 Added selectors for shibboleth login 2019-08-02 10:39:57 +02:00
Julius Gruber
52cfe846cb Added cases needed for shobboleth login to reducer 2019-08-02 10:39:57 +02:00
Julius Gruber
70d95b4764 Changed auth-interceptor: location used to makeAuthStatusObject() 2019-08-02 10:39:57 +02:00
Julius Gruber
10085ccf41 Added effect retrieveMethods$ 2019-08-02 10:39:28 +02:00
Julius Gruber
6b25dcfa70 Added Actions for ssoLogin to auth.actions.ts 2019-08-02 10:39:28 +02:00
Julius Gruber
78287f5504 Changed auth-status model: ssoLoginUrl: string 2019-08-02 10:39:27 +02:00
Tim Donohue
f4f6c21abf Merge pull request #434 from atmire/object-factory-refactoring
Replaced unnecessary model factories
2019-08-01 23:13:06 +02:00
Tim Donohue
2c3c07ce52 Merge pull request #444 from atmire/Travis-webdriver-manager-temp-fix
Patch protractor with the latest webdriver-manager
2019-08-01 17:28:32 +02:00
lotte
140a194b0a 62849: updated view mode tyypes 2019-08-01 14:59:11 +02:00
Art Lowel
6043d16429 Merge branch 'Travis-webdriver-manager-temp-fix' into ConfigurationSearchPageComponent 2019-08-01 14:28:00 +02:00
Art Lowel
22fa4c6dae Merge branch 'Travis-webdriver-manager-temp-fix' into Edit-current-item-query 2019-08-01 14:27:11 +02:00
lotte
a891a319d8 Merge branch 'Travis-webdriver-manager-temp-fix' into object-factory-refactoring 2019-08-01 14:26:40 +02:00
Art Lowel
d320c703b1 Merge branch 'Travis-webdriver-manager-temp-fix' into UI-language-cookie 2019-08-01 14:25:10 +02:00
Art Lowel
16b8184dad patch protractor with the latest webdriver-manager 2019-08-01 13:54:34 +02:00
lotte
01198c3ac5 removed unnecessary static type in NormalizedWorkflowItem and fixed generic type for NormalizedWorkspaceItem 2019-08-01 13:26:54 +02:00
lotte
19e28bf367 replacing with item type switcher - intermediate commit 2019-08-01 13:14:32 +02:00
Kristof De Langhe
344f355995 Merge branch 'master' into w2p-63825_UI-language-cookie 2019-07-31 17:04:54 +02:00
lotte
c7c150a7dd moving lookup button outside of input field 2019-07-31 16:53:05 +02:00
lotte
0749cbcc0f 62849: moving relation lookup from separate component to option for all input components 2019-07-30 16:18:42 +02:00
Kristof De Langhe
6f347868ff Merge branch 'master' into w2p-63469_Relations-delete-feedback-2
Conflicts:
	src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts
2019-07-30 10:34:22 +02:00
Kristof De Langhe
3807a16f9a 63945: Allow bitstreams from other pages to be deleted 2019-07-30 10:28:46 +02:00
Kristof De Langhe
e187778dbc 63945: Tests 2019-07-29 17:20:08 +02:00
lotte
1f7b8b8210 62849: fixed issues with multiple selections, improved UX, updating to use new REST response 2019-07-29 15:42:30 +02:00
Kristof De Langhe
841c4eabf3 63945: JSDocs 2019-07-29 13:41:20 +02:00
Kristof De Langhe
b4d7311a1c 63945: Loading bitstreams section 2019-07-29 13:33:44 +02:00
Kristof De Langhe
55a5b1891e 63945: Upload, Download and Edit buttons 2019-07-29 13:10:57 +02:00
Kristof De Langhe
ee11944645 Merge branch 'master' into w2p-63934_Edit-current-item-query 2019-07-29 11:03:55 +02:00
Kristof De Langhe
24a8e06ee7 Merge branch 'master' into w2p-63724_ConfigurationSearchPageComponent 2019-07-29 10:25:10 +02:00
Giuseppe Digilio
509fd0d802 Fixed an issue while editing repeatable fields 2019-07-26 19:43:15 +02:00
Giuseppe Digilio
861f8ddb6c Show hint message only when there is an error message 2019-07-26 19:41:28 +02:00
Kristof De Langhe
4f8fe9e611 63945: Bitstream pagination and removal of listing per bundle 2019-07-26 17:33:06 +02:00
Art Lowel
359cb10fa3 add json5 support 2019-07-26 17:21:57 +02:00
lotte
16feb61ebf reinstated select multiple behavior 2019-07-26 16:46:31 +02:00
Giuseppe Digilio
45ab326355 Added FindAllOptions param to getAuthorizedCollection and getAuthorizedCollectionByCommunity 2019-07-26 15:29:00 +02:00
Kristof De Langhe
27ec828142 63945: Bitstream delete notifications, de-caching, reloading and small layout changes 2019-07-26 13:28:32 +02:00
Art Lowel
64a60f561e flatten i18n files 2019-07-26 11:09:06 +02:00
Kristof De Langhe
f93a104d68 63945: deleteAndReturnResponse on data-service 2019-07-26 10:37:51 +02:00
Kristof De Langhe
277aad26c8 63945: BitstreamDataService + bitstream remove 2019-07-26 10:32:51 +02:00
lotte
650b77081f Merge branch 'master' into w2p-62849_relationships-in-submission 2019-07-26 10:01:50 +02:00
lotte
96bcb8c671 Merge branch 'master' into object-factory-refactoring 2019-07-26 08:53:11 +02:00
lotte
b442690350 Merge branch 'master' into w2p-62355_optimize-search-performance 2019-07-26 08:41:43 +02:00
Giuseppe Digilio
697b8199e4 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes 2019-07-25 19:19:22 +02:00
Giuseppe Digilio
3fe67b8da1 changed elementsPerPage on CollectionDataService 2019-07-25 19:18:11 +02:00
Giuseppe Digilio
50024c8c55 During submission retrieve collection list only at first load 2019-07-25 19:16:08 +02:00
Giuseppe Digilio
2ff1b88bac Fixed issue with collection change 2019-07-25 19:14:57 +02:00
Tim Donohue
81b19a96d7 Merge pull request #438 from DSpace/tdonohue-patch-1
Update environment.js with new demo site path
2019-07-25 18:19:31 +02:00
Tim Donohue
64c653feb9 Update environment.js with new demo site path 2019-07-25 10:53:19 -05:00
Kristof De Langhe
4461e9025b 63945: Edit bitstream tab intermediate commit 2019-07-25 17:46:23 +02:00
benbosman
5ca011e5fe Merge pull request #430 from atmire/One-Sided-Relationship-Filtering
One-sided relationship filtering and refactoring
2019-07-25 15:59:24 +02:00
lotte
f4ee930c4a fixing more routing issues 2019-07-25 15:41:13 +02:00
lotte
d335ab71af added some typedoc 2019-07-25 15:23:29 +02:00
lotte
0d34152398 Merge branch 'master' into w2p-62355_optimize-search-performance 2019-07-25 14:44:04 +02:00
lotte
fa6fe668c3 solved issues with tests 2019-07-25 14:41:47 +02:00
Kristof De Langhe
4f3ec612a1 63945: Abstract item-update component 2019-07-25 13:39:28 +02:00
Lotte Hofstede
c190cedcea fixed lint issue 2019-07-25 13:18:15 +02:00
Giuseppe Digilio
82426700fd Added getAuthorizedCollection method to CollectionDataService 2019-07-25 13:00:26 +02:00
Giuseppe Digilio
0ab2ca1880 added variable representing collection change processing status 2019-07-25 12:59:16 +02:00
Giuseppe Digilio
49c341b05a Fixed concat field hint message 2019-07-25 12:54:23 +02:00
Giuseppe Digilio
a2180c19ac during submission retrieve surrent collection name by current collection id 2019-07-25 11:58:21 +02:00
Lotte Hofstede
b0cf35e422 added missing typedoc 2019-07-25 11:55:55 +02:00
Giuseppe Digilio
062ff5b8a4 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes
# Conflicts:
#	src/app/submission/form/collection/submission-form-collection.component.spec.ts
#	src/app/submission/form/collection/submission-form-collection.component.ts
2019-07-25 11:27:18 +02:00
Kristof De Langhe
7269be9142 63825: use CookieService instead of ClientCookieService 2019-07-25 11:19:59 +02:00
Giuseppe Digilio
93b415a6be Checked there is no pending save when a new save operation is dispatched 2019-07-25 10:08:17 +02:00
Giuseppe Digilio
ec105b35a9 Disabled search button on lookup field on edit mode 2019-07-25 10:08:06 +02:00
Kristof De Langhe
ac5c7d5230 63934: Edit item search.resourceid query by default 2019-07-24 17:17:02 +02:00
lotte
170377f209 62849: fixed routing issues 2019-07-23 16:51:06 +02:00
lotte
1fd3b04a43 Merge branch 'w2p-63724_ConfigurationSearchPageComponent' into w2p-62849_relationships-in-submission
Conflicts:
	src/app/+search-page/search-page.module.ts
	src/app/+search-page/search-results/search-results.component.html
	src/app/core/shared/search/search-configuration.service.ts
	src/app/shared/search/search-result-element-decorator.ts
2019-07-23 16:50:23 +02:00
lotte
1530d7f3d1 solve fixedfilter issue 2019-07-22 16:11:42 +02:00
lotte
a8d9d74818 Merge branch 'w2p-63737_workspace-item-in-submission' into w2p-62849_relationships-in-submission 2019-07-22 09:57:48 +02:00
lotte
2478d44b2e fixed tests 2019-07-22 09:42:32 +02:00
lotte
3bb2ac15e9 added workspace item to fieldparsers 2019-07-19 16:24:40 +02:00
lotte
200b29f6f8 Merge branch 'master' into object-factory-refactoring
Conflicts:
	src/app/submission/sections/upload/section-upload.component.spec.ts
2019-07-19 09:08:03 +02:00
Art Lowel
5be883f9ce Merge pull request #427 from AlexanderS/add-missing-rp-service
Add missing ResourcePolicyService
2019-07-18 17:53:57 +02:00
lotte
aff3f3df03 solved issues with browse pages 2019-07-18 16:28:07 +02:00
lotte
5c74c0221a Merge branch 'master' into object-factory-refactoring
Conflicts:
	src/app/+item-page/simple/item-types/shared/item.component.spec.ts
	src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.spec.ts
	src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.spec.ts
	src/app/entity-groups/journal-entities/item-pages/journal/journal.component.spec.ts
	src/app/entity-groups/research-entities/item-pages/orgunit/orgunit.component.spec.ts
	src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts
	src/app/entity-groups/research-entities/item-pages/project/project.component.spec.ts
	src/app/submission/form/collection/submission-form-collection.component.spec.ts
2019-07-18 13:50:33 +02:00
Kristof De Langhe
c2345c1562 63825: UI language cookie 2019-07-18 13:01:17 +02:00
lotte
d16ee88641 fixed and tests for equals method 2019-07-17 16:28:17 +02:00
Kristof De Langhe
bd8177c17d 62741: AoT build fix 2019-07-17 14:14:21 +02:00
lotte
96f68695b0 Changed href to routerLink on edit item status page 2019-07-17 14:09:50 +02:00
lotte
651b4100dd solved issue with submission 2019-07-17 13:47:59 +02:00
Kristof De Langhe
cee7ffeb04 Merge branch 'master' into w2p-62741_Entities-grid-templates 2019-07-17 13:13:08 +02:00
lotte
2bfe6ceebb relation lookup progress/equatable 2019-07-16 16:37:48 +02:00
Kristof De Langhe
a185019da5 63724: new configuration based search-page component 2019-07-16 15:38:51 +02:00
Alexander Sulfrian
2f6ba1e219 Add another findByHref test 2019-07-16 14:43:55 +02:00
Alexander Sulfrian
e4f992ba1d Fix typescript syntax error 2019-07-16 14:37:51 +02:00
Tim Donohue
735408c336 Merge pull request #419 from atmire/selectable-themes
Selectable themes
2019-07-15 22:34:58 +02:00
lotte
65a66a104c continued refactoring 2019-07-15 16:26:27 +02:00
Kristof De Langhe
9a10abeff5 63123: Relationship filtering fix 2019-07-15 15:09:21 +02:00
Kristof De Langhe
9959176575 63669: InputModels array for easier iteration 2019-07-15 13:56:33 +02:00
Kristof De Langhe
f45f390c67 63669: Translated options 2019-07-15 13:49:50 +02:00
Kristof De Langhe
d97fcc5c15 63669: More ContentSourceComponennt tests 2019-07-15 13:34:56 +02:00
lotte
d60ba8cb76 reversed to default theme 2019-07-15 13:20:37 +02:00
Kristof De Langhe
8b70c1321e 63669: Hide form + harvest button styling 2019-07-15 13:15:04 +02:00
lotte
e877560ec7 removed unnecessary files 2019-07-15 12:45:54 +02:00
lotte
1c738ac276 renamed files from preview-release to mantis 2019-07-15 11:29:07 +02:00
lotte
f91e52f1ad 61949: fixed bug with adding a new md field 2019-07-15 09:59:29 +02:00
Tim Donohue
23a4a3f57b Merge pull request #420 from atmire/w2p-62651_Item-display-and-lists-field-changes
DS-4223 Metadata Schemas for configurable entities
2019-07-12 19:21:27 +02:00
Kristof De Langhe
1e56f03785 63669: ContentSource tests pt1 2019-07-12 17:43:19 +02:00
Kristof De Langhe
7774c3c83c 63669: Content Source valid check + JSDocs 2019-07-12 15:11:38 +02:00
Kristof De Langhe
615a47fe5b 63669: Content-Source integrated with FieldUpdate 2019-07-12 13:34:40 +02:00
Giuseppe Digilio
f1efe21df6 Merge remote-tracking branch 'remotes/origin/master' into submission-miscellaneous-fixes 2019-07-12 10:31:34 +02:00
Tim Donohue
d3e0ffed47 Merge pull request #421 from atmire/Configurable-Browse-By
Configurable browse-by
2019-07-11 23:19:21 +02:00
Giuseppe Digilio
cf73625830 Fixed comments 2019-07-11 19:12:31 +02:00
Kristof De Langhe
03887e7c41 63669: Intermediate commit 2019-07-11 17:57:54 +02:00
Giuseppe Digilio
7667cab772 Added hint message to form fields 2019-07-11 17:54:21 +02:00
Giuseppe Digilio
016afd84e4 Fixed edit link for workflow 2019-07-11 17:53:44 +02:00
Giuseppe Digilio
6856f95cb9 Fixed an issue when submission metadata auto save is triggered on a typeahead field 2019-07-11 17:53:30 +02:00
Giuseppe Digilio
4a1530eea5 fixed issue with submission footer z-index 2019-07-11 17:52:33 +02:00
Giuseppe Digilio
fe1e4931c3 hide upload section on init when is not mandatory and there a no file uploaded in the submission 2019-07-11 17:52:24 +02:00
Giuseppe Digilio
b665456b9d Fixed issues with relation group field 2019-07-11 17:52:07 +02:00
Giuseppe Digilio
ed959e492a Show only authorized collections list during submission 2019-07-11 17:50:44 +02:00
lotte
b1585ac7f2 progress july 11 - store/selection to object list 2019-07-11 15:09:28 +02:00
lotte
67cee55754 fixed bitstream format/metadataschema pages 2019-07-11 14:47:40 +02:00
Kristof De Langhe
1d98b8c29f 62063: Browse config refactoring property metadata to id 2019-07-11 13:59:23 +02:00
lotte
a573c507b4 resolved prod build issues 2019-07-11 13:35:08 +02:00
Kristof De Langhe
8188da0c75 63669: Intermediate commit 2019-07-11 13:24:24 +02:00
Kristof De Langhe
12f57e3975 63669: Missing JSDocs 2019-07-11 12:05:28 +02:00
Kristof De Langhe
dbf31f767d 63123: Test fix 2019-07-11 11:22:41 +02:00
dependabot[bot]
d20962e5cd Bump lodash.mergewith from 4.6.1 to 4.6.2
Bumps [lodash.mergewith](https://github.com/lodash/lodash) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2019-07-11 09:18:53 +00:00
Kristof De Langhe
6d64478f4f 63123: One-sided relationship refactoring 2019-07-11 10:43:38 +02:00
Kristof De Langhe
09c6a167fb 63669: Edit Col/Com Tabs Tests + JSDocs 2019-07-10 17:43:01 +02:00
Kristof De Langhe
3d9af688e7 63669: Edit Communtiy/Collection Tabs 2019-07-10 16:43:20 +02:00
lotte
42c690dfd4 moved search module contents to shared 2019-07-10 13:17:28 +02:00
Yana De Pauw
cdb2c30bd4 63667: Extract update tracker 2019-07-10 11:14:21 +02:00
lotte
7f3dab9fc0 62849: existing selected objects are already selected and disabled 2019-07-09 14:59:23 +02:00
lotte
1a30744f5b 62849: submission relation search on enter 2019-07-09 14:06:09 +02:00
lotte
7653558cc0 fixed URL polyfill issue 2019-07-09 13:34:36 +02:00
lotte
28f127122f 62849: fixed prod URL issue 2019-07-09 12:48:52 +02:00
lotte
d55bcc93bb 62849: enabled mock service in prod mode 2019-07-09 12:12:08 +02:00
lotte
f420cca78c layout changes, result list, fixed prod build 2019-07-09 12:11:04 +02:00
Kristof De Langhe
34e75a46e5 63469: JSDocs + tests 2019-07-08 14:30:19 +02:00
Kristof De Langhe
8265942f18 63469: Properly reload de-cached items 2019-07-08 13:41:20 +02:00
lotte
5c39d3c8d1 62849: progress july 5 2019-07-05 15:19:16 +02:00
lotte
998a7107a8 Merge branch 'w2p-63184_Relations-delete-feedback-1' into w2p-62849_relationships-in-submission 2019-07-05 13:37:28 +02:00
Kristof De Langhe
d734ed108e 63469: Intermediate commit 2019-07-04 17:52:14 +02:00
lotte
58f991aaa1 62849: added search results to lookup window with checkboxes 2019-06-27 13:31:44 +02:00
Kristof De Langhe
417f79ab6a 63184: Relationship list refreshing fix - Re-initializing itemUpdateSubscription 2019-06-27 11:55:10 +02:00
Kristof De Langhe
2f6c0fb126 63184: Fixed test cases 2019-06-27 10:19:53 +02:00
Kristof De Langhe
14d7437da9 63184: Edit-Relationships left/right Item refactoring 2019-06-26 17:47:44 +02:00
lotte
96959b401c added new input field type and started on lookup modal 2019-06-26 16:46:15 +02:00
Kristof De Langhe
74813aaedc Merge branch 'master' into w2p-63184_Relations-delete-feedback-1 2019-06-26 14:59:31 +02:00
Kristof De Langhe
d91b3b85b0 Merge branch 'master' into w2p-63123_Fix-filterRelationsByTypeLabel 2019-06-26 11:57:29 +02:00
Kristof De Langhe
966bcd31f6 63123: RelationshipSide argument for filterRelationsByTypeLabel, relationsToItems and new relationship util getRelatedItemsByTypeLabel 2019-06-26 11:55:49 +02:00
lotte
0746aaed43 added JSON response, created new submission section 2019-06-25 16:35:26 +02:00
lotte
deef684d70 Added response mocking service 2019-06-25 13:25:26 +02:00
lotte
78737ed1ab resolved lint errors 2019-06-25 11:26:40 +02:00
lotte
4106e7cb21 fixed remaining issues and tests 2019-06-25 11:17:22 +02:00
lotte
f980b55c1c refactored resource type and type mapping 2019-06-24 16:29:54 +02:00
Tim Donohue
395509a19a Merge pull request #408 from atmire/Relationship-items-HAL-links
Relationships link to items via HAL links
2019-06-21 23:50:49 +02:00
Tim Donohue
c244575e89 Merge pull request #425 from atmire/cleanup-search-service
Reverted #424
2019-06-21 23:41:55 +02:00
Kristof De Langhe
cc389e1149 Merge branch 'master' into w2p-62589_Item-mapper-update 2019-06-18 17:41:54 +02:00
Alexander Sulfrian
97374d47c5 Use delegation for MetadataSchemaDataService 2019-06-18 17:22:52 +02:00
Alexander Sulfrian
745245ef5d Add tests for ResourcePolicyService 2019-06-18 17:22:52 +02:00
Alexander Sulfrian
9ed8722169 Add missing ResourcePolicyService 2019-06-18 16:20:55 +02:00
lotte
bb76015aa1 Solved issue with non-existing search pages 2019-06-18 08:58:35 +02:00
Kristof De Langhe
080ea9e7a4 Merge branch 'master' into w2p-62339_Relationships-link-to-item-via-HAL-links 2019-06-17 13:33:15 +02:00
lotte
37fd04593b 62355: replaced all method calls in templates (except for metadata values...) 2019-06-14 16:15:45 +02:00
lotte
e1fea7f8e3 removed unnecessary code 2019-06-13 09:44:11 +02:00
Ben Bosman
a259446a60 metadata field updates for schema.org 2019-06-12 10:00:40 +02:00
Tim Donohue
e179596ac2 Merge pull request #424 from 4Science/DSpace#423
Fix issue with getSearchLink
2019-06-09 09:28:13 +02:00
Giuseppe Digilio
c956c212be Fix issue with getSearchLink 2019-06-08 19:38:29 +02:00
dependabot[bot]
cc7374351d Bump ecstatic from 3.2.2 to 3.3.2
Bumps [ecstatic](https://github.com/jfhbrook/node-ecstatic) from 3.2.2 to 3.3.2.
- [Release notes](https://github.com/jfhbrook/node-ecstatic/releases)
- [Changelog](https://github.com/jfhbrook/node-ecstatic/blob/3.3.2/CHANGELOG.md)
- [Commits](https://github.com/jfhbrook/node-ecstatic/compare/3.2.2...3.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-06-07 21:31:28 +00:00
Kristof De Langhe
3868b0aaae Merge branch 'master' into w2p-62589_Item-mapper-update 2019-06-07 16:35:40 +02:00
Kristof De Langhe
480a1b482a Merge branch 'master' into w2p-62063_Configurable-Browse-By 2019-06-07 16:22:57 +02:00
Kristof De Langhe
47994f9557 62741: Entities grid templates tests 2019-06-07 15:18:38 +02:00
Kristof De Langhe
0a32d3f915 62741: Remove whitespace and entity thumbnails from grid templates 2019-06-07 13:23:03 +02:00
Kristof De Langhe
22ae5a04e7 62741: Journal-types grid elements & grid thumbnail fix/improvement 2019-06-07 12:51:27 +02:00
Kristof De Langhe
d1bf380e46 restored empty html files 2019-06-07 11:12:58 +02:00
Kristof De Langhe
16bad82564 62741: Entities grid templates - publication, orgunit, person, project 2019-06-06 18:00:54 +02:00
Art Lowel
50c6cd4b27 Merge pull request #418 from 4Science/issue-#416
Fix #416
2019-06-06 17:35:44 +02:00
lotte
9f3997f103 reenabled default theme 2019-06-06 15:35:38 +02:00
lotte
1753d55d77 Merge branch 'master' into selectable-themes
Conflicts:
	src/app/core/core.effects.ts
2019-06-06 15:35:18 +02:00
lotte
20d15dab54 removed unnecessary config 2019-06-06 15:34:32 +02:00
Giuseppe Digilio
509cea087f when iterate over selected values, retrieve facet value from getFacetValue method 2019-06-06 15:02:42 +02:00
lotte
5bd1e050fe solve issue with backslashes in paths 2019-06-06 13:55:01 +02:00
Ben Bosman
2b1ce1e39a metadata field updates for schema.org 2019-06-06 13:23:12 +02:00
dependabot[bot]
0040ff2920 Bump handlebars from 4.0.11 to 4.1.2
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.0.11 to 4.1.2.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.11...v4.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-06-06 09:40:03 +00:00
Art Lowel
25edc3c952 Add support for resources in themes 2019-06-06 10:30:24 +02:00
Art Lowel
99ca2dedea Revert "switch to relative theme paths for windows support"
This reverts commit a5d61312
2019-06-06 09:28:39 +02:00
Art Lowel
a6bb83b4f8 Revert "make the relativethemePath relative to the project root instead of src root"
This reverts commit c6f18674
2019-06-06 09:28:34 +02:00
Art Lowel
2008c8bc92 Revert "always use forward slashes in relative theme paths"
This reverts commit 7fbde900
2019-06-06 09:28:28 +02:00
dependabot[bot]
072537968f Bump js-yaml from 3.12.0 to 3.13.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2019-06-06 04:38:52 +00:00
Art Lowel
7fbde90095 always use forward slashes in relative theme paths 2019-06-05 18:53:24 +02:00
Art Lowel
c6f1867478 make the relativethemePath relative to the project root instead of src root 2019-06-05 18:49:00 +02:00
Art Lowel
a5d6131238 switch to relative theme paths for windows support 2019-06-05 18:25:51 +02:00
Art Lowel
fac7cc266e remove dependency on replace-in-file 2019-06-05 17:17:53 +02:00
Art Lowel
743be6a2cd add projectroot to sass includedPaths instead of using replace to fix the paths during build 2019-06-05 17:14:22 +02:00
lotte
56b2ee1f0d fixed webpack.test config 2019-06-05 15:52:08 +02:00
lotte
d305adaa07 changed replace regexes to be windows compatible 2019-06-05 15:30:46 +02:00
lotte
ed128d1f17 removed node env variable 2019-06-05 14:25:58 +02:00
Art Lowel
5a47c2f4a7 fix case where there are no custom configs 2019-06-04 18:08:06 +02:00
dependabot[bot]
99b43e0a4e Bump pem from 1.12.3 to 1.13.2
Bumps [pem](https://github.com/Dexus/pem) from 1.12.3 to 1.13.2.
- [Release notes](https://github.com/Dexus/pem/releases)
- [Changelog](https://github.com/Dexus/pem/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Dexus/pem/compare/v1.12.3...v1.13.2)
2019-06-04 15:47:28 +00:00
Art Lowel
c58e6f6239 use config to determine active theme 2019-06-04 17:12:12 +02:00
Kristof De Langhe
9a915ae8c4 62651: person-metadata-list-element name fix 2019-06-04 15:41:58 +02:00
Ben Bosman
4f8d60c4d2 Discovery facet labels for new metadata fields 2019-06-04 12:03:57 +02:00
Kristof De Langhe
a7e8c279f2 62651: Fixed title on Person pages 2019-06-04 11:30:00 +02:00
Art Lowel
8bccdac99d fix dev build 2019-06-03 17:22:55 +02:00
Kristof De Langhe
a7fd250f4b Merge branch 'master' into w2p-62063_Configurable-Browse-By 2019-06-03 15:25:01 +02:00
Kristof De Langhe
bf469ef91b 62651: Entity item display and lists field changes 2019-06-03 15:03:53 +02:00
Tim Donohue
4a1a64b728 Merge pull request #409 from DSpace/dependabot/npm_and_yarn/webpack-bundle-analyzer-3.3.2
Bump webpack-bundle-analyzer from 2.13.1 to 3.3.2
2019-05-31 11:57:33 -05:00
Tim Donohue
95bd8c8653 Merge pull request #401 from atmire/Group-Entity-Types
Group logical entity types together
2019-05-31 11:42:13 -05:00
Tim Donohue
984da54e1a Merge pull request #407 from atmire/Fixed-filtered-search-page
Fixed filtered search page
2019-05-31 11:36:26 -05:00
Art Lowel
50effd3b70 fix exposed_variables issue with AoT build 2019-05-31 13:24:04 +02:00
lotte
16ebaf1bfe resolved PR feedback and solved possible bug 2019-05-31 13:10:47 +02:00
Art Lowel
d93173e8d2 add syncbuilddir step to aot build 2019-05-31 09:44:49 +02:00
dependabot[bot]
1f9e014df0 Bump webpack-bundle-analyzer from 2.13.1 to 3.3.2
Bumps [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) from 2.13.1 to 3.3.2.
- [Release notes](https://github.com/webpack-contrib/webpack-bundle-analyzer/releases)
- [Changelog](https://github.com/webpack-contrib/webpack-bundle-analyzer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/webpack-bundle-analyzer/compare/v2.13.1...v3.3.2)
2019-05-30 11:02:34 +00:00
Art Lowel
32e7b7a3b4 fix merge mistakes 2019-05-30 10:12:37 +02:00
Art Lowel
eca6aa9b04 refactor webpack config 2019-05-30 10:06:06 +02:00
Art Lowel
b352137fb3 add i18n labels for person facets 2019-05-29 18:05:30 +02:00
Kristof De Langhe
7d75454623 Merge branch 'travis-without-global-script' into w2p-62339_Relationships-link-to-item-via-HAL-links 2019-05-29 14:50:25 +02:00
lotte
813a856ed8 removed default value for search configuration 2019-05-29 13:48:50 +02:00
lotte
b846384ba7 Added typedoc and remove unnecessary import statements 2019-05-29 13:10:42 +02:00
Kristof De Langhe
acf83f6261 62589: Test provider fix 2019-05-29 12:03:27 +02:00
Kristof De Langhe
df730efbd0 62589: Provider and POST item-collection mapping fix 2019-05-29 11:44:34 +02:00
Kristof De Langhe
4143824bb8 Merge branch 'master' into w2p-62339_Relationships-link-to-item-via-HAL-links
Conflicts:
	src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts
	src/app/+item-page/simple/item-types/shared/item.component.ts
2019-05-29 10:27:19 +02:00
Kristof De Langhe
28fe62f918 62589: Fix mappedCollections endpoint 2019-05-29 10:01:47 +02:00
lotte
f763dcf752 Merge branch 'travis-without-global-script' into Fixed-filtered-search-page 2019-05-29 10:01:40 +02:00
lotte
b5c98e6917 Removed call to global script from travis setup 2019-05-29 10:00:08 +02:00
lotte
49dc4b86e2 Fixed issue with switch component on mydspace page 2019-05-29 09:24:33 +02:00
Philip Vissenaekens
a419e64cef 62571: removed duplicate line 2019-05-28 17:13:18 +02:00
Kristof De Langhe
045b87c1c8 62589: Post-Merge Tests and error fixes 2019-05-28 17:03:57 +02:00
Kristof De Langhe
2b1fd76365 62589: Fixed order of imports messing with routes 2019-05-28 16:42:02 +02:00
Art Lowel
da4115f122 fix issues following rebase 2019-05-28 16:21:02 +02:00
Kristof De Langhe
41e14e176c Merge branch 'master' into w2p-62589_Item-mapper-update
Conflicts:
	resources/i18n/en.json
	src/app/+collection-page/collection-page-routing.module.ts
	src/app/+collection-page/collection-page.module.ts
	src/app/+community-page/community-page.component.ts
	src/app/+item-page/edit-item-page/edit-item-page.component.ts
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts
	src/app/+item-page/edit-item-page/item-delete/item-delete.component.spec.ts
	src/app/+item-page/edit-item-page/item-delete/item-delete.component.ts
	src/app/+item-page/edit-item-page/item-private/item-private.component.spec.ts
	src/app/+item-page/edit-item-page/item-private/item-private.component.ts
	src/app/+item-page/edit-item-page/item-public/item-public.component.spec.ts
	src/app/+item-page/edit-item-page/item-public/item-public.component.ts
	src/app/+item-page/edit-item-page/item-reinstate/item-reinstate.component.spec.ts
	src/app/+item-page/edit-item-page/item-reinstate/item-reinstate.component.ts
	src/app/+item-page/edit-item-page/item-status/item-status.component.ts
	src/app/+item-page/edit-item-page/item-withdraw/item-withdraw.component.spec.ts
	src/app/+item-page/edit-item-page/item-withdraw/item-withdraw.component.ts
	src/app/+item-page/edit-item-page/simple-item-action/abstract-simple-item-action.component.spec.ts
	src/app/+item-page/item-page-routing.module.ts
	src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts
	src/app/+search-page/search-filters/search-filter/search-filter.component.ts
	src/app/+search-page/search-service/search.service.ts
	src/app/app.reducer.ts
	src/app/core/auth/auth-response-parsing.service.ts
	src/app/core/auth/auth.service.ts
	src/app/core/auth/server-auth.service.ts
	src/app/core/cache/builders/remote-data-build.service.ts
	src/app/core/cache/object-cache.service.ts
	src/app/core/core.module.ts
	src/app/core/data/collection-data.service.ts
	src/app/core/data/data.service.ts
	src/app/core/data/item-data.service.spec.ts
	src/app/core/data/item-data.service.ts
	src/app/core/data/request.models.ts
	src/app/core/data/request.reducer.ts
	src/app/core/data/request.service.spec.ts
	src/app/core/data/request.service.ts
	src/app/core/index/index.effects.ts
	src/app/core/index/index.reducer.ts
	src/app/core/metadata/metadata.service.spec.ts
	src/app/core/shared/operators.spec.ts
	src/app/core/shared/operators.ts
	src/app/header/header.component.spec.ts
	src/app/shared/shared.module.ts
2019-05-28 16:15:47 +02:00
Yana De Pauw
93075fc70f Merge branch 'w2p-55990_Move-item-component' into Move-item-component 2019-05-28 16:10:23 +02:00
Yana De Pauw
74bf69f984 62571: Move item update and test fixes 2019-05-28 15:47:42 +02:00
lotte
898795fba1 Solved issue where edit metadata page broke 2019-05-28 14:58:35 +02:00
lotte
81ba49f220 Simplified and refactored manual creation of remote data objects for tests 2019-05-28 14:58:10 +02:00
Art Lowel
11d06e34b1 moved themes to separate folder 2019-05-28 14:20:21 +02:00
lotte
cfcf496cc1 fixed tests 2019-05-28 14:18:56 +02:00
lotte
8a32777802 finished webpack config for switching themes 2019-05-28 14:18:56 +02:00
lotte
22928c3f23 intermediate theming commit 2019-05-28 13:53:12 +02:00
lotte
4a37759dea 61872: switching themes using wpack string replacer 2019-05-28 13:52:45 +02:00
lotte
3a7929369a working on extracting CSS in a separate file 2019-05-28 13:52:15 +02:00
lotte
139edd2df1 renamed theme to Mantis 2019-05-28 13:51:56 +02:00
lotte
1d99d8a535 61299: solved merge conflicts 2019-05-28 13:50:53 +02:00
lotte
a8aea654a1 cleaned up theming code 2019-05-28 13:50:29 +02:00
lotte
c0f3d38695 added banner and changed fonts 2019-05-28 13:47:43 +02:00
lotte
2cc3dd0694 added custom theming 2019-05-28 13:46:51 +02:00
lotte
856211d964 finished SCSS theming support 2019-05-28 13:44:00 +02:00
lotte
a4a4be9983 added different themes, issue with ngrx 2019-05-28 13:42:20 +02:00
Yana De Pauw
d55e234167 Merge remote-tracking branch 'upstream/master' into w2p-55990_Move-item-component 2019-05-28 13:15:43 +02:00
Yana De Pauw
395a78c360 62571: Update item move method 2019-05-28 13:14:59 +02:00
Yana De Pauw
41e9770a61 Merge branch 'master' into w2p-55990_Move-item-component 2019-05-28 11:50:32 +02:00
lotte
35f73708ef fixed issues after merging 2019-05-27 15:09:51 +02:00
lotte
a0a0830e5f 61949: merged master, resolving conflicts 2019-05-24 16:57:38 +02:00
lotte
233909d6ca Merge branch 'master' into w2p-61949_object-factory-refactoring
Conflicts:
	src/app/core/cache/models/normalized-object-factory.ts
	src/app/core/cache/response.models.ts
	src/app/core/core.module.ts
	src/app/core/data/base-response-parsing.service.ts
	src/app/core/shared/resource-type.ts
	src/app/core/submission/submission-response-parsing.service.ts
2019-05-24 15:42:24 +02:00
Kristof De Langhe
fca9b4d481 Merge branch 'master' into w2p-62063_Configurable-Browse-By 2019-05-24 14:13:24 +02:00
Kristof De Langhe
1fb6b45560 62063: 62063: Small Issue fixes 2019-05-24 14:12:43 +02:00
lotte
24fdbaf0bd 62530: fixed loading issue 2019-05-23 16:15:40 +02:00
lotte
c3bd151cc3 Fixed issue with retrieving request 2019-05-22 16:55:49 +02:00
lotte
8a5bffa881 62530: working on fixing preboot issue with fixed filters/route params 2019-05-21 17:02:36 +02:00
Kristof De Langhe
796afb3919 Merge branch 'master' into w2p-61142_Relations-add-edit-delete-and-permissions
Conflicts:
	src/app/core/cache/object-cache.service.ts
	src/app/core/core.module.ts
	src/app/core/data/request.service.ts
	src/app/core/shared/item.model.ts
2019-05-20 13:08:33 +02:00
Kristof De Langhe
b8822e996d 62264: Fix module export 2019-05-20 10:50:49 +02:00
Kristof De Langhe
e9bfb77300 Merge branch 'master' into w2p-62264_Group-logical-entity-types-together 2019-05-20 10:09:20 +02:00
Tim Donohue
2d07cc1913 Reset URL to use DSpace 7 REST API Demo site. 2019-05-17 13:37:57 -05:00
Tim Donohue
31c9694666 Merge pull request #398 from atmire/preview-misc-fixes-2
Miscellaneous fixes for Preview Release - Part 2
2019-05-17 10:07:50 -05:00
Kristof De Langhe
098298c1ea 62339: Remove f from fdescribe 2019-05-10 14:07:17 +02:00
Kristof De Langhe
37a8b9f253 62339: ItemComponent test fixes 2019-05-10 14:06:23 +02:00
Kristof De Langhe
54371503ae 62339: JSDocs 2019-05-10 13:47:27 +02:00
Kristof De Langhe
38625d2cd5 62339: itemIds to item remotedata in relationships 2019-05-10 13:44:58 +02:00
Kristof De Langhe
7ef769431a 62264: Fixed tests 2019-05-10 10:43:23 +02:00
Kristof De Langhe
461eacff45 62264: Group messages 2019-05-10 10:19:51 +02:00
Kristof De Langhe
2166e0633c 62264: Grouped logical entity types together into separate modules 2019-05-09 17:51:11 +02:00
Kristof De Langhe
80c7b86084 62063: browse-by-switcher + decorator tests 2019-05-06 15:27:16 +02:00
Kristof De Langhe
af2d376fb9 62063: Fixed existing tests 2019-05-06 14:08:55 +02:00
Kristof De Langhe
369a6dfaea 62063: JSDocs and comments 2019-04-30 17:24:58 +02:00
Kristof De Langhe
41e55d8d44 62063: Configurable Browse-By menus 2019-04-30 16:54:50 +02:00
Kristof De Langhe
67e5578bba 62063: Configurable browse-by 2019-04-30 16:24:22 +02:00
lotte
b2ceb8e9d6 61949: finished refactoring, adding type doc 2019-04-29 16:21:36 +02:00
lotte
af291845ec continued refactoring 2019-04-26 16:40:49 +02:00
lotte
6438c65381 continued refactoring resource type factories 2019-04-25 17:13:58 +02:00
Kristof De Langhe
15ed0cc8fa 61947: Thumbnail display fix 2019-04-25 11:34:01 +02:00
lotte
a5086b8d11 61949: replacing object factories with decorator 2019-04-24 16:51:46 +02:00
Kristof De Langhe
5a06c9195e 61142: Author seperator in publication list elements 2019-04-18 17:42:38 +02:00
Kristof De Langhe
dacf813676 61142: Notifications on failed relationship delete requests 2019-04-18 17:24:24 +02:00
Kristof De Langhe
eeb2c790c1 61142: Fixed AoT build errors 2019-04-08 16:16:55 +02:00
Kristof De Langhe
bbbd6959a8 61142: EditRelationshipList component to proper reload relationships and fix performance issues 2019-04-08 15:28:18 +02:00
Kristof De Langhe
01b60dbf34 61142: RemoveByHrefSubstring fix 2019-04-05 17:28:20 +02:00
Kristof De Langhe
9f27a89dc4 61142: RelationshipService tests 2019-04-05 15:21:10 +02:00
Kristof De Langhe
b78b2e5b82 61142: EditRelationshipComponent tests + de-caching of requests in ItemRelationships 2019-04-05 13:46:48 +02:00
Kristof De Langhe
0cf4cdc1c5 61142: ItemRelationshipComponent test + item de-caching 2019-04-04 17:43:40 +02:00
Kristof De Langhe
bb68373489 61142: Working submit (except reloading lists) and JSDocs 2019-04-04 15:19:28 +02:00
Kristof De Langhe
1e31fadb70 61142: Submit intermediate commit 2019-04-04 12:39:25 +02:00
Kristof De Langhe
3d9b3c68f3 61142: Layout improvement 2019-04-03 17:51:10 +02:00
Kristof De Langhe
7a74c3355b 61142: RelationshipService 2019-04-03 14:22:07 +02:00
Kristof De Langhe
a99fa4d4a2 61142: Renaming and refactoring item-relationships 2019-04-03 13:05:43 +02:00
Kristof De Langhe
4a749cf91d 61142: AbstractItemUpdate component and refactoring of item-metadata and item-relationships 2019-04-03 11:58:45 +02:00
Kristof De Langhe
cc862af249 61142: Item relations initial edit page 2019-04-02 17:36:51 +02:00
Kristof De Langhe
47294d37bf Merge branch 'master' into Item-Collection_Mapper
Conflicts:
	resources/i18n/en.json
	src/app/+item-page/edit-item-page/edit-item-page.component.ts
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts
	src/app/+item-page/edit-item-page/item-status/item-status.component.html
	src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts
	src/app/+item-page/edit-item-page/item-status/item-status.component.ts
	src/app/+item-page/item-page-routing.module.ts
	src/app/core/data/item-data.service.spec.ts
	src/app/core/data/item-data.service.ts
	src/app/core/shared/operators.spec.ts
	src/app/core/shared/operators.ts
2019-01-17 15:57:25 +01:00
Art Lowel
ff924abcfb fix a typo in a comment 2019-01-10 17:06:49 +01:00
Art Lowel
04ad79e416 remove exportToZip config property that was added accidentally 2019-01-10 13:16:27 +01:00
Art Lowel
0b164b33b9 remove unused 'first' imports 2019-01-10 13:14:20 +01:00
Kristof De Langhe
532cd4d717 Merge branch 'master' into w2p-55946_Item-mapping-on-item-level 2018-12-31 10:33:56 +01:00
Kristof De Langhe
eb7b4cbf0e 55946: Destroy on hide to prevent pagination issues 2 2018-12-31 10:19:15 +01:00
Kristof De Langhe
aeba5d683d 55946: Destroy on hide to prevent pagination issues 2018-12-31 10:18:32 +01:00
Kristof De Langhe
6e7024e31e Merge branch 'master' into w2p-55946_Item-mapping-on-item-level
Conflicts:
	src/app/+community-page/community-page.component.html
	src/app/app.reducer.ts
	src/app/core/auth/server-auth.service.ts
	src/app/core/core.module.ts
	src/app/core/index/index.effects.ts
	src/app/core/index/index.reducer.spec.ts
	src/app/core/index/index.reducer.ts
	src/app/header/header.component.spec.ts
	src/app/shared/shared.module.ts
2018-12-21 13:53:10 +01:00
Kristof De Langhe
13c1a553a1 55946: Remove TODOs (fixed) 2018-12-21 13:12:33 +01:00
Kristof De Langhe
69f4846407 55946: Removed console log 2018-12-20 16:13:26 +01:00
Kristof De Langhe
f2bfdbcf84 55946: Prevent list update from calling mapper over and over 2018-12-20 16:11:25 +01:00
Kristof De Langhe
1f19324ff6 55946: fdescribe to describe 2018-12-20 15:00:18 +01:00
Kristof De Langhe
90b4a0bf2d 55946: Fixed imports and declarations on ItemCollectionMapperComponent tests 2018-12-20 14:59:31 +01:00
Kristof De Langhe
c242ba0412 Merge branch 'response-cache-refactoring' into w2p-55946_Item-mapping-on-item-level 2018-12-20 13:26:12 +01:00
Kristof De Langhe
8bbc89d8f4 Merge branch 'response-cache-refactoring' into w2p-55946_Item-mapping-on-item-level 2018-12-20 11:04:46 +01:00
Kristof De Langhe
0193893e75 Merge branch 'response-cache-refactoring' into w2p-55946_Item-mapping-on-item-level
Conflicts:
	src/app/core/cache/builders/remote-data-build.service.ts
2018-12-19 15:55:41 +01:00
Yana De Pauw
1e62262050 Remove unrelated ItemOperation 2018-12-19 13:20:42 +01:00
Kristof De Langhe
791325f584 55946: TSLint fixes 2018-12-07 17:17:54 +01:00
Yana De Pauw
e2420c56d3 Fix item opertation test issue 2018-12-06 15:59:45 +01:00
Yana De Pauw
a698b56ae8 55990: Fix issues to move item component after master merge 2018-12-06 10:42:37 +01:00
Yana De Pauw
03d789560c Merge branch 'master' into w2p-55990_Move-item-component 2018-12-05 15:49:06 +01:00
Kristof De Langhe
32db97e67d 55946: Spec file fixes 2018-11-30 17:31:09 +01:00
Yana De Pauw
8498a16979 55990: Item move - tweaks 2018-11-30 11:18:57 +01:00
Yana De Pauw
b36a2ea66b 55990: Move item component - fix message 2018-11-29 11:39:57 +01:00
Yana De Pauw
eaa297cd90 Merge branch 'master' into w2p-55990_Move-item-component 2018-11-29 11:02:57 +01:00
Kristof De Langhe
930af49030 55946: Fixed tests and added JSDocs 2018-11-27 16:45:53 +01:00
Kristof De Langhe
2053078a16 55946: Dynamic reloading of item mapper on item-level 2018-11-27 14:54:53 +01:00
Yana De Pauw
849396459e 55990: Fix param name 2018-11-27 14:38:19 +01:00
Kristof De Langhe
55e37a63bc 55946: discovery requests reset and reload and list updates 2018-11-27 14:20:24 +01:00
Yana De Pauw
4411c312e5 55990: Add move item component 2018-11-26 16:28:39 +01:00
Kristof De Langhe
4307cb0ff1 55946: Clear data/request attached to the hrefs deleted from index 2018-11-26 13:18:17 +01:00
Kristof De Langhe
e275fe590b 55946: Remove href-to-uuid index cache on mapping 2018-11-23 17:58:14 +01:00
Kristof De Langhe
aa172b6c68 55946: Changes to comply to the new response cache features 2018-11-23 17:03:35 +01:00
Kristof De Langhe
7f0e7980cd Merge branch 'response-cache-refactoring' into w2p-55946_Item-mapping-on-item-level
Conflicts:
	src/app/core/data/data.service.ts
	src/app/core/data/item-data.service.ts
	src/app/shared/shared.module.ts
	src/app/shared/testing/active-router-stub.ts
2018-11-23 16:46:27 +01:00
Kristof De Langhe
44d18d2fb6 55946: Exclude already mapped collections from Map tab 2018-11-16 17:08:08 +01:00
Kristof De Langhe
3e75bc5591 55946: Search box inside Map tab on item-level 2018-11-16 14:32:13 +01:00
Kristof De Langhe
1c013bc85b Merge branch 'w2p-55693_Item-mapping-to-collections' into w2p-55946_Item-mapping-on-item-level
Conflicts:
	src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.html
2018-11-16 14:30:01 +01:00
Kristof De Langhe
904ee2cab4 55693: Search box inside Map tab 2018-11-16 14:21:48 +01:00
Kristof De Langhe
8d396f3832 55946: Multi-list object select support 2018-11-16 13:55:00 +01:00
Kristof De Langhe
08063154e7 55946: object-select store lists intermediate commit 2018-11-15 14:13:16 +01:00
Kristof De Langhe
b11a168e72 55946: CollectionItemMapper test fixes after merge 2018-11-14 10:54:47 +01:00
Kristof De Langhe
512b678b73 Merge branch 'w2p-55693_Item-mapping-to-collections' into w2p-55946_Item-mapping-on-item-level 2018-11-14 10:38:50 +01:00
Kristof De Langhe
e61467bb7f 55693: JSDocs and Test fixes 2018-11-14 10:37:27 +01:00
Kristof De Langhe
31fe5efaa1 Merge branch 'w2p-55693_Item-mapping-to-collections' into w2p-55946_Item-mapping-on-item-level 2018-11-13 17:57:55 +01:00
Kristof De Langhe
469b424cfe 55693: Map tab excludes already mapped items 2018-11-13 17:50:02 +01:00
Kristof De Langhe
2a4eebcfc4 Merge branch 'w2p-55693_Item-mapping-to-collections' into w2p-55946_Item-mapping-on-item-level
Conflicts:
	src/app/core/data/item-data.service.ts
2018-11-13 16:03:31 +01:00
Kristof De Langhe
7bd8fae72a 55693: Fixed getMappedItems to use object cache instead of response 2018-11-13 15:31:32 +01:00
Kristof De Langhe
0d89eb6cce 55693: TODO location query 2018-11-07 14:39:49 +01:00
Kristof De Langhe
9902209fb9 55946: Small import fix 2018-11-07 13:09:00 +01:00
Kristof De Langhe
dd36913496 55693: Functionality for removing mappings 2018-11-06 16:38:00 +01:00
Kristof De Langhe
3d9e4a66ff 55693: Mapped items using new REST endpoint + item-select component 2018-11-06 16:18:25 +01:00
Yana De Pauw
d26bba8e14 5590: Item move component 2018-10-25 18:14:22 +02:00
Yana De Pauw
8570ff2578 55990: Item move component 2018-10-25 18:13:49 +02:00
Kristof De Langhe
fc96700475 55946: Fixed search query not working 2018-10-11 11:16:47 +02:00
Kristof De Langhe
8f0d7b6a4e 55946: ItemCollectionMapperComponent tests 2018-10-11 10:10:45 +02:00
Kristof De Langhe
497f089c2f 55946: Improvement on mapping by excluding already existing mapped collections 2018-10-10 17:31:18 +02:00
Kristof De Langhe
378fbe86f4 55946: Functionality for removing mappings 2018-10-10 16:15:53 +02:00
Kristof De Langhe
dd38e61230 55946: Functional item-collection-mapper 2018-10-10 15:31:58 +02:00
Kristof De Langhe
0cf91fb05e 55946: Removal of unnecessary scss files and test fixes 2018-10-10 13:51:02 +02:00
Kristof De Langhe
0b3b5d3965 55946: Refactoring of object-select and collection-select component 2018-10-10 13:30:29 +02:00
Kristof De Langhe
c4203f25d5 55946: Refactored item-select to object-select to allow for easier implementation of collection-select 2018-10-09 17:16:43 +02:00
Kristof De Langhe
7021527f5c 55946: Fixed api calls for fetching collections with/without item 2018-10-09 16:33:33 +02:00
Kristof De Langhe
c25340fca0 erge branch 'w2p-55946_Item-mapping-on-item-level-old' into w2p-55946_Item-mapping-on-item-level
Conflicts:
	resources/i18n/en.json
	src/app/+item-page/edit-item-page/edit-item-page.component.ts
	src/app/+item-page/edit-item-page/edit-item-page.module.ts
	src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts
	src/app/+item-page/edit-item-page/item-status/item-status.component.html
	src/app/+item-page/edit-item-page/item-status/item-status.component.ts
2018-10-09 16:01:32 +02:00
Kristof De Langhe
7d9afeefea 55946: Removed unnecessary files and created tests 2018-10-09 15:32:55 +02:00
Kristof De Langhe
fb0e1d81e4 55946: Edit item page cleanup 2018-10-09 14:30:40 +02:00
Kristof De Langhe
05a4918ef0 55946: Finished edit-item-page and start of collection mapper 2018-10-09 14:15:59 +02:00
Kristof De Langhe
ec96962a87 55946: Start of Edit Item Page
Conflicts:
	resources/i18n/en.json
2018-10-09 14:15:56 +02:00
Kristof De Langhe
6bc4d061f1 55946: Intermediate commit 2018-10-09 14:09:56 +02:00
Kristof De Langhe
3a809cc671 55946: Finished edit-item-page and start of collection mapper 2018-10-09 11:51:52 +02:00
Kristof De Langhe
ba4d2861f5 55946: Start of Edit Item Page 2018-10-08 17:50:52 +02:00
Kristof De Langhe
24f6f982e9 55693: Authentication Guard and TSDocs 2018-10-01 14:14:26 +02:00
Kristof De Langhe
5f56d5959d 55693: ItemSelectReducer tests 2018-10-01 13:40:29 +02:00
Kristof De Langhe
199e6c7299 55693: Empty ItemSelectReducer test file 2018-10-01 11:43:37 +02:00
Kristof De Langhe
7934b87336 55693: ItemSelectService tests 2018-10-01 11:38:13 +02:00
Kristof De Langhe
8b99ea44b2 ItemSelectComponent tests 2018-10-01 10:30:05 +02:00
Kristof De Langhe
c3add84d86 55693: ItemSelectComponent tests intermediate + ItemSelectServiceStub 2018-09-28 17:31:05 +02:00
Kristof De Langhe
95b4635291 55693: CollectionItemMapperComponent tests 2018-09-28 16:02:39 +02:00
Kristof De Langhe
44caed878c Merge branch 'master' into w2p-55693_Item-mapping-to-collections
Conflicts:
	src/app/core/auth/auth-response-parsing.service.ts
	src/app/core/auth/auth.service.ts
	src/app/core/auth/models/auth-status.model.ts
	src/app/core/auth/models/normalized-auth-status.model.ts
	src/app/core/auth/server-auth.service.ts
	src/app/shared/testing/auth-request-service-stub.ts
	src/app/shared/testing/auth-service-stub.ts
2018-09-28 13:26:24 +02:00
Kristof De Langhe
e1c734e113 55693: CollectionItemMapperComponent test intermediate 2018-09-28 12:43:38 +02:00
Kristof De Langhe
0a8a6bb720 55693: Messages improvement 2018-09-28 11:27:53 +02:00
Kristof De Langhe
ba8be3f57d 55693: Temporary pagination fix (remove url params on tab change) 2018-09-28 10:56:17 +02:00
Kristof De Langhe
7b74d9c077 55693: Notifications on success/failure and small refactoring 2018-09-27 17:08:52 +02:00
Kristof De Langhe
6f64b943f5 Merge branch 'Authentication-issue-fix' into w2p-55693_Item-mapping-to-collections 2018-09-27 13:16:34 +02:00
Kristof De Langhe
4731da83cd 55693: Intermediate Commit 2018-09-27 13:16:26 +02:00
Kristof De Langhe
ce134bbd10 55693: emit only once and reset selected items + notification 2018-09-27 11:46:26 +02:00
Kristof De Langhe
09a84edb09 55693: Working store interaction for selecting items 2018-09-27 11:09:36 +02:00
Kristof De Langhe
5040d230fb 55693: (incomplete) store interraction for selecting items 2018-09-26 17:30:24 +02:00
Kristof De Langhe
9440401ca3 55693: Fixed scope being passed between tabs 2018-09-26 13:16:56 +02:00
Kristof De Langhe
3dc09062d0 55693: Tabset 2018-09-26 11:45:10 +02:00
Kristof De Langhe
315b6a9690 55693: Intermediate commit 2018-09-26 11:02:11 +02:00
Kristof De Langhe
6b986c8c91 55693: Item mapper page + ItemSelectComponent 2018-09-26 09:44:01 +02:00
1759 changed files with 126923 additions and 19971 deletions

View File

@@ -1,21 +1,28 @@
.git
node-modules
__build__
__server_build__
.idea
.vscode
.DS_Store
*.iml
# Build folders
node_modules
build
dist
typings
tsd_typings
npm-debug.log
dist
coverage
.idea
*.iml
__build__
__server_build__
# Node
*.log
npm-debug.log.*
# Angular files
*.ngfactory.ts
*.css.shim.ts
*.scss.shim.ts
.DS_Store
# Webpack files
webpack.records.json
npm-debug.log.*
morgan.log
yarn-error.log
*.css
package-lock.json

28
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,28 @@
## References
_Add references/links to any related tickets or PRs. These may include:_
* Link to [Angular issue or PR](https://github.com/DSpace/dspace-angular/issues) related to this PR, if any
* Link to [JIRA](https://jira.lyrasis.org/projects/DS/summary) ticket(s), if any
## Description
Short summary of changes (1-2 sentences).
## Instructions for Reviewers
Please add a more detailed description of the changes made by your PR. At a minimum, providing a bulleted list of changes in your PR is helpful to reviewers.
List of changes in this PR:
* First, ...
* Second, ...
**Include guidance for how to test or review your PR.** This may include: steps to reproduce a bug, screenshots or description of a new feature, or reasons behind specific changes.
## Checklist
_This checklist provides a reminder of what we are going to look for when reviewing your PR. You need not complete this checklist prior to creating your PR (draft PRs are always welcome). If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!_
- [ ] My PR is small in size (e.g. less than 1,000 lines of code, not including comments & specs/tests), or I have provided reasons as to why that's not possible.
- [ ] My PR passes [TSLint](https://palantir.github.io/tslint/) validation using `yarn run lint`
- [ ] My PR includes [TypeDoc](https://typedoc.org/) comments for _all new (or modified) public methods and classes_. It also includes TypeDoc for large or complex private methods.
- [ ] My PR passes all specs/tests and includes new/updated specs for any bug fixes, improvements or new features. A few reminders about what constitutes good tests:
* Include tests for different user types (if behavior differs), including: (1) Anonymous user, (2) Logged in user (non-admin), and (3) Administrator.
* Include tests for error scenarios, e.g. when errors/warnings should appear (or buttons should be disabled).
* For bug fixes, include a test that reproduces the bug and proves it is fixed. For clarity, it may be useful to provide the test in a separate commit from the bug fix.
- [ ] If my PR includes new, third-party dependencies (in `package.json`), I've made sure their licenses align with the [DSpace BSD License](https://github.com/DSpace/DSpace/blob/master/LICENSE) based on the [Licensing of Contributions](https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines#CodeContributionGuidelines-LicensingofContributions) documentation.

4
.gitignore vendored
View File

@@ -5,6 +5,8 @@
/tsd_typings/
npm-debug.log
/build/
/config/environment.dev.js
/config/environment.prod.js
@@ -32,3 +34,5 @@ yarn-error.log
*.css
package-lock.json
.java-version

View File

@@ -1,32 +1,58 @@
sudo: required
dist: trusty
addons:
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
dist: bionic
env:
# Install the latest docker-compose version for ci testing.
# The default installation in travis is not compatible with the latest docker-compose file version.
COMPOSE_VERSION: 1.24.1
# The ci step will test the dspace-angular code against DSpace REST.
# Direct that step to utilize a DSpace REST service that has been started in docker.
DSPACE_REST_HOST: localhost
DSPACE_REST_PORT: 8080
DSPACE_REST_NAMESPACE: '/server/api'
DSPACE_REST_SSL: false
services:
- xvfb
before_install:
# Docker Compose Install
- curl -L https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
install:
# update chrome
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
- sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
- sudo apt-get update
- sudo apt-get install google-chrome-stable
# Start up DSpace 7 using the entities database dump
- docker-compose -f ./docker/docker-compose-travis.yml up -d
# Use the dspace-cli image to populate the assetstore. Trigger a discovery and oai update
- docker-compose -f ./docker/cli.yml -f ./docker/cli.assetstore.yml run --rm dspace-cli
- travis_retry yarn install
before_script:
# The following line could be enabled to verify that the rest server is responding.
# Currently, "yarn run build" takes enough time to run to allow the service to be available
#- curl http://localhost:8080/
after_script:
- docker-compose -f ./docker/docker-compose-travis.yml down
language: node_js
node_js:
- "8"
- "9"
- "10"
- "12"
cache:
yarn: true
bundler_args: --retry 5
before_install:
- travis_retry yarn run global
install:
- travis_retry yarn install
script:
# Use Chromium instead of Chrome.
- export CHROME_BIN=chromium-browser
- yarn run build
- yarn run ci
- cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js

View File

@@ -1,10 +1,12 @@
# This image will be published as dspace/dspace-angular
# See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details
FROM node:8-alpine
FROM node:12-alpine
WORKDIR /app
ADD . /app/
EXPOSE 3000
RUN yarn install
# We run yarn install with an increased network timeout (5min) to avoid "ESOCKETTIMEDOUT" errors from hub.docker.com
# See, for example https://github.com/yarnpkg/yarn/issues/5540
RUN yarn install --network-timeout 300000
CMD yarn run watch

39
LICENSE Normal file
View File

@@ -0,0 +1,39 @@
DSpace source code BSD License:
Copyright (c) 2002-2020, LYRASIS. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name DuraSpace nor the name of the DSpace Foundation
nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
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.

15
LICENSES_THIRD_PARTY Normal file
View File

@@ -0,0 +1,15 @@
DSpace uses third-party libraries which may be distributed under different licenses.
A summary of all third-party, production dependencies used by this user interface may be found by running:
npx license-checker --production --summary
(Additional license-checker options may be found in its documentation: https://github.com/davglass/license-checker)
You must agree to the terms of these licenses, in addition to the DSpace source code license, in order to use this
software.
PLEASE NOTE: Some third-party dependencies may be listed under multiple licenses if they are dual-licensed.
This is especially true of anything listed as GPL (or similar), as DSpace does NOT allow for the inclusion of
any dependencies that are solely released under GPL (or similar) terms. For more info see:
https://wiki.lyrasis.org/display/DSPACE/Code+Contribution+Guidelines#CodeContributionGuidelines-LicensingofContributions

View File

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

View File

@@ -13,7 +13,7 @@ module.exports = {
host: 'dspace7.4science.cloud',
port: 443,
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: '/dspace-spring-rest/api'
nameSpace: '/server/api'
},
// Caching settings
cache: {
@@ -140,7 +140,19 @@ module.exports = {
}, {
code: 'nl',
label: 'Nederlands',
active: false,
active: true,
}, {
code: 'pt',
label: 'Português',
active: true,
}, {
code: 'fr',
label: 'Français',
active: true,
}, {
code: 'lv',
label: 'Latviešu',
active: true,
}],
// Browse-By Pages
browseBy: {
@@ -149,11 +161,44 @@ module.exports = {
// 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
defaultLowerLimit: 1900,
// List of all the active Browse-By types
// Adding a type will activate their Browse-By page and add them to the global navigation menu, as well as community and collection pages
// Allowed fields and their purpose:
// id: The browse id to use for fetching info from the rest api
// type: The type of Browse-By page to display
// metadataField: The metadata-field used to create starts-with options (only necessary when the type is set to 'date')
types: [
{
id: 'title',
type: 'title'
},
{
id: 'dateissued',
type: 'date',
metadataField: 'dc.date.issued'
},
{
id: 'author',
type: 'metadata'
},
{
id: 'subject',
type: 'metadata'
}
]
},
item: {
edit: {
undoTimeout: 10000 // 10 seconds
}
},
collection: {
edit: {
undoTimeout: 10000 // 10 seconds
}
},
theme: {
name: 'default',
}
};

View File

@@ -1,3 +1,4 @@
// This configuration is currently only being used for unit tests, end-to-end tests use environment.dev.ts
module.exports = {
};

79
docker/README.md Normal file
View File

@@ -0,0 +1,79 @@
# Docker Compose files
## docker directory
- docker-compose.yml
- Starts DSpace Angular with Docker Compose from the current branch. This file assumes that a DSpace 7 REST instance will also be started in Docker.
- docker-compose-rest.yml
- Runs a published instance of the DSpace 7 REST API - persists data in Docker volumes
- docker-compose-travis.yml
- Runs a published instance of the DSpace 7 REST API for CI testing. The database is re-populated from a SQL dump on each startup.
- cli.yml
- Docker compose file that provides a DSpace CLI container to work with a running DSpace REST container.
- 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.
- environment.dev.js
- 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
```
docker-compose -f docker/docker-compose.yml pull
```
## To build DSpace images using code in your branch
```
docker-compose -f docker/docker-compose.yml build
```
## To start DSpace (REST and Angular) from your branch
```
docker-compose -p d7 -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d
```
## Run DSpace REST and DSpace Angular from local branches.
_The system will be started in 2 steps. Each step shares the same docker network._
From DSpace/DSpace (build as needed)
```
docker-compose -p d7 up -d
```
From DSpace/DSpace-angular
```
docker-compose -p d7 -f docker/docker-compose.yml up -d
```
## Ingest test data from AIPDIR
Create an administrator
```
docker-compose -p d7 -f docker/cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en
```
Load content from AIP files
```
docker-compose -p d7 -f docker/cli.yml -f ./docker/cli.ingest.yml run --rm dspace-cli
```
## Alternative Ingest - Use Entities dataset
_Delete your docker volumes or use a unique project (-p) name_
Start DSpace with Database Content from a database dump
```
docker-compose -p d7 -f docker/docker-compose.yml -f docker/docker-compose-rest.yml -f docker/db.entities.yml up -d
```
Load assetstore content and trigger a re-index of the repository
```
docker-compose -p d7 -f docker/cli.yml -f docker/cli.assetstore.yml run --rm dspace-cli
```
## End to end testing of the rest api (runs in travis).
_In this instance, only the REST api runs in Docker using the Entities dataset. Travis will perform CI testing of Angular using Node to drive the tests._
```
docker-compose -p d7ci -f docker/docker-compose-travis.yml up -d
```

23
docker/cli.assetstore.yml Normal file
View File

@@ -0,0 +1,23 @@
version: "3.7"
networks:
dspacenet:
services:
dspace-cli:
networks:
dspacenet: {}
environment:
- LOADASSETS=https://www.dropbox.com/s/zv7lj8j2lp3egjs/assetstore.tar.gz?dl=1
entrypoint:
- /bin/bash
- '-c'
- |
if [ ! -z $${LOADASSETS} ]
then
curl $${LOADASSETS} -L -s --output /tmp/assetstore.tar.gz
cd /dspace
tar xvfz /tmp/assetstore.tar.gz
fi
/dspace/bin/dspace index-discovery

32
docker/cli.ingest.yml Normal file
View File

@@ -0,0 +1,32 @@
#
# 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/
#
version: "3.7"
services:
dspace-cli:
environment:
- AIPZIP=https://github.com/DSpace-Labs/AIP-Files/raw/master/dogAndReport.zip
- ADMIN_EMAIL=test@test.edu
- AIPDIR=/tmp/aip-dir
entrypoint:
- /bin/bash
- '-c'
- |
rm -rf $${AIPDIR}
mkdir $${AIPDIR} /dspace/upload
cd $${AIPDIR}
pwd
curl $${AIPZIP} -L -s --output aip.zip
unzip aip.zip
cd $${AIPDIR}
/dspace/bin/dspace packager -r -a -t AIP -e $${ADMIN_EMAIL} -f -u SITE*.zip
/dspace/bin/dspace database update-sequences
/dspace/bin/dspace index-discovery

22
docker/cli.yml Normal file
View File

@@ -0,0 +1,22 @@
version: "3.7"
services:
dspace-cli:
image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}"
container_name: dspace-cli
#environment:
volumes:
- "assetstore:/dspace/assetstore"
- "./local.cfg:/dspace/config/local.cfg"
entrypoint: /dspace/bin/dspace
command: help
networks:
- dspacenet
tty: true
stdin_open: true
volumes:
assetstore:
networks:
dspacenet:

16
docker/db.entities.yml Normal file
View File

@@ -0,0 +1,16 @@
#
# The contents of this file are subject to the license and copyright
# detailed in the LICENSE and NOTICE files at the root of the source
# tree and available online at
#
# http://www.dspace.org/license/
#
version: "3.7"
services:
dspacedb:
image: dspace/dspace-postgres-pgcrypto:loadsql
environment:
# Double underbars in env names will be replaced with periods for apache commons
- LOADSQL=https://www.dropbox.com/s/xh3ack0vg0922p2/configurable-entities-2019-05-08.sql?dl=1

View File

@@ -0,0 +1,59 @@
networks:
dspacenet:
services:
dspace:
container_name: dspace
depends_on:
- dspacedb
image: dspace/dspace:dspace-7_x-test
networks:
dspacenet:
ports:
- published: 8080
target: 8080
stdin_open: true
tty: true
volumes:
- assetstore:/dspace/assetstore
- "./local.cfg:/dspace/config/local.cfg"
# Ensure that the database is ready before starting tomcat
entrypoint:
- /bin/bash
- '-c'
- |
/dspace/bin/dspace database migrate
catalina.sh run
dspacedb:
container_name: dspacedb
image: dspace/dspace-postgres-pgcrypto
environment:
PGDATA: /pgdata
networks:
dspacenet:
stdin_open: true
tty: true
volumes:
- pgdata:/pgdata
dspacesolr:
container_name: dspacesolr
image: dspace/dspace-solr
networks:
dspacenet:
ports:
- published: 8983
target: 8983
stdin_open: true
tty: true
volumes:
- solr_authority:/opt/solr/server/solr/authority/data
- solr_oai:/opt/solr/server/solr/oai/data
- solr_search:/opt/solr/server/solr/search/data
- solr_statistics:/opt/solr/server/solr/statistics/data
version: '3.7'
volumes:
assetstore:
pgdata:
solr_authority:
solr_oai:
solr_search:
solr_statistics:

View File

@@ -0,0 +1,53 @@
networks:
dspacenet:
services:
dspace:
container_name: dspace
depends_on:
- dspacedb
image: dspace/dspace:dspace-7_x-test
networks:
dspacenet:
ports:
- published: 8080
target: 8080
stdin_open: true
tty: true
volumes:
- assetstore:/dspace/assetstore
- "./local.cfg:/dspace/config/local.cfg"
dspacedb:
container_name: dspacedb
environment:
LOADSQL: https://www.dropbox.com/s/xh3ack0vg0922p2/configurable-entities-2019-05-08.sql?dl=1
PGDATA: /pgdata
image: dspace/dspace-postgres-pgcrypto:loadsql
networks:
dspacenet:
stdin_open: true
tty: true
volumes:
- pgdata:/pgdata
dspacesolr:
container_name: dspacesolr
image: dspace/dspace-solr
networks:
dspacenet:
ports:
- published: 8983
target: 8983
stdin_open: true
tty: true
volumes:
- solr_authority:/opt/solr/server/solr/authority/data
- solr_oai:/opt/solr/server/solr/oai/data
- solr_search:/opt/solr/server/solr/search/data
- solr_statistics:/opt/solr/server/solr/statistics/data
version: '3.7'
volumes:
assetstore:
pgdata:
solr_authority:
solr_oai:
solr_search:
solr_statistics:

26
docker/docker-compose.yml Normal file
View File

@@ -0,0 +1,26 @@
version: '3.7'
networks:
dspacenet:
services:
dspace-angular:
container_name: dspace-angular
environment:
DSPACE_HOST: dspace-angular
DSPACE_NAMESPACE: /
DSPACE_PORT: '3000'
DSPACE_SSL: "false"
image: dspace/dspace-angular:latest
build:
context: ..
dockerfile: Dockerfile
networks:
dspacenet:
ports:
- published: 3000
target: 3000
- published: 9876
target: 9876
stdin_open: true
tty: true
volumes:
- ./environment.dev.js:/app/config/environment.dev.js

16
docker/environment.dev.js Normal file
View File

@@ -0,0 +1,16 @@
/*
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
module.exports = {
rest: {
ssl: false,
host: 'localhost',
port: 8080,
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: '/server/api'
}
};

5
docker/local.cfg Normal file
View File

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

View File

@@ -13,7 +13,7 @@ describe('protractor App', () => {
});
it('should contain a news section', () => {
page.navigateTo();
expect<any>(page.getHomePageNewsText()).toBeDefined();
page.navigateTo()
.then(() => expect<any>(page.getHomePageNewsText()).toBeDefined());
});
});

View File

@@ -2,7 +2,8 @@ import { browser, element, by } from 'protractor';
export class ProtractorPage {
navigateTo() {
return browser.get('/');
return browser.get('/')
.then(() => browser.waitForAngular());
}
getPageTitleText() {
@@ -10,6 +11,6 @@ export class ProtractorPage {
}
getHomePageNewsText() {
return element(by.xpath('//ds-home-news')).getText();
return element(by.css('ds-home-news')).getText();
}
}

View File

@@ -0,0 +1,46 @@
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

@@ -0,0 +1,35 @@
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('#search-navbar-container form input')).getAttribute('value');
}
expandAndFocusSearchBox() {
element(by.css('#search-navbar-container form a')).click();
}
setCurrentQuery(query: string) {
element(by.css('#search-navbar-container form input[name="query"]')).sendKeys(query);
}
submitNavbarSearchForm() {
element(by.css('#search-navbar-container form .submit-icon')).click();
}
submitByPressingEnter() {
element(by.css('#search-navbar-container form input[name="query"]')).sendKeys(protractor.Key.ENTER);
}
}

View File

@@ -11,33 +11,36 @@ describe('protractor SearchPage', () => {
it('should contain query value when navigating to page with query parameter', () => {
const queryString = 'Interesting query string';
page.navigateToSearchWithQueryParameter(queryString);
page.getCurrentQuery().then((query: string) => {
expect<string>(query).toEqual(queryString);
});
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', () => {
const scope: promise.Promise<string> = page.getRandomScopeOption();
scope.then((scopeString: string) => {
page.navigateToSearchWithScopeParameter(scopeString);
page.getCurrentScope().then((s: string) => {
expect<string>(s).toEqual(scopeString);
page.navigateToSearch()
.then(() => page.getRandomScopeOption())
.then((scopeString: string) => {
page.navigateToSearchWithScopeParameter(scopeString);
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', () => {
const scope: promise.Promise<string> = page.getRandomScopeOption();
scope.then((scopeString: string) => {
page.setCurrentScope(scopeString);
page.submitSearchForm();
browser.wait(() => {
return browser.getCurrentUrl().then((url: string) => {
return url.indexOf('scope=' + encodeURI(scopeString)) !== -1;
page.navigateToSearch()
.then(() => page.getRandomScopeOption())
.then((scopeString: string) => {
page.setCurrentScope(scopeString);
page.submitSearchForm();
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', () => {

View File

@@ -1,4 +1,4 @@
import { browser, element, by, protractor } from 'protractor';
import { browser, by, element, protractor } from 'protractor';
import { promise } from 'selenium-webdriver';
export class ProtractorPage {
@@ -27,15 +27,15 @@ export class ProtractorPage {
}
setCurrentScope(scope: string) {
element(by.css('option[value="' + scope + '"]')).click();
element(by.css('#search-form option[value="' + scope + '"]')).click();
}
setCurrentQuery(query: string) {
element(by.css('input[name="query"]')).sendKeys(query);
element(by.css('#search-form input[name="query"]')).sendKeys(query);
}
submitSearchForm() {
element(by.css('button.search-button')).click();
element(by.css('#search-form button.search-button')).click();
}
getRandomScopeOption(): promise.Promise<string> {

View File

@@ -15,7 +15,11 @@ module.exports = function (config) {
};
var configuration = {
client: {
jasmine: {
random: false
}
},
// base path that will be used to resolve all patterns (e.g. files, exclude)
basePath: '',

View File

@@ -8,7 +8,11 @@
},
"license": "BSD-2-Clause",
"engines": {
"node": ">=8.0.0"
"node": "10.* || >= 12.*"
},
"resolutions": {
"serialize-javascript": ">= 2.1.2",
"set-value": ">= 2.0.1"
},
"scripts": {
"global": "npm install -g @angular/cli marked node-gyp nodemon node-nightly npm-check-updates npm-run-all rimraf typescript ts-node typedoc webpack webpack-bundle-analyzer pm2 rollup",
@@ -17,15 +21,16 @@
"clean:doc": "rimraf doc",
"clean:log": "rimraf *.log*",
"clean:json": "rimraf *.records.json",
"clean:bld": "rimraf build",
"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",
"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": "yarn run clean:prod && yarn run clean:node",
"prebuild": "yarn run clean:dist",
"prebuild:aot": "yarn run prebuild",
"prebuild": "yarn run clean:bld && yarn run clean:dist",
"prebuild:ci": "yarn run prebuild",
"prebuild:prod": "yarn run prebuild",
"build": "node ./webpack/run-webpack.js --progress --mode development",
"build:aot": "node ./webpack/run-webpack.js --env.aot --env.server --mode development && node ./webpack/run-webpack.js --env.aot --env.client --mode development",
"build:prod": "node ./webpack/run-webpack.js --env.aot --env.server --mode production && node ./webpack/run-webpack.js --env.aot --env.client --mode production",
"build": "node ./scripts/webpack.js --progress --mode development",
"build:ci": "yarn run syncbuilddir && node ./scripts/webpack.js --env.aot --env.server --mode development && node ./scripts/webpack.js --env.aot --env.client --mode development",
"build:prod": "yarn run syncbuilddir && node ./scripts/webpack.js --env.aot --env.server --mode production && node ./scripts/webpack.js --env.aot --env.client --mode production",
"postbuild:prod": "yarn run rollup",
"rollup": "rollup -c rollup.config.js",
"prestart": "yarn run build:prod",
@@ -40,7 +45,8 @@
"server": "node dist/server.js",
"server:watch": "nodemon dist/server.js",
"server:watch:debug": "nodemon --debug dist/server.js",
"webpack:watch": "node ./webpack/run-webpack.js -w --mode development",
"syncbuilddir": "node ./scripts/sync-build-dir.js",
"webpack:watch": "node ./scripts/webpack.js -w --mode development",
"watch": "yarn run build && npm-run-all -p webpack:watch server:watch",
"watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug",
"predebug": "yarn run build",
@@ -49,10 +55,13 @@
"debug:server": "node-nightly --inspect --debug-brk dist/server.js",
"debug:build": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js --mode development",
"debug:build:prod": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js --env.aot --env.client --env.server --mode production",
"ci": "yarn run lint && yarn run build:aot && yarn run test:headless && npm-run-all -p -r server e2e",
"ci": "yarn run lint && yarn run build:ci && yarn run test:headless && npm-run-all -p -r server e2e",
"protractor": "node node_modules/protractor/bin/protractor",
"pree2e": "yarn run webdriver:update",
"e2e": "yarn run protractor",
"pretest": "yarn run clean:bld",
"pretest:headless": "yarn run pretest",
"pretest:watch": "yarn run pretest",
"test": "karma start --single-run",
"test:headless": "karma start --single-run --browsers ChromeHeadless",
"test:watch": "karma start --no-single-run --auto-watch",
@@ -60,84 +69,94 @@
"webdriver:update": "node node_modules/protractor/bin/webdriver-manager update --standalone --gecko false",
"lint": "tslint \"src/**/*.ts\" && tslint \"e2e/**/*.ts\"",
"docs": "typedoc --options typedoc.json ./src/",
"coverage": "http-server -c-1 -o -p 9875 ./coverage"
"coverage": "http-server -c-1 -o -p 9875 ./coverage",
"postinstall": "yarn run patch-protractor",
"patch-protractor": "ncp node_modules/webdriver-manager node_modules/protractor/node_modules/webdriver-manager",
"sync-i18n": "node ./scripts/sync-i18n-files.js"
},
"dependencies": {
"@angular/animations": "^6.1.4",
"@angular/cli": "^6.1.5",
"@angular/common": "^6.1.4",
"@angular/core": "^6.1.4",
"@angular/forms": "^6.1.4",
"@angular/http": "^6.1.4",
"@angular/platform-browser": "^6.1.4",
"@angular/platform-browser-dynamic": "^6.1.4",
"@angular/platform-server": "^6.1.4",
"@angular/router": "^6.1.4",
"@angular/animations": "^8.2.14",
"@angular/cdk": "8.2.3",
"@angular/cli": "^8.3.25",
"@angular/common": "^8.2.14",
"@angular/core": "^8.2.14",
"@angular/forms": "^8.2.14",
"@angular/platform-browser": "^8.2.14",
"@angular/platform-browser-dynamic": "^8.2.14",
"@angular/platform-server": "^8.2.14",
"@angular/router": "^8.2.14",
"@angularclass/bootloader": "1.0.1",
"@ng-bootstrap/ng-bootstrap": "^2.0.0",
"@ng-dynamic-forms/core": "6.2.0",
"@ng-dynamic-forms/ui-ng-bootstrap": "6.2.0",
"@ngrx/effects": "^6.1.0",
"@ngrx/router-store": "^6.1.0",
"@ngrx/store": "^6.1.0",
"@nguniversal/express-engine": "6.1.0",
"@ngx-translate/core": "10.0.2",
"@ngx-translate/http-loader": "3.0.1",
"@nicky-lenaers/ngx-scroll-to": "^1.0.0",
"@ng-bootstrap/ng-bootstrap": "^5.2.1",
"@ng-dynamic-forms/core": "8.1.1",
"@ng-dynamic-forms/ui-ng-bootstrap": "8.1.1",
"@ngrx/effects": "^8.6.0",
"@ngrx/router-store": "^8.6.0",
"@ngrx/store": "^8.6.0",
"@nguniversal/express-engine": "^8.2.6",
"@ngx-translate/core": "11.0.1",
"@ngx-translate/http-loader": "4.0.0",
"@nicky-lenaers/ngx-scroll-to": "^3.0.1",
"angular-idle-preload": "3.0.0",
"angular-sortablejs": "^2.5.0",
"angular2-text-mask": "9.0.0",
"angulartics2": "^6.2.0",
"angulartics2": "7.5.2",
"body-parser": "1.18.2",
"bootstrap": "4.3.1",
"cerialize": "0.1.18",
"compression": "1.7.1",
"cookie-parser": "1.4.3",
"core-js": "^2.5.7",
"core-js": "^3.6.4",
"debug-loader": "^0.0.1",
"express": "4.16.2",
"express-session": "1.15.6",
"fast-json-patch": "^2.0.7",
"file-saver": "^1.3.8",
"font-awesome": "4.7.0",
"fork-ts-checker-webpack-plugin": "^0.4.10",
"hammerjs": "^2.0.8",
"http-server": "0.11.1",
"https": "1.0.0",
"js-cookie": "2.2.0",
"js.clone": "0.0.3",
"json5": "^2.1.0",
"jsonschema": "1.2.2",
"jwt-decode": "^2.2.0",
"methods": "1.1.2",
"moment": "^2.22.1",
"moment-range": "^4.0.2",
"morgan": "^1.9.1",
"ng-mocks": "^6.2.1",
"ng-mocks": "^8.1.0",
"ng2-file-upload": "1.2.1",
"ng2-nouislider": "^1.7.11",
"ngx-bootstrap": "^3.2.0",
"ng2-nouislider": "^1.8.2",
"ngx-bootstrap": "^5.3.2",
"ngx-infinite-scroll": "6.0.1",
"ngx-moment": "^3.1.0",
"ngx-moment": "^3.4.0",
"ngx-pagination": "3.0.3",
"ngx-sortablejs": "^3.1.4",
"nouislider": "^11.0.0",
"pem": "1.12.3",
"reflect-metadata": "0.1.12",
"rxjs": "6.2.2",
"pem": "1.13.2",
"reflect-metadata": "^0.1.13",
"rxjs": "6.5.4",
"rxjs-spy": "^7.5.1",
"sass-resources-loader": "^2.0.0",
"sortablejs": "1.7.0",
"text-mask-core": "5.0.1",
"ts-loader": "^5.2.1",
"ts-md5": "^1.2.4",
"url-parse": "^1.4.7",
"uuid": "^3.2.1",
"webfontloader": "1.6.28",
"webpack-cli": "^3.1.0",
"zone.js": "^0.8.26"
"webpack-cli": "^3.2.0",
"zone.js": "^0.9.1"
},
"devDependencies": {
"@angular/compiler": "^6.1.4",
"@angular/compiler-cli": "^6.1.4",
"@angular-devkit/build-angular": "^0.803.25",
"@angular/compiler": "^8.2.14",
"@angular/compiler-cli": "^8.2.14",
"@fortawesome/fontawesome-free": "^5.5.0",
"@ngrx/entity": "^6.1.0",
"@ngrx/schematics": "^6.1.0",
"@ngrx/store-devtools": "^6.1.0",
"@ngtools/webpack": "^6.1.5",
"@ngrx/entity": "^8.6.0",
"@ngrx/schematics": "^8.6.0",
"@ngrx/store-devtools": "^8.6.0",
"@ngtools/webpack": "^8.3.25",
"@schematics/angular": "^0.7.5",
"@types/acorn": "^4.0.3",
"@types/cookie-parser": "1.4.1",
@@ -146,49 +165,55 @@
"@types/express-serve-static-core": "4.16.0",
"@types/file-saver": "^1.3.0",
"@types/hammerjs": "2.0.35",
"@types/jasmine": "^2.8.6",
"@types/jasmine": "^3.3.9",
"@types/js-cookie": "2.1.0",
"@types/json5": "^0.0.30",
"@types/lodash": "^4.14.110",
"@types/memory-cache": "0.2.0",
"@types/mime": "2.0.0",
"@types/node": "^10.9.4",
"@types/node": "^11.11.2",
"@types/serve-static": "1.13.2",
"@types/uuid": "^3.4.3",
"@types/webfontloader": "1.6.29",
"@typescript-eslint/eslint-plugin": "^2.12.0",
"@typescript-eslint/parser": "^2.12.0",
"ajv": "^6.1.1",
"ajv-keywords": "^3.1.0",
"angular2-template-loader": "0.6.2",
"autoprefixer": "^9.1.3",
"caniuse-lite": "^1.0.30000697",
"codelyzer": "^4.4.4",
"compression-webpack-plugin": "^1.1.6",
"copy-webpack-plugin": "^4.4.1",
"cli-progress": "^3.3.1",
"codelyzer": "^5.1.0",
"commander": "^3.0.2",
"compression-webpack-plugin": "^3.0.1",
"copy-webpack-plugin": "^5.1.1",
"copyfiles": "^2.1.1",
"coveralls": "3.0.0",
"css-loader": "1.0.0",
"css-loader": "3.4.0",
"cssnano": "^4.1.10",
"deep-freeze": "0.0.1",
"eslint": "^6.7.2",
"exports-loader": "^0.7.0",
"html-webpack-plugin": "^4.0.0-alpha",
"html-webpack-plugin": "3.2.0",
"imports-loader": "0.8.0",
"istanbul-instrumenter-loader": "3.0.1",
"jasmine-core": "^3.2.1",
"jasmine-core": "^3.3.0",
"jasmine-marbles": "0.3.1",
"jasmine-spec-reporter": "4.2.1",
"karma": "3.0.0",
"karma": "4.0.1",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "1.0.1",
"karma-cli": "2.0.0",
"karma-coverage": "1.1.2",
"karma-istanbul-preprocessor": "0.0.2",
"karma-jasmine": "1.1.2",
"karma-jasmine": "2.0.1",
"karma-mocha-reporter": "2.2.5",
"karma-phantomjs-launcher": "1.0.4",
"karma-remap-coverage": "^0.1.5",
"karma-remap-istanbul": "0.6.0",
"karma-sourcemap-loader": "0.3.7",
"karma-webdriver-launcher": "1.0.5",
"karma-webdriver-launcher": "^1.0.7",
"karma-webpack": "3.0.0",
"ngrx-store-freeze": "^0.2.4",
"node-sass": "^4.11.0",
"ncp": "^2.0.0",
"nodemon": "^1.15.0",
"npm-run-all": "4.1.3",
"optimize-css-assets-webpack-plugin": "^5.0.1",
@@ -199,31 +224,32 @@
"postcss-loader": "^3.0.0",
"postcss-responsive-type": "1.0.0",
"postcss-smart-import": "0.7.6",
"protractor": "^5.3.0",
"protractor": "^5.4.2",
"protractor-istanbul-plugin": "2.0.0",
"raw-loader": "0.5.1",
"resolve-url-loader": "^2.3.0",
"rimraf": "2.6.2",
"rollup": "^0.65.0",
"rollup-plugin-commonjs": "^9.1.6",
"rollup-plugin-node-globals": "1.2.1",
"rollup-plugin-node-resolve": "^3.0.3",
"rollup-plugin-terser": "^2.0.2",
"sass-loader": "7.1.0",
"script-ext-html-webpack-plugin": "2.0.1",
"sass-loader": "7.3.1",
"script-ext-html-webpack-plugin": "2.1.4",
"source-map": "0.7.3",
"source-map-loader": "0.2.4",
"string-replace-loader": "2.1.1",
"string-replace-loader": "^2.1.1",
"terser-webpack-plugin": "^2.3.1",
"to-string-loader": "1.1.5",
"ts-helpers": "1.1.2",
"ts-node": "4.1.0",
"tslint": "5.11.0",
"typedoc": "^0.9.0",
"typescript": "^2.9.1",
"webpack": "^4.17.1",
"webpack-bundle-analyzer": "^2.13.1",
"typescript": "3.5.3",
"webdriver-manager": "^12.1.7",
"webpack": "^4.29.6",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-dev-middleware": "3.2.0",
"webpack-dev-server": "^3.1.5",
"webpack-dev-server": "^3.1.11",
"webpack-import-glob-loader": "^1.6.3",
"webpack-merge": "4.1.4",
"webpack-node-externals": "1.7.2"

View File

@@ -5,7 +5,7 @@
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
exports.config = {
allScriptsTimeout: 11000,
allScriptsTimeout: 600000,
// -----------------------------------------------------------------
// Uncomment to run tests using a remote Selenium server
//seleniumAddress: 'http://selenium.address:4444/wd/hub',
@@ -73,7 +73,7 @@ exports.config = {
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
defaultTimeoutInterval: 600000,
print: function () {}
},
useAllAngular2AppRoots: true,

View File

@@ -0,0 +1,3 @@
# Supported font formats
DSpace supports EOT, TTF, OTF, SVG, WOFF and WOFF2 fonts.

4778
resources/i18n/ar.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,277 +0,0 @@
{
"footer": {
"copyright": "copyright © 2002-{{ year }}",
"link.dspace": "software DSpace",
"link.duraspace": "DuraSpace"
},
"collection": {
"page": {
"news": "Novinky",
"license": "Licence",
"browse": {
"recent": {
"head": "Poslední příspěvky"
}
}
}
},
"community": {
"page": {
"news": "Novinky",
"license": "Licence"
},
"sub-collection-list": {
"head": "Kolekce v této komunitě"
}
},
"item": {
"page": {
"author": "Autor",
"abstract": "Abstract",
"date": "Datum",
"uri": "URI",
"files": "Soubory",
"collections": "Kolekce",
"filesection": {
"download": "Stáhnout",
"name": "Název:",
"format": "Formát:",
"size": "Velikost:",
"description": "Popis:"
},
"link": {
"simple": "Minimální záznam",
"full": "Úplný záznam"
}
}
},
"nav": {
"home": "Domů",
"login": "Přihlásit se",
"logout": "Odhlásit se"
},
"pagination": {
"results-per-page": "Výsledků na stránku",
"sort-direction": "Seřazení",
"showing": {
"label": "Zobrazují se záznamy ",
"detail": "{{ range }} z {{ total }}"
}
},
"sorting": {
"score": {
"DESC": "Relevance"
},
"dc.title": {
"ASC": "Název vzestupně",
"DESC": "Název sestupně"
}
},
"title": "DSpace",
"404": {
"help": "Nepodařilo se najít stránku, kterou hledáte. Je možné, že stránka byla přesunuta nebo smazána. Pomocí tlačítka níže můžete přejít na domovskou stránku. ",
"page-not-found": "stránka nenalezena",
"link": {
"home-page": "Přejít na domovskou stránku"
}
},
"home": {
"title": "DSpace Angular :: Domů",
"description": "",
"top-level-communities": {
"head": "Komunity v DSpace",
"help": "Vybráním komunity můžete prohlížet její kolekce."
}
},
"search": {
"title": "DSpace Angular :: Hledat",
"description": "",
"form": {
"search": "Hledat",
"search_dspace": "Hledat v DSpace"
},
"results": {
"head": "Výsledky hledání",
"no-results": "Nebyli nalezeny žádné výsledky"
},
"sidebar": {
"close": "Zpět na výsledky",
"open": "Vyhledávací nástroje",
"results": "výsledky",
"filters": {
"title": "Filtry"
},
"settings": {
"title": "Nastavení",
"sort-by": "Řadit dle",
"rpp": "Výsledků na stránku"
}
},
"view-switch": {
"show-list": "Zobrazit seznam",
"show-grid": "Zobrazit mřížku"
},
"filters": {
"head": "Filtry",
"reset": "Obnovit filtry",
"applied": {
"f.author": "Autor",
"f.dateIssued.min": "Od data",
"f.dateIssued.max": "Do data",
"f.subject": "Předmět",
"f.has_content_in_original_bundle": "Má soubory"
},
"filter": {
"show-more": "Zobrazit více",
"show-less": "Sbalit",
"author": {
"placeholder": "Jméno autora",
"head": "Autor"
},
"scope": {
"placeholder": "Filtr rozsahu",
"head": "Rozsah"
},
"subject": {
"placeholder": "Předmět",
"head": "Předmět"
},
"dateIssued": {
"max": {
"placeholder": "Datum od"
},
"min": {
"placeholder": "Datum do"
},
"head": "Datum"
},
"has_content_in_original_bundle": {
"head": "Má soubory"
}
}
}
},
"browse": {
"title": "Prohlížíte {{ collection }} dle {{ field }} {{ value }}"
},
"admin": {
"registries": {
"metadata": {
"title": "DSpace Angular :: Registr metadat",
"head": "Registr metadat",
"description": "Registr metadat je seznam všech metadatových polí dostupných v repozitáři. Tyto pole mohou být rozdělena do více schémat. DSpace však vyžaduje použití schématu kvalifikový Dublin Core.",
"schemas": {
"table": {
"id": "ID",
"namespace": "Jmenný prostor",
"name": "Název"
},
"no-items": "Žádná schémata metadat."
}
},
"schema": {
"title": "DSpace Angular :: Registr schémat metadat",
"head": "Metadata Schema",
"description": "Toto je schéma metadat pro „{{namespace}}“.",
"fields": {
"head": "Pole schématu metadat",
"table": {
"field": "Pole",
"scopenote": "Poznámka o rozsahu"
},
"no-items": "Žádná metadatová pole."
}
},
"bitstream-formats": {
"title": "DSpace Angular :: Registr formátů souborů",
"head": "Registr formátů souborů",
"description": "Tento seznam formátů souborů poskytuje informace o známých formátech a o úrovni jejich podpory.",
"formats": {
"table": {
"name": "Název",
"mimetype": "Typ MIME",
"supportLevel": {
"head": "Úroveň podpory",
"0": "Neznámá",
"1": "Známá",
"2": "Podpora"
},
"internal": "interní"
},
"no-items": "Žádné formáty souborů."
}
}
}
},
"loading": {
"default": "Načítá se...",
"top-level-communities": "Načítají se komunity nejvyšší úrovně...",
"community": "Načítá se komunita...",
"collection": "Načítá se kolekce...",
"sub-collections": "Načítají se subkolekce...",
"recent-submissions": "Načítají se poslední příspěvky...",
"item": "Načítá se záznam...",
"objects": "Načítá se...",
"search-results": "Načítají se výsledky hledání...",
"browse-by": "Načítají se záznamy..."
},
"error": {
"default": "Chyba",
"top-level-communities": "Chyba během stahování komunit nejvyšší úrovně",
"community": "Chyba během stahování komunity",
"collection": "Chyba během stahování kolekce",
"sub-collections": "Chyba během stahování subkolekcí",
"recent-submissions": "Chyba během stahování posledních příspěvků",
"item": "Chyba během stahování záznamu",
"objects": "Chyba během stahování objektů",
"search-results": "Chyba během stahování výsledků hledání",
"browse-by": "Chyba během stahování záznamů",
"validation": {
"pattern": "Tento vstup je omezen dle vzoru: {{ pattern }}.",
"license": {
"notgranted": "Pro dokončení zaslání Musíte udělit licenci. Pokud v tuto chvíli tuto licenci nemůžete udělit, můžete svou práci uložit a později se k svému příspěveku vrátit nebo jej smazat."
}
}
},
"form": {
"submit": "Odeslat",
"cancel": "Zrušit",
"search": "Hledat",
"remove": "Smazat",
"first-name": "Křestní jméno",
"last-name": "Příjmení",
"loading": "Načítá se...",
"no-results": "Nebyli nalezeny žádné výsledky",
"no-value": "Nebyla zadána hodnota",
"group-collapse": "Sbalit",
"group-expand": "Rozbalit",
"group-collapse-help": "Kliknutím sem sbalíte",
"group-expand-help": "Kliknutím sem rozbalíte a přidáte další prvky"
},
"login": {
"title": "Přihlásit se",
"form": {
"header": "Prosím, přihlaste se do DSpace",
"email": "E-mailová adresa",
"forgot-password": "Zapomněli jste své heslo?",
"new-user": "Nový uživatel? Zaregistrujte se kliknutím sem.",
"password": "Heslo",
"submit": "Přihlásit se"
}
},
"logout": {
"title": "Odhlásit se",
"form": {
"header": "Odhlásit se z DSpace",
"submit": "Odhlásit se"
}
},
"auth": {
"messages": {
"expired": "Vaše relace vypršela. Prosím, znova se přihlaste."
},
"errors": {
"invalid-user": "Neplatná e-mailová adresa nebo heslo."
}
}
}

4645
resources/i18n/cs.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,277 +0,0 @@
{
"footer": {
"copyright": "Copyright © 2002-{{ year }}",
"link.dspace": "DSpace Software",
"link.duraspace": "DuraSpace"
},
"collection": {
"page": {
"news": "Neuigkeiten",
"license": "Lizenz",
"browse": {
"recent": {
"head": "Aktuellste Veröffentlichungen"
}
}
}
},
"community": {
"page": {
"news": "Neuigkeiten",
"license": "Lizenz"
},
"sub-collection-list": {
"head": "Sammlungen in diesem Bereich"
}
},
"item": {
"page": {
"author": "Autor",
"abstract": "Kurzfassung",
"date": "Datum",
"uri": "URI",
"files": "Dateien",
"collections": "Sammlungen",
"filesection": {
"download": "Herunterladen",
"name": "Name:",
"format": "Format:",
"size": "Größe:",
"description": "Beschreibung:"
},
"link": {
"simple": "Kurzanzeige",
"full": "Vollanzeige"
}
}
},
"nav": {
"home": "Zur Startseite",
"login": "Anmelden",
"logout": "Abmelden"
},
"pagination": {
"results-per-page": "Ergebnisse pro Seite",
"sort-direction": "Sortiermöglichkeiten",
"showing": {
"label": "Anzeige der Treffer ",
"detail": "{{ range }} bis {{ total }}"
}
},
"sorting": {
"score": {
"DESC": "Relevanz"
},
"dc.title": {
"ASC": "Titel aufsteigend",
"DESC": "Titel absteigend"
}
},
"title": "DSpace",
"404": {
"help": "Die Seite, die Sie aufrufen wollten, konnte nicht gefunden werden. Sie könnte verschoben oder gelöscht worden sein. Mit dem Link unten kommen Sie zurück zur Startseite. ",
"page-not-found": "Seite nicht gefunden",
"link": {
"home-page": "Zurück zur Startseite"
}
},
"home": {
"title": "DSpace Angular :: Startseite",
"description": "",
"top-level-communities": {
"head": "Bereiche in DSpace",
"help": "Wählen Sie einen Bereich, um seine Sammlungen einzusehen."
}
},
"search": {
"title": "DSpace Angular :: Suche",
"description": "",
"form": {
"search": "Suche",
"search_dspace": "DSpace durchsuchen"
},
"results": {
"head": "Suchergebnisse",
"no-results": "Zu dieser Suche gibt es keine Treffer."
},
"sidebar": {
"close": "Zurück zu den Ergebnissen",
"open": "Suchwerkzeuge",
"results": "Ergebnisse",
"filters": {
"title": "Filter"
},
"settings": {
"title": "Einstellungen",
"sort-by": "Sortiere nach",
"rpp": "Treffer pro Seite"
}
},
"view-switch": {
"show-list": "Zeige als Liste",
"show-grid": "Zeige als Raster"
},
"filters": {
"head": "Filter",
"reset": "Filter zurücksetzen",
"applied": {
"f.author": "Autor",
"f.dateIssued.min": "Anfangsdatum",
"f.dateIssued.max": "Enddatum",
"f.subject": "Thema",
"f.has_content_in_original_bundle": "Besitzt Dateien"
},
"filter": {
"show-more": "Zeige mehr",
"show-less": "Zeige weniger",
"author": {
"placeholder": "Autor",
"head": "Autor"
},
"scope": {
"placeholder": "Bereichsfilter",
"head": "Bereich"
},
"subject": {
"placeholder": "Schlagwort",
"head": "Schlagwort"
},
"dateIssued": {
"max": {
"placeholder": "Frühestes Datum"
},
"min": {
"placeholder": "Ältestes Datum"
},
"head": "Datum"
},
"has_content_in_original_bundle": {
"head": "Besitzt Dateien"
}
}
}
},
"browse": {
"title": "Anzeige {{ collection }} nach {{ field }} {{ value }}"
},
"admin": {
"registries": {
"metadata": {
"title": "DSpace Angular :: Metadatenreferenzliste",
"head": "Metadatenreferenzliste",
"description": "Die Metadatenreferenzliste beinhaltet alle Metadatenfelder, die zur Verfügung stehen. Die Felder können in unterschiedlichen Schemata enthalten sein. Nichtsdestotrotz benötigt DSpace mindestens qualifiziertes Dublin Core.",
"schemas": {
"table": {
"id": "ID",
"namespace": "Namensraum",
"name": "Name"
},
"no-items": "Es gbit keine Metadatenschemata."
}
},
"schema": {
"title": "DSpace Angular :: Referenzliste der Metadatenschemata",
"head": "Metadatenschemata",
"description": "Dies ist das Metadatenschema für \"{{namespace}}\".",
"fields": {
"head": "Felder in diesem Schema",
"table": {
"field": "Feld",
"scopenote": "Gültigkeitsbereich"
},
"no-items": "Es gibt keine Felder in diesem Schema."
}
},
"bitstream-formats": {
"title": "DSpace Angular :: Referenzliste der Dateiformate",
"head": "Referenzliste der Dateiformate",
"description": "Diese Liste enhtält die in diesem Repositorium zulässigen Dateiformate und den jeweiligen Unterstützungsgrad.",
"formats": {
"table": {
"name": "Name",
"mimetype": "MIME Type",
"supportLevel": {
"head": "Unterstützungsgrad",
"0": "Unbekannt",
"1": "Bekannt",
"2": "Unterstützt"
},
"internal": "intern"
},
"no-items": "Es gibt keine Formate in dieser Referenzliste."
}
}
}
},
"loading": {
"default": "Am Laden ...",
"top-level-communities": "Die Hauptbereiche werden geladen ...",
"community": "Der Bereich wird geladen ...",
"collection": "Die Sammlung wird geladen ...",
"sub-collections": "Die untergeordneten Sammlungen werden geladen ...",
"recent-submissions": "Die aktuellsten Veröffentlichungen werden geladen ...",
"item": "Die Ressource wird geladen ...",
"objects": "Am Laden ...",
"search-results": "Die Suchergebnisse werden geladen ...",
"browse-by": "Die Ressourcen werden geladen ..."
},
"error": {
"default": "Fehler",
"top-level-communities": "Fehler beim Laden der Hauptbereiche.",
"community": "Fehler beim Laden des Bereiches.",
"collection": "Fehler beim Laden der Sammlung.",
"sub-collections": "Fehler beim Laden der untergeordneten Sammlungen.",
"recent-submissions": "Fehler beim Laden der aktuellsten Veröffentlichungen.",
"item": "Fehler beim Laden der Ressource.",
"objects": "Fehler beim Laden der Objekte.",
"search-results": "Fehler beim Laden der Suchergebnisse.",
"browse-by": "Fehler beim Laden der Ressourcen",
"validation": {
"pattern": "Die Eingabe kann nur folgendes Muster haben: {{ pattern }}.",
"license": {
"notgranted": "Sie müssen der Lizenz zustimmen, um die Ressource einzureichen. Wenn dies zur Zeit nicht geht, können Sie die Einreichung speichern und später wiederaufnehmen oder löschen."
}
}
},
"form": {
"submit": "Los",
"cancel": "Abbrechen",
"search": "Suchen",
"remove": "Löschen",
"first-name": "Vorname",
"last-name": "Nachname",
"loading": "Am Laden ...",
"no-results": "Keine Ergebnisse gefunden",
"no-value": "Kein Wert eingegeben",
"group-collapse": "Weniger",
"group-expand": "Mehr",
"group-collapse-help": "Hier klicken, um die Anzeige zu reduzieren",
"group-expand-help": "Hier klicken, um mehr Elemente anzuzeigen"
},
"login": {
"title": "Einloggen",
"form": {
"header": "Bitte Loggen Sie sich ein.",
"email": "E-Mail-Adresse",
"forgot-password": "Haben Sie Ihr Passwort vergessen?",
"new-user": "Sind Sie neu hier? Klicken Sie hier, um sich zu registrieren.",
"password": "Passwort",
"submit": "Einloggen"
}
},
"logout": {
"title": "Ausloggen",
"form": {
"header": "Ausloggen aus DSpace",
"submit": "Ausloggen"
}
},
"auth": {
"messages": {
"expired": "Ihre Sitzung ist abgelaufen, bitte melden Sie sich erneut an."
},
"errors": {
"invalid-user": "Ungültige E-Mail-Adresse oder Passwort."
}
}
}

3871
resources/i18n/de.json5 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2540
resources/i18n/en.json5 Normal file

File diff suppressed because it is too large Load Diff

4029
resources/i18n/es.json5 Normal file

File diff suppressed because it is too large Load Diff

4778
resources/i18n/fi.json5 Normal file

File diff suppressed because it is too large Load Diff

4032
resources/i18n/fr.json5 Normal file

File diff suppressed because it is too large Load Diff

4778
resources/i18n/ja.json5 Normal file

File diff suppressed because it is too large Load Diff

3772
resources/i18n/lv.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,277 +0,0 @@
{
"footer": {
"copyright": "copyright © 2002-{{ year }}",
"link.dspace": "DSpace software",
"link.duraspace": "DuraSpace"
},
"collection": {
"page": {
"news": "Nieuws",
"license": "Licentie",
"browse": {
"recent": {
"head": "Recent toegevoegd"
}
}
}
},
"community": {
"page": {
"news": "Nieuws",
"license": "Licentie"
},
"sub-collection-list": {
"head": "Collecties in deze Community"
}
},
"item": {
"page": {
"author": "Auteur",
"abstract": "Abstract",
"date": "Datum",
"uri": "URI",
"files": "Bestanden",
"collections": "Collecties",
"filesection": {
"download": "Download",
"name": "Naam:",
"format": "Formaat:",
"size": "Grootte:",
"description": "Beschrijving:"
},
"link": {
"simple": "Eenvoudige itemweergave",
"full": "Volledige itemweergave"
}
}
},
"nav": {
"home": "Home",
"login": "Log In",
"logout": "Log Uit"
},
"pagination": {
"results-per-page": "Resultaten per pagina",
"sort-direction": "Sorteermogelijkheden",
"showing": {
"label": "Resultaten ",
"detail": "{{ range }} van {{ total }}"
}
},
"sorting": {
"score": {
"DESC": "Relevantie"
},
"dc.title": {
"ASC": "Oplopend op titel",
"DESC": "Aflopend op titel"
}
},
"title": "DSpace",
"404": {
"help": "De pagina die u zoekt kan niet gevonden worden. De pagina werd mogelijk verplaatst of verwijderd. U kan onderstaande knop gebruiken om terug naar de homepagina te gaan. ",
"page-not-found": "Pagina niet gevonden",
"link": {
"home-page": "Terug naar de homepagina"
}
},
"home": {
"title": "DSpace Angular :: Home",
"description": "",
"top-level-communities": {
"head": "Communities in DSpace",
"help": "Selecteer een community om diens collecties te verkennen."
}
},
"search": {
"title": "DSpace Angular :: Zoek",
"description": "",
"form": {
"search": "Zoek",
"search_dspace": "Zoek in DSpace"
},
"results": {
"head": "Zoekresultaten",
"no-results": "Er waren geen resultaten voor deze zoekopdracht"
},
"sidebar": {
"close": "Terug naar de resultaten",
"open": "Zoek Tools",
"results": "resultaten",
"filters": {
"title": "Filters"
},
"settings": {
"title": "Instellingen",
"sort-by": "Sorteer volgens",
"rpp": "Resultaten per pagina"
}
},
"view-switch": {
"show-list": "Toon als lijst",
"show-grid": "Toon in raster"
},
"filters": {
"head": "Filters",
"reset": "Filters verwijderen",
"applied": {
"f.author": "Auteur",
"f.dateIssued.min": "Startdatum",
"f.dateIssued.max": "Einddatum",
"f.subject": "Sleutelwoord",
"f.has_content_in_original_bundle": "Heeft bestanden"
},
"filter": {
"show-more": "Toon meer",
"show-less": "Inklappen",
"author": {
"placeholder": "Auteursnaam",
"head": "Auteur"
},
"scope": {
"placeholder": "Bereikfilter",
"head": "Bereik"
},
"subject": {
"placeholder": "Onderwerp",
"head": "Onderwerp"
},
"dateIssued": {
"max": {
"placeholder": "Vroegste Datum"
},
"min": {
"placeholder": "Laatste Datum"
},
"head": "Datum"
},
"has_content_in_original_bundle": {
"head": "Heeft bestanden"
}
}
}
},
"browse": {
"title": "Verken {{ collection }} volgens {{ field }} {{ value }}"
},
"admin": {
"registries": {
"metadata": {
"title": "DSpace Angular :: Metadata Register",
"head": "Metadata Register",
"description": "Het metadataregister omvat de lijst van alle metadatavelden die beschikbaar zijn in het systeem. Deze velden kunnen verspreid zijn over verschillende metadataschema's. Het qualified Dublin Core schema (dc) is een verplicht schema en kan niet worden verwijderd.",
"schemas": {
"table": {
"id": "ID",
"namespace": "Naamruimte",
"name": "Naam"
},
"no-items": "Er kunnen geen metadataschema's getoond worden."
}
},
"schema": {
"title": "DSpace Angular :: Metadata Schema Register",
"head": "Metadata Schema",
"description": "Dit is het metadataschema voor \"{{namespace}}\".",
"fields": {
"head": "Schema metadatavelden",
"table": {
"field": "Veld",
"scopenote": "Opmerking over bereik"
},
"no-items": "Er kunnen geen metadatavelden getoond worden."
}
},
"bitstream-formats": {
"title": "DSpace Angular :: Bitstream Formaat Register",
"head": "Bitstream Formaat Register",
"description": "Deze lijst van Bitstream formaten biedt informatie over de formaten die in deze repository zijn toegelaten en op welke manier ze ondersteund worden. De term Bitstream wordt in DSpace gebruikt om een bestand aan te duiden dat samen met metadata onderdeel uitmaakt van een item. De naam bitstream duidt op het feit dat het bestand achterliggend wordt opgeslaan zonder bestandsextensie.",
"formats": {
"table": {
"name": "Naam",
"mimetype": "MIME Type",
"supportLevel": {
"head": "Ondersteuning",
"0": "Onbekend",
"1": "Gekend",
"2": "Ondersteund"
},
"internal": "intern"
},
"no-items": "Er kunnen geen bitstreamformaten getoond worden."
}
}
}
},
"loading": {
"default": "Laden...",
"top-level-communities": "Inladen van de Communities op het hoogste niveau...",
"community": "Community wordt ingeladen...",
"collection": "Collectie wordt ingeladen...",
"sub-collections": "De sub-collecties worden ingeladen...",
"recent-submissions": "Recent toegevoegde items worden ingeladen...",
"item": "Item wordt ingeladen...",
"objects": "Laden...",
"search-results": "Zoekresultaten worden ingeladen...",
"browse-by": "Items worden ingeladen..."
},
"error": {
"default": "Fout",
"top-level-communities": "Fout bij het inladen van communities op het hoogste niveau",
"community": "Fout bij het ophalen van een community",
"collection": "Fout bij het ophalen van een collectie",
"sub-collections": "Fout bij het ophalen van sub-collecties",
"recent-submissions": "Fout bij het ophalen van recent toegevoegde items",
"item": "Fout bij het ophalen van items",
"objects": "Fout bij het ophalen van objecten",
"search-results": "Fout bij het ophalen van zoekresultaten",
"browse-by": "Fout bij het ophalen van items",
"validation": {
"pattern": "Deze invoer is niet toegelaten volgens dit patroon: {{ pattern }}.",
"license": {
"notgranted": "U moet de invoerlicentie goedkeuren om de invoer af te werken. Indien u deze licentie momenteel niet kan of mag goedkeuren, kan u uw werk opslaan en de invoer later afwerken. U kunt dit nieuwe item ook verwijderen indien u niet voldoet aan de vereisten van de invoerlicentie."
}
}
},
"form": {
"submit": "Verstuur",
"cancel": "Annuleer",
"search": "Zoek",
"remove": "Verwijder",
"first-name": "Voornaam",
"last-name": "Achternaam",
"loading": "Inladen...",
"no-results": "Geen resultaten gevonden",
"no-value": "Geen waarde ingevoerd",
"group-collapse": "Inklappen",
"group-expand": "Uitklappen",
"group-collapse-help": "Klik hier op in te klappen",
"group-expand-help": "Klik hier om uit te klappen en om meer onderdelen toe te voegen"
},
"login": {
"title": "Aanmelden",
"form": {
"header": "Gelieve in te loggen in DSpace",
"email": "Email adres",
"forgot-password": "Bent u uw wachtwoord vergeten?",
"new-user": "Nieuwe gebruiker? Gelieve u hier te registreren",
"password": "Wachtwoord",
"submit": "Aanmelden"
}
},
"logout": {
"title": "Afmelden",
"form": {
"header": "Afmelden in DSpace",
"submit": "Afmelden"
}
},
"auth": {
"messages": {
"expired": "Uw sessie is vervallen. Gelieve opnieuw aan te melden."
},
"errors": {
"invalid-user": "Ongeldig e-mailadres of wachtwoord."
}
}
}

4026
resources/i18n/nl.json5 Normal file

File diff suppressed because it is too large Load Diff

4778
resources/i18n/pl.json5 Normal file

File diff suppressed because it is too large Load Diff

4026
resources/i18n/pt.json5 Normal file

File diff suppressed because it is too large Load Diff

4778
resources/i18n/sw.json5 Normal file

File diff suppressed because it is too large Load Diff

4778
resources/i18n/tr.json5 Normal file

File diff suppressed because it is too large Load Diff

22
scripts/sync-build-dir.js Normal file
View File

@@ -0,0 +1,22 @@
const syncBuildDir = require('copyfiles');
const path = require('path');
const {
projectRoot,
theme,
themePath,
} = require('../webpack/helpers');
const projectDepth = projectRoot('./').split(path.sep).length;
let callback;
if (theme !== null && theme !== undefined) {
callback = () => {
syncBuildDir([path.join(themePath, '**/*'), 'build'], { up: projectDepth + 2 }, () => {})
}
}
else {
callback = () => {};
}
syncBuildDir([projectRoot('src/**/*'), 'build'], { up: projectDepth + 1 }, callback);

342
scripts/sync-i18n-files.js Executable file
View File

@@ -0,0 +1,342 @@
#!/usr/bin/env node
const commander = require('commander');
const fs = require('fs');
const JSON5 = require('json5');
const _cliProgress = require('cli-progress');
const _ = require('lodash');
const {projectRoot} = require('../webpack/helpers');
const program = new commander.Command();
program.version('1.0.0', '-v, --version');
const NEW_MESSAGE_TODO = '// TODO New key - Add a translation';
const MESSAGE_CHANGED_TODO = '// TODO Source message changed - Revise the translation';
const COMMENTS_CHANGED_TODO = '// TODO Source comments changed - Revise the translation';
const DEFAULT_SOURCE_FILE_LOCATION = 'resources/i18n/en.json5';
const LANGUAGE_FILES_LOCATION = 'resources/i18n';
parseCliInput();
/**
* Parses the CLI input given by the user
* If no parameters are set (standard usage) -> source file is default (set to DEFAULT_SOURCE_FILE_LOCATION) and all
* other language files in the LANGUAGE_FILES_LOCATION are synced with this one in-place
* (replaced with newly synced file)
* If only target-file -t is set -> either -i in-place or -o output-file must be set
* Source file can be set with -s if it should be something else than DEFAULT_SOURCE_FILE_LOCATION
*
* If any of the paths to files/dirs given by user are not valid, an error message is printed and script gets aborted
*/
function parseCliInput() {
program
.option('-d, --output-dir <output-dir>', 'output dir when running script on all language files; mutually exclusive with -o')
.option('-t, --target-file <target>', 'target file we compare with and where completed output ends up if -o is not configured and -i is')
.option('-i, --edit-in-place', 'edit-in-place; store output straight in target file; mutually exclusive with -o')
.option('-s, --source-file <source>', 'source file to be parsed for translation', projectRoot(DEFAULT_SOURCE_FILE_LOCATION))
.option('-o, --output-file <output>', 'where output of script ends up; mutually exclusive with -i')
.usage('([-d <output-dir>] [-s <source-file>]) || (-t <target-file> (-i | -o <output>) [-s <source-file>])')
.parse(process.argv);
if (!program.targetFile) {
fs.readdirSync(projectRoot(LANGUAGE_FILES_LOCATION)).forEach(file => {
if (!program.sourceFile.toString().endsWith(file)) {
const targetFileLocation = projectRoot(LANGUAGE_FILES_LOCATION + "/" + file);
console.log('Syncing file at: ' + targetFileLocation + ' with source file at: ' + program.sourceFile);
if (program.outputDir) {
if (!fs.existsSync(program.outputDir)) {
fs.mkdirSync(program.outputDir);
}
const outputFileLocation = program.outputDir + "/" + file;
console.log('Output location: ' + outputFileLocation);
syncFileWithSource(targetFileLocation, outputFileLocation);
} else {
console.log('Replacing in target location');
syncFileWithSource(targetFileLocation, targetFileLocation);
}
}
});
} else {
if (program.targetFile && !checkIfPathToFileIsValid(program.targetFile)) {
console.error('Directory path of target file is not valid.');
console.log(program.outputHelp());
process.exit(1);
}
if (program.targetFile && checkIfFileExists(program.targetFile) && !(program.editInPlace || program.outputFile)) {
console.error('This target file already exists, if you want to overwrite this add option -i, or add an -o output location');
console.log(program.outputHelp());
process.exit(1);
}
if (!checkIfFileExists(program.sourceFile)) {
console.error('Path of source file is not valid.');
console.log(program.outputHelp());
process.exit(1);
}
if (program.outputFile && !checkIfPathToFileIsValid(program.outputFile)) {
console.error('Directory path of output file is not valid.');
console.log(program.outputHelp());
process.exit(1);
}
syncFileWithSource(program.targetFile, getOutputFileLocationIfExistsElseTargetFileLocation(program.targetFile));
}
}
/**
* Creates chunk lists for both the source and the target files (for example en.json5 and nl.json5 respectively)
* > Creates output chunks by comparing the source chunk with corresponding target chunk (based on key of translation)
* > Writes the output chunks to a new valid lang.json5 file, either replacing the target file (-i in-place)
* or sending it to an output file specified by the user
* @param pathToTargetFile Valid path to target file to generate target chunks from
* @param pathToOutputFile Valid path to output file to write output chunks to
*/
function syncFileWithSource(pathToTargetFile, pathToOutputFile) {
const progressBar = new _cliProgress.SingleBar({}, _cliProgress.Presets.shades_classic);
progressBar.start(100, 0);
const sourceLines = [];
const targetLines = [];
const existingTargetFile = readFileIfExists(pathToTargetFile);
existingTargetFile.toString().split("\n").forEach((function (line) {
targetLines.push(line.trim());
}));
progressBar.update(10);
const sourceFile = readFileIfExists(program.sourceFile);
sourceFile.toString().split("\n").forEach((function (line) {
sourceLines.push(line.trim());
}));
progressBar.update(20);
const sourceChunks = createChunks(sourceLines, progressBar, false);
const targetChunks = createChunks(targetLines, progressBar, true);
const outputChunks = compareChunksAndCreateOutput(sourceChunks, targetChunks, progressBar);
const file = fs.createWriteStream(pathToOutputFile);
file.on('error', function (err) {
console.error('Something went wrong writing to output file at: ' + pathToOutputFile + err)
});
file.on('open', function() {
file.write("{\n");
outputChunks.forEach(function (chunk) {
progressBar.increment();
chunk.split("\n").forEach(function (line) {
file.write(" " + line + "\n");
});
});
file.write("\n}");
file.end();
});
file.on('finish', function() {
const osName = process.platform;
if (osName.startsWith("win")) {
replaceLineEndingsToCRLF(pathToOutputFile);
}
});
progressBar.update(100);
progressBar.stop();
}
/**
* For each of the source chunks:
* - Determine if it's a new key-value => Add it to output, with source comments, source key-value commented, a message indicating it's new and the source-key value uncommented
* - If it's not new, compare it with the corresponding target chunk and log the differences, see createNewChunkComparingSourceAndTarget
* @param sourceChunks All the source chunks, split per key-value pair group
* @param targetChunks All the target chunks, split per key-value pair group
* @param progressBar The progressbar for the CLI
* @return {Array} All the output chunks, split per key-value pair group
*/
function compareChunksAndCreateOutput(sourceChunks, targetChunks, progressBar) {
const outputChunks = [];
sourceChunks.map((sourceChunk) => {
progressBar.increment();
if (sourceChunk.trim().length !== 0) {
let newChunk = [];
const sourceList = sourceChunk.split("\n");
const keyValueSource = sourceList[sourceList.length - 1];
const keySource = getSubStringBeforeLastString(keyValueSource, ":");
const commentSource = getSubStringBeforeLastString(sourceChunk, keyValueSource);
const correspondingTargetChunk = targetChunks.find((targetChunk) => {
return targetChunk.includes(keySource);
});
// Create new chunk with: the source comments, the commented source key-value, the todos and either the old target key-value pair or if it's a new pair, the source key-value pair
newChunk.push(removeWhiteLines(commentSource));
newChunk.push("// " + keyValueSource);
if (correspondingTargetChunk === undefined) {
newChunk.push(NEW_MESSAGE_TODO);
newChunk.push(keyValueSource);
} else {
createNewChunkComparingSourceAndTarget(correspondingTargetChunk, sourceChunk, commentSource, keyValueSource, newChunk);
}
outputChunks.push(newChunk.filter(Boolean).join("\n"));
} else {
outputChunks.push(sourceChunk);
}
});
return outputChunks;
}
/**
* If a corresponding target chunk is found:
* - If old key value is not found in comments > Assumed it is new key
* - If the target comments do not contain the source comments (because they have changed since last time) => Add comments changed message
* - If the key-value in the target comments is not the same as the source key-value (because it changes since last time) => Add message changed message
* - Add the old todos if they haven't been added already
* - End with the original target key-value
*/
function createNewChunkComparingSourceAndTarget(correspondingTargetChunk, sourceChunk, commentSource, keyValueSource, newChunk) {
let commentsOfSourceHaveChanged = false;
let messageOfSourceHasChanged = false;
const targetList = correspondingTargetChunk.split("\n");
const oldKeyValueInTargetComments = getSubStringWithRegex(correspondingTargetChunk, "\\s*\\/\\/\\s*\".*");
const keyValueTarget = targetList[targetList.length - 1];
if (oldKeyValueInTargetComments != null) {
const oldKeyValueUncommented = getSubStringWithRegex(oldKeyValueInTargetComments[0], "\".*")[0];
if (!(_.isEmpty(correspondingTargetChunk) && _.isEmpty(commentSource)) && !removeWhiteLines(correspondingTargetChunk).includes(removeWhiteLines(commentSource.trim()))) {
commentsOfSourceHaveChanged = true;
newChunk.push(COMMENTS_CHANGED_TODO);
}
const parsedOldKey = JSON5.stringify("{" + oldKeyValueUncommented + "}");
const parsedSourceKey = JSON5.stringify("{" + keyValueSource + "}");
if (!_.isEqual(parsedOldKey, parsedSourceKey)) {
messageOfSourceHasChanged = true;
newChunk.push(MESSAGE_CHANGED_TODO);
}
addOldTodosIfNeeded(targetList, newChunk, commentsOfSourceHaveChanged, messageOfSourceHasChanged);
}
newChunk.push(keyValueTarget);
}
// Adds old todos found in target comments if they've not been added already
function addOldTodosIfNeeded(targetList, newChunk, commentsOfSourceHaveChanged, messageOfSourceHasChanged) {
targetList.map((targetLine) => {
const foundTODO = getSubStringWithRegex(targetLine, "\\s*//\\s*TODO.*");
if (foundTODO != null) {
const todo = foundTODO[0];
if (!((todo.includes(COMMENTS_CHANGED_TODO) && commentsOfSourceHaveChanged)
|| (todo.includes(MESSAGE_CHANGED_TODO) && messageOfSourceHasChanged))) {
newChunk.push(todo);
}
}
});
}
/**
* Creates chunks from an array of lines, each chunk contains either an empty line or a grouping of comments with their corresponding key-value pair
* @param lines Array of lines, to be grouped into chunks
* @param progressBar Progressbar of the CLI
* @return {Array} Array of chunks, grouped by key-value and their corresponding comments or an empty line
*/
function createChunks(lines, progressBar, creatingTarget) {
const chunks = [];
let nextChunk = [];
let onMultiLineComment = false;
lines.map((line) => {
progressBar.increment();
if (line.length === 0) {
chunks.push(line);
}
if (isOneLineCommentLine(line)) {
nextChunk.push(line);
}
if (onMultiLineComment) {
nextChunk.push(line);
if (isEndOfMultiLineComment(line)) {
onMultiLineComment = false;
}
}
if (isStartOfMultiLineComment(line)) {
nextChunk.push(line);
onMultiLineComment = true;
}
if (isKeyValuePair(line)) {
nextChunk.push(line);
const newMessageLineIfExists = nextChunk.find((lineInChunk) => lineInChunk.trim().startsWith(NEW_MESSAGE_TODO));
if (newMessageLineIfExists === undefined || !creatingTarget) {
chunks.push(nextChunk.join("\n"));
}
nextChunk = [];
}
});
return chunks;
}
function readFileIfExists(pathToFile) {
if (checkIfFileExists(pathToFile)) {
try {
return fs.readFileSync(pathToFile, 'utf8');
} catch (e) {
console.error('Error:', e.stack);
}
}
return null;
}
function isOneLineCommentLine(line) {
return (line.startsWith("//"));
}
function isStartOfMultiLineComment(line) {
return (line.startsWith("/*"));
}
function isEndOfMultiLineComment(line) {
return (line.endsWith("*/"));
}
function isKeyValuePair(line) {
return (line.startsWith("\""));
}
function getSubStringWithRegex(string, regex) {
return string.match(regex);
}
function getSubStringBeforeLastString(string, char) {
const lastCharIndex = string.lastIndexOf(char);
return string.substr(0, lastCharIndex);
}
function getOutputFileLocationIfExistsElseTargetFileLocation(targetLocation) {
if (program.outputFile) {
return program.outputFile;
}
return targetLocation;
}
function checkIfPathToFileIsValid(pathToCheck) {
if (!pathToCheck.includes("/")) {
return true;
}
return checkIfFileExists(getPathOfDirectory(pathToCheck));
}
function checkIfFileExists(pathToCheck) {
return fs.existsSync(pathToCheck);
}
function getPathOfDirectory(pathToCheck) {
return getSubStringBeforeLastString(pathToCheck, "/");
}
function removeWhiteLines(string) {
return string.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, "")
}
/**
* Replaces UNIX \n LF line endings to windows \r\n CRLF line endings.
* @param filePath Path to file whose line endings are being converted
*/
function replaceLineEndingsToCRLF(filePath) {
const data = readFileIfExists(filePath);
const result = data.replace(/\n/g,"\r\n");
fs.writeFileSync(filePath, result, 'utf8');
}

View File

@@ -13,8 +13,8 @@
*/
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('core-js/es');
require('core-js/features/reflect');
// Typescript emit helpers polyfill
require('ts-helpers');

View File

@@ -0,0 +1,38 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { EPeopleRegistryComponent } from './epeople-registry/epeople-registry.component';
import { GroupFormComponent } from './group-registry/group-form/group-form.component';
import { GroupsRegistryComponent } from './group-registry/groups-registry.component';
import { URLCombiner } from '../../core/url-combiner/url-combiner';
import { getAccessControlModulePath } from '../admin-routing.module';
const GROUP_EDIT_PATH = 'groups';
export function getGroupEditPath(id: string) {
return new URLCombiner(getAccessControlModulePath(), GROUP_EDIT_PATH, id).toString();
}
@NgModule({
imports: [
RouterModule.forChild([
{ path: 'epeople', component: EPeopleRegistryComponent, data: { title: 'admin.access-control.epeople.title' } },
{ path: GROUP_EDIT_PATH, component: GroupsRegistryComponent, data: { title: 'admin.access-control.groups.title' } },
{
path: `${GROUP_EDIT_PATH}/:groupId`,
component: GroupFormComponent,
data: {title: 'admin.registries.schema.title'}
},
{
path: `${GROUP_EDIT_PATH}/newGroup`,
component: GroupFormComponent,
data: {title: 'admin.registries.schema.title'}
},
])
]
})
/**
* Routing module for the AccessControl section of the admin sidebar
*/
export class AdminAccessControlRoutingModule {
}

View File

@@ -0,0 +1,37 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { SharedModule } from '../../shared/shared.module';
import { AdminAccessControlRoutingModule } from './admin-access-control-routing.module';
import { EPeopleRegistryComponent } from './epeople-registry/epeople-registry.component';
import { EPersonFormComponent } from './epeople-registry/eperson-form/eperson-form.component';
import { GroupFormComponent } from './group-registry/group-form/group-form.component';
import { MembersListComponent } from './group-registry/group-form/members-list/members-list.component';
import { SubgroupsListComponent } from './group-registry/group-form/subgroup-list/subgroups-list.component';
import { GroupsRegistryComponent } from './group-registry/groups-registry.component';
@NgModule({
imports: [
CommonModule,
SharedModule,
RouterModule,
TranslateModule,
AdminAccessControlRoutingModule
],
declarations: [
EPeopleRegistryComponent,
EPersonFormComponent,
GroupsRegistryComponent,
GroupFormComponent,
SubgroupsListComponent,
MembersListComponent
],
entryComponents: []
})
/**
* This module handles all components related to the access control pages
*/
export class AdminAccessControlModule {
}

View File

@@ -0,0 +1,49 @@
import { Action } from '@ngrx/store';
import { EPerson } from '../../../core/eperson/models/eperson.model';
import { type } from '../../../shared/ngrx/type';
/**
* For each action type in an action group, make a simple
* enum object for all of this group's action types.
*
* The 'type' utility function coerces strings into string
* literal types and runs a simple check to guarantee all
* action types in the application are unique.
*/
export const EPeopleRegistryActionTypes = {
EDIT_EPERSON: type('dspace/epeople-registry/EDIT_EPERSON'),
CANCEL_EDIT_EPERSON: type('dspace/epeople-registry/CANCEL_EDIT_EPERSON'),
};
/* tslint:disable:max-classes-per-file */
/**
* Used to edit an EPerson in the EPeople registry
*/
export class EPeopleRegistryEditEPersonAction implements Action {
type = EPeopleRegistryActionTypes.EDIT_EPERSON;
eperson: EPerson;
constructor(eperson: EPerson) {
this.eperson = eperson;
}
}
/**
* Used to cancel the editing of an EPerson in the EPeople registry
*/
export class EPeopleRegistryCancelEPersonAction implements Action {
type = EPeopleRegistryActionTypes.CANCEL_EDIT_EPERSON;
}
/* tslint:enable:max-classes-per-file */
/**
* Export a type alias of all actions in this action group
* so that reducers can easily compose action types
* These are all the actions to perform on the EPeople registry state
*/
export type EPeopleRegistryAction
= EPeopleRegistryEditEPersonAction
| EPeopleRegistryCancelEPersonAction

View File

@@ -0,0 +1,93 @@
<div class="container">
<div class="epeople-registry row">
<div class="col-12">
<h2 id="header" class="border-bottom pb-2">{{labelPrefix + 'head' | translate}}</h2>
<ds-eperson-form *ngIf="isEPersonFormShown" (submitForm)="forceUpdateEPeople()"
(cancelForm)="isEPersonFormShown = false"></ds-eperson-form>
<div *ngIf="!isEPersonFormShown" class="button-row top d-flex pb-2">
<button class="mr-auto btn btn-success addEPerson-button"
(click)="isEPersonFormShown = true">
<i class="fas fa-plus"></i>
<span class="d-none d-sm-inline">{{labelPrefix + 'button.add' | translate}}</span>
</button>
</div>
<h3 id="search" class="border-bottom pb-2">{{labelPrefix + 'search.head' | translate}}
<button (click)="clearFormAndResetResult();"
class="btn btn-primary float-right">{{labelPrefix + 'button.see-all' | translate}}</button>
</h3>
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
<div class="col-12 col-sm-3">
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
<option value="metadata">{{labelPrefix + 'search.scope.metadata' | translate}}</option>
<option value="email">{{labelPrefix + 'search.scope.email' | translate}}</option>
</select>
</div>
<div class="col-sm-9 col-12">
<div class="form-group input-group">
<input type="text" name="query" id="query" formControlName="query"
class="form-control" aria-label="Search input">
<span class="input-group-append">
<button type="submit"
class="search-button btn btn-secondary">{{ labelPrefix + 'search.button' | translate }}</button>
</span>
</div>
</div>
</form>
<ds-pagination
*ngIf="(ePeople | async)?.payload?.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(ePeople | async)?.payload"
[collectionSize]="(ePeople | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
<div class="table-responsive">
<table id="epeople" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{labelPrefix + 'table.id' | translate}}</th>
<th scope="col">{{labelPrefix + 'table.name' | translate}}</th>
<th scope="col">{{labelPrefix + 'table.email' | translate}}</th>
<th>{{labelPrefix + 'table.edit' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let eperson of (ePeople | async)?.payload?.page"
[ngClass]="{'table-primary' : isActive(eperson) | async}">
<td>{{eperson.id}}</td>
<td>{{eperson.name}}</td>
<td>{{eperson.email}}</td>
<td>
<div class="btn-group edit-field">
<button (click)="toggleEditEPerson(eperson)"
class="btn btn-outline-primary btn-sm access-control-editEPersonButton"
title="{{labelPrefix + 'table.edit.buttons.edit' | translate: {name: eperson.name} }}">
<i class="fas fa-edit fa-fw"></i>
</button>
<button (click)="deleteEPerson(eperson)"
class="btn btn-outline-danger btn-sm access-control-deleteEPersonButton"
title="{{labelPrefix + 'table.edit.buttons.remove' | translate: {name: eperson.name} }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(ePeople | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2" role="alert">
{{labelPrefix + 'no-items' | translate}}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,214 @@
import { Router } from '@angular/router';
import { of as observableOf } from 'rxjs';
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, By } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { PaginatedList } from '../../../core/data/paginated-list';
import { RemoteData } from '../../../core/data/remote-data';
import { FindListOptions } from '../../../core/data/request.models';
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
import { EPerson } from '../../../core/eperson/models/eperson.model';
import { PageInfo } from '../../../core/shared/page-info.model';
import { FormBuilderService } from '../../../shared/form/builder/form-builder.service';
import { getMockFormBuilderService } from '../../../shared/mocks/mock-form-builder-service';
import { MockTranslateLoader } from '../../../shared/mocks/mock-translate-loader';
import { getMockTranslateService } from '../../../shared/mocks/mock-translate.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { EPersonMock, EPersonMock2 } from '../../../shared/testing/eperson-mock';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
import { RouterStub } from '../../../shared/testing/router-stub';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
import { EPeopleRegistryComponent } from './epeople-registry.component';
describe('EPeopleRegistryComponent', () => {
let component: EPeopleRegistryComponent;
let fixture: ComponentFixture<EPeopleRegistryComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;
let mockEPeople;
let ePersonDataServiceStub: any;
beforeEach(async(() => {
mockEPeople = [EPersonMock, EPersonMock2];
ePersonDataServiceStub = {
activeEPerson: null,
allEpeople: mockEPeople,
getEPeople(): Observable<RemoteData<PaginatedList<EPerson>>> {
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
},
getActiveEPerson(): Observable<EPerson> {
return observableOf(this.activeEPerson);
},
searchByScope(scope: string, query: string, options: FindListOptions = {}): Observable<RemoteData<PaginatedList<EPerson>>> {
if (scope === 'email') {
const result = this.allEpeople.find((ePerson: EPerson) => {
return ePerson.email === query
});
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
}
if (scope === 'metadata') {
if (query === '') {
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
}
const result = this.allEpeople.find((ePerson: EPerson) => {
return (ePerson.name.includes(query) || ePerson.email.includes(query))
});
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
}
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
},
deleteEPerson(ePerson: EPerson): Observable<boolean> {
this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => {
return (ePerson2.uuid !== ePerson.uuid);
});
return observableOf(true);
},
editEPerson(ePerson: EPerson) {
this.activeEPerson = ePerson;
},
cancelEditEPerson() {
this.activeEPerson = null;
},
clearEPersonRequests(): void {
// empty
},
getEPeoplePageRouterLink(): string {
return '/admin/access-control/epeople';
}
};
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();
TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
],
declarations: [EPeopleRegistryComponent],
providers: [EPeopleRegistryComponent,
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: FormBuilderService, useValue: builderService },
{ provide: Router, useValue: new RouterStub() },
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EPeopleRegistryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create EPeopleRegistryComponent', inject([EPeopleRegistryComponent], (comp: EPeopleRegistryComponent) => {
expect(comp).toBeDefined();
}));
it('should display list of ePeople', () => {
const ePeopleIdsFound = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
expect(ePeopleIdsFound.length).toEqual(2);
mockEPeople.map((ePerson: EPerson) => {
expect(ePeopleIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === ePerson.uuid);
})).toBeTruthy();
})
});
describe('search', () => {
describe('when searching with scope/query (scope metadata)', () => {
let ePeopleIdsFound;
beforeEach(fakeAsync(() => {
component.search({ scope: 'metadata', query: EPersonMock2.name });
tick();
fixture.detectChanges();
ePeopleIdsFound = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
}));
it('should display search result', () => {
expect(ePeopleIdsFound.length).toEqual(1);
expect(ePeopleIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === EPersonMock2.uuid);
})).toBeTruthy();
});
});
describe('when searching with scope/query (scope email)', () => {
let ePeopleIdsFound;
beforeEach(fakeAsync(() => {
component.search({ scope: 'email', query: EPersonMock.email });
tick();
fixture.detectChanges();
ePeopleIdsFound = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
}));
it('should display search result', () => {
expect(ePeopleIdsFound.length).toEqual(1);
expect(ePeopleIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === EPersonMock.uuid);
})).toBeTruthy();
});
});
});
describe('toggleEditEPerson', () => {
describe('when you click on first edit eperson button', () => {
beforeEach(fakeAsync(() => {
const editButtons = fixture.debugElement.queryAll(By.css('.access-control-editEPersonButton'));
editButtons[0].triggerEventHandler('click', {
preventDefault: () => {/**/
}
});
tick();
fixture.detectChanges();
}));
it('editEPerson form is toggled', () => {
const ePeopleIds = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
ePersonDataServiceStub.getActiveEPerson().subscribe((activeEPerson: EPerson) => {
if (activeEPerson === ePeopleIds[0].nativeElement.textContent) {
expect(component.isEPersonFormShown).toEqual(false);
} else {
expect(component.isEPersonFormShown).toEqual(true);
}
})
});
});
});
describe('deleteEPerson', () => {
describe('when you click on first delete eperson button', () => {
let ePeopleIdsFoundBeforeDelete;
let ePeopleIdsFoundAfterDelete;
beforeEach(fakeAsync(() => {
ePeopleIdsFoundBeforeDelete = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
const deleteButtons = fixture.debugElement.queryAll(By.css('.access-control-deleteEPersonButton'));
deleteButtons[0].triggerEventHandler('click', {
preventDefault: () => {/**/
}
});
tick();
fixture.detectChanges();
ePeopleIdsFoundAfterDelete = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
}));
it('first ePerson is deleted', () => {
expect(ePeopleIdsFoundBeforeDelete.length === ePeopleIdsFoundAfterDelete + 1);
ePeopleIdsFoundAfterDelete.forEach((epersonElement) => {
expect(epersonElement !== ePeopleIdsFoundBeforeDelete[0].nativeElement.textContent).toBeTrue();
});
});
});
});
});

View File

@@ -0,0 +1,202 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { Subscription } from 'rxjs/internal/Subscription';
import { map, take } from 'rxjs/operators';
import { PaginatedList } from '../../../core/data/paginated-list';
import { RemoteData } from '../../../core/data/remote-data';
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
import { EPerson } from '../../../core/eperson/models/eperson.model';
import { hasValue } from '../../../shared/empty.util';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
@Component({
selector: 'ds-epeople-registry',
templateUrl: './epeople-registry.component.html',
})
/**
* A component used for managing all existing epeople within the repository.
* The admin can create, edit or delete epeople here.
*/
export class EPeopleRegistryComponent implements OnInit, OnDestroy {
labelPrefix = 'admin.access-control.epeople.';
/**
* A list of all the current EPeople within the repository or the result of the search
*/
ePeople: Observable<RemoteData<PaginatedList<EPerson>>>;
/**
* Pagination config used to display the list of epeople
*/
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'epeople-list-pagination',
pageSize: 5,
currentPage: 1
});
/**
* Whether or not to show the EPerson form
*/
isEPersonFormShown: boolean;
// The search form
searchForm;
// Current search in epersons registry
currentSearchQuery: string;
currentSearchScope: string;
/**
* List of subscriptions
*/
subs: Subscription[] = [];
constructor(private epersonService: EPersonDataService,
private translateService: TranslateService,
private notificationsService: NotificationsService,
private formBuilder: FormBuilder,
private router: Router) {
this.currentSearchQuery = '';
this.currentSearchScope = 'metadata';
this.searchForm = this.formBuilder.group(({
scope: 'metadata',
query: '',
}));
}
ngOnInit() {
this.isEPersonFormShown = false;
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery });
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
if (eperson != null && eperson.id) {
this.isEPersonFormShown = true;
}
}));
}
/**
* Event triggered when the user changes page
* @param event
*/
onPageChange(event) {
this.config.currentPage = event;
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery })
}
/**
* Force-update the list of EPeople by first clearing the cache related to EPeople, then performing
* a new REST call
*/
public forceUpdateEPeople() {
this.epersonService.clearEPersonRequests();
this.isEPersonFormShown = false;
this.search({ query: '', scope: 'metadata' })
}
/**
* Search in the EPeople by metadata (default) or email
* @param data Contains scope and query param
*/
search(data: any) {
const query: string = data.query;
const scope: string = data.scope;
if (query != null && this.currentSearchQuery !== query) {
this.router.navigateByUrl(this.epersonService.getEPeoplePageRouterLink());
this.currentSearchQuery = query;
this.config.currentPage = 1;
}
if (scope != null && this.currentSearchScope !== scope) {
this.router.navigateByUrl(this.epersonService.getEPeoplePageRouterLink());
this.currentSearchScope = scope;
this.config.currentPage = 1;
}
this.ePeople = this.epersonService.searchByScope(this.currentSearchScope, this.currentSearchQuery, {
currentPage: this.config.currentPage,
elementsPerPage: this.config.pageSize
});
}
/**
* Checks whether the given EPerson is active (being edited)
* @param eperson
*/
isActive(eperson: EPerson): Observable<boolean> {
return this.getActiveEPerson().pipe(
map((activeEPerson) => eperson === activeEPerson)
);
}
/**
* Gets the active eperson (being edited)
*/
getActiveEPerson(): Observable<EPerson> {
return this.epersonService.getActiveEPerson();
}
/**
* Start editing the selected EPerson
* @param ePerson
*/
toggleEditEPerson(ePerson: EPerson) {
this.getActiveEPerson().pipe(take(1)).subscribe((activeEPerson: EPerson) => {
if (ePerson === activeEPerson) {
this.epersonService.cancelEditEPerson();
this.isEPersonFormShown = false;
} else {
this.epersonService.editEPerson(ePerson);
this.isEPersonFormShown = true;
}
});
this.scrollToTop()
}
/**
* Deletes EPerson, show notification on success/failure & updates EPeople list
*/
deleteEPerson(ePerson: EPerson) {
if (hasValue(ePerson.id)) {
this.epersonService.deleteEPerson(ePerson).pipe(take(1)).subscribe((success: boolean) => {
if (success) {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: ePerson.name }));
this.forceUpdateEPeople();
} else {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.deleted.failure', { name: ePerson.name }));
}
this.epersonService.cancelEditEPerson();
this.isEPersonFormShown = false;
})
}
}
/**
* Unsub all subscriptions
*/
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
scrollToTop() {
(function smoothscroll() {
const currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
if (currentScroll > 0) {
window.requestAnimationFrame(smoothscroll);
window.scrollTo(0, currentScroll - (currentScroll / 8));
}
})();
}
/**
* Reset all input-fields to be empty and search all search
*/
clearFormAndResetResult() {
this.searchForm.patchValue({
query: '',
});
this.search({ query: '' });
}
}

View File

@@ -0,0 +1,54 @@
import { EPersonMock } from '../../../shared/testing/eperson-mock';
import { EPeopleRegistryCancelEPersonAction, EPeopleRegistryEditEPersonAction } from './epeople-registry.actions';
import { ePeopleRegistryReducer, EPeopleRegistryState } from './epeople-registry.reducers';
const initialState: EPeopleRegistryState = {
editEPerson: null,
};
const editState: EPeopleRegistryState = {
editEPerson: EPersonMock,
};
class NullAction extends EPeopleRegistryEditEPersonAction {
type = null;
constructor() {
super(undefined);
}
}
describe('epeopleRegistryReducer', () => {
it('should return the current state when no valid actions have been made', () => {
const state = initialState;
const action = new NullAction();
const newState = ePeopleRegistryReducer(state, action);
expect(newState).toEqual(state);
});
it('should start with an initial state', () => {
const state = initialState;
const action = new NullAction();
const initState = ePeopleRegistryReducer(undefined, action);
expect(initState).toEqual(state);
});
it('should update the current state to change the editEPerson to a new eperson when EPeopleRegistryEditEPersonAction is dispatched', () => {
const state = editState;
const action = new EPeopleRegistryEditEPersonAction(EPersonMock);
const newState = ePeopleRegistryReducer(state, action);
expect(newState.editEPerson).toEqual(EPersonMock);
});
it('should update the current state to remove the editEPerson from the state when EPeopleRegistryCancelEPersonAction is dispatched', () => {
const state = editState;
const action = new EPeopleRegistryCancelEPersonAction();
const newState = ePeopleRegistryReducer(state, action);
expect(newState.editEPerson).toEqual(null);
});
});

View File

@@ -0,0 +1,46 @@
import { EPerson } from '../../../core/eperson/models/eperson.model';
import {
EPeopleRegistryAction,
EPeopleRegistryActionTypes,
EPeopleRegistryEditEPersonAction
} from './epeople-registry.actions';
/**
* The EPeople registry state.
* @interface EPeopleRegistryState
*/
export interface EPeopleRegistryState {
editEPerson: EPerson;
}
/**
* The initial state.
*/
const initialState: EPeopleRegistryState = {
editEPerson: null,
};
/**
* Reducer that handles EPeopleRegistryActions to modify EPeople
* @param state The current EPeopleRegistryState
* @param action The EPeopleRegistryAction to perform on the state
*/
export function ePeopleRegistryReducer(state = initialState, action: EPeopleRegistryAction): EPeopleRegistryState {
switch (action.type) {
case EPeopleRegistryActionTypes.EDIT_EPERSON: {
return Object.assign({}, state, {
editEPerson: (action as EPeopleRegistryEditEPersonAction).eperson
});
}
case EPeopleRegistryActionTypes.CANCEL_EDIT_EPERSON: {
return Object.assign({}, state, {
editEPerson: null
});
}
default:
return state;
}
}

View File

@@ -0,0 +1,58 @@
<div *ngIf="epersonService.getActiveEPerson() | async; then editheader; else createHeader"></div>
<ng-template #createHeader>
<h4>{{messagePrefix + '.create' | translate}}</h4>
</ng-template>
<ng-template #editheader>
<h4>{{messagePrefix + '.edit' | translate}}</h4>
</ng-template>
<ds-form [formId]="formId"
[formModel]="formModel"
[formGroup]="formGroup"
[formLayout]="formLayout"
(cancel)="onCancel()"
(submitForm)="onSubmit()">
</ds-form>
<div *ngIf="epersonService.getActiveEPerson() | async">
<h5>{{messagePrefix + '.groupsEPersonIsMemberOf' | translate}}</h5>
<ds-pagination
*ngIf="(groups | async)?.payload?.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(groups | async)?.payload"
[collectionSize]="(groups | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
<div class="table-responsive">
<table id="groups" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{messagePrefix + '.table.id' | translate}}</th>
<th scope="col">{{messagePrefix + '.table.name' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let group of (groups | async)?.payload?.page">
<td>{{group.id}}</td>
<td><a (click)="groupsDataService.startEditingNewGroup(group)"
[routerLink]="[groupsDataService.getGroupEditPageRouterLink(group)]">{{group.name}}</a></td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(groups | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2" role="alert">
<div>{{messagePrefix + '.memberOfNoGroups' | translate}}</div>
<div>
<button [routerLink]="[groupsDataService.getGroupRegistryRouterLink()]"
class="btn btn-primary">{{messagePrefix + '.goToGroups' | translate}}</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,231 @@
import { HttpClient } from '@angular/common/http';
import { Store } from '@ngrx/store';
import { of as observableOf } from 'rxjs';
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } 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 { RestResponse } from '../../../../core/cache/response.models';
import { DSOChangeAnalyzer } from '../../../../core/data/dso-change-analyzer.service';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { RemoteData } from '../../../../core/data/remote-data';
import { FindListOptions } from '../../../../core/data/request.models';
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
import { EPerson } from '../../../../core/eperson/models/eperson.model';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { PageInfo } from '../../../../core/shared/page-info.model';
import { UUIDService } from '../../../../core/shared/uuid.service';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { getMockFormBuilderService } from '../../../../shared/mocks/mock-form-builder-service';
import { getMockTranslateService } from '../../../../shared/mocks/mock-translate.service';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { EPersonMock, EPersonMock2 } from '../../../../shared/testing/eperson-mock';
import { MockTranslateLoader } from '../../../../shared/testing/mock-translate-loader';
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service-stub';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { EPeopleRegistryComponent } from '../epeople-registry.component';
import { EPersonFormComponent } from './eperson-form.component';
describe('EPersonFormComponent', () => {
let component: EPersonFormComponent;
let fixture: ComponentFixture<EPersonFormComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;
let mockEPeople;
let ePersonDataServiceStub: any;
beforeEach(async(() => {
mockEPeople = [EPersonMock, EPersonMock2];
ePersonDataServiceStub = {
activeEPerson: null,
allEpeople: mockEPeople,
getEPeople(): Observable<RemoteData<PaginatedList<EPerson>>> {
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
},
getActiveEPerson(): Observable<EPerson> {
return observableOf(this.activeEPerson);
},
searchByScope(scope: string, query: string, options: FindListOptions = {}): Observable<RemoteData<PaginatedList<EPerson>>> {
if (scope === 'email') {
const result = this.allEpeople.find((ePerson: EPerson) => {
return ePerson.email === query
});
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
}
if (scope === 'metadata') {
if (query === '') {
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
}
const result = this.allEpeople.find((ePerson: EPerson) => {
return (ePerson.name.includes(query) || ePerson.email.includes(query))
});
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
}
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
},
deleteEPerson(ePerson: EPerson): Observable<boolean> {
this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => {
return (ePerson2.uuid !== ePerson.uuid);
});
return observableOf(true);
},
create(ePerson: EPerson) {
this.allEpeople = [...this.allEpeople, ePerson]
},
editEPerson(ePerson: EPerson) {
this.activeEPerson = ePerson;
},
cancelEditEPerson() {
this.activeEPerson = null;
},
clearEPersonRequests(): void {
// empty
},
tryToCreate(ePerson: EPerson): Observable<RestResponse> {
this.allEpeople = [...this.allEpeople, ePerson]
return observableOf(new RestResponse(true, 200, 'Success'));
},
updateEPerson(ePerson: EPerson): Observable<RestResponse> {
this.allEpeople.forEach((ePersonInList: EPerson, i: number) => {
if (ePersonInList.id === ePerson.id) {
this.allEpeople[i] = ePerson;
}
});
return observableOf(new RestResponse(true, 200, 'Success'));
}
};
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();
TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
],
declarations: [EPeopleRegistryComponent, EPersonFormComponent],
providers: [EPersonFormComponent,
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: FormBuilderService, useValue: builderService },
{ provide: DSOChangeAnalyzer, useValue: {} },
{ provide: HttpClient, useValue: {} },
{ provide: ObjectCacheService, useValue: {} },
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
EPeopleRegistryComponent
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EPersonFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create EPersonFormComponent', inject([EPersonFormComponent], (comp: EPersonFormComponent) => {
expect(comp).toBeDefined();
}));
describe('when submitting the form', () => {
let firstName;
let lastName;
let email;
let canLogIn;
let requireCertificate;
let expected;
beforeEach(() => {
firstName = 'testName';
lastName = 'testLastName';
email = 'testEmail@test.com';
canLogIn = false;
requireCertificate = false;
expected = Object.assign(new EPerson(), {
metadata: {
'eperson.firstname': [
{
value: firstName
}
],
'eperson.lastname': [
{
value: lastName
},
],
},
email: email,
canLogIn: canLogIn,
requireCertificate: requireCertificate,
});
spyOn(component.submitForm, 'emit');
component.firstName.value = firstName;
component.lastName.value = lastName;
component.email.value = email;
component.canLogIn.value = canLogIn;
component.requireCertificate.value = requireCertificate;
});
describe('without active EPerson', () => {
beforeEach(() => {
spyOn(ePersonDataServiceStub, 'getActiveEPerson').and.returnValue(observableOf(undefined));
component.onSubmit();
fixture.detectChanges();
});
it('should emit a new eperson using the correct values', async(() => {
fixture.whenStable().then(() => {
expect(component.submitForm.emit).toHaveBeenCalledWith(expected);
});
}));
});
describe('with an active eperson', () => {
let expectedWithId;
beforeEach(() => {
expectedWithId = Object.assign(new EPerson(), {
metadata: {
'eperson.firstname': [
{
value: firstName
}
],
'eperson.lastname': [
{
value: lastName
},
],
},
email: email,
canLogIn: canLogIn,
requireCertificate: requireCertificate,
});
spyOn(ePersonDataServiceStub, 'getActiveEPerson').and.returnValue(observableOf(expectedWithId));
component.onSubmit();
fixture.detectChanges();
});
it('should emit the existing eperson using the correct values', async(() => {
fixture.whenStable().then(() => {
expect(component.submitForm.emit).toHaveBeenCalledWith(expectedWithId);
});
}));
});
});
});

View File

@@ -0,0 +1,374 @@
import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
import {
DynamicCheckboxModel,
DynamicFormControlModel,
DynamicFormLayout,
DynamicInputModel
} from '@ng-dynamic-forms/core';
import { TranslateService } from '@ngx-translate/core';
import { Subscription, combineLatest } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { take } from 'rxjs/operators';
import { RestResponse } from '../../../../core/cache/response.models';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { RemoteData } from '../../../../core/data/remote-data';
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../../core/eperson/group-data.service';
import { EPerson } from '../../../../core/eperson/models/eperson.model';
import { Group } from '../../../../core/eperson/models/group.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
import { hasValue } from '../../../../shared/empty.util';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model';
@Component({
selector: 'ds-eperson-form',
templateUrl: './eperson-form.component.html'
})
/**
* A form used for creating and editing EPeople
*/
export class EPersonFormComponent implements OnInit, OnDestroy {
labelPrefix = 'admin.access-control.epeople.form.';
/**
* A unique id used for ds-form
*/
formId = 'eperson-form';
/**
* The labelPrefix for all messages related to this form
*/
messagePrefix = 'admin.access-control.epeople.form';
/**
* Dynamic input models for the inputs of form
*/
firstName: DynamicInputModel;
lastName: DynamicInputModel;
email: DynamicInputModel;
// booleans
canLogIn: DynamicCheckboxModel;
requireCertificate: DynamicCheckboxModel;
/**
* A list of all dynamic input models
*/
formModel: DynamicFormControlModel[];
/**
* Layout used for structuring the form inputs
*/
formLayout: DynamicFormLayout = {
firstName: {
grid: {
host: 'row'
}
},
lastName: {
grid: {
host: 'row'
}
},
email: {
grid: {
host: 'row'
}
},
canLogIn: {
grid: {
host: 'col col-sm-6 d-inline-block'
}
},
requireCertificate: {
grid: {
host: 'col col-sm-6 d-inline-block'
}
},
};
/**
* A FormGroup that combines all inputs
*/
formGroup: FormGroup;
/**
* An EventEmitter that's fired whenever the form is being submitted
*/
@Output() submitForm: EventEmitter<any> = new EventEmitter();
/**
* An EventEmitter that's fired whenever the form is cancelled
*/
@Output() cancelForm: EventEmitter<any> = new EventEmitter();
/**
* List of subscriptions
*/
subs: Subscription[] = [];
/**
* A list of all the groups this EPerson is a member of
*/
groups: Observable<RemoteData<PaginatedList<Group>>>;
/**
* Pagination config used to display the list of groups
*/
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'groups-ePersonMemberOf-list-pagination',
pageSize: 5,
currentPage: 1
});
/**
* Try to retrieve initial active eperson, to fill in checkboxes at component creation
*/
epersonInitial: EPerson;
constructor(public epersonService: EPersonDataService,
public groupsDataService: GroupDataService,
private formBuilderService: FormBuilderService,
private translateService: TranslateService,
private notificationsService: NotificationsService,) {
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
this.epersonInitial = eperson;
}));
}
ngOnInit() {
combineLatest(
this.translateService.get(`${this.messagePrefix}.firstName`),
this.translateService.get(`${this.messagePrefix}.lastName`),
this.translateService.get(`${this.messagePrefix}.email`),
this.translateService.get(`${this.messagePrefix}.canLogIn`),
this.translateService.get(`${this.messagePrefix}.requireCertificate`),
this.translateService.get(`${this.messagePrefix}.emailHint`),
).subscribe(([firstName, lastName, email, canLogIn, requireCertificate, emailHint]) => {
this.firstName = new DynamicInputModel({
id: 'firstName',
label: firstName,
name: 'firstName',
validators: {
required: null,
},
required: true,
});
this.lastName = new DynamicInputModel({
id: 'lastName',
label: lastName,
name: 'lastName',
validators: {
required: null,
},
required: true,
});
this.email = new DynamicInputModel({
id: 'email',
label: email,
name: 'email',
validators: {
required: null,
pattern: '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$'
},
required: true,
hint: emailHint
});
this.canLogIn = new DynamicCheckboxModel(
{
id: 'canLogIn',
label: canLogIn,
name: 'canLogIn',
value: (this.epersonInitial != null ? this.epersonInitial.canLogIn : true)
});
this.requireCertificate = new DynamicCheckboxModel(
{
id: 'requireCertificate',
label: requireCertificate,
name: 'requireCertificate',
value: (this.epersonInitial != null ? this.epersonInitial.requireCertificate : false)
});
this.formModel = [
this.firstName,
this.lastName,
this.email,
this.canLogIn,
this.requireCertificate,
];
this.formGroup = this.formBuilderService.createFormGroup(this.formModel);
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
if (eperson != null) {
this.groups = this.groupsDataService.findAllByHref(eperson._links.groups.href, {
currentPage: 1,
elementsPerPage: this.config.pageSize
});
}
this.formGroup.patchValue({
firstName: eperson != null ? eperson.firstMetadataValue('eperson.firstname') : '',
lastName: eperson != null ? eperson.firstMetadataValue('eperson.lastname') : '',
email: eperson != null ? eperson.email : '',
canLogIn: eperson != null ? eperson.canLogIn : true,
requireCertificate: eperson != null ? eperson.requireCertificate : false
});
}));
});
}
/**
* Stop editing the currently selected eperson
*/
onCancel() {
this.epersonService.cancelEditEPerson();
this.cancelForm.emit();
}
/**
* Submit the form
* When the eperson has an id attached -> Edit the eperson
* When the eperson has no id attached -> Create new eperson
* Emit the updated/created eperson using the EventEmitter submitForm
*/
onSubmit() {
this.epersonService.getActiveEPerson().pipe(take(1)).subscribe(
(ePerson: EPerson) => {
const values = {
metadata: {
'eperson.firstname': [
{
value: this.firstName.value
}
],
'eperson.lastname': [
{
value: this.lastName.value
},
],
},
email: this.email.value,
canLogIn: this.canLogIn.value,
requireCertificate: this.requireCertificate.value,
};
if (ePerson == null) {
this.createNewEPerson(values);
} else {
this.editEPerson(ePerson, values);
}
}
);
}
/**
* Creates new EPerson based on given values from form
* @param values
*/
createNewEPerson(values) {
const ePersonToCreate = Object.assign(new EPerson(), values);
const response = this.epersonService.tryToCreate(ePersonToCreate);
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.created.success', { name: ePersonToCreate.name }));
this.submitForm.emit(ePersonToCreate);
} else {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.created.failure', { name: ePersonToCreate.name }));
this.cancelForm.emit();
}
});
this.showNotificationIfEmailInUse(ePersonToCreate, 'created');
}
/**
* Edits existing EPerson based on given values from form and old EPerson
* @param ePerson ePerson to edit
* @param values new ePerson values (of form)
*/
editEPerson(ePerson: EPerson, values) {
const editedEperson = Object.assign(new EPerson(), {
id: ePerson.id,
metadata: {
'eperson.firstname': [
{
value: (this.firstName.value ? this.firstName.value : ePerson.firstMetadataValue('eperson.firstname'))
}
],
'eperson.lastname': [
{
value: (this.lastName.value ? this.lastName.value : ePerson.firstMetadataValue('eperson.lastname'))
},
],
},
email: (hasValue(values.email) ? values.email : ePerson.email),
canLogIn: (hasValue(values.canLogIn) ? values.canLogIn : ePerson.canLogIn),
requireCertificate: (hasValue(values.requireCertificate) ? values.requireCertificate : ePerson.requireCertificate),
_links: ePerson._links,
});
const response = this.epersonService.updateEPerson(editedEperson);
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.edited.success', { name: editedEperson.name }));
this.submitForm.emit(editedEperson);
} else {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.edited.failure', { name: editedEperson.name }));
this.cancelForm.emit();
}
});
if (values.email != null && values.email !== ePerson.email) {
this.showNotificationIfEmailInUse(editedEperson, 'edited');
}
}
/**
* Checks for the given ePerson if there is already an ePerson in the system with that email
* and shows notification if this is the case
* @param ePerson ePerson values to check
* @param notificationSection whether in create or edit
*/
private showNotificationIfEmailInUse(ePerson: EPerson, notificationSection: string) {
// Relevant message for email in use
this.subs.push(this.epersonService.searchByScope('email', ePerson.email, {
currentPage: 1,
elementsPerPage: 0
}).pipe(getSucceededRemoteData(), getRemoteDataPayload())
.subscribe((list: PaginatedList<EPerson>) => {
if (list.totalElements > 0) {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.' + notificationSection + '.failure.emailInUse', {
name: ePerson.name,
email: ePerson.email
}));
}
}));
}
/**
* Event triggered when the user changes page
* @param event
*/
onPageChange(event) {
this.updateGroups({
currentPage: event,
elementsPerPage: this.config.pageSize
});
}
/**
* Update the list of groups by fetching it from the rest api or cache
*/
private updateGroups(options) {
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
this.groups = this.groupsDataService.findAllByHref(eperson._links.groups.href, options);
}));
}
/**
* Cancel the current edit when component is destroyed & unsub all subscriptions
*/
ngOnDestroy(): void {
this.onCancel();
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
}

View File

@@ -0,0 +1,33 @@
<div class="container">
<div class="group-form row">
<div class="col-12">
<div *ngIf="groupDataService.getActiveGroup() | async; then editheader; else createHeader"></div>
<ng-template #createHeader>
<h2 class="border-bottom pb-2">{{messagePrefix + '.head.create' | translate}}</h2>
</ng-template>
<ng-template #editheader>
<h2 class="border-bottom pb-2">{{messagePrefix + '.head.edit' | translate}}</h2>
</ng-template>
<ds-form [formId]="formId"
[formModel]="formModel"
[formGroup]="formGroup"
[formLayout]="formLayout"
(cancel)="onCancel()"
(submitForm)="onSubmit()">
</ds-form>
<ds-members-list *ngIf="groupBeingEdited != null" [messagePrefix]="messagePrefix + '.members-list'"></ds-members-list>
<ds-subgroups-list *ngIf="groupBeingEdited != null" [messagePrefix]="messagePrefix + '.subgroups-list'"></ds-subgroups-list>
<div>
<button [routerLink]="[this.groupDataService.getGroupRegistryRouterLink()]"
class="btn btn-primary">{{messagePrefix + '.return' | translate}}</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,153 @@
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { Store } from '@ngrx/store';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
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 { RestResponse } from '../../../../core/cache/response.models';
import { DSOChangeAnalyzer } from '../../../../core/data/dso-change-analyzer.service';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { RemoteData } from '../../../../core/data/remote-data';
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../../core/eperson/group-data.service';
import { Group } from '../../../../core/eperson/models/group.model';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { PageInfo } from '../../../../core/shared/page-info.model';
import { UUIDService } from '../../../../core/shared/uuid.service';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { getMockFormBuilderService } from '../../../../shared/mocks/mock-form-builder-service';
import { MockRouter } from '../../../../shared/mocks/mock-router';
import { getMockTranslateService } from '../../../../shared/mocks/mock-translate.service';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { GroupMock, GroupMock2 } from '../../../../shared/testing/group-mock';
import { MockTranslateLoader } from '../../../../shared/testing/mock-translate-loader';
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service-stub';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { GroupFormComponent } from './group-form.component';
describe('GroupFormComponent', () => {
let component: GroupFormComponent;
let fixture: ComponentFixture<GroupFormComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;
let ePersonDataServiceStub: any;
let groupsDataServiceStub: any;
let router;
let groups;
let groupName;
let groupDescription;
let expected;
beforeEach(async(() => {
groups = [GroupMock, GroupMock2]
groupName = 'testGroupName';
groupDescription = 'testDescription';
expected = Object.assign(new Group(), {
name: groupName,
metadata: {
'dc.description': [
{
value: groupDescription
}
],
},
});
ePersonDataServiceStub = {};
groupsDataServiceStub = {
allGroups: groups,
activeGroup: null,
getActiveGroup(): Observable<Group> {
return observableOf(this.activeGroup);
},
getGroupRegistryRouterLink(): string {
return '/admin/access-control/groups';
},
editGroup(group: Group) {
this.activeGroup = group
},
cancelEditGroup(): void {
this.activeGroup = null;
},
findById(id: string) {
return observableOf({ payload: null, hasSucceeded: true });
},
tryToCreate(group: Group): Observable<RestResponse> {
this.allGroups = [...this.allGroups, group]
return observableOf(new RestResponse(true, 200, 'Success'));
},
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
}
};
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();
router = new MockRouter();
TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
],
declarations: [GroupFormComponent],
providers: [GroupFormComponent,
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
{ provide: GroupDataService, useValue: groupsDataServiceStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: FormBuilderService, useValue: builderService },
{ provide: DSOChangeAnalyzer, useValue: {} },
{ provide: HttpClient, useValue: {} },
{ provide: ObjectCacheService, useValue: {} },
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: ActivatedRoute, useValue: { data: observableOf({ dso: { payload: {} } }), params: observableOf({}) } },
{ provide: Router, useValue: router },
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GroupFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create GroupFormComponent', inject([GroupFormComponent], (comp: GroupFormComponent) => {
expect(comp).toBeDefined();
}));
describe('when submitting the form', () => {
beforeEach(() => {
spyOn(component.submitForm, 'emit');
component.groupName.value = groupName;
component.groupDescription.value = groupDescription;
});
describe('without active Group', () => {
beforeEach(() => {
component.onSubmit();
fixture.detectChanges();
});
it('should emit a new group using the correct values', async(() => {
fixture.whenStable().then(() => {
expect(component.submitForm.emit).toHaveBeenCalledWith(expected);
});
}));
});
});
});

View File

@@ -0,0 +1,280 @@
import { Component, EventEmitter, HostListener, OnDestroy, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import {
DynamicFormControlModel,
DynamicFormLayout,
DynamicInputModel,
DynamicTextAreaModel
} from '@ng-dynamic-forms/core';
import { TranslateService } from '@ngx-translate/core';
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
import { Subscription } from 'rxjs/internal/Subscription';
import { take } from 'rxjs/operators';
import { RestResponse } from '../../../../core/cache/response.models';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../../core/eperson/group-data.service';
import { Group } from '../../../../core/eperson/models/group.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
import { hasValue, isNotEmpty } from '../../../../shared/empty.util';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
@Component({
selector: 'ds-group-form',
templateUrl: './group-form.component.html'
})
/**
* A form used for creating and editing groups
*/
export class GroupFormComponent implements OnInit, OnDestroy {
messagePrefix = 'admin.access-control.groups.form';
/**
* A unique id used for ds-form
*/
formId = 'group-form';
/**
* Dynamic models for the inputs of form
*/
groupName: DynamicInputModel;
groupDescription: DynamicTextAreaModel;
/**
* A list of all dynamic input models
*/
formModel: DynamicFormControlModel[];
/**
* Layout used for structuring the form inputs
*/
formLayout: DynamicFormLayout = {
groupName: {
grid: {
host: 'row'
}
},
groupDescription: {
grid: {
host: 'row'
}
},
};
/**
* A FormGroup that combines all inputs
*/
formGroup: FormGroup;
/**
* An EventEmitter that's fired whenever the form is being submitted
*/
@Output() submitForm: EventEmitter<any> = new EventEmitter();
/**
* An EventEmitter that's fired whenever the form is cancelled
*/
@Output() cancelForm: EventEmitter<any> = new EventEmitter();
/**
* List of subscriptions
*/
subs: Subscription[] = [];
/**
* Group currently being edited
*/
groupBeingEdited: Group;
constructor(public groupDataService: GroupDataService,
private ePersonDataService: EPersonDataService,
private formBuilderService: FormBuilderService,
private translateService: TranslateService,
private notificationsService: NotificationsService,
private route: ActivatedRoute,
protected router: Router) {
}
ngOnInit() {
this.subs.push(this.route.params.subscribe((params) => {
this.setActiveGroup(params.groupId)
}));
combineLatest(
this.translateService.get(`${this.messagePrefix}.groupName`),
this.translateService.get(`${this.messagePrefix}.groupDescription`),
).subscribe(([groupName, groupDescription]) => {
this.groupName = new DynamicInputModel({
id: 'groupName',
label: groupName,
name: 'groupName',
validators: {
required: null,
},
required: true,
});
this.groupDescription = new DynamicTextAreaModel({
id: 'groupDescription',
label: groupDescription,
name: 'groupDescription',
required: false,
});
this.formModel = [
this.groupName,
this.groupDescription
];
this.formGroup = this.formBuilderService.createFormGroup(this.formModel);
this.subs.push(this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupBeingEdited = activeGroup;
this.formGroup.patchValue({
groupName: activeGroup != null ? activeGroup.name : '',
groupDescription: activeGroup != null ? activeGroup.firstMetadataValue('dc.description') : '',
});
if (activeGroup.permanent) {
this.formGroup.get('groupName').disable();
}
}
}));
});
}
/**
* Stop editing the currently selected group
*/
onCancel() {
this.groupDataService.cancelEditGroup();
this.cancelForm.emit();
this.router.navigate([this.groupDataService.getGroupRegistryRouterLink()]);
}
/**
* Submit the form
* When the eperson has an id attached -> Edit the eperson
* When the eperson has no id attached -> Create new eperson
* Emit the updated/created eperson using the EventEmitter submitForm
*/
onSubmit() {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe(
(group: Group) => {
const values = {
name: this.groupName.value,
metadata: {
'dc.description': [
{
value: this.groupDescription.value
}
],
},
};
if (group === null) {
this.createNewGroup(values);
} else {
this.editGroup(group, values);
}
}
);
}
/**
* Creates new Group based on given values from form
* @param values
*/
createNewGroup(values) {
const groupToCreate = Object.assign(new Group(), values);
const response = this.groupDataService.tryToCreate(groupToCreate);
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.created.success', { name: groupToCreate.name }));
this.submitForm.emit(groupToCreate);
const resp: any = restResponse;
if (isNotEmpty(resp.resourceSelfLinks)) {
const groupSelfLink = resp.resourceSelfLinks[0];
this.setActiveGroupWithLink(groupSelfLink);
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLinkWithID(this.groupDataService.getUUIDFromString(groupSelfLink)));
}
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.created.failure', { name: groupToCreate.name }));
this.showNotificationIfNameInUse(groupToCreate, 'created');
this.cancelForm.emit();
}
});
}
/**
* Checks for the given group if there is already a group in the system with that group name and shows error if that
* is the case
* @param group group to check
* @param notificationSection whether in create or edit
*/
private showNotificationIfNameInUse(group: Group, notificationSection: string) {
// Relevant message for group name in use
this.subs.push(this.groupDataService.searchGroups(group.name, {
currentPage: 1,
elementsPerPage: 0
}).pipe(getSucceededRemoteData(), getRemoteDataPayload())
.subscribe((list: PaginatedList<Group>) => {
if (list.totalElements > 0) {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.' + notificationSection + '.failure.groupNameInUse', {
name: group.name
}));
}
}));
}
/**
* // TODO
* @param group
* @param values
*/
editGroup(group: Group, values) {
// TODO (backend)
console.log('TODO implement editGroup', values);
this.notificationsService.error('TODO implement editGroup (not yet implemented in backend) ');
}
/**
* Start editing the selected group
* @param groupId ID of group to set as active
*/
setActiveGroup(groupId: string) {
this.groupDataService.cancelEditGroup();
this.groupDataService.findById(groupId)
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload())
.subscribe((group: Group) => {
this.groupDataService.editGroup(group);
});
}
/**
* Start editing the selected group
* @param groupSelfLink SelfLink of group to set as active
*/
setActiveGroupWithLink(groupSelfLink: string) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup === null) {
this.groupDataService.cancelEditGroup();
this.groupDataService.findByHref(groupSelfLink)
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload())
.subscribe((group: Group) => {
this.groupDataService.editGroup(group);
})
}
});
}
/**
* Cancel the current edit when component is destroyed & unsub all subscriptions
*/
@HostListener('window:beforeunload')
ngOnDestroy(): void {
this.onCancel();
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
}

View File

@@ -0,0 +1,124 @@
<ng-container>
<h3 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h3>
<h4 id="search" class="border-bottom pb-2">{{messagePrefix + '.search.head' | translate}}
<button (click)="clearFormAndResetResult();"
class="btn btn-primary float-right">{{messagePrefix + '.button.see-all' | translate}}</button>
</h4>
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
<div class="col-12 col-sm-3">
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
<option value="metadata">{{messagePrefix + '.search.scope.metadata' | translate}}</option>
<option value="email">{{messagePrefix + '.search.scope.email' | translate}}</option>
</select>
</div>
<div class="col-sm-9 col-12">
<div class="form-group input-group">
<input type="text" name="query" id="query" formControlName="query"
class="form-control" aria-label="Search input">
<span class="input-group-append">
<button type="submit"
class="search-button btn btn-secondary">{{ messagePrefix + '.search.button' | translate }}</button>
</span>
</div>
</div>
</form>
<ds-pagination *ngIf="(ePeopleSearch | async)?.payload.totalElements > 0"
[paginationOptions]="configSearch"
[pageInfoState]="(ePeopleSearch | async)?.payload"
[collectionSize]="(ePeopleSearch | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChangeSearch($event)">
<div class="table-responsive">
<table id="epersonsSearch" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{messagePrefix + '.table.id' | translate}}</th>
<th scope="col">{{messagePrefix + '.table.name' | translate}}</th>
<th>{{messagePrefix + '.table.edit' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let ePerson of (ePeopleSearch | async)?.payload?.page">
<td>{{ePerson.id}}</td>
<td><a (click)="ePersonDataService.startEditingNewEPerson(ePerson)"
[routerLink]="[ePersonDataService.getEPeoplePageRouterLink()]">{{ePerson.name}}</a></td>
<td>
<div class="btn-group edit-field">
<button *ngIf="(isMemberOfGroup(ePerson) | async)"
(click)="deleteMemberFromGroup(ePerson)"
class="btn btn-outline-danger btn-sm"
title="{{messagePrefix + '.table.edit.buttons.remove' | translate: {name: ePerson.name} }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
<button *ngIf="!(isMemberOfGroup(ePerson) | async)"
(click)="addMemberToGroup(ePerson)"
class="btn btn-outline-primary btn-sm"
title="{{messagePrefix + '.table.edit.buttons.add' | translate: {name: ePerson.name} }}">
<i class="fas fa-plus fa-fw"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(ePeopleSearch | async)?.payload.totalElements == 0 && searchDone"
class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-items' | translate}}
</div>
<h4>{{messagePrefix + '.headMembers' | translate}}</h4>
<ds-pagination *ngIf="(ePeopleMembersOfGroup | async)?.payload.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(ePeopleMembersOfGroup | async)?.payload"
[collectionSize]="(ePeopleMembersOfGroup | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
<div class="table-responsive">
<table id="ePeopleMembersOfGroup" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{messagePrefix + '.table.id' | translate}}</th>
<th scope="col">{{messagePrefix + '.table.name' | translate}}</th>
<th>{{messagePrefix + '.table.edit' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let ePerson of (ePeopleMembersOfGroup | async)?.payload?.page">
<td>{{ePerson.id}}</td>
<td><a (click)="ePersonDataService.startEditingNewEPerson(ePerson)"
[routerLink]="[ePersonDataService.getEPeoplePageRouterLink()]">{{ePerson.name}}</a></td>
<td>
<div class="btn-group edit-field">
<button (click)="deleteMemberFromGroup(ePerson)"
class="btn btn-outline-danger btn-sm"
title="{{messagePrefix + '.table.edit.buttons.remove' | translate: {name: ePerson.name} }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(ePeopleMembersOfGroup | async)?.payload.totalElements == 0" class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-members-yet' | translate}}
</div>
</ng-container>

View File

@@ -0,0 +1,241 @@
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, flush, inject, TestBed, tick } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { RestResponse } from '../../../../../core/cache/response.models';
import { PaginatedList } from '../../../../../core/data/paginated-list';
import { RemoteData } from '../../../../../core/data/remote-data';
import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
import { EPerson } from '../../../../../core/eperson/models/eperson.model';
import { Group } from '../../../../../core/eperson/models/group.model';
import { PageInfo } from '../../../../../core/shared/page-info.model';
import { FormBuilderService } from '../../../../../shared/form/builder/form-builder.service';
import { getMockFormBuilderService } from '../../../../../shared/mocks/mock-form-builder-service';
import { MockRouter } from '../../../../../shared/mocks/mock-router';
import { getMockTranslateService } from '../../../../../shared/mocks/mock-translate.service';
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
import { EPersonMock, EPersonMock2 } from '../../../../../shared/testing/eperson-mock';
import { GroupMock, GroupMock2 } from '../../../../../shared/testing/group-mock';
import { MockTranslateLoader } from '../../../../../shared/testing/mock-translate-loader';
import { NotificationsServiceStub } from '../../../../../shared/testing/notifications-service-stub';
import { of as observableOf } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils';
import { MembersListComponent } from './members-list.component';
describe('MembersListComponent', () => {
let component: MembersListComponent;
let fixture: ComponentFixture<MembersListComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;
let ePersonDataServiceStub: any;
let groupsDataServiceStub: any;
let activeGroup;
let allEPersons;
let allGroups;
let epersonMembers;
let subgroupMembers;
beforeEach(async(() => {
activeGroup = GroupMock;
epersonMembers = [EPersonMock2];
subgroupMembers = [GroupMock2];
allEPersons = [EPersonMock, EPersonMock2];
allGroups = [GroupMock, GroupMock2];
ePersonDataServiceStub = {
activeGroup: activeGroup,
epersonMembers: epersonMembers,
subgroupMembers: subgroupMembers,
findAllByHref(href: string): Observable<RemoteData<PaginatedList<EPerson>>> {
return createSuccessfulRemoteDataObject$(new PaginatedList<EPerson>(new PageInfo(), groupsDataServiceStub.getEPersonMembers()))
},
searchByScope(scope: string, query: string): Observable<RemoteData<PaginatedList<EPerson>>> {
if (query === '') {
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), allEPersons))
}
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
},
clearEPersonRequests() {
// empty
},
clearLinkRequests() {
// empty
},
getEPeoplePageRouterLink(): string {
return '/admin/access-control/epeople';
}
};
groupsDataServiceStub = {
activeGroup: activeGroup,
epersonMembers: epersonMembers,
subgroupMembers: subgroupMembers,
allGroups: allGroups,
getActiveGroup(): Observable<Group> {
return observableOf(activeGroup);
},
getEPersonMembers() {
return this.epersonMembers;
},
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
if (query === '') {
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), this.allGroups))
}
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
},
addMemberToGroup(parentGroup, eperson: EPerson): Observable<RestResponse> {
this.epersonMembers = [...this.epersonMembers, eperson];
return observableOf(new RestResponse(true, 200, 'Success'));
},
clearGroupsRequests() {
// empty
},
clearGroupLinkRequests() {
// empty
},
getGroupEditPageRouterLink(group: Group): string {
return '/admin/access-control/groups/' + group.id;
},
deleteMemberFromGroup(parentGroup, epersonToDelete: EPerson): Observable<RestResponse> {
this.epersonMembers = this.epersonMembers.find((eperson: EPerson) => {
if (eperson.id !== epersonToDelete.id) {
return eperson;
}
});
if (this.epersonMembers === undefined) {
this.epersonMembers = []
}
return observableOf(new RestResponse(true, 200, 'Success'));
}
};
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();
TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
],
declarations: [MembersListComponent],
providers: [MembersListComponent,
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
{ provide: GroupDataService, useValue: groupsDataServiceStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: FormBuilderService, useValue: builderService },
{ provide: Router, useValue: new MockRouter() },
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MembersListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(fakeAsync(() => {
fixture.destroy();
flush();
component = null;
}));
it('should create MembersListComponent', inject([MembersListComponent], (comp: MembersListComponent) => {
expect(comp).toBeDefined();
}));
it('should show list of eperson members of current active group', () => {
const epersonIdsFound = fixture.debugElement.queryAll(By.css('#ePeopleMembersOfGroup tr td:first-child'));
expect(epersonIdsFound.length).toEqual(1);
epersonMembers.map((eperson: EPerson) => {
expect(epersonIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === eperson.uuid);
})).toBeTruthy();
});
});
describe('search', () => {
describe('when searching without query', () => {
let epersonsFound;
beforeEach(fakeAsync(() => {
component.search({ scope: 'metadata', query: '' });
tick();
fixture.detectChanges();
epersonsFound = fixture.debugElement.queryAll(By.css('#epersonsSearch tbody tr'));
}));
it('should display all epersons', () => {
expect(epersonsFound.length).toEqual(2);
});
describe('if eperson is already a eperson', () => {
it('should have delete button, else it should have add button', () => {
activeGroup.epersons.map((eperson: EPerson) => {
epersonsFound.map((foundEPersonRowElement) => {
if (foundEPersonRowElement.debugElement !== undefined) {
const epersonId = foundEPersonRowElement.debugElement.query(By.css('td:first-child'));
const addButton = foundEPersonRowElement.debugElement.query(By.css('td:last-child .fa-plus'));
const deleteButton = foundEPersonRowElement.debugElement.query(By.css('td:last-child .fa-trash-alt'));
if (epersonId.nativeElement.textContent === eperson.id) {
expect(addButton).toBeUndefined();
expect(deleteButton).toBeDefined();
} else {
expect(deleteButton).toBeUndefined();
expect(addButton).toBeDefined();
}
}
})
})
});
});
describe('if first add button is pressed', () => {
beforeEach(fakeAsync(() => {
const addButton = fixture.debugElement.query(By.css('#epersonsSearch tbody .fa-plus'));
addButton.nativeElement.click();
tick();
fixture.detectChanges();
}));
it('all groups in search member of selected group', () => {
epersonsFound = fixture.debugElement.queryAll(By.css('#epersonsSearch tbody tr'));
expect(epersonsFound.length).toEqual(2);
epersonsFound.map((foundEPersonRowElement) => {
if (foundEPersonRowElement.debugElement !== undefined) {
const addButton = foundEPersonRowElement.debugElement.query(By.css('td:last-child .fa-plus'));
const deleteButton = foundEPersonRowElement.debugElement.query(By.css('td:last-child .fa-trash-alt'));
expect(addButton).toBeUndefined();
expect(deleteButton).toBeDefined();
}
})
});
});
describe('if first delete button is pressed', () => {
beforeEach(fakeAsync(() => {
const addButton = fixture.debugElement.query(By.css('#epersonsSearch tbody .fa-trash-alt'));
addButton.nativeElement.click();
tick();
fixture.detectChanges();
}));
it('first eperson in search delete button, because now member', () => {
epersonsFound = fixture.debugElement.queryAll(By.css('#epersonsSearch tbody tr'));
epersonsFound.map((foundEPersonRowElement) => {
if (foundEPersonRowElement.debugElement !== undefined) {
const addButton = foundEPersonRowElement.debugElement.query(By.css('td:last-child .fa-plus'));
const deleteButton = foundEPersonRowElement.debugElement.query(By.css('td:last-child .fa-trash-alt'));
expect(deleteButton).toBeUndefined();
expect(addButton).toBeDefined();
}
})
});
});
});
});
});

View File

@@ -0,0 +1,247 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { map, mergeMap, take } from 'rxjs/operators';
import { RestResponse } from '../../../../../core/cache/response.models';
import { PaginatedList } from '../../../../../core/data/paginated-list';
import { RemoteData } from '../../../../../core/data/remote-data';
import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
import { EPerson } from '../../../../../core/eperson/models/eperson.model';
import { Group } from '../../../../../core/eperson/models/group.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../core/shared/operators';
import { hasValue } from '../../../../../shared/empty.util';
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model';
@Component({
selector: 'ds-members-list',
templateUrl: './members-list.component.html'
})
/**
* The list of members in the edit group page
*/
export class MembersListComponent implements OnInit, OnDestroy {
@Input()
messagePrefix: string;
/**
* EPeople being displayed in search result, initially all members, after search result of search
*/
ePeopleSearch: Observable<RemoteData<PaginatedList<EPerson>>>;
/**
* List of EPeople members of currently active group being edited
*/
ePeopleMembersOfGroup: Observable<RemoteData<PaginatedList<EPerson>>>;
/**
* Pagination config used to display the list of EPeople that are result of EPeople search
*/
configSearch: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'search-members-list-pagination',
pageSize: 5,
currentPage: 1
});
/**
* Pagination config used to display the list of EPerson Membes of active group being edited
*/
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'members-list-pagination',
pageSize: 5,
currentPage: 1
});
/**
* List of subscriptions
*/
subs: Subscription[] = [];
// The search form
searchForm;
// Current search in edit group - epeople search form
currentSearchQuery: string;
currentSearchScope: string;
// Whether or not user has done a EPeople search yet
searchDone: boolean;
// current active group being edited
groupBeingEdited: Group;
constructor(private groupDataService: GroupDataService,
public ePersonDataService: EPersonDataService,
private translateService: TranslateService,
private notificationsService: NotificationsService,
private formBuilder: FormBuilder,
private router: Router) {
this.currentSearchQuery = '';
this.currentSearchScope = 'metadata';
}
ngOnInit() {
this.searchForm = this.formBuilder.group(({
scope: 'metadata',
query: '',
}));
this.subs.push(this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupBeingEdited = activeGroup;
this.forceUpdateEPeople(activeGroup);
}
}));
}
/**
* Event triggered when the user changes page on search result
* @param event
*/
onPageChangeSearch(event) {
this.configSearch.currentPage = event;
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery });
}
/**
* Event triggered when the user changes page on EPerson embers of active group
* @param event
*/
onPageChange(event) {
this.ePeopleMembersOfGroup = this.ePersonDataService.findAllByHref(this.groupBeingEdited._links.epersons.href, {
currentPage: event,
elementsPerPage: this.config.pageSize
})
}
/**
* Deletes a given EPerson from the members list of the group currently being edited
* @param ePerson EPerson we want to delete as member from group that is currently being edited
*/
deleteMemberFromGroup(ePerson: EPerson) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
const response = this.groupDataService.deleteMemberFromGroup(activeGroup, ePerson);
this.showNotifications('deleteMember', response, ePerson.name, activeGroup);
this.forceUpdateEPeople(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
});
}
/**
* Adds a given EPerson to the members list of the group currently being edited
* @param ePerson EPerson we want to add as member to group that is currently being edited
*/
addMemberToGroup(ePerson: EPerson) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
const response = this.groupDataService.addMemberToGroup(activeGroup, ePerson);
this.showNotifications('addMember', response, ePerson.name, activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
});
this.forceUpdateEPeople(this.groupBeingEdited, ePerson);
}
/**
* Whether or not the given ePerson is a member of the group currently being edited
* @param possibleMember EPerson that is a possible member (being tested) of the group currently being edited
*/
isMemberOfGroup(possibleMember: EPerson): Observable<boolean> {
return this.groupDataService.getActiveGroup().pipe(take(1),
mergeMap((group: Group) => {
if (group != null) {
return this.ePersonDataService.findAllByHref(group._links.epersons.href, {
currentPage: 0,
elementsPerPage: Number.MAX_SAFE_INTEGER
})
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
map((listEPeopleInGroup: PaginatedList<EPerson>) => listEPeopleInGroup.page.filter((ePersonInList: EPerson) => ePersonInList.id === possibleMember.id)),
map((epeople: EPerson[]) => epeople.length > 0))
} else {
return observableOf(false);
}
}))
}
/**
* Search in the EPeople by name, email or metadata
* @param data Contains scope and query param
*/
search(data: any) {
const query: string = data.query;
const scope: string = data.scope;
if (query != null && this.currentSearchQuery !== query && this.groupBeingEdited) {
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(this.groupBeingEdited));
this.currentSearchQuery = query;
this.configSearch.currentPage = 1;
}
if (scope != null && this.currentSearchScope !== scope && this.groupBeingEdited) {
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(this.groupBeingEdited));
this.currentSearchScope = scope;
this.configSearch.currentPage = 1;
}
this.searchDone = true;
this.ePeopleSearch = this.ePersonDataService.searchByScope(this.currentSearchScope, this.currentSearchQuery, {
currentPage: this.configSearch.currentPage,
elementsPerPage: this.configSearch.pageSize
});
}
/**
* Force-update the list of EPeople by first clearing the cache related to EPeople, then performing
* a new REST call
* @param activeGroup Group currently being edited
*/
public forceUpdateEPeople(activeGroup: Group, ePersonToUpdate?: EPerson) {
if (ePersonToUpdate != null) {
this.ePersonDataService.clearLinkRequests(ePersonToUpdate._links.groups.href);
}
this.ePersonDataService.clearLinkRequests(activeGroup._links.epersons.href);
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(activeGroup));
this.ePeopleMembersOfGroup = this.ePersonDataService.findAllByHref(activeGroup._links.epersons.href, {
currentPage: this.configSearch.currentPage,
elementsPerPage: this.configSearch.pageSize
})
}
/**
* unsub all subscriptions
*/
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
/**
* Shows a notification based on the success/failure of the request
* @param messageSuffix Suffix for message
* @param response RestResponse observable containing success/failure request
* @param nameObject Object request was about
* @param activeGroup Group currently being edited
*/
showNotifications(messageSuffix: string, response: Observable<RestResponse>, nameObject: string, activeGroup: Group) {
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
}
})
}
/**
* Reset all input-fields to be empty and search all search
*/
clearFormAndResetResult() {
this.searchForm.patchValue({
query: '',
});
this.search({ query: '' });
}
}

View File

@@ -0,0 +1,117 @@
<ng-container>
<h3 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h3>
<h4 id="search" class="border-bottom pb-2">{{messagePrefix + '.search.head' | translate}}
<button (click)="clearFormAndResetResult();"
class="btn btn-primary float-right">{{messagePrefix + '.button.see-all' | translate}}</button>
</h4>
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
<div class="col-12">
<div class="form-group input-group">
<input type="text" name="query" id="query" formControlName="query"
class="form-control" aria-label="Search input">
<span class="input-group-append">
<button type="submit"
class="search-button btn btn-secondary">{{ messagePrefix + '.search.button' | translate }}</button>
</span>
</div>
</div>
</form>
<ds-pagination *ngIf="(groupsSearch | async)?.payload.totalElements > 0"
[paginationOptions]="configSearch"
[pageInfoState]="(groupsSearch | async)?.payload"
[collectionSize]="(groupsSearch | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChangeSearch($event)">
<div class="table-responsive">
<table id="groupsSearch" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{messagePrefix + '.table.id' | translate}}</th>
<th scope="col">{{messagePrefix + '.table.name' | translate}}</th>
<th>{{messagePrefix + '.table.edit' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let group of (groupsSearch | async)?.payload?.page">
<td>{{group.id}}</td>
<td><a (click)="groupDataService.startEditingNewGroup(group)"
[routerLink]="[groupDataService.getGroupEditPageRouterLink(group)]">{{group.name}}</a></td>
<td>
<div class="btn-group edit-field">
<button *ngIf="(isSubgroupOfGroup(group) | async) && !(isActiveGroup(group) | async)"
(click)="deleteSubgroupFromGroup(group)"
class="btn btn-outline-danger btn-sm deleteButton"
title="{{messagePrefix + '.table.edit.buttons.remove' | translate: {name: group.name} }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
<p *ngIf="(isActiveGroup(group) | async)">{{ messagePrefix + '.table.edit.currentGroup' | translate }}</p>
<button *ngIf="!(isSubgroupOfGroup(group) | async) && !(isActiveGroup(group) | async)"
(click)="addSubgroupToGroup(group)"
class="btn btn-outline-primary btn-sm addButton"
title="{{messagePrefix + '.table.edit.buttons.add' | translate: {name: group.name} }}">
<i class="fas fa-plus fa-fw"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(groupsSearch | async)?.payload.totalElements == 0 && searchDone" class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-items' | translate}}
</div>
<h4>{{messagePrefix + '.headSubgroups' | translate}}</h4>
<ds-pagination *ngIf="(subgroupsOfGroup | async)?.payload.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(subgroupsOfGroup | async)?.payload"
[collectionSize]="(subgroupsOfGroup | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
<div class="table-responsive">
<table id="subgroupsOfGroup" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{messagePrefix + '.table.id' | translate}}</th>
<th scope="col">{{messagePrefix + '.table.name' | translate}}</th>
<th>{{messagePrefix + '.table.edit' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let group of (subgroupsOfGroup | async)?.payload?.page">
<td>{{group.id}}</td>
<td><a (click)="groupDataService.startEditingNewGroup(group)"
[routerLink]="[groupDataService.getGroupEditPageRouterLink(group)]">{{group.name}}</a></td>
<td>
<div class="btn-group edit-field">
<button (click)="deleteSubgroupFromGroup(group)"
class="btn btn-outline-danger btn-sm deleteButton"
title="{{messagePrefix + '.table.edit.buttons.remove' | translate: {name: group.name} }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(subgroupsOfGroup | async)?.payload.totalElements == 0" class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-subgroups-yet' | translate}}
</div>
</ng-container>

View File

@@ -0,0 +1,208 @@
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, flush, inject, TestBed, tick } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { RestResponse } from '../../../../../core/cache/response.models';
import { PaginatedList } from '../../../../../core/data/paginated-list';
import { RemoteData } from '../../../../../core/data/remote-data';
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
import { Group } from '../../../../../core/eperson/models/group.model';
import { PageInfo } from '../../../../../core/shared/page-info.model';
import { FormBuilderService } from '../../../../../shared/form/builder/form-builder.service';
import { getMockFormBuilderService } from '../../../../../shared/mocks/mock-form-builder-service';
import { MockRouter } from '../../../../../shared/mocks/mock-router';
import { getMockTranslateService } from '../../../../../shared/mocks/mock-translate.service';
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
import { GroupMock, GroupMock2 } from '../../../../../shared/testing/group-mock';
import { MockTranslateLoader } from '../../../../../shared/testing/mock-translate-loader';
import { NotificationsServiceStub } from '../../../../../shared/testing/notifications-service-stub';
import { of as observableOf } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils';
import { SubgroupsListComponent } from './subgroups-list.component';
describe('SubgroupsListComponent', () => {
let component: SubgroupsListComponent;
let fixture: ComponentFixture<SubgroupsListComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;
let ePersonDataServiceStub: any;
let groupsDataServiceStub: any;
let activeGroup;
let subgroups;
let allGroups;
let routerStub;
beforeEach(async(() => {
activeGroup = GroupMock;
subgroups = [GroupMock2];
allGroups = [GroupMock, GroupMock2];
ePersonDataServiceStub = {};
groupsDataServiceStub = {
activeGroup: activeGroup,
subgroups: subgroups,
getActiveGroup(): Observable<Group> {
return observableOf(this.activeGroup);
},
getSubgroups(): Group {
return this.activeGroup;
},
findAllByHref(href: string): Observable<RemoteData<PaginatedList<Group>>> {
return createSuccessfulRemoteDataObject$(new PaginatedList<Group>(new PageInfo(), this.subgroups))
},
getGroupEditPageRouterLink(group: Group): string {
return '/admin/access-control/groups/' + group.id;
},
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
if (query === '') {
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), allGroups))
}
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
},
addSubGroupToGroup(parentGroup, subgroup: Group): Observable<RestResponse> {
this.subgroups = [...this.subgroups, subgroup];
return observableOf(new RestResponse(true, 200, 'Success'));
},
clearGroupsRequests() {
// empty
},
clearGroupLinkRequests() {
// empty
},
deleteSubGroupFromGroup(parentGroup, subgroup: Group): Observable<RestResponse> {
this.subgroups = this.subgroups.find((group: Group) => {
if (group.id !== subgroup.id) {
return group;
}
});
return observableOf(new RestResponse(true, 200, 'Success'));
}
};
routerStub = new MockRouter();
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();
TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
],
declarations: [SubgroupsListComponent],
providers: [SubgroupsListComponent,
{ provide: GroupDataService, useValue: groupsDataServiceStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: FormBuilderService, useValue: builderService },
{ provide: Router, useValue: routerStub },
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SubgroupsListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(fakeAsync(() => {
fixture.destroy();
flush();
component = null;
}));
it('should create SubgroupsListComponent', inject([SubgroupsListComponent], (comp: SubgroupsListComponent) => {
expect(comp).toBeDefined();
}));
it('should show list of subgroups of current active group', () => {
const groupIdsFound = fixture.debugElement.queryAll(By.css('#subgroupsOfGroup tr td:first-child'));
expect(groupIdsFound.length).toEqual(1);
activeGroup.subgroups.map((group: Group) => {
expect(groupIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === group.uuid);
})).toBeTruthy();
})
});
describe('if first group delete button is pressed', () => {
let groupsFound;
beforeEach(fakeAsync(() => {
const addButton = fixture.debugElement.query(By.css('#subgroupsOfGroup tbody .deleteButton'));
addButton.triggerEventHandler('click', {
preventDefault: () => {/**/
}
});
tick();
fixture.detectChanges();
}));
it('one less subgroup in list from 1 to 0 (of 2 total groups)', () => {
groupsFound = fixture.debugElement.queryAll(By.css('#subgroupsOfGroup tbody tr'));
expect(groupsFound.length).toEqual(0);
});
});
describe('search', () => {
describe('when searching with empty query', () => {
let groupsFound;
beforeEach(fakeAsync(() => {
component.search({ query: '' });
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
}));
it('should display all groups', () => {
fixture.detectChanges();
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
expect(groupsFound.length).toEqual(2);
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
const groupIdsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr td:first-child'));
allGroups.map((group: Group) => {
expect(groupIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === group.uuid);
})).toBeTruthy();
})
});
describe('if group is already a subgroup', () => {
it('should have delete button, else it should have add button', () => {
fixture.detectChanges();
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
const getSubgroups = groupsDataServiceStub.getSubgroups().subgroups;
if (getSubgroups !== undefined && getSubgroups.length > 0) {
groupsFound.map((foundGroupRowElement) => {
if (foundGroupRowElement.debugElement !== undefined) {
const addButton = foundGroupRowElement.debugElement.query(By.css('td:last-child .fa-plus'));
const deleteButton = foundGroupRowElement.debugElement.query(By.css('td:last-child .fa-trash-alt'));
expect(addButton).toBeUndefined();
expect(deleteButton).toBeDefined();
}
})
} else {
getSubgroups.map((group: Group) => {
groupsFound.map((foundGroupRowElement) => {
if (foundGroupRowElement.debugElement !== undefined) {
const groupId = foundGroupRowElement.debugElement.query(By.css('td:first-child'));
const addButton = foundGroupRowElement.debugElement.query(By.css('td:last-child .fa-plus'));
const deleteButton = foundGroupRowElement.debugElement.query(By.css('td:last-child .fa-trash-alt'));
if (groupId.nativeElement.textContent === group.id) {
expect(addButton).toBeUndefined();
expect(deleteButton).toBeDefined();
} else {
expect(deleteButton).toBeUndefined();
expect(addButton).toBeDefined();
}
}
})
})
}
});
});
});
});
});

View File

@@ -0,0 +1,253 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { map, mergeMap, take } from 'rxjs/operators';
import { RestResponse } from '../../../../../core/cache/response.models';
import { PaginatedList } from '../../../../../core/data/paginated-list';
import { RemoteData } from '../../../../../core/data/remote-data';
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
import { Group } from '../../../../../core/eperson/models/group.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../core/shared/operators';
import { hasValue } from '../../../../../shared/empty.util';
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model';
@Component({
selector: 'ds-subgroups-list',
templateUrl: './subgroups-list.component.html'
})
/**
* The list of subgroups in the edit group page
*/
export class SubgroupsListComponent implements OnInit, OnDestroy {
@Input()
messagePrefix: string;
/**
* Result of search groups, initially all groups
*/
groupsSearch: Observable<RemoteData<PaginatedList<Group>>>;
/**
* List of all subgroups of group being edited
*/
subgroupsOfGroup: Observable<RemoteData<PaginatedList<Group>>>;
/**
* List of subscriptions
*/
subs: Subscription[] = [];
/**
* Pagination config used to display the list of groups that are result of groups search
*/
configSearch: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'search-subgroups-list-pagination',
pageSize: 5,
currentPage: 1
});
/**
* Pagination config used to display the list of subgroups of currently active group being edited
*/
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'subgroups-list-pagination',
pageSize: 5,
currentPage: 1
});
// The search form
searchForm;
// Current search in edit group - groups search form
currentSearchQuery: string;
// Whether or not user has done a Groups search yet
searchDone: boolean;
// current active group being edited
groupBeingEdited: Group;
constructor(public groupDataService: GroupDataService,
private translateService: TranslateService,
private notificationsService: NotificationsService,
private formBuilder: FormBuilder,
private router: Router) {
this.currentSearchQuery = '';
}
ngOnInit() {
this.searchForm = this.formBuilder.group(({
query: '',
}));
this.subs.push(this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupBeingEdited = activeGroup;
this.forceUpdateGroups(activeGroup);
}
}));
}
/**
* Event triggered when the user changes page on search result
* @param event
*/
onPageChangeSearch(event) {
this.configSearch.currentPage = event;
this.search({ query: this.currentSearchQuery });
}
/**
* Event triggered when the user changes page on subgroups of active group
* @param event
*/
onPageChange(event) {
this.subgroupsOfGroup = this.groupDataService.findAllByHref(this.groupBeingEdited._links.subgroups.href, {
currentPage: event,
elementsPerPage: this.config.pageSize
});
}
/**
* Whether or not the given group is a subgroup of the group currently being edited
* @param possibleSubgroup Group that is a possible subgroup (being tested) of the group currently being edited
*/
isSubgroupOfGroup(possibleSubgroup: Group): Observable<boolean> {
return this.groupDataService.getActiveGroup().pipe(take(1),
mergeMap((activeGroup: Group) => {
if (activeGroup != null) {
if (activeGroup.uuid === possibleSubgroup.uuid) {
return observableOf(false);
} else {
return this.groupDataService.findAllByHref(activeGroup._links.subgroups.href, {
currentPage: 0,
elementsPerPage: Number.MAX_SAFE_INTEGER
})
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
map((listTotalGroups: PaginatedList<Group>) => listTotalGroups.page.filter((groupInList: Group) => groupInList.id === possibleSubgroup.id)),
map((groups: Group[]) => groups.length > 0))
}
} else {
return observableOf(false);
}
}));
}
/**
* Whether or not the given group is the current group being edited
* @param group Group that is possibly the current group being edited
*/
isActiveGroup(group: Group): Observable<boolean> {
return this.groupDataService.getActiveGroup().pipe(take(1),
mergeMap((activeGroup: Group) => {
if (activeGroup != null && activeGroup.uuid === group.uuid) {
return observableOf(true);
}
return observableOf(false);
}));
}
/**
* Deletes given subgroup from the group currently being edited
* @param subgroup Group we want to delete from the subgroups of the group currently being edited
*/
deleteSubgroupFromGroup(subgroup: Group) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
const response = this.groupDataService.deleteSubGroupFromGroup(activeGroup, subgroup);
this.showNotifications('deleteSubgroup', response, subgroup.name, activeGroup);
this.forceUpdateGroups(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
});
}
/**
* Adds given subgroup to the group currently being edited
* @param subgroup Subgroup to add to group currently being edited
*/
addSubgroupToGroup(subgroup: Group) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
if (activeGroup.uuid !== subgroup.uuid) {
const response = this.groupDataService.addSubGroupToGroup(activeGroup, subgroup);
this.showNotifications('addSubgroup', response, subgroup.name, activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.subgroupToAddIsActiveGroup'));
}
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
});
this.forceUpdateGroups(this.groupBeingEdited);
}
/**
* Search in the groups (searches by group name and by uuid exact match)
* @param data Contains query param
*/
search(data: any) {
const query: string = data.query;
if (query != null && this.currentSearchQuery !== query) {
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(this.groupBeingEdited));
this.currentSearchQuery = query;
this.configSearch.currentPage = 1;
}
this.searchDone = true;
this.groupsSearch = this.groupDataService.searchGroups(this.currentSearchQuery, {
currentPage: this.configSearch.currentPage,
elementsPerPage: this.configSearch.pageSize
});
}
/**
* Force-update the list of groups by first clearing the cache of results of this active groups' subgroups, then performing a new REST call
* @param activeGroup Group currently being edited
*/
public forceUpdateGroups(activeGroup: Group) {
this.groupDataService.clearGroupLinkRequests(activeGroup._links.subgroups.href);
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(activeGroup));
this.subgroupsOfGroup = this.groupDataService.findAllByHref(activeGroup._links.subgroups.href, {
currentPage: this.config.currentPage,
elementsPerPage: this.config.pageSize
});
}
/**
* unsub all subscriptions
*/
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
/**
* Shows a notification based on the success/failure of the request
* @param messageSuffix Suffix for message
* @param response RestResponse observable containing success/failure request
* @param nameObject Object request was about
* @param activeGroup Group currently being edited
*/
showNotifications(messageSuffix: string, response: Observable<RestResponse>, nameObject: string, activeGroup: Group) {
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
}
})
}
/**
* Reset all input-fields to be empty and search all search
*/
clearFormAndResetResult() {
this.searchForm.patchValue({
query: '',
});
this.search({ query: '' });
}
}

View File

@@ -0,0 +1,49 @@
import { Action } from '@ngrx/store';
import { Group } from '../../../core/eperson/models/group.model';
import { type } from '../../../shared/ngrx/type';
/**
* For each action type in an action group, make a simple
* enum object for all of this group's action types.
*
* The 'type' utility function coerces strings into string
* literal types and runs a simple check to guarantee all
* action types in the application are unique.
*/
export const GroupRegistryActionTypes = {
EDIT_GROUP: type('dspace/epeople-registry/EDIT_GROUP'),
CANCEL_EDIT_GROUP: type('dspace/epeople-registry/CANCEL_EDIT_GROUP'),
};
/* tslint:disable:max-classes-per-file */
/**
* Used to edit a Group in the Group registry
*/
export class GroupRegistryEditGroupAction implements Action {
type = GroupRegistryActionTypes.EDIT_GROUP;
group: Group;
constructor(group: Group) {
this.group = group;
}
}
/**
* Used to cancel the editing of a Group in the Group registry
*/
export class GroupRegistryCancelGroupAction implements Action {
type = GroupRegistryActionTypes.CANCEL_EDIT_GROUP;
}
/* tslint:enable:max-classes-per-file */
/**
* Export a type alias of all actions in this action group
* so that reducers can easily compose action types
* These are all the actions to perform on the EPeople registry state
*/
export type GroupRegistryAction
= GroupRegistryEditGroupAction
| GroupRegistryCancelGroupAction

View File

@@ -0,0 +1,54 @@
import { GroupMock } from '../../../shared/testing/group-mock';
import { GroupRegistryCancelGroupAction, GroupRegistryEditGroupAction } from './group-registry.actions';
import { groupRegistryReducer, GroupRegistryState } from './group-registry.reducers';
const initialState: GroupRegistryState = {
editGroup: null,
};
const editState: GroupRegistryState = {
editGroup: GroupMock,
};
class NullAction extends GroupRegistryEditGroupAction {
type = null;
constructor() {
super(undefined);
}
}
describe('groupRegistryReducer', () => {
it('should return the current state when no valid actions have been made', () => {
const state = initialState;
const action = new NullAction();
const newState = groupRegistryReducer(state, action);
expect(newState).toEqual(state);
});
it('should start with an initial state', () => {
const state = initialState;
const action = new NullAction();
const initState = groupRegistryReducer(undefined, action);
expect(initState).toEqual(state);
});
it('should update the current state to change the editGroup to a new group when GroupRegistryEditGroupAction is dispatched', () => {
const state = editState;
const action = new GroupRegistryEditGroupAction(GroupMock);
const newState = groupRegistryReducer(state, action);
expect(newState.editGroup).toEqual(GroupMock);
});
it('should update the current state to remove the editGroup from the state when GroupRegistryCancelGroupAction is dispatched', () => {
const state = editState;
const action = new GroupRegistryCancelGroupAction();
const newState = groupRegistryReducer(state, action);
expect(newState.editGroup).toEqual(null);
});
});

View File

@@ -0,0 +1,43 @@
import { Group } from '../../../core/eperson/models/group.model';
import { GroupRegistryAction, GroupRegistryActionTypes, GroupRegistryEditGroupAction } from './group-registry.actions';
/**
* The metadata registry state.
* @interface GroupRegistryState
*/
export interface GroupRegistryState {
editGroup: Group;
}
/**
* The initial state.
*/
const initialState: GroupRegistryState = {
editGroup: null,
};
/**
* Reducer that handles GroupRegistryActions to modify Groups
* @param state The current GroupRegistryState
* @param action The GroupRegistryAction to perform on the state
*/
export function groupRegistryReducer(state = initialState, action: GroupRegistryAction): GroupRegistryState {
switch (action.type) {
case GroupRegistryActionTypes.EDIT_GROUP: {
return Object.assign({}, state, {
editGroup: (action as GroupRegistryEditGroupAction).group
});
}
case GroupRegistryActionTypes.CANCEL_EDIT_GROUP: {
return Object.assign({}, state, {
editGroup: null
});
}
default:
return state;
}
}

View File

@@ -0,0 +1,84 @@
<div class="container">
<div class="groups-registry row">
<div class="col-12">
<h2 id="header" class="border-bottom pb-2">{{messagePrefix + 'head' | translate}}</h2>
<div class="button-row top d-flex pb-2">
<button class="mr-auto btn btn-success"
[routerLink]="['newGroup']">
<i class="fas fa-plus"></i>
<span class="d-none d-sm-inline">&nbsp;{{messagePrefix + 'button.add' | translate}}</span>
</button>
</div>
<h3 id="search" class="border-bottom pb-2">{{messagePrefix + 'search.head' | translate}}
<button (click)="clearFormAndResetResult();"
class="btn btn-primary float-right">{{messagePrefix + 'button.see-all' | translate}}</button>
</h3>
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
<div class="col-12">
<div class="form-group input-group">
<input type="text" name="query" id="query" formControlName="query"
class="form-control" aria-label="Search input">
<span class="input-group-append">
<button type="submit"
class="search-button btn btn-secondary">{{ messagePrefix + 'search.button' | translate }}</button>
</span>
</div>
</div>
</form>
<ds-pagination
*ngIf="(groups | async)?.payload?.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(groups | async)?.payload"
[collectionSize]="(groups | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
<div class="table-responsive">
<table id="groups" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col">{{messagePrefix + 'table.id' | translate}}</th>
<th scope="col">{{messagePrefix + 'table.name' | translate}}</th>
<th scope="col">{{messagePrefix + 'table.members' | translate}}</th>
<!-- <th scope="col">{{messagePrefix + 'table.comcol' | translate}}</th>-->
<th>{{messagePrefix + 'table.edit' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let group of (groups | async)?.payload?.page">
<td>{{group.id}}</td>
<td>{{group.name}}</td>
<td>{{(getMembers(group) | async)?.payload?.totalElements + (getSubgroups(group) | async)?.payload?.totalElements}}</td>
<!-- <td>{{getOptionalComColFromName(group.name)}}</td>-->
<td>
<div class="btn-group edit-field">
<button [routerLink]="groupService.getGroupEditPageRouterLink(group)"
class="btn btn-outline-primary btn-sm"
title="{{messagePrefix + 'table.edit.buttons.edit' | translate: {name: group.name} }}">
<i class="fas fa-edit fa-fw"></i>
</button>
<button *ngIf="!group?.permanent" (click)="deleteGroup(group)"
class="btn btn-outline-danger btn-sm"
title="{{messagePrefix + 'table.edit.buttons.remove' | translate: {name: group.name} }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(groups | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2" role="alert">
{{messagePrefix + 'no-items' | translate}}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,139 @@
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { PaginatedList } from '../../../core/data/paginated-list';
import { RemoteData } from '../../../core/data/remote-data';
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../core/eperson/group-data.service';
import { EPerson } from '../../../core/eperson/models/eperson.model';
import { Group } from '../../../core/eperson/models/group.model';
import { RouteService } from '../../../core/services/route.service';
import { PageInfo } from '../../../core/shared/page-info.model';
import { MockRouter } from '../../../shared/mocks/mock-router';
import { MockTranslateLoader } from '../../../shared/mocks/mock-translate-loader';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { EPersonMock, EPersonMock2 } from '../../../shared/testing/eperson-mock';
import { GroupMock, GroupMock2 } from '../../../shared/testing/group-mock';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
import { routeServiceStub } from '../../../shared/testing/route-service-stub';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
import { GroupsRegistryComponent } from './groups-registry.component';
describe('GroupRegistryComponent', () => {
let component: GroupsRegistryComponent;
let fixture: ComponentFixture<GroupsRegistryComponent>;
let ePersonDataServiceStub: any;
let groupsDataServiceStub: any;
let mockGroups;
let mockEPeople;
beforeEach(async(() => {
mockGroups = [GroupMock, GroupMock2];
mockEPeople = [EPersonMock, EPersonMock2];
ePersonDataServiceStub = {
findAllByHref(href: string): Observable<RemoteData<PaginatedList<EPerson>>> {
switch (href) {
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid2/epersons':
return createSuccessfulRemoteDataObject$(new PaginatedList(null, []));
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid/epersons':
return createSuccessfulRemoteDataObject$(new PaginatedList(null, [EPersonMock]));
default:
return createSuccessfulRemoteDataObject$(new PaginatedList(null, []));
}
}
};
groupsDataServiceStub = {
allGroups: mockGroups,
findAllByHref(href: string): Observable<RemoteData<PaginatedList<Group>>> {
switch (href) {
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid2/groups':
return createSuccessfulRemoteDataObject$(new PaginatedList(null, []));
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid/groups':
return createSuccessfulRemoteDataObject$(new PaginatedList(null, [GroupMock2]));
default:
return createSuccessfulRemoteDataObject$(new PaginatedList(null, []));
}
},
getGroupEditPageRouterLink(group: Group): string {
return '/admin/access-control/groups/' + group.id;
},
getGroupRegistryRouterLink(): string {
return '/admin/access-control/groups';
},
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
if (query === '') {
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allGroups));
}
const result = this.allGroups.find((group: Group) => {
return (group.id.includes(query))
});
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
}
};
TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
],
declarations: [GroupsRegistryComponent],
providers: [GroupsRegistryComponent,
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
{ provide: GroupDataService, useValue: groupsDataServiceStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: RouteService, useValue: routeServiceStub },
{ provide: Router, useValue: new MockRouter() },
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GroupsRegistryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create GroupRegistryComponent', inject([GroupsRegistryComponent], (comp: GroupsRegistryComponent) => {
expect(comp).toBeDefined();
}));
it('should display list of groups', () => {
const groupIdsFound = fixture.debugElement.queryAll(By.css('#groups tr td:first-child'));
expect(groupIdsFound.length).toEqual(2);
mockGroups.map((group: Group) => {
expect(groupIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === group.uuid);
})).toBeTruthy();
})
});
describe('search', () => {
describe('when searching with query', () => {
let groupIdsFound;
beforeEach(fakeAsync(() => {
component.search({ query: GroupMock2.id });
tick();
fixture.detectChanges();
groupIdsFound = fixture.debugElement.queryAll(By.css('#groups tr td:first-child'));
}));
it('should display search result', () => {
expect(groupIdsFound.length).toEqual(1);
expect(groupIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === GroupMock2.uuid);
})).toBeTruthy();
});
});
});
});

View File

@@ -0,0 +1,154 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import { PaginatedList } from '../../../core/data/paginated-list';
import { RemoteData } from '../../../core/data/remote-data';
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
import { GroupDataService } from '../../../core/eperson/group-data.service';
import { EPerson } from '../../../core/eperson/models/eperson.model';
import { Group } from '../../../core/eperson/models/group.model';
import { RouteService } from '../../../core/services/route.service';
import { hasValue } from '../../../shared/empty.util';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
@Component({
selector: 'ds-groups-registry',
templateUrl: './groups-registry.component.html',
})
/**
* A component used for managing all existing groups within the repository.
* The admin can create, edit or delete groups here.
*/
export class GroupsRegistryComponent implements OnInit {
messagePrefix = 'admin.access-control.groups.';
/**
* Pagination config used to display the list of groups
*/
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'groups-list-pagination',
pageSize: 5,
currentPage: 1
});
/**
* A list of all the current groups within the repository or the result of the search
*/
groups: Observable<RemoteData<PaginatedList<Group>>>;
// The search form
searchForm;
// Current search in groups registry
currentSearchQuery: string;
constructor(private groupService: GroupDataService,
private ePersonDataService: EPersonDataService,
private translateService: TranslateService,
private notificationsService: NotificationsService,
private formBuilder: FormBuilder,
protected routeService: RouteService,
private router: Router) {
this.currentSearchQuery = '';
this.searchForm = this.formBuilder.group(({
query: this.currentSearchQuery,
}));
}
ngOnInit() {
this.search({ query: this.currentSearchQuery });
}
/**
* Event triggered when the user changes page
* @param event
*/
onPageChange(event) {
this.config.currentPage = event;
this.search({ query: this.currentSearchQuery })
}
/**
* Search in the groups (searches by group name and by uuid exact match)
* @param data Contains query param
*/
search(data: any) {
const query: string = data.query;
if (query != null && this.currentSearchQuery !== query) {
this.router.navigateByUrl(this.groupService.getGroupRegistryRouterLink());
this.currentSearchQuery = query;
this.config.currentPage = 1;
}
this.groups = this.groupService.searchGroups(this.currentSearchQuery.trim(), {
currentPage: this.config.currentPage,
elementsPerPage: this.config.pageSize
});
}
/**
* Delete Group
*/
deleteGroup(group: Group) {
// TODO (backend)
console.log('TODO implement editGroup', group);
this.notificationsService.error('TODO implement deleteGroup (not yet implemented in backend)');
if (hasValue(group.id)) {
this.groupService.deleteGroup(group).pipe(take(1)).subscribe((success: boolean) => {
if (success) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + 'notification.deleted.success', { name: group.name }));
this.forceUpdateGroup();
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + 'notification.deleted.failure', { name: group.name }));
}
})
}
}
/**
* Force-update the list of groups by first clearing the cache related to groups, then performing a new REST call
*/
public forceUpdateGroup() {
this.groupService.clearGroupsRequests();
this.search({ query: this.currentSearchQuery })
}
/**
* Get the members (epersons embedded value of a group)
* @param group
*/
getMembers(group: Group): Observable<RemoteData<PaginatedList<EPerson>>> {
return this.ePersonDataService.findAllByHref(group._links.epersons.href);
}
/**
* Get the subgroups (groups embedded value of a group)
* @param group
*/
getSubgroups(group: Group): Observable<RemoteData<PaginatedList<Group>>> {
return this.groupService.findAllByHref(group._links.subgroups.href);
}
/**
* Reset all input-fields to be empty and search all search
*/
clearFormAndResetResult() {
this.searchForm.patchValue({
query: '',
});
this.search({ query: '' });
}
/**
* Extract optional UUID from a group name => To be resolved to community or collection with link
* (Or will be resolved in backend and added to group object, tbd) //TODO
* @param groupName
*/
getOptionalComColFromName(groupName: string): string {
return this.groupService.getUUIDFromString(groupName);
}
}

View File

@@ -2,14 +2,29 @@ import { MetadataRegistryComponent } from './metadata-registry/metadata-registry
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { MetadataSchemaComponent } from './metadata-schema/metadata-schema.component';
import { BitstreamFormatsComponent } from './bitstream-formats/bitstream-formats.component';
import { URLCombiner } from '../../core/url-combiner/url-combiner';
import { getRegistriesModulePath } from '../admin-routing.module';
const BITSTREAMFORMATS_MODULE_PATH = 'bitstream-formats';
export function getBitstreamFormatsModulePath() {
return new URLCombiner(getRegistriesModulePath(), BITSTREAMFORMATS_MODULE_PATH).toString();
}
@NgModule({
imports: [
RouterModule.forChild([
{ path: 'metadata', component: MetadataRegistryComponent, data: { title: 'admin.registries.metadata.title' } },
{ path: 'metadata/:schemaName', component: MetadataSchemaComponent, data: { title: 'admin.registries.schema.title' } },
{ path: 'bitstream-formats', component: BitstreamFormatsComponent, data: { title: 'admin.registries.bitstream-formats.title' } },
{path: 'metadata', component: MetadataRegistryComponent, data: {title: 'admin.registries.metadata.title'}},
{
path: 'metadata/:schemaName',
component: MetadataSchemaComponent,
data: {title: 'admin.registries.schema.title'}
},
{
path: BITSTREAMFORMATS_MODULE_PATH,
loadChildren: './bitstream-formats/bitstream-formats.module#BitstreamFormatsModule',
data: {title: 'admin.registries.bitstream-formats.title'}
},
])
]
})

View File

@@ -5,10 +5,10 @@ import { CommonModule } from '@angular/common';
import { MetadataSchemaComponent } from './metadata-schema/metadata-schema.component';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { BitstreamFormatsComponent } from './bitstream-formats/bitstream-formats.component';
import { SharedModule } from '../../shared/shared.module';
import { MetadataSchemaFormComponent } from './metadata-registry/metadata-schema-form/metadata-schema-form.component';
import {MetadataFieldFormComponent} from './metadata-schema/metadata-field-form/metadata-field-form.component';
import { MetadataFieldFormComponent } from './metadata-schema/metadata-field-form/metadata-field-form.component';
import { BitstreamFormatsModule } from './bitstream-formats/bitstream-formats.module';
@NgModule({
imports: [
@@ -16,12 +16,12 @@ import {MetadataFieldFormComponent} from './metadata-schema/metadata-field-form/
SharedModule,
RouterModule,
TranslateModule,
BitstreamFormatsModule,
AdminRegistriesRoutingModule
],
declarations: [
MetadataRegistryComponent,
MetadataSchemaComponent,
BitstreamFormatsComponent,
MetadataSchemaFormComponent,
MetadataFieldFormComponent
],

View File

@@ -0,0 +1,11 @@
<div class="container">
<div class="row">
<div class="col-12 mb-4">
<h2 id="sub-header"
class="border-bottom mb-2">{{ 'admin.registries.bitstream-formats.create.new' | translate }}</h2>
<ds-bitstream-format-form (updatedFormat)="createBitstreamFormat($event)"></ds-bitstream-format-form>
</div>
</div>
</div>

View File

@@ -0,0 +1,105 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { RestResponse } from '../../../../core/cache/response.models';
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
import { BitstreamFormatSupportLevel } from '../../../../core/shared/bitstream-format-support-level';
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service-stub';
import { RouterStub } from '../../../../shared/testing/router-stub';
import { AddBitstreamFormatComponent } from './add-bitstream-format.component';
describe('AddBitstreamFormatComponent', () => {
let comp: AddBitstreamFormatComponent;
let fixture: ComponentFixture<AddBitstreamFormatComponent>;
const bitstreamFormat = new BitstreamFormat();
bitstreamFormat.uuid = 'test-uuid-1';
bitstreamFormat.id = 'test-uuid-1';
bitstreamFormat.shortDescription = 'Unknown';
bitstreamFormat.description = 'Unknown data format';
bitstreamFormat.mimetype = 'application/octet-stream';
bitstreamFormat.supportLevel = BitstreamFormatSupportLevel.Unknown;
bitstreamFormat.internal = false;
bitstreamFormat.extensions = null;
let router;
let notificationService: NotificationsServiceStub;
let bitstreamFormatDataService: BitstreamFormatDataService;
const initAsync = () => {
router = new RouterStub();
notificationService = new NotificationsServiceStub();
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
createBitstreamFormat: observableOf(new RestResponse(true, 200, 'Success')),
clearBitStreamFormatRequests: observableOf(null)
});
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [AddBitstreamFormatComponent],
providers: [
{provide: Router, useValue: router},
{provide: NotificationsService, useValue: notificationService},
{provide: BitstreamFormatDataService, useValue: bitstreamFormatDataService},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
};
const initBeforeEach = () => {
fixture = TestBed.createComponent(AddBitstreamFormatComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
};
describe('createBitstreamFormat success', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should send the updated form to the service, show a notification and navigate to ', () => {
comp.createBitstreamFormat(bitstreamFormat);
expect(bitstreamFormatDataService.createBitstreamFormat).toHaveBeenCalledWith(bitstreamFormat);
expect(notificationService.success).toHaveBeenCalled();
expect(router.navigate).toHaveBeenCalledWith(['/admin/registries/bitstream-formats']);
});
});
describe('createBitstreamFormat error', () => {
beforeEach(async(() => {
router = new RouterStub();
notificationService = new NotificationsServiceStub();
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
createBitstreamFormat: observableOf(new RestResponse(false, 400, 'Bad Request')),
clearBitStreamFormatRequests: observableOf(null)
});
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [AddBitstreamFormatComponent],
providers: [
{provide: Router, useValue: router},
{provide: NotificationsService, useValue: notificationService},
{provide: BitstreamFormatDataService, useValue: bitstreamFormatDataService},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
}));
beforeEach(initBeforeEach);
it('should send the updated form to the service, show a notification and navigate to ', () => {
comp.createBitstreamFormat(bitstreamFormat);
expect(bitstreamFormatDataService.createBitstreamFormat).toHaveBeenCalledWith(bitstreamFormat);
expect(notificationService.error).toHaveBeenCalled();
expect(router.navigate).not.toHaveBeenCalled();
});
});
});

View File

@@ -0,0 +1,49 @@
import { take } from 'rxjs/operators';
import { Router } from '@angular/router';
import { Component } from '@angular/core';
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
import { RestResponse } from '../../../../core/cache/response.models';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { getBitstreamFormatsModulePath } from '../../admin-registries-routing.module';
import { TranslateService } from '@ngx-translate/core';
/**
* This component renders the page to create a new bitstream format.
*/
@Component({
selector: 'ds-add-bitstream-format',
templateUrl: './add-bitstream-format.component.html',
})
export class AddBitstreamFormatComponent {
constructor(
private router: Router,
private notificationService: NotificationsService,
private translateService: TranslateService,
private bitstreamFormatDataService: BitstreamFormatDataService,
) {
}
/**
* Creates a new bitstream format based on the provided bitstream format emitted by the form.
* When successful, a success notification will be shown and the user will be navigated back to the overview page.
* When failed, an error notification will be shown.
* @param bitstreamFormat
*/
createBitstreamFormat(bitstreamFormat: BitstreamFormat) {
this.bitstreamFormatDataService.createBitstreamFormat(bitstreamFormat).pipe(take(1)
).subscribe((response: RestResponse) => {
if (response.isSuccessful) {
this.notificationService.success(this.translateService.get('admin.registries.bitstream-formats.create.success.head'),
this.translateService.get('admin.registries.bitstream-formats.create.success.content'));
this.router.navigate([getBitstreamFormatsModulePath()]);
this.bitstreamFormatDataService.clearBitStreamFormatRequests().subscribe();
} else {
this.notificationService.error(this.translateService.get('admin.registries.bitstream-formats.create.failure.head'),
this.translateService.get('admin.registries.bitstream-formats.create.failure.content'));
}
}
);
}
}

View File

@@ -0,0 +1,64 @@
import { Action } from '@ngrx/store';
import { type } from '../../../shared/ngrx/type';
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
/**
* For each action type in an action group, make a simple
* enum object for all of this group's action types.
*
* The 'type' utility function coerces strings into string
* literal types and runs a simple check to guarantee all
* action types in the application are unique.
*/
export const BitstreamFormatsRegistryActionTypes = {
SELECT_FORMAT: type('dspace/bitstream-formats-registry/SELECT_FORMAT'),
DESELECT_FORMAT: type('dspace/bitstream-formats-registry/DESELECT_FORMAT'),
DESELECT_ALL_FORMAT: type('dspace/bitstream-formats-registry/DESELECT_ALL_FORMAT')
};
/* tslint:disable:max-classes-per-file */
/**
* Used to select a single bitstream format in the bitstream format registry
*/
export class BitstreamFormatsRegistrySelectAction implements Action {
type = BitstreamFormatsRegistryActionTypes.SELECT_FORMAT;
bitstreamFormat: BitstreamFormat;
constructor(bitstreamFormat: BitstreamFormat) {
this.bitstreamFormat = bitstreamFormat;
}
}
/**
* Used to deselect a single bitstream format in the bitstream format registry
*/
export class BitstreamFormatsRegistryDeselectAction implements Action {
type = BitstreamFormatsRegistryActionTypes.DESELECT_FORMAT;
bitstreamFormat: BitstreamFormat;
constructor(bitstreamFormat: BitstreamFormat) {
this.bitstreamFormat = bitstreamFormat;
}
}
/**
* Used to deselect all bitstream formats in the bitstream format registry
*/
export class BitstreamFormatsRegistryDeselectAllAction implements Action {
type = BitstreamFormatsRegistryActionTypes.DESELECT_ALL_FORMAT;
}
/* tslint:enable:max-classes-per-file */
/**
* Export a type alias of all actions in this action group
* so that reducers can easily compose action types
* These are all the actions to perform on the bitstream format registry state
*/
export type BitstreamFormatsRegistryAction
= BitstreamFormatsRegistrySelectAction
| BitstreamFormatsRegistryDeselectAction
| BitstreamFormatsRegistryDeselectAllAction

View File

@@ -0,0 +1,83 @@
import { Action } from '@ngrx/store';
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
import { bitstreamFormatReducer, BitstreamFormatRegistryState } from './bitstream-format.reducers';
import {
BitstreamFormatsRegistryDeselectAction,
BitstreamFormatsRegistryDeselectAllAction,
BitstreamFormatsRegistrySelectAction
} from './bitstream-format.actions';
const bitstreamFormat1: BitstreamFormat = new BitstreamFormat();
bitstreamFormat1.id = 'test-uuid-1';
bitstreamFormat1.shortDescription = 'test-short-1';
const bitstreamFormat2: BitstreamFormat = new BitstreamFormat();
bitstreamFormat2.id = 'test-uuid-2';
bitstreamFormat2.shortDescription = 'test-short-2';
const initialState: BitstreamFormatRegistryState = {
selectedBitstreamFormats: []
};
const bitstream1SelectedState: BitstreamFormatRegistryState = {
selectedBitstreamFormats: [bitstreamFormat1]
};
const bitstream1and2SelectedState: BitstreamFormatRegistryState = {
selectedBitstreamFormats: [bitstreamFormat1, bitstreamFormat2]
};
describe('BitstreamFormatReducer', () => {
describe('BitstreamFormatsRegistryActionTypes.SELECT_FORMAT', () => {
it('should add the format to the list of selected formats when initial list is empty', () => {
const state = initialState;
const action = new BitstreamFormatsRegistrySelectAction(bitstreamFormat1);
const newState = bitstreamFormatReducer(state, action);
expect(newState).toEqual(bitstream1SelectedState);
});
it('should add the format to the list of selected formats when formats are already present', () => {
const state = bitstream1SelectedState;
const action = new BitstreamFormatsRegistrySelectAction(bitstreamFormat2);
const newState = bitstreamFormatReducer(state, action);
expect(newState).toEqual(bitstream1and2SelectedState);
});
});
describe('BitstreamFormatsRegistryActionTypes.DESELECT_FORMAT', () => {
it('should deselect a format', () => {
const state = bitstream1and2SelectedState;
const action = new BitstreamFormatsRegistryDeselectAction(bitstreamFormat2);
const newState = bitstreamFormatReducer(state, action);
expect(newState).toEqual(bitstream1SelectedState);
});
});
describe('BitstreamFormatsRegistryActionTypes.DESELECT_ALL_FORMAT', () => {
it('should deselect all formats', () => {
const state = bitstream1and2SelectedState;
const action = new BitstreamFormatsRegistryDeselectAllAction();
const newState = bitstreamFormatReducer(state, action);
expect(newState).toEqual(initialState);
});
});
describe('Invalid action', () => {
it('should return the current state', () => {
const state = initialState;
const action = new NullAction();
const newState = bitstreamFormatReducer(state, action);
expect(newState).toEqual(state);
});
});
});
class NullAction implements Action {
type = null;
constructor() {
// empty constructor
}
}

View File

@@ -0,0 +1,55 @@
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
import {
BitstreamFormatsRegistryAction,
BitstreamFormatsRegistryActionTypes,
BitstreamFormatsRegistryDeselectAction,
BitstreamFormatsRegistrySelectAction
} from './bitstream-format.actions';
/**
* The bitstream format registry state.
* @interface BitstreamFormatRegistryState
*/
export interface BitstreamFormatRegistryState {
selectedBitstreamFormats: BitstreamFormat[];
}
/**
* The initial state.
*/
const initialState: BitstreamFormatRegistryState = {
selectedBitstreamFormats: [],
};
/**
* Reducer that handles BitstreamFormatsRegistryActions to modify the bitstream format registry state
* @param state The current BitstreamFormatRegistryState
* @param action The BitstreamFormatsRegistryAction to perform on the state
*/
export function bitstreamFormatReducer(state = initialState, action: BitstreamFormatsRegistryAction): BitstreamFormatRegistryState {
switch (action.type) {
case BitstreamFormatsRegistryActionTypes.SELECT_FORMAT: {
return Object.assign({}, state, {
selectedBitstreamFormats: [...state.selectedBitstreamFormats, (action as BitstreamFormatsRegistrySelectAction).bitstreamFormat]
});
}
case BitstreamFormatsRegistryActionTypes.DESELECT_FORMAT: {
return Object.assign({}, state, {
selectedBitstreamFormats: state.selectedBitstreamFormats.filter(
(selectedBitstreamFormats) => selectedBitstreamFormats !== (action as BitstreamFormatsRegistryDeselectAction).bitstreamFormat
)
});
}
case BitstreamFormatsRegistryActionTypes.DESELECT_ALL_FORMAT: {
return Object.assign({}, state, {
selectedBitstreamFormats: []
});
}
default:
return state;
}
}

View File

@@ -0,0 +1,37 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { BitstreamFormatsResolver } from './bitstream-formats.resolver';
import { EditBitstreamFormatComponent } from './edit-bitstream-format/edit-bitstream-format.component';
import { BitstreamFormatsComponent } from './bitstream-formats.component';
import { AddBitstreamFormatComponent } from './add-bitstream-format/add-bitstream-format.component';
const BITSTREAMFORMAT_EDIT_PATH = ':id/edit';
const BITSTREAMFORMAT_ADD_PATH = 'add';
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: BitstreamFormatsComponent
},
{
path: BITSTREAMFORMAT_ADD_PATH,
component: AddBitstreamFormatComponent,
},
{
path: BITSTREAMFORMAT_EDIT_PATH,
component: EditBitstreamFormatComponent,
resolve: {
bitstreamFormat: BitstreamFormatsResolver
}
},
])
],
providers: [
BitstreamFormatsResolver,
]
})
export class BitstreamFormatsRoutingModule {
}

View File

@@ -2,13 +2,15 @@
<div class="bitstream-formats row">
<div class="col-12">
<h2 id="header" class="border-bottom pb-2">{{'admin.registries.bitstream-formats.head' | translate}}</h2>
<h2 id="header" class="border-bottom pb-2 ">{{'admin.registries.bitstream-formats.head' | translate}}</h2>
<p id="description">{{'admin.registries.bitstream-formats.description' | translate}}</p>
<p id="create-new" class="mb-2"><a [routerLink]="'add'" class="btn btn-success">{{'admin.registries.bitstream-formats.create.new' | translate}}</a></p>
<p id="description" class="pb-2">{{'admin.registries.bitstream-formats.description' | translate}}</p>
<ds-pagination
*ngIf="(bitstreamFormats | async)?.payload?.totalElements > 0"
[paginationOptions]="config"
[paginationOptions]="pageConfig"
[pageInfoState]="(bitstreamFormats | async)?.payload"
[collectionSize]="(bitstreamFormats | async)?.payload?.totalElements"
[hideGear]="true"
@@ -18,25 +20,38 @@
<table id="formats" class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">{{'admin.registries.bitstream-formats.formats.table.name' | translate}}</th>
<th scope="col">{{'admin.registries.bitstream-formats.formats.table.mimetype' | translate}}</th>
<th scope="col">{{'admin.registries.bitstream-formats.formats.table.supportLevel.head' | translate}}</th>
<th scope="col"></th>
<th scope="col">{{'admin.registries.bitstream-formats.table.name' | translate}}</th>
<th scope="col">{{'admin.registries.bitstream-formats.table.mimetype' | translate}}</th>
<th scope="col">{{'admin.registries.bitstream-formats.table.supportLevel.head' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let bitstreamFormat of (bitstreamFormats | async)?.payload?.page">
<td>{{bitstreamFormat.shortDescription}}</td>
<td>{{bitstreamFormat.mimetype}} <span *ngIf="bitstreamFormat.internal">({{'admin.registries.bitstream-formats.formats.table.internal' | translate}})</span></td>
<td>{{'admin.registries.bitstream-formats.formats.table.supportLevel.'+bitstreamFormat.supportLevel | translate}}</td>
<td>
<label>
<input type="checkbox"
[checked]="isSelected(bitstreamFormat) | async"
(change)="selectBitStreamFormat(bitstreamFormat, $event)"
>
</label>
</td>
<td><a [routerLink]="['/admin/registries/bitstream-formats', bitstreamFormat.id, 'edit']">{{bitstreamFormat.shortDescription}}</a></td>
<td><a [routerLink]="['/admin/registries/bitstream-formats', bitstreamFormat.id, 'edit']">{{bitstreamFormat.mimetype}} <span *ngIf="bitstreamFormat.internal">({{'admin.registries.bitstream-formats.table.internal' | translate}})</span></a></td>
<td><a [routerLink]="['/admin/registries/bitstream-formats', bitstreamFormat.id, 'edit']">{{'admin.registries.bitstream-formats.table.supportLevel.'+bitstreamFormat.supportLevel | translate}}</a></td>
</tr>
</tbody>
</table>
</div>
</ds-pagination>
<div *ngIf="(bitstreamFormats | async)?.payload?.totalElements == 0" class="alert alert-info" role="alert">
{{'admin.registries.bitstream-formats.formats.no-items' | translate}}
{{'admin.registries.bitstream-formats.no-items' | translate}}
</div>
<div>
<button *ngIf="(bitstreamFormats | async)?.payload?.page?.length > 0" class="btn btn-primary deselect" (click)="deselectAll()">{{'admin.registries.bitstream-formats.table.deselect-all' | translate}}</button>
<button *ngIf="(bitstreamFormats | async)?.payload?.page?.length > 0" type="submit" class="btn btn-danger float-right" (click)="deleteFormats()">{{'admin.registries.bitstream-formats.table.delete' | translate}}</button>
</div>
</div>
</div>
</div>

View File

@@ -1,6 +1,5 @@
import { BitstreamFormatsComponent } from './bitstream-formats.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RegistryService } from '../../../core/registry/registry.service';
import { of as observableOf } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list';
@@ -13,85 +12,278 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { EnumKeysPipe } from '../../../shared/utils/enum-keys-pipe';
import { HostWindowService } from '../../../shared/host-window.service';
import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub';
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
import { BitstreamFormatSupportLevel } from '../../../core/shared/bitstream-format-support-level';
import { cold, getTestScheduler, hot } from 'jasmine-marbles';
import { TestScheduler } from 'rxjs/testing';
describe('BitstreamFormatsComponent', () => {
let comp: BitstreamFormatsComponent;
let fixture: ComponentFixture<BitstreamFormatsComponent>;
let registryService: RegistryService;
const mockFormatsList = [
{
shortDescription: 'Unknown',
description: 'Unknown data format',
mimetype: 'application/octet-stream',
supportLevel: 0,
internal: false,
extensions: null
},
{
shortDescription: 'License',
description: 'Item-specific license agreed upon to submission',
mimetype: 'text/plain; charset=utf-8',
supportLevel: 1,
internal: true,
extensions: null
},
{
shortDescription: 'CC License',
description: 'Item-specific Creative Commons license agreed upon to submission',
mimetype: 'text/html; charset=utf-8',
supportLevel: 2,
internal: true,
extensions: null
},
{
shortDescription: 'Adobe PDF',
description: 'Adobe Portable Document Format',
mimetype: 'application/pdf',
supportLevel: 0,
internal: false,
extensions: null
}
];
const mockFormats = observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFormatsList)));
const registryServiceStub = {
getBitstreamFormats: () => mockFormats
};
let bitstreamFormatService;
let scheduler: TestScheduler;
let notificationsServiceStub;
const bitstreamFormat1 = new BitstreamFormat();
bitstreamFormat1.uuid = 'test-uuid-1';
bitstreamFormat1.id = 'test-uuid-1';
bitstreamFormat1.shortDescription = 'Unknown';
bitstreamFormat1.description = 'Unknown data format';
bitstreamFormat1.mimetype = 'application/octet-stream';
bitstreamFormat1.supportLevel = BitstreamFormatSupportLevel.Unknown;
bitstreamFormat1.internal = false;
bitstreamFormat1.extensions = null;
const bitstreamFormat2 = new BitstreamFormat();
bitstreamFormat2.uuid = 'test-uuid-2';
bitstreamFormat2.id = 'test-uuid-2';
bitstreamFormat2.shortDescription = 'License';
bitstreamFormat2.description = 'Item-specific license agreed upon to submission';
bitstreamFormat2.mimetype = 'text/plain; charset=utf-8';
bitstreamFormat2.supportLevel = BitstreamFormatSupportLevel.Known;
bitstreamFormat2.internal = true;
bitstreamFormat2.extensions = null;
const bitstreamFormat3 = new BitstreamFormat();
bitstreamFormat3.uuid = 'test-uuid-3';
bitstreamFormat3.id = 'test-uuid-3';
bitstreamFormat3.shortDescription = 'CC License';
bitstreamFormat3.description = 'Item-specific Creative Commons license agreed upon to submission';
bitstreamFormat3.mimetype = 'text/html; charset=utf-8';
bitstreamFormat3.supportLevel = BitstreamFormatSupportLevel.Supported;
bitstreamFormat3.internal = true;
bitstreamFormat3.extensions = null;
const bitstreamFormat4 = new BitstreamFormat();
bitstreamFormat4.uuid = 'test-uuid-4';
bitstreamFormat4.id = 'test-uuid-4';
bitstreamFormat4.shortDescription = 'Adobe PDF';
bitstreamFormat4.description = 'Adobe Portable Document Format';
bitstreamFormat4.mimetype = 'application/pdf';
bitstreamFormat4.supportLevel = BitstreamFormatSupportLevel.Unknown;
bitstreamFormat4.internal = false;
bitstreamFormat4.extensions = null;
const mockFormatsList: BitstreamFormat[] = [
bitstreamFormat1,
bitstreamFormat2,
bitstreamFormat3,
bitstreamFormat4
];
const mockFormatsRD = new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFormatsList));
const initAsync = () => {
notificationsServiceStub = new NotificationsServiceStub();
scheduler = getTestScheduler();
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
findAll: observableOf(mockFormatsRD),
find: observableOf(new RemoteData(false, false, true, undefined, mockFormatsList[0])),
getSelectedBitstreamFormats: hot('a', {a: mockFormatsList}),
selectBitstreamFormat: {},
deselectBitstreamFormat: {},
deselectAllBitstreamFormats: {},
delete: observableOf(true),
clearBitStreamFormatRequests: observableOf('cleared')
});
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule.forRoot()],
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [BitstreamFormatsComponent, PaginationComponent, EnumKeysPipe],
providers: [
{ provide: RegistryService, useValue: registryServiceStub },
{ provide: HostWindowService, useValue: new HostWindowServiceStub(0) }
{provide: BitstreamFormatDataService, useValue: bitstreamFormatService},
{provide: HostWindowService, useValue: new HostWindowServiceStub(0)},
{provide: NotificationsService, useValue: notificationsServiceStub}
]
}).compileComponents();
}));
};
beforeEach(() => {
const initBeforeEach = () => {
fixture = TestBed.createComponent(BitstreamFormatsComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
registryService = (comp as any).service;
};
describe('Bitstream format page content', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should contain four formats', () => {
const tbody: HTMLElement = fixture.debugElement.query(By.css('#formats>tbody')).nativeElement;
expect(tbody.children.length).toBe(4);
});
it('should contain the correct formats', () => {
const unknownName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(1) td:nth-child(2)')).nativeElement;
expect(unknownName.textContent).toBe('Unknown');
const licenseName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(2) td:nth-child(2)')).nativeElement;
expect(licenseName.textContent).toBe('License');
const ccLicenseName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(3) td:nth-child(2)')).nativeElement;
expect(ccLicenseName.textContent).toBe('CC License');
const adobeName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(4) td:nth-child(2)')).nativeElement;
expect(adobeName.textContent).toBe('Adobe PDF');
});
});
it('should contain four formats', () => {
const tbody: HTMLElement = fixture.debugElement.query(By.css('#formats>tbody')).nativeElement;
expect(tbody.children.length).toBe(4);
describe('selectBitStreamFormat', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should select a bitstreamFormat if it was selected in the event', () => {
const event = {target: {checked: true}};
comp.selectBitStreamFormat(bitstreamFormat1, event);
expect(bitstreamFormatService.selectBitstreamFormat).toHaveBeenCalledWith(bitstreamFormat1);
});
it('should deselect a bitstreamFormat if it is deselected in the event', () => {
const event = {target: {checked: false}};
comp.selectBitStreamFormat(bitstreamFormat1, event);
expect(bitstreamFormatService.deselectBitstreamFormat).toHaveBeenCalledWith(bitstreamFormat1);
});
it('should be called when a user clicks a checkbox', () => {
spyOn(comp, 'selectBitStreamFormat');
const unknownFormat = fixture.debugElement.query(By.css('#formats tr:nth-child(1) input'));
const event = {target: {checked: true}};
unknownFormat.triggerEventHandler('change', event);
expect(comp.selectBitStreamFormat).toHaveBeenCalledWith(bitstreamFormat1, event);
});
});
it('should contain the correct formats', () => {
const unknownName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(1) td:nth-child(1)')).nativeElement;
expect(unknownName.textContent).toBe('Unknown');
describe('isSelected', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should return an observable of true if the provided bistream is in the list returned by the service', () => {
const result = comp.isSelected(bitstreamFormat1);
const licenseName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(2) td:nth-child(1)')).nativeElement;
expect(licenseName.textContent).toBe('License');
expect(result).toBeObservable(cold('b', {b: true}));
});
it('should return an observable of false if the provided bistream is not in the list returned by the service', () => {
const format = new BitstreamFormat();
format.uuid = 'new';
const ccLicenseName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(3) td:nth-child(1)')).nativeElement;
expect(ccLicenseName.textContent).toBe('CC License');
const result = comp.isSelected(format);
const adobeName: HTMLElement = fixture.debugElement.query(By.css('#formats tr:nth-child(4) td:nth-child(1)')).nativeElement;
expect(adobeName.textContent).toBe('Adobe PDF');
expect(result).toBeObservable(cold('b', {b: false}));
});
});
describe('deselectAll', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should deselect all bitstreamFormats', () => {
comp.deselectAll();
expect(bitstreamFormatService.deselectAllBitstreamFormats).toHaveBeenCalled();
});
it('should be called when the deselect all button is clicked', () => {
spyOn(comp, 'deselectAll');
const deselectAllButton = fixture.debugElement.query(By.css('button.deselect'));
deselectAllButton.triggerEventHandler('click', null);
expect(comp.deselectAll).toHaveBeenCalled();
});
});
describe('deleteFormats success', () => {
beforeEach(async(() => {
notificationsServiceStub = new NotificationsServiceStub();
scheduler = getTestScheduler();
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
findAll: observableOf(mockFormatsRD),
find: observableOf(new RemoteData(false, false, true, undefined, mockFormatsList[0])),
getSelectedBitstreamFormats: observableOf(mockFormatsList),
selectBitstreamFormat: {},
deselectBitstreamFormat: {},
deselectAllBitstreamFormats: {},
delete: observableOf(true),
clearBitStreamFormatRequests: observableOf('cleared')
});
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [BitstreamFormatsComponent, PaginationComponent, EnumKeysPipe],
providers: [
{provide: BitstreamFormatDataService, useValue: bitstreamFormatService},
{provide: HostWindowService, useValue: new HostWindowServiceStub(0)},
{provide: NotificationsService, useValue: notificationsServiceStub}
]
}).compileComponents();
}
));
beforeEach(initBeforeEach);
it('should clear bitstream formats ', () => {
comp.deleteFormats();
expect(bitstreamFormatService.clearBitStreamFormatRequests).toHaveBeenCalled();
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat1.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat2.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat3.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat4.id);
expect(notificationsServiceStub.success).toHaveBeenCalledWith('admin.registries.bitstream-formats.delete.success.head',
'admin.registries.bitstream-formats.delete.success.amount');
expect(notificationsServiceStub.error).not.toHaveBeenCalled();
});
});
describe('deleteFormats error', () => {
beforeEach(async(() => {
notificationsServiceStub = new NotificationsServiceStub();
scheduler = getTestScheduler();
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
findAll: observableOf(mockFormatsRD),
find: observableOf(new RemoteData(false, false, true, undefined, mockFormatsList[0])),
getSelectedBitstreamFormats: observableOf(mockFormatsList),
selectBitstreamFormat: {},
deselectBitstreamFormat: {},
deselectAllBitstreamFormats: {},
delete: observableOf(false),
clearBitStreamFormatRequests: observableOf('cleared')
});
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [BitstreamFormatsComponent, PaginationComponent, EnumKeysPipe],
providers: [
{provide: BitstreamFormatDataService, useValue: bitstreamFormatService},
{provide: HostWindowService, useValue: new HostWindowServiceStub(0)},
{provide: NotificationsService, useValue: notificationsServiceStub}
]
}).compileComponents();
}
));
beforeEach(initBeforeEach);
it('should clear bitstream formats ', () => {
comp.deleteFormats();
expect(bitstreamFormatService.clearBitStreamFormatRequests).toHaveBeenCalled();
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat1.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat2.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat3.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat4.id);
expect(notificationsServiceStub.error).toHaveBeenCalledWith('admin.registries.bitstream-formats.delete.failure.head',
'admin.registries.bitstream-formats.delete.failure.amount');
expect(notificationsServiceStub.success).not.toHaveBeenCalled();
});
});
});

View File

@@ -1,10 +1,16 @@
import { Component } from '@angular/core';
import { RegistryService } from '../../../core/registry/registry.service';
import { Observable } from 'rxjs';
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, zip } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list';
import { BitstreamFormat } from '../../../core/registry/mock-bitstream-format.model';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
import { FindListOptions } from '../../../core/data/request.models';
import { map, switchMap, take } from 'rxjs/operators';
import { hasValue } from '../../../shared/empty.util';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
/**
* This component renders a list of bitstream formats
@@ -13,24 +19,125 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio
selector: 'ds-bitstream-formats',
templateUrl: './bitstream-formats.component.html'
})
export class BitstreamFormatsComponent {
export class BitstreamFormatsComponent implements OnInit {
/**
* A paginated list of bitstream formats to be shown on the page
*/
bitstreamFormats: Observable<RemoteData<PaginatedList<BitstreamFormat>>>;
/**
* A BehaviourSubject that keeps track of the pageState used to update the currently displayed bitstreamFormats
*/
pageState: BehaviorSubject<string>;
/**
* The current pagination configuration for the page used by the FindAll method
* Currently simply renders all bitstream formats
*/
config: FindListOptions = Object.assign(new FindListOptions(), {
elementsPerPage: 20
});
/**
* The current pagination configuration for the page
* Currently simply renders all bitstream formats
*/
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
pageConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'registry-bitstreamformats-pagination',
pageSize: 10000
pageSize: 20
});
constructor(private registryService: RegistryService) {
this.updateFormats();
constructor(private notificationsService: NotificationsService,
private router: Router,
private translateService: TranslateService,
private bitstreamFormatService: BitstreamFormatDataService) {
}
/**
* Deletes the currently selected formats from the registry and updates the presented list
*/
deleteFormats() {
this.bitstreamFormatService.clearBitStreamFormatRequests().subscribe();
this.bitstreamFormatService.getSelectedBitstreamFormats().pipe(take(1)).subscribe(
(formats) => {
const tasks$ = [];
for (const format of formats) {
if (hasValue(format.id)) {
tasks$.push(this.bitstreamFormatService.delete(format.id));
}
}
zip(...tasks$).subscribe((results: boolean[]) => {
const successResponses = results.filter((result: boolean) => result);
const failedResponses = results.filter((result: boolean) => !result);
if (successResponses.length > 0) {
this.showNotification(true, successResponses.length);
}
if (failedResponses.length > 0) {
this.showNotification(false, failedResponses.length);
}
this.deselectAll();
this.router.navigate([], {
queryParams: Object.assign({}, { page: 1 }),
queryParamsHandling: 'merge'
}); });
}
);
}
/**
* Deselects all selecetd bitstream formats
*/
deselectAll() {
this.bitstreamFormatService.deselectAllBitstreamFormats();
}
/**
* Checks whether a given bitstream format is selected in the list (checkbox)
* @param bitstreamFormat
*/
isSelected(bitstreamFormat: BitstreamFormat): Observable<boolean> {
return this.bitstreamFormatService.getSelectedBitstreamFormats().pipe(
map((bitstreamFormats: BitstreamFormat[]) => {
return bitstreamFormats.find((selectedFormat) => selectedFormat.id === bitstreamFormat.id) != null;
})
);
}
/**
* Selects or deselects a bitstream format based on the checkbox state
* @param bitstreamFormat
* @param event
*/
selectBitStreamFormat(bitstreamFormat: BitstreamFormat, event) {
event.target.checked ?
this.bitstreamFormatService.selectBitstreamFormat(bitstreamFormat) :
this.bitstreamFormatService.deselectBitstreamFormat(bitstreamFormat);
}
/**
* Show notifications for an amount of deleted bitstream formats
* @param success Whether or not the notification should be a success message (error message when false)
* @param amount The amount of deleted bitstream formats
*/
private showNotification(success: boolean, amount: number) {
const prefix = 'admin.registries.bitstream-formats.delete';
const suffix = success ? 'success' : 'failure';
const messages = observableCombineLatest(
this.translateService.get(`${prefix}.${suffix}.head`),
this.translateService.get(`${prefix}.${suffix}.amount`, {amount: amount})
);
messages.subscribe(([head, content]) => {
if (success) {
this.notificationsService.success(head, content);
} else {
this.notificationsService.error(head, content);
}
});
}
/**
@@ -38,14 +145,26 @@ export class BitstreamFormatsComponent {
* @param event The page change event
*/
onPageChange(event) {
this.config.currentPage = event;
this.updateFormats();
this.config = Object.assign(new FindListOptions(), this.config, {
currentPage: event,
});
this.pageConfig.currentPage = event;
this.pageState.next('pageChange');
}
ngOnInit(): void {
this.pageState = new BehaviorSubject('init');
this.bitstreamFormats = this.pageState.pipe(
switchMap(() => {
return this.updateFormats()
;
}));
}
/**
* Method to update the bitstream formats that are shown
* Finds all formats based on the current config
*/
private updateFormats() {
this.bitstreamFormats = this.registryService.getBitstreamFormats(this.config);
return this.bitstreamFormatService.findAll(this.config);
}
}

View File

@@ -0,0 +1,30 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { BitstreamFormatsComponent } from './bitstream-formats.component';
import { SharedModule } from '../../../shared/shared.module';
import { FormatFormComponent } from './format-form/format-form.component';
import { EditBitstreamFormatComponent } from './edit-bitstream-format/edit-bitstream-format.component';
import { BitstreamFormatsRoutingModule } from './bitstream-formats-routing.module';
import { AddBitstreamFormatComponent } from './add-bitstream-format/add-bitstream-format.component';
@NgModule({
imports: [
CommonModule,
SharedModule,
RouterModule,
TranslateModule,
BitstreamFormatsRoutingModule
],
declarations: [
BitstreamFormatsComponent,
EditBitstreamFormatComponent,
AddBitstreamFormatComponent,
FormatFormComponent
],
entryComponents: []
})
export class BitstreamFormatsModule {
}

View File

@@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { find } from 'rxjs/operators';
import { RemoteData } from '../../../core/data/remote-data';
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
import { hasValue } from '../../../shared/empty.util';
/**
* This class represents a resolver that requests a specific bitstreamFormat before the route is activated
*/
@Injectable()
export class BitstreamFormatsResolver implements Resolve<RemoteData<BitstreamFormat>> {
constructor(private bitstreamFormatDataService: BitstreamFormatDataService) {
}
/**
* Method for resolving an bitstreamFormat based on the parameters in the current route
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
* @returns Observable<<RemoteData<BitstreamFormat>> Emits the found bitstreamFormat based on the parameters in the current route,
* or an error if something went wrong
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<BitstreamFormat>> {
return this.bitstreamFormatDataService.findById(route.params.id)
.pipe(
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
);
}
}

View File

@@ -0,0 +1,11 @@
<div class="container">
<div class="row">
<div class="col-12 mb-4">
<h2 id="sub-header"
class="border-bottom mb-2">{{'admin.registries.bitstream-formats.edit.head' | translate:{format: (bitstreamFormatRD$ | async)?.payload.shortDescription} }}</h2>
<ds-bitstream-format-form [bitstreamFormat]="(bitstreamFormatRD$ | async)?.payload" (updatedFormat)="updateFormat($event)"></ds-bitstream-format-form>
</div>
</div>
</div>

View File

@@ -0,0 +1,122 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { RestResponse } from '../../../../core/cache/response.models';
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
import { RemoteData } from '../../../../core/data/remote-data';
import { BitstreamFormatSupportLevel } from '../../../../core/shared/bitstream-format-support-level';
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service-stub';
import { RouterStub } from '../../../../shared/testing/router-stub';
import { EditBitstreamFormatComponent } from './edit-bitstream-format.component';
describe('EditBitstreamFormatComponent', () => {
let comp: EditBitstreamFormatComponent;
let fixture: ComponentFixture<EditBitstreamFormatComponent>;
const bitstreamFormat = new BitstreamFormat();
bitstreamFormat.uuid = 'test-uuid-1';
bitstreamFormat.id = 'test-uuid-1';
bitstreamFormat.shortDescription = 'Unknown';
bitstreamFormat.description = 'Unknown data format';
bitstreamFormat.mimetype = 'application/octet-stream';
bitstreamFormat.supportLevel = BitstreamFormatSupportLevel.Unknown;
bitstreamFormat.internal = false;
bitstreamFormat.extensions = null;
const routeStub = {
data: observableOf({
bitstreamFormat: new RemoteData(false, false, true, null, bitstreamFormat)
})
};
let router;
let notificationService: NotificationsServiceStub;
let bitstreamFormatDataService: BitstreamFormatDataService;
const initAsync = () => {
router = new RouterStub();
notificationService = new NotificationsServiceStub();
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
updateBitstreamFormat: observableOf(new RestResponse(true, 200, 'Success'))
});
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [EditBitstreamFormatComponent],
providers: [
{provide: ActivatedRoute, useValue: routeStub},
{provide: Router, useValue: router},
{provide: NotificationsService, useValue: notificationService},
{provide: BitstreamFormatDataService, useValue: bitstreamFormatDataService},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
};
const initBeforeEach = () => {
fixture = TestBed.createComponent(EditBitstreamFormatComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
};
describe('init', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should initialise the bitstreamFormat based on the route', () => {
comp.bitstreamFormatRD$.subscribe((format: RemoteData<BitstreamFormat>) => {
expect(format).toEqual(new RemoteData(false, false, true, null, bitstreamFormat));
});
});
});
describe('updateFormat success', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should send the updated form to the service, show a notification and navigate to ', () => {
comp.updateFormat(bitstreamFormat);
expect(bitstreamFormatDataService.updateBitstreamFormat).toHaveBeenCalledWith(bitstreamFormat);
expect(notificationService.success).toHaveBeenCalled();
expect(router.navigate).toHaveBeenCalledWith(['/admin/registries/bitstream-formats']);
});
});
describe('updateFormat error', () => {
beforeEach(async( () => {
router = new RouterStub();
notificationService = new NotificationsServiceStub();
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
updateBitstreamFormat: observableOf(new RestResponse(false, 400, 'Bad Request'))
});
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
declarations: [EditBitstreamFormatComponent],
providers: [
{provide: ActivatedRoute, useValue: routeStub},
{provide: Router, useValue: router},
{provide: NotificationsService, useValue: notificationService},
{provide: BitstreamFormatDataService, useValue: bitstreamFormatDataService},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
}));
beforeEach(initBeforeEach);
it('should send the updated form to the service, show a notification and navigate to ', () => {
comp.updateFormat(bitstreamFormat);
expect(bitstreamFormatDataService.updateBitstreamFormat).toHaveBeenCalledWith(bitstreamFormat);
expect(notificationService.error).toHaveBeenCalled();
expect(router.navigate).not.toHaveBeenCalled();
});
});
});

View File

@@ -0,0 +1,62 @@
import { map, take } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { Component, OnInit } from '@angular/core';
import { RemoteData } from '../../../../core/data/remote-data';
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
import { RestResponse } from '../../../../core/cache/response.models';
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { getBitstreamFormatsModulePath } from '../../admin-registries-routing.module';
import { TranslateService } from '@ngx-translate/core';
/**
* This component renders the edit page of a bitstream format.
* The route parameter 'id' is used to request the bitstream format.
*/
@Component({
selector: 'ds-edit-bitstream-format',
templateUrl: './edit-bitstream-format.component.html',
})
export class EditBitstreamFormatComponent implements OnInit {
/**
* The bitstream format wrapped in a remote-data object
*/
bitstreamFormatRD$: Observable<RemoteData<BitstreamFormat>>;
constructor(
private route: ActivatedRoute,
private router: Router,
private notificationService: NotificationsService,
private translateService: TranslateService,
private bitstreamFormatDataService: BitstreamFormatDataService,
) {
}
ngOnInit(): void {
this.bitstreamFormatRD$ = this.route.data.pipe(
map((data) => data.bitstreamFormat as RemoteData<BitstreamFormat>)
);
}
/**
* Updates the bitstream format based on the provided bitstream format emitted by the form.
* When successful, a success notification will be shown and the user will be navigated back to the overview page.
* When failed, an error notification will be shown.
*/
updateFormat(bitstreamFormat: BitstreamFormat) {
this.bitstreamFormatDataService.updateBitstreamFormat(bitstreamFormat).pipe(take(1)
).subscribe((response: RestResponse) => {
if (response.isSuccessful) {
this.notificationService.success(this.translateService.get('admin.registries.bitstream-formats.edit.success.head'),
this.translateService.get('admin.registries.bitstream-formats.edit.success.content'));
this.router.navigate([getBitstreamFormatsModulePath()]);
} else {
this.notificationService.error('admin.registries.bitstream-formats.edit.failure.head',
'admin.registries.bitstream-formats.create.edit.content');
}
}
);
}
}

View File

@@ -0,0 +1,3 @@
<ds-form *ngIf="formModel"
[formId]="'comcol-form-id'"
[formModel]="formModel" (submitForm)="onSubmit()" (cancel)="onCancel()"></ds-form>

View File

@@ -0,0 +1,104 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { RouterStub } from '../../../../shared/testing/router-stub';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { FormatFormComponent } from './format-form.component';
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
import { BitstreamFormatSupportLevel } from '../../../../core/shared/bitstream-format-support-level';
import { DynamicCheckboxModel, DynamicFormArrayModel, DynamicInputModel } from '@ng-dynamic-forms/core';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { isEmpty } from '../../../../shared/empty.util';
describe('FormatFormComponent', () => {
let comp: FormatFormComponent;
let fixture: ComponentFixture<FormatFormComponent>;
const router = new RouterStub();
const bitstreamFormat = new BitstreamFormat();
bitstreamFormat.uuid = 'test-uuid-1';
bitstreamFormat.id = 'test-uuid-1';
bitstreamFormat.shortDescription = 'Unknown';
bitstreamFormat.description = 'Unknown data format';
bitstreamFormat.mimetype = 'application/octet-stream';
bitstreamFormat.supportLevel = BitstreamFormatSupportLevel.Unknown;
bitstreamFormat.internal = false;
bitstreamFormat.extensions = [];
const submittedBitstreamFormat = new BitstreamFormat();
submittedBitstreamFormat.id = bitstreamFormat.id;
submittedBitstreamFormat.shortDescription = bitstreamFormat.shortDescription;
submittedBitstreamFormat.mimetype = bitstreamFormat.mimetype;
submittedBitstreamFormat.description = bitstreamFormat.description;
submittedBitstreamFormat.supportLevel = bitstreamFormat.supportLevel;
submittedBitstreamFormat.internal = bitstreamFormat.internal;
submittedBitstreamFormat.extensions = bitstreamFormat.extensions;
const initAsync = () => {
TestBed.configureTestingModule({
imports: [CommonModule, RouterTestingModule.withRoutes([]), ReactiveFormsModule, FormsModule, TranslateModule.forRoot(), NgbModule],
declarations: [FormatFormComponent],
providers: [
{provide: Router, useValue: router},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
};
const initBeforeEach = () => {
fixture = TestBed.createComponent(FormatFormComponent);
comp = fixture.componentInstance;
comp.bitstreamFormat = bitstreamFormat;
fixture.detectChanges();
};
describe('initialise', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should initialises the values in the form', () => {
expect((comp.formModel[0] as DynamicInputModel).value).toBe(bitstreamFormat.shortDescription);
expect((comp.formModel[1] as DynamicInputModel).value).toBe(bitstreamFormat.mimetype);
expect((comp.formModel[2] as DynamicInputModel).value).toBe(bitstreamFormat.description);
expect((comp.formModel[3] as DynamicInputModel).value).toBe(bitstreamFormat.supportLevel);
expect((comp.formModel[4] as DynamicCheckboxModel).value).toBe(bitstreamFormat.internal);
const formArray = (comp.formModel[5] as DynamicFormArrayModel);
const extensions = [];
for (let i = 0; i < formArray.groups.length; i++) {
const value = (formArray.get(i).get(0) as DynamicInputModel).value;
if (!isEmpty(value)) {
extensions.push((formArray.get(i).get(0) as DynamicInputModel).value);
}
}
expect(extensions).toEqual(bitstreamFormat.extensions);
});
});
describe('onSubmit', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should emit the bitstreamFormat currently present in the form', () => {
spyOn(comp.updatedFormat, 'emit');
comp.onSubmit();
expect(comp.updatedFormat.emit).toHaveBeenCalledWith(submittedBitstreamFormat);
});
});
describe('onCancel', () => {
beforeEach(async(initAsync));
beforeEach(initBeforeEach);
it('should navigate back to the bitstream overview', () => {
comp.onCancel();
expect(router.navigate).toHaveBeenCalledWith(['/admin/registries/bitstream-formats']);
});
});
});

View File

@@ -0,0 +1,194 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
import { BitstreamFormatSupportLevel } from '../../../../core/shared/bitstream-format-support-level';
import {
DynamicCheckboxModel,
DynamicFormArrayModel,
DynamicFormControlLayout, DynamicFormControlLayoutConfig,
DynamicFormControlModel,
DynamicFormService,
DynamicInputModel,
DynamicSelectModel,
DynamicTextAreaModel
} from '@ng-dynamic-forms/core';
import { Router } from '@angular/router';
import { getBitstreamFormatsModulePath } from '../../admin-registries-routing.module';
import { hasValue, isEmpty } from '../../../../shared/empty.util';
import { TranslateService } from '@ngx-translate/core';
/**
* The component responsible for rendering the form to create/edit a bitstream format
*/
@Component({
selector: 'ds-bitstream-format-form',
templateUrl: './format-form.component.html'
})
export class FormatFormComponent implements OnInit {
/**
* The current bitstream format
* This can either be and existing one or a new one
*/
@Input() bitstreamFormat: BitstreamFormat = new BitstreamFormat();
/**
* EventEmitter that will emit the updated bitstream format
*/
@Output() updatedFormat: EventEmitter<BitstreamFormat> = new EventEmitter<BitstreamFormat>();
/**
* The different supported support level of the bitstream format
*/
supportLevelOptions = [{label: BitstreamFormatSupportLevel.Known, value: BitstreamFormatSupportLevel.Known},
{label: BitstreamFormatSupportLevel.Unknown, value: BitstreamFormatSupportLevel.Unknown},
{label: BitstreamFormatSupportLevel.Supported, value: BitstreamFormatSupportLevel.Supported}];
/**
* Styling element for repeatable field
*/
arrayElementLayout: DynamicFormControlLayout = {
grid: {
group: 'form-row',
},
};
/**
* Styling element for element of repeatable field
*/
arrayInputElementLayout: DynamicFormControlLayout = {
grid: {
host: 'col'
}
};
/**
* The form model representing the bitstream format
*/
formModel: DynamicFormControlModel[] = [
new DynamicInputModel({
id: 'shortDescription',
name: 'shortDescription',
label: 'admin.registries.bitstream-formats.edit.shortDescription.label',
hint: 'admin.registries.bitstream-formats.edit.shortDescription.hint',
required: true,
validators: {
required: null
},
errorMessages: {
required: 'Please enter a name for this bitstream format'
},
}),
new DynamicInputModel({
id: 'mimetype',
name: 'mimetype',
label: 'admin.registries.bitstream-formats.edit.mimetype.label',
hint: 'admin.registries.bitstream-formats.edit.mimetype.hint',
}),
new DynamicTextAreaModel({
id: 'description',
name: 'description',
label: 'admin.registries.bitstream-formats.edit.description.label',
hint: 'admin.registries.bitstream-formats.edit.description.hint',
}),
new DynamicSelectModel({
id: 'supportLevel',
name: 'supportLevel',
options: this.supportLevelOptions,
label: 'admin.registries.bitstream-formats.edit.supportLevel.label',
hint: 'admin.registries.bitstream-formats.edit.supportLevel.hint',
value: this.supportLevelOptions[0].value
}),
new DynamicCheckboxModel({
id: 'internal',
name: 'internal',
label: 'Internal',
hint: 'admin.registries.bitstream-formats.edit.internal.hint',
}),
new DynamicFormArrayModel({
id: 'extensions',
name: 'extensions',
label: 'admin.registries.bitstream-formats.edit.extensions.label',
groupFactory: () => [
new DynamicInputModel({
id: 'extension',
placeholder: 'admin.registries.bitstream-formats.edit.extensions.placeholder',
}, this.arrayInputElementLayout)
]
}, this.arrayElementLayout),
];
constructor(private dynamicFormService: DynamicFormService,
private translateService: TranslateService,
private router: Router) {
}
ngOnInit(): void {
this.initValues();
}
/**
* Initializes the form based on the provided bitstream format
*/
initValues() {
this.formModel.forEach(
(fieldModel: DynamicFormControlModel) => {
if (fieldModel.name === 'extensions') {
if (hasValue(this.bitstreamFormat.extensions)) {
const extenstions = this.bitstreamFormat.extensions;
const formArray = (fieldModel as DynamicFormArrayModel);
for (let i = 0; i < extenstions.length; i++) {
formArray.insertGroup(i).group[0] = new DynamicInputModel({
id: `extension-${i}`,
value: extenstions[i]
}, this.arrayInputElementLayout);
}
}
} else {
if (hasValue(this.bitstreamFormat[fieldModel.name])) {
(fieldModel as DynamicInputModel).value = this.bitstreamFormat[fieldModel.name];
}
}
});
}
/**
* Creates an updated bistream format based on the current values in the form
* Emits the updated bitstream format trouhg the updatedFormat emitter
*/
onSubmit() {
const updatedBitstreamFormat = Object.assign(new BitstreamFormat(),
{
id: this.bitstreamFormat.id
});
this.formModel.forEach(
(fieldModel: DynamicFormControlModel) => {
if (fieldModel.name === 'extensions') {
const formArray = (fieldModel as DynamicFormArrayModel);
const extensions = [];
for (let i = 0; i < formArray.groups.length; i++) {
const value = (formArray.get(i).get(0) as DynamicInputModel).value;
if (!isEmpty(value)) {
extensions.push((formArray.get(i).get(0) as DynamicInputModel).value);
}
}
updatedBitstreamFormat.extensions = extensions;
} else {
updatedBitstreamFormat[fieldModel.name] = (fieldModel as DynamicInputModel).value;
}
});
this.updatedFormat.emit(updatedBitstreamFormat);
}
/**
* Cancels the edit/create action of the bitstream format and navigates back to the bitstream format registry
*/
onCancel() {
this.router.navigate([getBitstreamFormatsModulePath()]);
}
}

View File

@@ -1,7 +1,7 @@
import { Action } from '@ngrx/store';
import { type } from '../../../shared/ngrx/type';
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
import { MetadataField } from '../../../core/metadata/metadatafield.model';
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
import { MetadataField } from '../../../core/metadata/metadata-field.model';
/**
* For each action type in an action group, make a simple
@@ -148,4 +148,6 @@ export type MetadataRegistryAction
| MetadataRegistryEditFieldAction
| MetadataRegistryCancelFieldAction
| MetadataRegistrySelectFieldAction
| MetadataRegistryDeselectFieldAction;
| MetadataRegistryDeselectFieldAction
| MetadataRegistryDeselectAllSchemaAction
| MetadataRegistryDeselectAllFieldAction;

View File

@@ -1,5 +1,3 @@
@import '../../../../styles/variables.scss';
.selectable-row:hover {
cursor: pointer;
}

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