From 84cb8fe09d574ef08c3bc48d83e74188498efdc4 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Thu, 3 Nov 2022 12:21:37 -0400 Subject: [PATCH 01/14] Make 'yarn install' succeed. Make 'yarn install' succeed. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 705dc8e345..993b8e079e 100644 --- a/package.json +++ b/package.json @@ -177,7 +177,7 @@ "eslint": "^8.2.0", "eslint-plugin-deprecation": "^1.3.2", "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jsdoc": "^38.0.6", + "eslint-plugin-jsdoc": "^39.3.6", "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-unused-imports": "^2.0.0", "express-static-gzip": "^2.1.5", From fd43adea755537c5cefb7e0ff972c015b84ddf93 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Thu, 3 Nov 2022 12:40:51 -0400 Subject: [PATCH 02/14] Check in updated yarn lockfile (newbie error). --- yarn.lock | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/yarn.lock b/yarn.lock index f229ed4fcc..703fd01e62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1487,14 +1487,14 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@es-joy/jsdoccomment@~0.22.1": - version "0.22.1" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.22.1.tgz#3c86d458780231769215a795105bd3b03b2616f2" - integrity sha512-/WMkqLYfwCf0waCAMC8Eddt3iAOdghkDF5vmyKEu8pfO66KRFY1L15yks8mfgURiwOAOJpAQ3blvB3Znj6ZwBw== +"@es-joy/jsdoccomment@~0.36.0": + version "0.36.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.36.0.tgz#e3898aad334281a10ceb3c0ec406297a79f2b043" + integrity sha512-u0XZyvUF6Urb2cSivSXA8qXIpT/CxkHcdtZKoWusAzgzmsTWpg0F2FpWXsolHmMUyVY3dLWaoy+0ccJ5uf2QjA== dependencies: comment-parser "1.3.1" esquery "^1.4.0" - jsdoc-type-pratt-parser "~2.2.5" + jsdoc-type-pratt-parser "~3.1.0" "@eslint/eslintrc@^1.2.1": version "1.2.1" @@ -5700,18 +5700,17 @@ eslint-plugin-import@^2.25.4: resolve "^1.20.0" tsconfig-paths "^3.12.0" -eslint-plugin-jsdoc@^38.0.6: - version "38.0.6" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-38.0.6.tgz#b26843bdc445202b9f0e3830bda39ec5aacbfa97" - integrity sha512-Wvh5ERLUL8zt2yLZ8LLgi8RuF2UkjDvD+ri1/i7yMpbfreK2S29B9b5JC7iBIoFR7KDaEWCLnUPHTqgwcXX1Sg== +eslint-plugin-jsdoc@^39.3.6: + version "39.6.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.2.tgz#dcc86cec7cce47aa1a646e38debd5bdf76f63742" + integrity sha512-dvgY/W7eUFoAIIiaWHERIMI61ZWqcz9YFjEeyTzdPlrZc3TY/3aZm5aB91NUoTLWYZmO/vFlYSuQi15tF7uE5A== dependencies: - "@es-joy/jsdoccomment" "~0.22.1" + "@es-joy/jsdoccomment" "~0.36.0" comment-parser "1.3.1" debug "^4.3.4" escape-string-regexp "^4.0.0" esquery "^1.4.0" - regextras "^0.8.0" - semver "^7.3.5" + semver "^7.3.8" spdx-expression-parse "^3.0.1" eslint-plugin-lodash@^7.4.0: @@ -7764,10 +7763,10 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdoc-type-pratt-parser@~2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.5.tgz#c9f93afac7ee4b5ed4432fe3f09f7d36b05ed0ff" - integrity sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw== +jsdoc-type-pratt-parser@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz#a4a56bdc6e82e5865ffd9febc5b1a227ff28e67e" + integrity sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw== jsdom@19.0.0: version "19.0.0" @@ -11114,11 +11113,6 @@ regexpu-core@^5.0.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -regextras@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.8.0.tgz#ec0f99853d4912839321172f608b544814b02217" - integrity sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ== - registry-auth-token@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" @@ -11609,6 +11603,13 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" From 7690d36e4b5cf2d12c309e4bc6fff2c30e4e67ab Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Thu, 17 Nov 2022 09:00:11 -0500 Subject: [PATCH 03/14] Update Node versions with which to test. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c58e09edf2..49061a8ebf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: strategy: # Create a matrix of Node versions to test against (in parallel) matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] # Do NOT exit immediately if one matrix job fails fail-fast: false # These are the actual CI steps to perform per job From 2ef78741cc8b3fd221f55f9e79600222a0bb0785 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 2 Dec 2022 08:47:01 -0500 Subject: [PATCH 04/14] Name resolution changed in Node 18 -- avoid it. --- .github/workflows/build.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49061a8ebf..44dd883f78 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -112,7 +112,7 @@ jobs: start: yarn run serve:ssr # Wait for backend & frontend to be available # NOTE: We use the 'sites' REST endpoint to also ensure the database is ready - wait-on: http://localhost:8080/server/api/core/sites, http://localhost:4000 + wait-on: http://127.0.0.1:8080/server/api/core/sites, http://127.0.0.1:4000 # Wait for 2 mins max for everything to respond wait-on-timeout: 120 diff --git a/README.md b/README.md index 0ede4d4d19..baef9d5de1 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ https://wiki.lyrasis.org/display/DSDOC7x/Installing+DSpace Quick start ----------- -**Ensure you're running [Node](https://nodejs.org) `v14.x` or `v16.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) == `v1.x`** +**Ensure you're running [Node](https://nodejs.org) `v16.x` or `v18.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) == `v1.x`** ```bash # clone the repo @@ -90,7 +90,7 @@ Requirements ------------ - [Node.js](https://nodejs.org) and [yarn](https://yarnpkg.com) -- Ensure you're running node `v14.x` or `v16.x` and yarn == `v1.x` +- Ensure you're running node `v16.x` or `v18.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. From 20faa40f224c1e80478435230f0bf84527025ebd Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 2 Dec 2022 09:24:30 -0500 Subject: [PATCH 05/14] More name resolution repairs. --- cypress.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress.json b/cypress.json index 80358eb6dd..3adf7839c2 100644 --- a/cypress.json +++ b/cypress.json @@ -5,7 +5,7 @@ "screenshotsFolder": "cypress/screenshots", "pluginsFile": "cypress/plugins/index.ts", "fixturesFolder": "cypress/fixtures", - "baseUrl": "http://localhost:4000", + "baseUrl": "http://127.0.0.1:4000", "retries": { "runMode": 2, "openMode": 0 @@ -22,4 +22,4 @@ "DSPACE_TEST_SUBMIT_USER": "dspacedemo+submit@gmail.com", "DSPACE_TEST_SUBMIT_USER_PASSWORD": "dspace" } -} \ No newline at end of file +} From 1215a7ee7ab1690120d4d600cb84d7816907ae29 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 2 Dec 2022 10:08:45 -0600 Subject: [PATCH 06/14] Fix email validation regex to use HTML5 provided regex --- .../register-email-form/register-email-form.component.spec.ts | 4 ++++ src/app/register-email-form/register-email-form.component.ts | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.spec.ts b/src/app/register-email-form/register-email-form.component.spec.ts index bac922c73b..cf3b4b13d2 100644 --- a/src/app/register-email-form/register-email-form.component.spec.ts +++ b/src/app/register-email-form/register-email-form.component.spec.ts @@ -95,6 +95,10 @@ describe('RegisterEmailComponent', () => { comp.form.patchValue({email: 'valid@email.org'}); expect(comp.form.invalid).toBeFalse(); }); + it('should be valid when uppercase letters are used', () => { + comp.form.patchValue({email: 'VALID@email.org'}); + expect(comp.form.invalid).toBeFalse(); + }); }); describe('register', () => { it('should send a registration to the service and on success display a message and return to home', () => { diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index ced87b9e75..561bd53e67 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -79,7 +79,9 @@ export class RegisterEmailFormComponent implements OnInit { this.form = this.formBuilder.group({ email: new FormControl('', { validators: [Validators.required, - Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$') + // Regex pattern borrowed from HTML5 specs for a valid email address: + // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address + Validators.pattern('^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$') ], }) }); From 8341882b0f320dabd297ec79fa87a9f604fbf627 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 23 Nov 2022 19:38:37 +0100 Subject: [PATCH 07/14] 96252: Extract form-specific code from SharedModule --- src/app/core/core.module.ts | 14 ------ .../lookup/dynamic-lookup.component.spec.ts | 2 +- .../onebox/dynamic-onebox.component.spec.ts | 4 +- .../models/onebox/dynamic-onebox.component.ts | 2 +- .../dynamic-relation-group.component.spec.ts | 2 +- .../dynamic-relation-group.components.ts | 4 +- .../models/tag/dynamic-tag.component.spec.ts | 2 +- .../models/tag/dynamic-tag.component.ts | 2 +- .../{ => form}/chips/chips.component.html | 0 .../{ => form}/chips/chips.component.scss | 0 .../{ => form}/chips/chips.component.spec.ts | 12 +++--- .../{ => form}/chips/chips.component.ts | 8 ++-- .../chips/models/chips-item.model.spec.ts | 2 +- .../chips/models/chips-item.model.ts | 8 ++-- .../chips/models/chips.model.spec.ts | 2 +- .../{ => form}/chips/models/chips.model.ts | 10 ++--- .../authority-confidence-state.directive.ts | 22 +++++++--- src/app/shared/form/form.module.ts | 43 ++++++++++++++----- .../number-picker.component.html | 0 .../number-picker.component.scss | 0 .../number-picker.component.spec.ts | 4 +- .../number-picker/number-picker.component.ts | 2 +- .../vocabulary-tree-flat-data-source.ts | 0 .../vocabulary-tree-flattener.ts | 0 .../vocabulary-treeview-node.model.ts | 4 +- .../vocabulary-treeview.component.html | 0 .../vocabulary-treeview.component.scss | 0 .../vocabulary-treeview.component.spec.ts | 18 ++++---- .../vocabulary-treeview.component.ts | 14 +++--- .../vocabulary-treeview.service.spec.ts | 16 +++---- .../vocabulary-treeview.service.ts | 16 +++---- src/app/shared/shared.module.ts | 9 ---- .../submission-upload-files.component.ts | 2 +- src/app/submission/submission.module.ts | 7 ++- src/app/submit-page/submit-page.module.ts | 2 + 35 files changed, 122 insertions(+), 111 deletions(-) rename src/app/shared/{ => form}/chips/chips.component.html (100%) rename src/app/shared/{ => form}/chips/chips.component.scss (100%) rename src/app/shared/{ => form}/chips/chips.component.spec.ts (92%) rename src/app/shared/{ => form}/chips/chips.component.ts (94%) rename src/app/shared/{ => form}/chips/models/chips-item.model.spec.ts (94%) rename src/app/shared/{ => form}/chips/models/chips-item.model.ts (89%) rename src/app/shared/{ => form}/chips/models/chips.model.spec.ts (96%) rename src/app/shared/{ => form}/chips/models/chips.model.ts (89%) rename src/app/shared/{authority-confidence => form/directives}/authority-confidence-state.directive.ts (83%) rename src/app/shared/{ => form}/number-picker/number-picker.component.html (100%) rename src/app/shared/{ => form}/number-picker/number-picker.component.scss (100%) rename src/app/shared/{ => form}/number-picker/number-picker.component.spec.ts (96%) rename src/app/shared/{ => form}/number-picker/number-picker.component.ts (98%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-tree-flat-data-source.ts (100%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-tree-flattener.ts (100%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview-node.model.ts (88%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview.component.html (100%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview.component.scss (100%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview.component.spec.ts (91%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview.component.ts (93%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview.service.spec.ts (94%) rename src/app/shared/{ => form}/vocabulary-treeview/vocabulary-treeview.service.ts (94%) diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 3ba0b39a0e..699543f29a 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -9,8 +9,6 @@ import { Action, StoreConfig, StoreModule } from '@ngrx/store'; import { MyDSpaceGuard } from '../my-dspace-page/my-dspace.guard'; import { isNotEmpty } from '../shared/empty.util'; -import { FormBuilderService } from '../shared/form/builder/form-builder.service'; -import { FormService } from '../shared/form/form.service'; import { HostWindowService } from '../shared/host-window.service'; import { MenuService } from '../shared/menu/menu.service'; import { EndpointMockingRestService } from '../shared/mocks/dspace-rest/endpoint-mocking-rest.service'; @@ -138,9 +136,6 @@ import { import { Registration } from './shared/registration.model'; import { MetadataSchemaDataService } from './data/metadata-schema-data.service'; import { MetadataFieldDataService } from './data/metadata-field-data.service'; -import { - DsDynamicTypeBindRelationService -} from '../shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service'; import { TokenResponseParsingService } from './auth/token-response-parsing.service'; import { SubmissionCcLicenseDataService } from './submission/submission-cc-license-data.service'; import { SubmissionCcLicence } from './submission/models/submission-cc-license.model'; @@ -150,7 +145,6 @@ import { VocabularyEntry } from './submission/vocabularies/models/vocabulary-ent import { Vocabulary } from './submission/vocabularies/models/vocabulary.model'; import { VocabularyEntryDetail } from './submission/vocabularies/models/vocabulary-entry-detail.model'; import { VocabularyService } from './submission/vocabularies/vocabulary.service'; -import { VocabularyTreeviewService } from '../shared/vocabulary-treeview/vocabulary-treeview.service'; import { ConfigurationDataService } from './data/configuration-data.service'; import { ConfigurationProperty } from './shared/configuration-property.model'; import { ReloadGuard } from './reload/reload.guard'; @@ -211,12 +205,6 @@ const PROVIDERS = [ DSOResponseParsingService, { provide: MOCK_RESPONSE_MAP, useValue: mockResponseMap }, { provide: DspaceRestService, useFactory: restServiceFactory, deps: [MOCK_RESPONSE_MAP, HttpClient] }, - DynamicFormLayoutService, - DynamicFormService, - DynamicFormValidationService, - FormBuilderService, - SectionFormOperationsService, - FormService, EPersonDataService, LinkHeadService, HALEndpointService, @@ -268,7 +256,6 @@ const PROVIDERS = [ ClaimedTaskDataService, PoolTaskDataService, BitstreamDataService, - DsDynamicTypeBindRelationService, EntityTypeDataService, ContentSourceResponseParsingService, ItemTemplateDataService, @@ -304,7 +291,6 @@ const PROVIDERS = [ VocabularyService, VocabularyDataService, VocabularyEntryDetailsDataService, - VocabularyTreeviewService, SequenceService, GroupDataService, FeedbackDataService, diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts index dd97bb74ab..27029ff2be 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts @@ -20,7 +20,7 @@ import { FormFieldMetadataValueObject } from '../../../models/form-field-metadat import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model'; import { createTestComponent } from '../../../../../testing/utils.test'; import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; -import { AuthorityConfidenceStateDirective } from '../../../../../authority-confidence/authority-confidence-state.directive'; +import { AuthorityConfidenceStateDirective } from '../../../../directives/authority-confidence-state.directive'; import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe'; import { mockDynamicFormLayoutService, diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.spec.ts index 1102ae2e74..cf417145a7 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.spec.ts @@ -21,11 +21,11 @@ import { DsDynamicOneboxComponent } from './dynamic-onebox.component'; import { DynamicOneboxModel } from './dynamic-onebox.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { createTestComponent } from '../../../../../testing/utils.test'; -import { AuthorityConfidenceStateDirective } from '../../../../../authority-confidence/authority-confidence-state.directive'; +import { AuthorityConfidenceStateDirective } from '../../../../directives/authority-confidence-state.directive'; import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model'; import { createSuccessfulRemoteDataObject$ } from '../../../../../remote-data.utils'; -import { VocabularyTreeviewComponent } from '../../../../../vocabulary-treeview/vocabulary-treeview.component'; +import { VocabularyTreeviewComponent } from '../../../../vocabulary-treeview/vocabulary-treeview.component'; import { mockDynamicFormLayoutService, mockDynamicFormValidationService diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts index 9d2799177c..008328bf73 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts @@ -30,7 +30,7 @@ import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/ import { PageInfo } from '../../../../../../core/shared/page-info.model'; import { DsDynamicVocabularyComponent } from '../dynamic-vocabulary.component'; import { Vocabulary } from '../../../../../../core/submission/vocabularies/models/vocabulary.model'; -import { VocabularyTreeviewComponent } from '../../../../../vocabulary-treeview/vocabulary-treeview.component'; +import { VocabularyTreeviewComponent } from '../../../../vocabulary-treeview/vocabulary-treeview.component'; import { VocabularyEntryDetail } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; /** diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts index 83baeaaeaa..733758fd27 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts @@ -16,7 +16,7 @@ import { FormFieldModel } from '../../../models/form-field.model'; import { FormBuilderService } from '../../../form-builder.service'; import { FormService } from '../../../../form.service'; import { FormComponent } from '../../../../form.component'; -import { Chips } from '../../../../../chips/models/chips.model'; +import { Chips } from '../../../../chips/models/chips.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { DsDynamicInputModel } from '../ds-dynamic-input.model'; import { createTestComponent } from '../../../../../testing/utils.test'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts index cd10b9a4a3..06e8c01a9b 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts @@ -18,10 +18,10 @@ import { FormBuilderService } from '../../../form-builder.service'; import { SubmissionFormsModel } from '../../../../../../core/config/models/config-submission-forms.model'; import { FormService } from '../../../../form.service'; import { FormComponent } from '../../../../form.component'; -import { Chips } from '../../../../../chips/models/chips.model'; +import { Chips } from '../../../../chips/models/chips.model'; import { hasValue, isEmpty, isNotEmpty, isNotNull } from '../../../../../empty.util'; import { shrinkInOut } from '../../../../../animations/shrink'; -import { ChipsItem } from '../../../../../chips/models/chips-item.model'; +import { ChipsItem } from '../../../../chips/models/chips-item.model'; import { hasOnlyEmptyProperties } from '../../../../../object.util'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts index 7b2c416699..162d9c3cec 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts @@ -13,7 +13,7 @@ import { VocabularyService } from '../../../../../../core/submission/vocabularie import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub'; import { DsDynamicTagComponent } from './dynamic-tag.component'; import { DynamicTagModel } from './dynamic-tag.model'; -import { Chips } from '../../../../../chips/models/chips.model'; +import { Chips } from '../../../../chips/models/chips.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model'; import { createTestComponent } from '../../../../../testing/utils.test'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts index ef5e84e501..8a9f8e3c84 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts @@ -9,7 +9,7 @@ import { isEqual } from 'lodash'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service'; import { DynamicTagModel } from './dynamic-tag.model'; -import { Chips } from '../../../../../chips/models/chips.model'; +import { Chips } from '../../../../chips/models/chips.model'; import { hasValue, isNotEmpty } from '../../../../../empty.util'; import { environment } from '../../../../../../../environments/environment'; import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators'; diff --git a/src/app/shared/chips/chips.component.html b/src/app/shared/form/chips/chips.component.html similarity index 100% rename from src/app/shared/chips/chips.component.html rename to src/app/shared/form/chips/chips.component.html diff --git a/src/app/shared/chips/chips.component.scss b/src/app/shared/form/chips/chips.component.scss similarity index 100% rename from src/app/shared/chips/chips.component.scss rename to src/app/shared/form/chips/chips.component.scss diff --git a/src/app/shared/chips/chips.component.spec.ts b/src/app/shared/form/chips/chips.component.spec.ts similarity index 92% rename from src/app/shared/chips/chips.component.spec.ts rename to src/app/shared/form/chips/chips.component.spec.ts index 6f9b948002..2b8a469bd1 100644 --- a/src/app/shared/chips/chips.component.spec.ts +++ b/src/app/shared/form/chips/chips.component.spec.ts @@ -3,17 +3,16 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/c import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync, } from '@angular/core/testing'; import { Chips } from './models/chips.model'; -import { UploaderService } from '../uploader/uploader.service'; import { ChipsComponent } from './chips.component'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { By } from '@angular/platform-browser'; -import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; -import { createTestComponent } from '../testing/utils.test'; -import { AuthorityConfidenceStateDirective } from '../authority-confidence/authority-confidence-state.directive'; +import { FormFieldMetadataValueObject } from '../builder/models/form-field-metadata-value.model'; +import { createTestComponent } from '../../testing/utils.test'; +import { AuthorityConfidenceStateDirective } from '../directives/authority-confidence-state.directive'; import { TranslateModule } from '@ngx-translate/core'; -import { ConfidenceType } from '../../core/shared/confidence-type'; +import { ConfidenceType } from '../../../core/shared/confidence-type'; import { SortablejsModule } from 'ngx-sortablejs'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; describe('ChipsComponent test suite', () => { @@ -41,7 +40,6 @@ describe('ChipsComponent test suite', () => { providers: [ ChangeDetectorRef, ChipsComponent, - UploaderService ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }); diff --git a/src/app/shared/chips/chips.component.ts b/src/app/shared/form/chips/chips.component.ts similarity index 94% rename from src/app/shared/chips/chips.component.ts rename to src/app/shared/form/chips/chips.component.ts index 17a6b034ee..31aaf04db0 100644 --- a/src/app/shared/chips/chips.component.ts +++ b/src/app/shared/form/chips/chips.component.ts @@ -5,7 +5,7 @@ import { isObject } from 'lodash'; import { Chips } from './models/chips.model'; import { ChipsItem } from './models/chips-item.model'; -import { UploaderService } from '../uploader/uploader.service'; +import { DragService } from '../../../core/drag.service'; import { TranslateService } from '@ngx-translate/core'; import { Options } from 'sortablejs'; import { BehaviorSubject } from 'rxjs'; @@ -33,7 +33,7 @@ export class ChipsComponent implements OnChanges { constructor( private cdr: ChangeDetectorRef, - private uploaderService: UploaderService, + private dragService: DragService, private translate: TranslateService) { this.options = { @@ -76,12 +76,12 @@ export class ChipsComponent implements OnChanges { onDragStart(index) { this.isDragging.next(true); - this.uploaderService.overrideDragOverPage(); + this.dragService.overrideDragOverPage(); this.dragged = index; } onDragEnd(event) { - this.uploaderService.allowDragOverPage(); + this.dragService.allowDragOverPage(); this.dragged = -1; this.chips.updateOrder(); this.isDragging.next(false); diff --git a/src/app/shared/chips/models/chips-item.model.spec.ts b/src/app/shared/form/chips/models/chips-item.model.spec.ts similarity index 94% rename from src/app/shared/chips/models/chips-item.model.spec.ts rename to src/app/shared/form/chips/models/chips-item.model.spec.ts index c85ff83c31..27b4840d46 100644 --- a/src/app/shared/chips/models/chips-item.model.spec.ts +++ b/src/app/shared/form/chips/models/chips-item.model.spec.ts @@ -1,5 +1,5 @@ import { ChipsItem, ChipsItemIcon } from './chips-item.model'; -import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; +import { FormFieldMetadataValueObject } from '../../builder/models/form-field-metadata-value.model'; describe('ChipsItem model test suite', () => { let item: ChipsItem; diff --git a/src/app/shared/chips/models/chips-item.model.ts b/src/app/shared/form/chips/models/chips-item.model.ts similarity index 89% rename from src/app/shared/chips/models/chips-item.model.ts rename to src/app/shared/form/chips/models/chips-item.model.ts index 5d0ff20e2f..a43386862b 100644 --- a/src/app/shared/chips/models/chips-item.model.ts +++ b/src/app/shared/form/chips/models/chips-item.model.ts @@ -1,8 +1,8 @@ import { isObject, uniqueId } from 'lodash'; -import { hasValue, isNotEmpty } from '../../empty.util'; -import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; -import { ConfidenceType } from '../../../core/shared/confidence-type'; -import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/ds-dynamic-form-constants'; +import { hasValue, isNotEmpty } from '../../../empty.util'; +import { FormFieldMetadataValueObject } from '../../builder/models/form-field-metadata-value.model'; +import { ConfidenceType } from '../../../../core/shared/confidence-type'; +import { PLACEHOLDER_PARENT_METADATA } from '../../builder/ds-dynamic-form-ui/ds-dynamic-form-constants'; export interface ChipsItemIcon { metadata: string; diff --git a/src/app/shared/chips/models/chips.model.spec.ts b/src/app/shared/form/chips/models/chips.model.spec.ts similarity index 96% rename from src/app/shared/chips/models/chips.model.spec.ts rename to src/app/shared/form/chips/models/chips.model.spec.ts index a6cf5faf81..c86ff55c6f 100644 --- a/src/app/shared/chips/models/chips.model.spec.ts +++ b/src/app/shared/form/chips/models/chips.model.spec.ts @@ -1,6 +1,6 @@ import { Chips } from './chips.model'; import { ChipsItem } from './chips-item.model'; -import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; +import { FormFieldMetadataValueObject } from '../../builder/models/form-field-metadata-value.model'; describe('Chips model test suite', () => { let items: any[]; diff --git a/src/app/shared/chips/models/chips.model.ts b/src/app/shared/form/chips/models/chips.model.ts similarity index 89% rename from src/app/shared/chips/models/chips.model.ts rename to src/app/shared/form/chips/models/chips.model.ts index c15badb976..73ccdd3e54 100644 --- a/src/app/shared/chips/models/chips.model.ts +++ b/src/app/shared/form/chips/models/chips.model.ts @@ -1,11 +1,11 @@ import { findIndex, isEqual, isObject } from 'lodash'; import { BehaviorSubject } from 'rxjs'; import { ChipsItem, ChipsItemIcon } from './chips-item.model'; -import { hasValue, isNotEmpty } from '../../empty.util'; -import { MetadataIconConfig } from '../../../../config/submission-config.interface'; -import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; -import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; -import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/ds-dynamic-form-constants'; +import { hasValue, isNotEmpty } from '../../../empty.util'; +import { MetadataIconConfig } from '../../../../../config/submission-config.interface'; +import { FormFieldMetadataValueObject } from '../../builder/models/form-field-metadata-value.model'; +import { VocabularyEntry } from '../../../../core/submission/vocabularies/models/vocabulary-entry.model'; +import { PLACEHOLDER_PARENT_METADATA } from '../../builder/ds-dynamic-form-ui/ds-dynamic-form-constants'; export class Chips { chipsItems: BehaviorSubject; diff --git a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts b/src/app/shared/form/directives/authority-confidence-state.directive.ts similarity index 83% rename from src/app/shared/authority-confidence/authority-confidence-state.directive.ts rename to src/app/shared/form/directives/authority-confidence-state.directive.ts index 8999a643e8..0500b42dfb 100644 --- a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts +++ b/src/app/shared/form/directives/authority-confidence-state.directive.ts @@ -1,3 +1,11 @@ +/** + * 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/ + */ + import { AfterViewInit, Directive, @@ -13,13 +21,13 @@ import { import { findIndex } from 'lodash'; -import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; -import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; -import { ConfidenceType } from '../../core/shared/confidence-type'; -import { isNotEmpty, isNull } from '../empty.util'; -import { ConfidenceIconConfig } from '../../../config/submission-config.interface'; -import { environment } from '../../../environments/environment'; -import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; +import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; +import { FormFieldMetadataValueObject } from '../builder/models/form-field-metadata-value.model'; +import { ConfidenceType } from '../../../core/shared/confidence-type'; +import { isNotEmpty, isNull } from '../../empty.util'; +import { ConfidenceIconConfig } from '../../../../config/submission-config.interface'; +import { environment } from '../../../../environments/environment'; +import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; /** * Directive to add to the element a bootstrap utility class based on metadata confidence value diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index 62ab5bd647..dd370fdf31 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -2,10 +2,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormComponent } from './form.component'; import { DsDynamicFormComponent } from './builder/ds-dynamic-form-ui/ds-dynamic-form.component'; -import { - DsDynamicFormControlContainerComponent, - dsDynamicFormControlMapFn -} from './builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component'; +import { DsDynamicFormControlContainerComponent, dsDynamicFormControlMapFn } from './builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component'; import { DsDynamicListComponent } from './builder/ds-dynamic-form-ui/models/list/dynamic-list.component'; import { DsDynamicLookupComponent } from './builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component'; import { DsDynamicDisabledComponent } from './builder/ds-dynamic-form-ui/models/disabled/dynamic-disabled.component'; @@ -24,12 +21,21 @@ import { DsDynamicLookupRelationExternalSourceTabComponent } from './builder/ds- import { SharedModule } from '../shared.module'; import { TranslateModule } from '@ngx-translate/core'; import { SearchModule } from '../search/search.module'; -import { DYNAMIC_FORM_CONTROL_MAP_FN, DynamicFormsCoreModule } from '@ng-dynamic-forms/core'; +import { DYNAMIC_FORM_CONTROL_MAP_FN, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { ExistingMetadataListElementComponent } from './builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component'; import { ExistingRelationListElementComponent } from './builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component'; import { ExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; import { CustomSwitchComponent } from './builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.component'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; +import { ChipsComponent } from './chips/chips.component'; +import { NumberPickerComponent } from './number-picker/number-picker.component'; +import { AuthorityConfidenceStateDirective } from './directives/authority-confidence-state.directive'; +import { SortablejsModule } from 'ngx-sortablejs'; +import { VocabularyTreeviewComponent } from './vocabulary-treeview/vocabulary-treeview.component'; +import { VocabularyTreeviewService } from './vocabulary-treeview/vocabulary-treeview.service'; +import { FormBuilderService } from './builder/form-builder.service'; +import { DsDynamicTypeBindRelationService } from './builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service'; +import { FormService } from './form.service'; const COMPONENTS = [ CustomSwitchComponent, @@ -53,12 +59,20 @@ const COMPONENTS = [ ExistingMetadataListElementComponent, ExistingRelationListElementComponent, ExternalSourceEntryImportModalComponent, - FormComponent + FormComponent, + ChipsComponent, + NumberPickerComponent, + VocabularyTreeviewComponent, +]; + +const DIRECTIVES = [ + AuthorityConfidenceStateDirective, ]; @NgModule({ declarations: [ - ...COMPONENTS + ...COMPONENTS, + ...DIRECTIVES, ], imports: [ CommonModule, @@ -66,16 +80,25 @@ const COMPONENTS = [ DynamicFormsNGBootstrapUIModule, SearchModule, SharedModule, - TranslateModule + TranslateModule, + SortablejsModule, ], exports: [ - ...COMPONENTS + ...COMPONENTS, + ...DIRECTIVES, ], providers: [ { provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn - } + }, + VocabularyTreeviewService, + DynamicFormLayoutService, + DynamicFormService, + DynamicFormValidationService, + FormBuilderService, + DsDynamicTypeBindRelationService, + FormService, ] }) export class FormModule { diff --git a/src/app/shared/number-picker/number-picker.component.html b/src/app/shared/form/number-picker/number-picker.component.html similarity index 100% rename from src/app/shared/number-picker/number-picker.component.html rename to src/app/shared/form/number-picker/number-picker.component.html diff --git a/src/app/shared/number-picker/number-picker.component.scss b/src/app/shared/form/number-picker/number-picker.component.scss similarity index 100% rename from src/app/shared/number-picker/number-picker.component.scss rename to src/app/shared/form/number-picker/number-picker.component.scss diff --git a/src/app/shared/number-picker/number-picker.component.spec.ts b/src/app/shared/form/number-picker/number-picker.component.spec.ts similarity index 96% rename from src/app/shared/number-picker/number-picker.component.spec.ts rename to src/app/shared/form/number-picker/number-picker.component.spec.ts index 0cc073644e..d4484dbfa3 100644 --- a/src/app/shared/number-picker/number-picker.component.spec.ts +++ b/src/app/shared/form/number-picker/number-picker.component.spec.ts @@ -2,12 +2,11 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, inject, TestBed, waitForAsync, } from '@angular/core/testing'; -import { UploaderService } from '../uploader/uploader.service'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { By } from '@angular/platform-browser'; import { NumberPickerComponent } from './number-picker.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { createTestComponent } from '../testing/utils.test'; +import { createTestComponent } from '../../testing/utils.test'; describe('NumberPickerComponent test suite', () => { @@ -33,7 +32,6 @@ describe('NumberPickerComponent test suite', () => { providers: [ ChangeDetectorRef, NumberPickerComponent, - UploaderService ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }); diff --git a/src/app/shared/number-picker/number-picker.component.ts b/src/app/shared/form/number-picker/number-picker.component.ts similarity index 98% rename from src/app/shared/number-picker/number-picker.component.ts rename to src/app/shared/form/number-picker/number-picker.component.ts index 465e905713..0df1e050cd 100644 --- a/src/app/shared/number-picker/number-picker.component.ts +++ b/src/app/shared/form/number-picker/number-picker.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, SimpleChanges, } from '@angular/core'; import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { isEmpty } from '../empty.util'; +import { isEmpty } from '../../empty.util'; @Component({ selector: 'ds-number-picker', diff --git a/src/app/shared/vocabulary-treeview/vocabulary-tree-flat-data-source.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-tree-flat-data-source.ts similarity index 100% rename from src/app/shared/vocabulary-treeview/vocabulary-tree-flat-data-source.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-tree-flat-data-source.ts diff --git a/src/app/shared/vocabulary-treeview/vocabulary-tree-flattener.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-tree-flattener.ts similarity index 100% rename from src/app/shared/vocabulary-treeview/vocabulary-tree-flattener.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-tree-flattener.ts diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview-node.model.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview-node.model.ts similarity index 88% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview-node.model.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview-node.model.ts index 63039e6c75..c167328cab 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview-node.model.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview-node.model.ts @@ -1,7 +1,7 @@ /* eslint-disable max-classes-per-file */ import { BehaviorSubject } from 'rxjs'; -import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; -import { PageInfo } from '../../core/shared/page-info.model'; +import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; +import { PageInfo } from '../../../core/shared/page-info.model'; export const LOAD_MORE = 'LOAD_MORE'; export const LOAD_MORE_ROOT = 'LOAD_MORE_ROOT'; diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.html b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.html similarity index 100% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview.component.html rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.html diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.scss b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.scss similarity index 100% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview.component.scss rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.scss diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.spec.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts similarity index 91% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview.component.spec.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts index 1bdf4b9df7..cf8fbd8c49 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.spec.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts @@ -8,18 +8,18 @@ import { TranslateModule } from '@ngx-translate/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { provideMockStore } from '@ngrx/store/testing'; -import { createTestComponent } from '../testing/utils.test'; +import { createTestComponent } from '../../testing/utils.test'; import { VocabularyTreeviewComponent } from './vocabulary-treeview.component'; import { VocabularyTreeviewService } from './vocabulary-treeview.service'; -import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; +import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { TreeviewFlatNode } from './vocabulary-treeview-node.model'; -import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; -import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; -import { PageInfo } from '../../core/shared/page-info.model'; -import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; -import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model'; -import { authReducer } from '../../core/auth/auth.reducer'; -import { storeModuleConfig } from '../../app.reducer'; +import { FormFieldMetadataValueObject } from '../builder/models/form-field-metadata-value.model'; +import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; +import { PageInfo } from '../../../core/shared/page-info.model'; +import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; +import { AuthTokenInfo } from '../../../core/auth/models/auth-token-info.model'; +import { authReducer } from '../../../core/auth/auth.reducer'; +import { storeModuleConfig } from '../../../app.reducer'; describe('VocabularyTreeviewComponent test suite', () => { diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts similarity index 93% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts index 9850947f60..408d656f42 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts @@ -7,17 +7,17 @@ import { Observable, Subscription } from 'rxjs'; import { select, Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; -import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; -import { hasValue, isEmpty, isNotEmpty } from '../empty.util'; -import { isAuthenticated } from '../../core/auth/selectors'; +import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; +import { hasValue, isEmpty, isNotEmpty } from '../../empty.util'; +import { isAuthenticated } from '../../../core/auth/selectors'; import { VocabularyTreeviewService } from './vocabulary-treeview.service'; import { LOAD_MORE, LOAD_MORE_ROOT, TreeviewFlatNode, TreeviewNode } from './vocabulary-treeview-node.model'; -import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; -import { PageInfo } from '../../core/shared/page-info.model'; -import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; +import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; +import { PageInfo } from '../../../core/shared/page-info.model'; +import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; import { VocabularyTreeFlattener } from './vocabulary-tree-flattener'; import { VocabularyTreeFlatDataSource } from './vocabulary-tree-flat-data-source'; -import { CoreState } from '../../core/core-state.model'; +import { CoreState } from '../../../core/core-state.model'; /** * Component that show a hierarchical vocabulary in a tree view diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.spec.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.service.spec.ts similarity index 94% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview.service.spec.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview.service.spec.ts index c1c64c80bd..752ef10fee 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.spec.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.service.spec.ts @@ -5,15 +5,15 @@ import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-transla import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { VocabularyTreeviewService } from './vocabulary-treeview.service'; -import { VocabularyService } from '../../core/submission/vocabularies/vocabulary.service'; -import { TranslateLoaderMock } from '../mocks/translate-loader.mock'; -import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; +import { VocabularyService } from '../../../core/submission/vocabularies/vocabulary.service'; +import { TranslateLoaderMock } from '../../mocks/translate-loader.mock'; +import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; import { LOAD_MORE_NODE, LOAD_MORE_ROOT_NODE, TreeviewFlatNode, TreeviewNode } from './vocabulary-treeview-node.model'; -import { PageInfo } from '../../core/shared/page-info.model'; -import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; -import { buildPaginatedList } from '../../core/data/paginated-list.model'; -import { createSuccessfulRemoteDataObject } from '../remote-data.utils'; -import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; +import { PageInfo } from '../../../core/shared/page-info.model'; +import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; +import { buildPaginatedList } from '../../../core/data/paginated-list.model'; +import { createSuccessfulRemoteDataObject } from '../../remote-data.utils'; +import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; import { expand, map, switchMap } from 'rxjs/operators'; import { from as observableFrom } from 'rxjs'; diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.service.ts similarity index 94% rename from src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts rename to src/app/shared/form/vocabulary-treeview/vocabulary-treeview.service.ts index ad2525bb7f..04203ebf79 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.service.ts @@ -10,17 +10,17 @@ import { TreeviewFlatNode, TreeviewNode } from './vocabulary-treeview-node.model'; -import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; -import { VocabularyService } from '../../core/submission/vocabularies/vocabulary.service'; -import { PageInfo } from '../../core/shared/page-info.model'; -import { isEmpty, isNotEmpty } from '../empty.util'; -import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; +import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; +import { VocabularyService } from '../../../core/submission/vocabularies/vocabulary.service'; +import { PageInfo } from '../../../core/shared/page-info.model'; +import { isEmpty, isNotEmpty } from '../../empty.util'; +import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; import { getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteListPayload -} from '../../core/shared/operators'; -import { PaginatedList } from '../../core/data/paginated-list.model'; -import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; +} from '../../../core/shared/operators'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; /** * A service that provides methods to deal with vocabulary tree diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 45e9764151..a47712f261 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -74,8 +74,6 @@ import { TruncatableComponent } from './truncatable/truncatable.component'; import { TruncatableService } from './truncatable/truncatable.service'; import { TruncatablePartComponent } from './truncatable/truncatable-part/truncatable-part.component'; import { UploaderComponent } from './uploader/uploader.component'; -import { ChipsComponent } from './chips/chips.component'; -import { NumberPickerComponent } from './number-picker/number-picker.component'; import { MockAdminGuard } from './mocks/admin-guard.service.mock'; import { AlertComponent } from './alert/alert.component'; import { @@ -111,7 +109,6 @@ import { EmphasizePipe } from './utils/emphasize.pipe'; import { InputSuggestionsComponent } from './input-suggestions/input-suggestions.component'; import { CapitalizePipe } from './utils/capitalize.pipe'; import { ObjectKeysPipe } from './utils/object-keys-pipe'; -import { AuthorityConfidenceStateDirective } from './authority-confidence/authority-confidence-state.directive'; import { LangSwitchComponent } from './lang-switch/lang-switch.component'; import { PlainTextMetadataListElementComponent @@ -232,7 +229,6 @@ import { ImportableListItemControlComponent } from './object-collection/shared/importable-list-item-control/importable-list-item-control.component'; import { ItemVersionsComponent } from './item/item-versions/item-versions.component'; -import { SortablejsModule } from 'ngx-sortablejs'; import { LogInContainerComponent } from './log-in/container/log-in-container.component'; import { LogInShibbolethComponent } from './log-in/methods/shibboleth/log-in-shibboleth.component'; import { LogInPasswordComponent } from './log-in/methods/password/log-in-password.component'; @@ -258,7 +254,6 @@ import { NgForTrackByIdDirective } from './ng-for-track-by-id.directive'; import { FileDownloadLinkComponent } from './file-download-link/file-download-link.component'; import { CollectionDropdownComponent } from './collection-dropdown/collection-dropdown.component'; import { EntityDropdownComponent } from './entity-dropdown/entity-dropdown.component'; -import { VocabularyTreeviewComponent } from './vocabulary-treeview/vocabulary-treeview.component'; import { CurationFormComponent } from '../curation-form/curation-form.component'; import { PublicationSidebarSearchListElementComponent @@ -327,7 +322,6 @@ import { GoogleRecaptchaModule } from '../core/google-recaptcha/google-recaptcha const MODULES = [ CommonModule, - SortablejsModule, FileUploadModule, FormsModule, InfiniteScrollModule, @@ -377,7 +371,6 @@ const COMPONENTS = [ AuthNavMenuComponent, ThemedAuthNavMenuComponent, UserMenuComponent, - ChipsComponent, DsSelectComponent, ErrorComponent, FileSectionComponent, @@ -386,7 +379,6 @@ const COMPONENTS = [ ThemedLoadingComponent, LogInComponent, LogOutComponent, - NumberPickerComponent, ObjectListComponent, ThemedObjectListComponent, ObjectDetailComponent, @@ -605,7 +597,6 @@ const DIRECTIVES = [ DragClickDirective, DebounceDirective, ClickOutsideDirective, - AuthorityConfidenceStateDirective, InListValidator, AutoFocusDirective, RoleDirective, diff --git a/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts b/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts index a56b371456..721a6c108b 100644 --- a/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts +++ b/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts @@ -9,7 +9,7 @@ import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util'; import { normalizeSectionData } from '../../../core/submission/submission-response-parsing.service'; import { SubmissionService } from '../../submission.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; -import { UploaderOptions } from '../../../shared/uploader/uploader-options.model'; +import { UploaderOptions } from '../../../shared/upload/uploader/uploader-options.model'; import parseSectionErrors from '../../utils/parseSectionErrors'; import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model'; diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index d1e8dfd44e..0324ea345a 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -63,6 +63,7 @@ import { import { MetadataInformationComponent } from './sections/sherpa-policies/metadata-information/metadata-information.component'; +import { SectionFormOperationsService } from './sections/form/section-form-operations.service'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -117,13 +118,17 @@ const DECLARATIONS = [ NgbAccordionModule ], declarations: DECLARATIONS, - exports: DECLARATIONS, + exports: [ + ...DECLARATIONS, + FormModule, + ], providers: [ SectionUploadService, SectionsService, SubmissionUploadsConfigDataService, SubmissionAccessesConfigDataService, SectionAccessesService, + SectionFormOperationsService, ] }) diff --git a/src/app/submit-page/submit-page.module.ts b/src/app/submit-page/submit-page.module.ts index e43d9d36aa..6942628e9e 100644 --- a/src/app/submit-page/submit-page.module.ts +++ b/src/app/submit-page/submit-page.module.ts @@ -3,6 +3,7 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../shared/shared.module'; import { SubmitPageRoutingModule } from './submit-page-routing.module'; import { SubmissionModule } from '../submission/submission.module'; +import { FormModule } from '../shared/form/form.module'; @NgModule({ imports: [ @@ -10,6 +11,7 @@ import { SubmissionModule } from '../submission/submission.module'; CommonModule, SharedModule, SubmissionModule, + FormModule, ], }) /** From 3739fa4121c6c5251dee89d5caaf7a332cc798f0 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 23 Nov 2022 20:33:40 +0100 Subject: [PATCH 08/14] 96252: Move dynamic forms out of AppModule --- src/app/access-control/access-control.module.ts | 16 ++++++++++++++++ src/app/app.module.ts | 16 ---------------- src/app/shared/form/form.module.ts | 5 ++++- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/app/access-control/access-control.module.ts b/src/app/access-control/access-control.module.ts index 891238bbed..afb92a9111 100644 --- a/src/app/access-control/access-control.module.ts +++ b/src/app/access-control/access-control.module.ts @@ -10,6 +10,16 @@ import { MembersListComponent } from './group-registry/group-form/members-list/m import { SubgroupsListComponent } from './group-registry/group-form/subgroup-list/subgroups-list.component'; import { GroupsRegistryComponent } from './group-registry/groups-registry.component'; import { FormModule } from '../shared/form/form.module'; +import { DYNAMIC_ERROR_MESSAGES_MATCHER, DynamicErrorMessagesMatcher } from '@ng-dynamic-forms/core'; +import { AbstractControl } from '@angular/forms'; + +/** + * Condition for displaying error messages on email form field + */ +export const ValidateEmailErrorStateMatcher: DynamicErrorMessagesMatcher = + (control: AbstractControl, model: any, hasFocus: boolean) => { + return (control.touched && !hasFocus) || (control.errors?.emailTaken && hasFocus); + }; @NgModule({ imports: [ @@ -26,6 +36,12 @@ import { FormModule } from '../shared/form/form.module'; GroupFormComponent, SubgroupsListComponent, MembersListComponent + ], + providers: [ + { + provide: DYNAMIC_ERROR_MESSAGES_MATCHER, + useValue: ValidateEmailErrorStateMatcher + }, ] }) /** diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 392969d041..2fba48c8b2 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -8,7 +8,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { EffectsModule } from '@ngrx/effects'; import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store'; import { MetaReducer, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store'; -import { DYNAMIC_ERROR_MESSAGES_MATCHER, DYNAMIC_MATCHER_PROVIDERS, DynamicErrorMessagesMatcher } from '@ng-dynamic-forms/core'; import { TranslateModule } from '@ngx-translate/core'; import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to'; import { AppRoutingModule } from './app-routing.module'; @@ -28,7 +27,6 @@ import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor'; import { LogInterceptor } from './core/log/log.interceptor'; import { EagerThemesModule } from '../themes/eager-themes.module'; import { APP_CONFIG, AppConfig } from '../config/app-config.interface'; -import { NgxMaskModule } from 'ngx-mask'; import { StoreDevModules } from '../config/store/devtools'; import { RootModule } from './root.module'; @@ -46,14 +44,6 @@ export function getMetaReducers(appConfig: AppConfig): MetaReducer[] { return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers; } -/** - * Condition for displaying error messages on email form field - */ -export const ValidateEmailErrorStateMatcher: DynamicErrorMessagesMatcher = - (control: AbstractControl, model: any, hasFocus: boolean) => { - return (control.touched && !hasFocus) || (control.errors?.emailTaken && hasFocus); - }; - const IMPORTS = [ CommonModule, SharedModule, @@ -64,7 +54,6 @@ const IMPORTS = [ ScrollToModule.forRoot(), NgbModule, TranslateModule.forRoot(), - NgxMaskModule.forRoot(), EffectsModule.forRoot(appEffects), StoreModule.forRoot(appReducers, storeModuleConfig), StoreRouterConnectingModule.forRoot(), @@ -113,11 +102,6 @@ const PROVIDERS = [ useClass: LogInterceptor, multi: true }, - { - provide: DYNAMIC_ERROR_MESSAGES_MATCHER, - useValue: ValidateEmailErrorStateMatcher - }, - ...DYNAMIC_MATCHER_PROVIDERS, ]; const DECLARATIONS = [ diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index dd370fdf31..598cc2d32c 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -21,7 +21,7 @@ import { DsDynamicLookupRelationExternalSourceTabComponent } from './builder/ds- import { SharedModule } from '../shared.module'; import { TranslateModule } from '@ngx-translate/core'; import { SearchModule } from '../search/search.module'; -import { DYNAMIC_FORM_CONTROL_MAP_FN, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; +import { DYNAMIC_FORM_CONTROL_MAP_FN, DYNAMIC_MATCHER_PROVIDERS, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { ExistingMetadataListElementComponent } from './builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component'; import { ExistingRelationListElementComponent } from './builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component'; import { ExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; @@ -36,6 +36,7 @@ import { VocabularyTreeviewService } from './vocabulary-treeview/vocabulary-tree import { FormBuilderService } from './builder/form-builder.service'; import { DsDynamicTypeBindRelationService } from './builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service'; import { FormService } from './form.service'; +import { NgxMaskModule } from 'ngx-mask'; const COMPONENTS = [ CustomSwitchComponent, @@ -82,6 +83,7 @@ const DIRECTIVES = [ SharedModule, TranslateModule, SortablejsModule, + NgxMaskModule.forRoot(), ], exports: [ ...COMPONENTS, @@ -92,6 +94,7 @@ const DIRECTIVES = [ provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn }, + ...DYNAMIC_MATCHER_PROVIDERS, VocabularyTreeviewService, DynamicFormLayoutService, DynamicFormService, From db3e8f92468e8de0bcaa9c57de875f5385acf0ec Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 23 Nov 2022 19:38:52 +0100 Subject: [PATCH 09/14] 96252: Extract upload-specific code from SharedModule --- src/app/admin/admin.module.ts | 4 +- .../collection-page/collection-page.module.ts | 4 +- .../edit-collection-page.module.ts | 2 +- .../community-page/community-page.module.ts | 2 +- .../edit-community-page.module.ts | 2 +- src/app/core/core.module.ts | 3 -- .../drag.service.ts} | 14 ++++++- .../upload/upload-bitstream.component.ts | 4 +- src/app/item-page/item-page.module.ts | 4 +- ...my-dspace-new-submission.component.spec.ts | 6 +-- .../my-dspace-new-submission.component.ts | 6 +-- .../my-dspace-page/my-dspace-page.module.ts | 4 +- .../comcol-form/comcol-form.component.ts | 4 +- src/app/shared/comcol/comcol.module.ts | 9 +++-- src/app/shared/shared.module.ts | 8 ---- .../file-dropzone-no-uploader.component.html | 0 .../file-dropzone-no-uploader.component.ts | 0 .../file-dropzone-no-uploader.scss | 0 src/app/shared/upload/upload.module.ts | 38 +++++++++++++++++++ .../uploader/uploader-error.model.ts | 0 .../uploader/uploader-options.model.ts | 2 +- .../uploader/uploader-properties.model.ts | 2 +- .../uploader/uploader.component.html | 0 .../uploader/uploader.component.scss | 0 .../uploader/uploader.component.spec.ts | 12 +++--- .../uploader/uploader.component.ts | 20 ++++++---- .../form/submission-form.component.ts | 2 +- .../submission-upload-files.component.spec.ts | 2 +- src/app/submission/submission.module.ts | 4 +- 29 files changed, 104 insertions(+), 54 deletions(-) rename src/app/{shared/uploader/uploader.service.ts => core/drag.service.ts} (53%) rename src/app/shared/{ => upload}/file-dropzone-no-uploader/file-dropzone-no-uploader.component.html (100%) rename src/app/shared/{ => upload}/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts (100%) rename src/app/shared/{ => upload}/file-dropzone-no-uploader/file-dropzone-no-uploader.scss (100%) create mode 100644 src/app/shared/upload/upload.module.ts rename src/app/shared/{ => upload}/uploader/uploader-error.model.ts (100%) rename src/app/shared/{ => upload}/uploader/uploader-options.model.ts (86%) rename src/app/shared/{ => upload}/uploader/uploader-properties.model.ts (83%) rename src/app/shared/{ => upload}/uploader/uploader.component.html (100%) rename src/app/shared/{ => upload}/uploader/uploader.component.scss (100%) rename src/app/shared/{ => upload}/uploader/uploader.component.spec.ts (86%) rename src/app/shared/{ => upload}/uploader/uploader.component.ts (93%) diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 0ddbefd253..dff2e506c3 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -10,6 +10,7 @@ import { AdminSearchModule } from './admin-search-page/admin-search.module'; import { AdminSidebarSectionComponent } from './admin-sidebar/admin-sidebar-section/admin-sidebar-section.component'; import { ExpandableAdminSidebarSectionComponent } from './admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component'; import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; +import { UploadModule } from '../shared/upload/upload.module'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -25,7 +26,8 @@ const ENTRY_COMPONENTS = [ AccessControlModule, AdminSearchModule.withEntryComponents(), AdminWorkflowModuleModule.withEntryComponents(), - SharedModule + SharedModule, + UploadModule, ], declarations: [ AdminCurationTasksComponent, diff --git a/src/app/collection-page/collection-page.module.ts b/src/app/collection-page/collection-page.module.ts index c35ebf9021..ff49b983ff 100644 --- a/src/app/collection-page/collection-page.module.ts +++ b/src/app/collection-page/collection-page.module.ts @@ -25,7 +25,7 @@ import { ComcolModule } from '../shared/comcol/comcol.module'; StatisticsModule.forRoot(), EditItemPageModule, CollectionFormModule, - ComcolModule + ComcolModule, ], declarations: [ CollectionPageComponent, @@ -38,7 +38,7 @@ import { ComcolModule } from '../shared/comcol/comcol.module'; ], providers: [ SearchService, - ] + ], }) export class CollectionPageModule { diff --git a/src/app/collection-page/edit-collection-page/edit-collection-page.module.ts b/src/app/collection-page/edit-collection-page/edit-collection-page.module.ts index 45612be41a..18f7feb699 100644 --- a/src/app/collection-page/edit-collection-page/edit-collection-page.module.ts +++ b/src/app/collection-page/edit-collection-page/edit-collection-page.module.ts @@ -25,7 +25,7 @@ import { ComcolModule } from '../../shared/comcol/comcol.module'; CollectionFormModule, ResourcePoliciesModule, FormModule, - ComcolModule + ComcolModule, ], declarations: [ EditCollectionPageComponent, diff --git a/src/app/community-page/community-page.module.ts b/src/app/community-page/community-page.module.ts index 7cf2c8db8a..1dd9e82499 100644 --- a/src/app/community-page/community-page.module.ts +++ b/src/app/community-page/community-page.module.ts @@ -36,7 +36,7 @@ const DECLARATIONS = [CommunityPageComponent, CommunityPageRoutingModule, StatisticsModule.forRoot(), CommunityFormModule, - ComcolModule + ComcolModule, ], declarations: [ ...DECLARATIONS diff --git a/src/app/community-page/edit-community-page/edit-community-page.module.ts b/src/app/community-page/edit-community-page/edit-community-page.module.ts index 2b0fc73f2a..0479ea6bc6 100644 --- a/src/app/community-page/edit-community-page/edit-community-page.module.ts +++ b/src/app/community-page/edit-community-page/edit-community-page.module.ts @@ -21,7 +21,7 @@ import { ComcolModule } from '../../shared/comcol/comcol.module'; EditCommunityPageRoutingModule, CommunityFormModule, ComcolModule, - ResourcePoliciesModule + ResourcePoliciesModule, ], declarations: [ EditCommunityPageComponent, diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 699543f29a..491d394e73 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -23,7 +23,6 @@ import { ObjectSelectService } from '../shared/object-select/object-select.servi import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { CSSVariableService } from '../shared/sass-helper/sass-helper.service'; import { SidebarService } from '../shared/sidebar/sidebar.service'; -import { UploaderService } from '../shared/uploader/uploader.service'; import { SectionFormOperationsService } from '../submission/sections/form/section-form-operations.service'; import { AuthenticatedGuard } from './auth/authenticated.guard'; import { AuthStatus } from './auth/models/auth-status.model'; @@ -233,12 +232,10 @@ const PROVIDERS = [ SubmissionResponseParsingService, SubmissionJsonPatchOperationsService, JsonPatchOperationsBuilder, - UploaderService, UUIDService, NotificationsService, WorkspaceitemDataService, WorkflowItemDataService, - UploaderService, DSpaceObjectDataService, ConfigurationDataService, DSOChangeAnalyzer, diff --git a/src/app/shared/uploader/uploader.service.ts b/src/app/core/drag.service.ts similarity index 53% rename from src/app/shared/uploader/uploader.service.ts rename to src/app/core/drag.service.ts index 548de34f9c..d5f329d362 100644 --- a/src/app/shared/uploader/uploader.service.ts +++ b/src/app/core/drag.service.ts @@ -1,7 +1,17 @@ +/** + * 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/ + */ + import { Injectable } from '@angular/core'; -@Injectable() -export class UploaderService { +@Injectable({ + providedIn: 'root' +}) +export class DragService { private _overrideDragOverPage = false; public overrideDragOverPage() { diff --git a/src/app/item-page/bitstreams/upload/upload-bitstream.component.ts b/src/app/item-page/bitstreams/upload/upload-bitstream.component.ts index 1e5295a347..74019de7cc 100644 --- a/src/app/item-page/bitstreams/upload/upload-bitstream.component.ts +++ b/src/app/item-page/bitstreams/upload/upload-bitstream.component.ts @@ -4,7 +4,7 @@ import { RemoteData } from '../../../core/data/remote-data'; import { Item } from '../../../core/shared/item.model'; import { map, take, switchMap } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; -import { UploaderOptions } from '../../../shared/uploader/uploader-options.model'; +import { UploaderOptions } from '../../../shared/upload/uploader/uploader-options.model'; import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util'; import { ItemDataService } from '../../../core/data/item-data.service'; import { AuthService } from '../../../core/auth/auth.service'; @@ -14,7 +14,7 @@ import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Bundle } from '../../../core/shared/bundle.model'; import { BundleDataService } from '../../../core/data/bundle-data.service'; import { getFirstSucceededRemoteDataPayload, getFirstCompletedRemoteData } from '../../../core/shared/operators'; -import { UploaderComponent } from '../../../shared/uploader/uploader.component'; +import { UploaderComponent } from '../../../shared/upload/uploader/uploader.component'; import { RequestService } from '../../../core/data/request.service'; import { getBitstreamModuleRoute } from '../../../app-routing-paths'; import { getEntityEditRoute } from '../../item-page-routing-paths'; diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index c4e86a37fb..de9f2f60c5 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -46,6 +46,7 @@ import { OrcidPageComponent } from './orcid-page/orcid-page.component'; import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; import { OrcidSyncSettingsComponent } from './orcid-page/orcid-sync-settings/orcid-sync-settings.component'; import { OrcidQueueComponent } from './orcid-page/orcid-queue/orcid-queue.component'; +import { UploadModule } from '../shared/upload/upload.module'; const ENTRY_COMPONENTS = [ @@ -94,7 +95,8 @@ const DECLARATIONS = [ JournalEntitiesModule.withEntryComponents(), ResearchEntitiesModule.withEntryComponents(), NgxGalleryModule, - NgbAccordionModule + NgbAccordionModule, + UploadModule, ], declarations: [ ...DECLARATIONS, diff --git a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.spec.ts b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.spec.ts index fb43c253eb..ed61fab1d6 100644 --- a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.spec.ts +++ b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.spec.ts @@ -16,10 +16,10 @@ import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { getMockScrollToService } from '../../shared/mocks/scroll-to-service.mock'; -import { UploaderService } from '../../shared/uploader/uploader.service'; +import { DragService } from '../../core/drag.service'; import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; -import { UploaderComponent } from '../../shared/uploader/uploader.component'; +import { UploaderComponent } from '../../shared/upload/uploader/uploader.component'; import { HttpXsrfTokenExtractor } from '@angular/common/http'; import { CookieService } from '../../core/services/cookie.service'; import { CookieServiceMock } from '../../shared/mocks/cookie.service.mock'; @@ -59,7 +59,7 @@ describe('MyDSpaceNewSubmissionComponent test', () => { NgbModal, ChangeDetectorRef, MyDSpaceNewSubmissionComponent, - UploaderService, + DragService, { provide: HttpXsrfTokenExtractor, useValue: new HttpXsrfTokenExtractorMock('mock-token') }, { provide: CookieService, useValue: new CookieServiceMock() }, { provide: HostWindowService, useValue: new HostWindowServiceStub(800) }, diff --git a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.ts b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.ts index b2ba6fe2af..0694fc63bf 100644 --- a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.ts +++ b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission.component.ts @@ -8,13 +8,13 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { AuthService } from '../../core/auth/auth.service'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; -import { UploaderOptions } from '../../shared/uploader/uploader-options.model'; +import { UploaderOptions } from '../../shared/upload/uploader/uploader-options.model'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { hasValue } from '../../shared/empty.util'; import { SearchResult } from '../../shared/search/models/search-result.model'; import { CollectionSelectorComponent } from '../collection-selector/collection-selector.component'; -import { UploaderComponent } from '../../shared/uploader/uploader.component'; -import { UploaderError } from '../../shared/uploader/uploader-error.model'; +import { UploaderComponent } from '../../shared/upload/uploader/uploader.component'; +import { UploaderError } from '../../shared/upload/uploader/uploader-error.model'; import { Router } from '@angular/router'; /** diff --git a/src/app/my-dspace-page/my-dspace-page.module.ts b/src/app/my-dspace-page/my-dspace-page.module.ts index 2ccddd87f7..6ad50af96a 100644 --- a/src/app/my-dspace-page/my-dspace-page.module.ts +++ b/src/app/my-dspace-page/my-dspace-page.module.ts @@ -14,6 +14,7 @@ import { MyDSpaceNewSubmissionDropdownComponent } from './my-dspace-new-submissi import { MyDSpaceNewExternalDropdownComponent } from './my-dspace-new-submission/my-dspace-new-external-dropdown/my-dspace-new-external-dropdown.component'; import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component'; import { SearchModule } from '../shared/search/search.module'; +import { UploadModule } from '../shared/upload/upload.module'; const DECLARATIONS = [ MyDSpacePageComponent, @@ -30,7 +31,8 @@ const DECLARATIONS = [ SharedModule, SearchModule, MyDspacePageRoutingModule, - MyDspaceSearchModule.withEntryComponents() + MyDspaceSearchModule.withEntryComponents(), + UploadModule, ], declarations: DECLARATIONS, providers: [ diff --git a/src/app/shared/comcol/comcol-forms/comcol-form/comcol-form.component.ts b/src/app/shared/comcol/comcol-forms/comcol-form/comcol-form.component.ts index 29be240753..23dfca8616 100644 --- a/src/app/shared/comcol/comcol-forms/comcol-form/comcol-form.component.ts +++ b/src/app/shared/comcol/comcol-forms/comcol-form/comcol-form.component.ts @@ -17,8 +17,8 @@ import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.mod import { ResourceType } from '../../../../core/shared/resource-type'; import { hasValue, isNotEmpty } from '../../../empty.util'; import { NotificationsService } from '../../../notifications/notifications.service'; -import { UploaderOptions } from '../../../uploader/uploader-options.model'; -import { UploaderComponent } from '../../../uploader/uploader.component'; +import { UploaderOptions } from '../../../upload/uploader/uploader-options.model'; +import { UploaderComponent } from '../../../upload/uploader/uploader.component'; import { Operation } from 'fast-json-patch'; import { NoContent } from '../../../../core/shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../../../../core/shared/operators'; diff --git a/src/app/shared/comcol/comcol.module.ts b/src/app/shared/comcol/comcol.module.ts index 094387929a..efbcedf2c6 100644 --- a/src/app/shared/comcol/comcol.module.ts +++ b/src/app/shared/comcol/comcol.module.ts @@ -15,6 +15,7 @@ import { ThemedComcolPageBrowseByComponent } from './comcol-page-browse-by/theme import { ComcolRoleComponent } from './comcol-forms/edit-comcol-page/comcol-role/comcol-role.component'; import { SharedModule } from '../shared.module'; import { FormModule } from '../form/form.module'; +import { UploadModule } from '../upload/upload.module'; const COMPONENTS = [ ComcolPageContentComponent, @@ -28,9 +29,7 @@ const COMPONENTS = [ ComcolPageBrowseByComponent, ThemedComcolPageBrowseByComponent, ComcolRoleComponent, - ThemedComcolPageHandleComponent - ]; @NgModule({ @@ -40,10 +39,12 @@ const COMPONENTS = [ imports: [ CommonModule, FormModule, - SharedModule + SharedModule, + UploadModule, ], exports: [ - ...COMPONENTS + ...COMPONENTS, + UploadModule, ] }) export class ComcolModule { } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index a47712f261..9569faeee3 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -17,7 +17,6 @@ import { } from '@ng-bootstrap/ng-bootstrap'; import { MissingTranslationHandler, TranslateModule } from '@ngx-translate/core'; import { NgxPaginationModule } from 'ngx-pagination'; -import { FileUploadModule } from 'ng2-file-upload'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { MomentModule } from 'ngx-moment'; import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component'; @@ -30,7 +29,6 @@ import { import { ImportBatchSelectorComponent } from './dso-selector/modal-wrappers/import-batch-selector/import-batch-selector.component'; -import { FileDropzoneNoUploaderComponent } from './file-dropzone-no-uploader/file-dropzone-no-uploader.component'; import { ItemListElementComponent } from './object-list/item-list-element/item-types/item/item-list-element.component'; import { EnumKeysPipe } from './utils/enum-keys-pipe'; import { FileSizePipe } from './utils/file-size-pipe'; @@ -73,7 +71,6 @@ import { TruncatePipe } from './utils/truncate.pipe'; import { TruncatableComponent } from './truncatable/truncatable.component'; import { TruncatableService } from './truncatable/truncatable.service'; import { TruncatablePartComponent } from './truncatable/truncatable-part/truncatable-part.component'; -import { UploaderComponent } from './uploader/uploader.component'; import { MockAdminGuard } from './mocks/admin-guard.service.mock'; import { AlertComponent } from './alert/alert.component'; import { @@ -322,7 +319,6 @@ import { GoogleRecaptchaModule } from '../core/google-recaptcha/google-recaptcha const MODULES = [ CommonModule, - FileUploadModule, FormsModule, InfiniteScrollModule, NgbNavModule, @@ -393,8 +389,6 @@ const COMPONENTS = [ SidebarFilterComponent, SidebarFilterSelectedOptionComponent, ThumbnailComponent, - UploaderComponent, - FileDropzoneNoUploaderComponent, ItemListPreviewComponent, ThemedItemListPreviewComponent, MyDSpaceItemStatusComponent, @@ -479,7 +473,6 @@ const COMPONENTS = [ ImportBatchSelectorComponent, ExportBatchSelectorComponent, ConfirmationModalComponent, - VocabularyTreeviewComponent, AuthorizedCollectionSelectorComponent, CurationFormComponent, SearchResultListElementComponent, @@ -560,7 +553,6 @@ const ENTRY_COMPONENTS = [ ImportBatchSelectorComponent, ExportBatchSelectorComponent, ConfirmationModalComponent, - VocabularyTreeviewComponent, SidebarSearchListElementComponent, PublicationSidebarSearchListElementComponent, CollectionSidebarSearchListElementComponent, diff --git a/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.html b/src/app/shared/upload/file-dropzone-no-uploader/file-dropzone-no-uploader.component.html similarity index 100% rename from src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.html rename to src/app/shared/upload/file-dropzone-no-uploader/file-dropzone-no-uploader.component.html diff --git a/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts b/src/app/shared/upload/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts similarity index 100% rename from src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts rename to src/app/shared/upload/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts diff --git a/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.scss b/src/app/shared/upload/file-dropzone-no-uploader/file-dropzone-no-uploader.scss similarity index 100% rename from src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.scss rename to src/app/shared/upload/file-dropzone-no-uploader/file-dropzone-no-uploader.scss diff --git a/src/app/shared/upload/upload.module.ts b/src/app/shared/upload/upload.module.ts new file mode 100644 index 0000000000..9f2895d7ac --- /dev/null +++ b/src/app/shared/upload/upload.module.ts @@ -0,0 +1,38 @@ +/** + * 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/ + */ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SharedModule } from '../shared.module'; +import { FileUploadModule } from 'ng2-file-upload'; +import { UploaderComponent } from './uploader/uploader.component'; +import { FileDropzoneNoUploaderComponent } from './file-dropzone-no-uploader/file-dropzone-no-uploader.component'; + +const COMPONENTS = [ + UploaderComponent, + FileDropzoneNoUploaderComponent, +]; + +@NgModule({ + imports: [ + CommonModule, + SharedModule, + FileUploadModule, + ], + declarations: [ + ...COMPONENTS, + ], + providers: [ + ...COMPONENTS, + ], + exports: [ + ...COMPONENTS, + FileUploadModule, + ] +}) +export class UploadModule { +} diff --git a/src/app/shared/uploader/uploader-error.model.ts b/src/app/shared/upload/uploader/uploader-error.model.ts similarity index 100% rename from src/app/shared/uploader/uploader-error.model.ts rename to src/app/shared/upload/uploader/uploader-error.model.ts diff --git a/src/app/shared/uploader/uploader-options.model.ts b/src/app/shared/upload/uploader/uploader-options.model.ts similarity index 86% rename from src/app/shared/uploader/uploader-options.model.ts rename to src/app/shared/upload/uploader/uploader-options.model.ts index 959e5c3295..559fb0485b 100644 --- a/src/app/shared/uploader/uploader-options.model.ts +++ b/src/app/shared/upload/uploader/uploader-options.model.ts @@ -1,4 +1,4 @@ -import { RestRequestMethod } from '../../core/data/rest-request-method'; +import { RestRequestMethod } from '../../../core/data/rest-request-method'; export class UploaderOptions { /** diff --git a/src/app/shared/uploader/uploader-properties.model.ts b/src/app/shared/upload/uploader/uploader-properties.model.ts similarity index 83% rename from src/app/shared/uploader/uploader-properties.model.ts rename to src/app/shared/upload/uploader/uploader-properties.model.ts index bc0376b809..b84ae30bf8 100644 --- a/src/app/shared/uploader/uploader-properties.model.ts +++ b/src/app/shared/upload/uploader/uploader-properties.model.ts @@ -1,4 +1,4 @@ -import { MetadataMap } from '../../core/shared/metadata.models'; +import { MetadataMap } from '../../../core/shared/metadata.models'; /** * Properties to send to the REST API for uploading a bitstream diff --git a/src/app/shared/uploader/uploader.component.html b/src/app/shared/upload/uploader/uploader.component.html similarity index 100% rename from src/app/shared/uploader/uploader.component.html rename to src/app/shared/upload/uploader/uploader.component.html diff --git a/src/app/shared/uploader/uploader.component.scss b/src/app/shared/upload/uploader/uploader.component.scss similarity index 100% rename from src/app/shared/uploader/uploader.component.scss rename to src/app/shared/upload/uploader/uploader.component.scss diff --git a/src/app/shared/uploader/uploader.component.spec.ts b/src/app/shared/upload/uploader/uploader.component.spec.ts similarity index 86% rename from src/app/shared/uploader/uploader.component.spec.ts rename to src/app/shared/upload/uploader/uploader.component.spec.ts index 84fee2e147..8ea23c8acb 100644 --- a/src/app/shared/uploader/uploader.component.spec.ts +++ b/src/app/shared/upload/uploader/uploader.component.spec.ts @@ -4,16 +4,16 @@ import { ComponentFixture, inject, TestBed, waitForAsync, } from '@angular/core/ import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; -import { UploaderService } from './uploader.service'; +import { DragService } from '../../../core/drag.service'; import { UploaderOptions } from './uploader-options.model'; import { UploaderComponent } from './uploader.component'; import { FileUploadModule } from 'ng2-file-upload'; import { TranslateModule } from '@ngx-translate/core'; -import { createTestComponent } from '../testing/utils.test'; +import { createTestComponent } from '../../testing/utils.test'; import { HttpXsrfTokenExtractor } from '@angular/common/http'; -import { CookieService } from '../../core/services/cookie.service'; -import { CookieServiceMock } from '../mocks/cookie.service.mock'; -import { HttpXsrfTokenExtractorMock } from '../mocks/http-xsrf-token-extractor.mock'; +import { CookieService } from '../../../core/services/cookie.service'; +import { CookieServiceMock } from '../../mocks/cookie.service.mock'; +import { HttpXsrfTokenExtractorMock } from '../../mocks/http-xsrf-token-extractor.mock'; describe('Chips component', () => { @@ -37,7 +37,7 @@ describe('Chips component', () => { ChangeDetectorRef, ScrollToService, UploaderComponent, - UploaderService, + DragService, { provide: HttpXsrfTokenExtractor, useValue: new HttpXsrfTokenExtractorMock('mock-token') }, { provide: CookieService, useValue: new CookieServiceMock() }, ], diff --git a/src/app/shared/uploader/uploader.component.ts b/src/app/shared/upload/uploader/uploader.component.ts similarity index 93% rename from src/app/shared/uploader/uploader.component.ts rename to src/app/shared/upload/uploader/uploader.component.ts index a0dd0e5bba..50e7478157 100644 --- a/src/app/shared/uploader/uploader.component.ts +++ b/src/app/shared/upload/uploader/uploader.component.ts @@ -6,12 +6,12 @@ import { uniqueId } from 'lodash'; import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; import { UploaderOptions } from './uploader-options.model'; -import { hasValue, isNotEmpty, isUndefined } from '../empty.util'; -import { UploaderService } from './uploader.service'; +import { hasValue, isNotEmpty, isUndefined } from '../../empty.util'; import { UploaderProperties } from './uploader-properties.model'; import { HttpXsrfTokenExtractor } from '@angular/common/http'; -import { XSRF_COOKIE, XSRF_REQUEST_HEADER, XSRF_RESPONSE_HEADER } from '../../core/xsrf/xsrf.interceptor'; -import { CookieService } from '../../core/services/cookie.service'; +import { XSRF_COOKIE, XSRF_REQUEST_HEADER, XSRF_RESPONSE_HEADER } from '../../../core/xsrf/xsrf.interceptor'; +import { CookieService } from '../../../core/services/cookie.service'; +import { DragService } from '../../../core/drag.service'; @Component({ selector: 'ds-uploader', @@ -76,7 +76,7 @@ export class UploaderComponent { @HostListener('window:dragover', ['$event']) onDragOver(event: any) { - if (this.enableDragOverDocument && this.uploaderService.isAllowedDragOverPage()) { + if (this.enableDragOverDocument && this.dragService.isAllowedDragOverPage()) { // Show drop area on the page event.preventDefault(); if ((event.target as any).tagName !== 'HTML') { @@ -85,9 +85,13 @@ export class UploaderComponent { } } - constructor(private cdr: ChangeDetectorRef, private scrollToService: ScrollToService, - private uploaderService: UploaderService, private tokenExtractor: HttpXsrfTokenExtractor, - private cookieService: CookieService) { + constructor( + private cdr: ChangeDetectorRef, + private scrollToService: ScrollToService, + private dragService: DragService, + private tokenExtractor: HttpXsrfTokenExtractor, + private cookieService: CookieService + ) { } /** diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index 6c17be0c71..42ee9f05ac 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -10,7 +10,7 @@ import { SubmissionObject } from '../../core/submission/models/submission-object import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; -import { UploaderOptions } from '../../shared/uploader/uploader-options.model'; +import { UploaderOptions } from '../../shared/upload/uploader/uploader-options.model'; import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; import { SectionDataObject } from '../sections/models/section-data.model'; import { SubmissionService } from '../submission.service'; diff --git a/src/app/submission/form/submission-upload-files/submission-upload-files.component.spec.ts b/src/app/submission/form/submission-upload-files/submission-upload-files.component.spec.ts index bcdd01d5a1..fa7ecebbff 100644 --- a/src/app/submission/form/submission-upload-files/submission-upload-files.component.spec.ts +++ b/src/app/submission/form/submission-upload-files/submission-upload-files.component.spec.ts @@ -28,7 +28,7 @@ import { SubmissionJsonPatchOperationsServiceStub } from '../../../shared/testin import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; import { SharedModule } from '../../../shared/shared.module'; import { createTestComponent } from '../../../shared/testing/utils.test'; -import { UploaderOptions } from '../../../shared/uploader/uploader-options.model'; +import { UploaderOptions } from '../../../shared/upload/uploader/uploader-options.model'; describe('SubmissionUploadFilesComponent Component', () => { diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index 0324ea345a..cab4f19c33 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -60,6 +60,7 @@ import { PublisherPolicyComponent } from './sections/sherpa-policies/publisher-p import { PublicationInformationComponent } from './sections/sherpa-policies/publication-information/publication-information.component'; +import { UploadModule } from '../shared/upload/upload.module'; import { MetadataInformationComponent } from './sections/sherpa-policies/metadata-information/metadata-information.component'; @@ -115,7 +116,8 @@ const DECLARATIONS = [ FormModule, NgbModalModule, NgbCollapseModule, - NgbAccordionModule + NgbAccordionModule, + UploadModule, ], declarations: DECLARATIONS, exports: [ From 9e731909ae523a4b352dc3913a3a3c2b0426e396 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 23 Nov 2022 19:39:18 +0100 Subject: [PATCH 10/14] 96252: Move menu support code to MenuModule --- src/app/shared/menu/menu.module.ts | 11 ++++++++--- src/app/shared/shared.module.ts | 10 ++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/app/shared/menu/menu.module.ts b/src/app/shared/menu/menu.module.ts index 1d186a9b7d..c007af517d 100644 --- a/src/app/shared/menu/menu.module.ts +++ b/src/app/shared/menu/menu.module.ts @@ -12,8 +12,11 @@ import { ExternalLinkMenuItemComponent } from './menu-item/external-link-menu-it const COMPONENTS = [ MenuSectionComponent, MenuComponent, - LinkMenuItemComponent, +]; + +const ENTRY_COMPONENTS = [ TextMenuItemComponent, + LinkMenuItemComponent, OnClickMenuItemComponent, ExternalLinkMenuItemComponent, ]; @@ -32,10 +35,12 @@ const PROVIDERS = [ ...MODULES ], declarations: [ - ...COMPONENTS + ...COMPONENTS, + ...ENTRY_COMPONENTS, ], providers: [ - ...PROVIDERS + ...PROVIDERS, + ...ENTRY_COMPONENTS, ], exports: [ ...COMPONENTS diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 9569faeee3..cf2b6ef167 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -285,9 +285,6 @@ import { MetadataRepresentationListComponent } from '../item-page/simple/metadata-representation-list/metadata-representation-list.component'; import { RelatedItemsComponent } from '../item-page/simple/related-items/related-items-component'; -import { LinkMenuItemComponent } from './menu/menu-item/link-menu-item.component'; -import { OnClickMenuItemComponent } from './menu/menu-item/onclick-menu-item.component'; -import { TextMenuItemComponent } from './menu/menu-item/text-menu-item.component'; import { SearchNavbarComponent } from '../search-navbar/search-navbar.component'; import { ThemedSearchNavbarComponent } from '../search-navbar/themed-search-navbar.component'; import { @@ -304,7 +301,6 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; -import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; import { DsoPageOrcidButtonComponent } from './dso-page/dso-page-orcid-button/dso-page-orcid-button.component'; import { LogInOrcidComponent } from './log-in/methods/orcid/log-in-orcid.component'; import { BrowserOnlyPipe } from './utils/browser-only.pipe'; @@ -316,6 +312,7 @@ import { } from '../item-page/simple/field-components/specific-field/title/item-page-title-field.component'; import { MarkdownPipe } from './utils/markdown.pipe'; import { GoogleRecaptchaModule } from '../core/google-recaptcha/google-recaptcha.module'; +import { MenuModule } from './menu/menu.module'; const MODULES = [ CommonModule, @@ -336,6 +333,7 @@ const MODULES = [ DragDropModule, CdkTreeModule, GoogleRecaptchaModule, + MenuModule, ]; const ROOT_MODULES = [ @@ -557,11 +555,7 @@ const ENTRY_COMPONENTS = [ PublicationSidebarSearchListElementComponent, CollectionSidebarSearchListElementComponent, CommunitySidebarSearchListElementComponent, - LinkMenuItemComponent, - OnClickMenuItemComponent, - TextMenuItemComponent, ScopeSelectorModalComponent, - ExternalLinkMenuItemComponent ]; const SHARED_ITEM_PAGE_COMPONENTS = [ From d0c74ed49f6f8141eb8cf415f3db0834b37cc65e Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 23 Nov 2022 20:43:31 +0100 Subject: [PATCH 11/14] 96252: Clean up SharedModule & CoreModule --- src/app/app.module.ts | 1 - src/app/core/core.module.ts | 2 - src/app/shared/shared.module.ts | 65 ++------------------------------- 3 files changed, 3 insertions(+), 65 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2fba48c8b2..750d63beda 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,7 +1,6 @@ import { APP_BASE_HREF, CommonModule, DOCUMENT } from '@angular/common'; import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; -import { AbstractControl } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 491d394e73..6790d9a3bb 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -2,7 +2,6 @@ import { CommonModule } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; -import { DynamicFormLayoutService, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { EffectsModule } from '@ngrx/effects'; import { Action, StoreConfig, StoreModule } from '@ngrx/store'; @@ -23,7 +22,6 @@ import { ObjectSelectService } from '../shared/object-select/object-select.servi import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { CSSVariableService } from '../shared/sass-helper/sass-helper.service'; import { SidebarService } from '../shared/sidebar/sidebar.service'; -import { SectionFormOperationsService } from '../submission/sections/form/section-form-operations.service'; import { AuthenticatedGuard } from './auth/authenticated.guard'; import { AuthStatus } from './auth/models/auth-status.model'; import { BrowseService } from './browse/browse.service'; diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index cf2b6ef167..5e3742e5b9 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -394,10 +394,6 @@ const COMPONENTS = [ ItemDetailPreviewComponent, ItemDetailPreviewFieldComponent, ClaimedTaskActionsComponent, - ClaimedTaskActionsApproveComponent, - ClaimedTaskActionsRejectComponent, - ClaimedTaskActionsReturnToPoolComponent, - ClaimedTaskActionsEditMetadataComponent, ClaimedTaskActionsLoaderComponent, ItemActionsComponent, PoolTaskActionsComponent, @@ -412,87 +408,30 @@ const COMPONENTS = [ ValidationSuggestionsComponent, DsoInputSuggestionsComponent, DSOSelectorComponent, - CreateCommunityParentSelectorComponent, - ThemedCreateCommunityParentSelectorComponent, - CreateCollectionParentSelectorComponent, - ThemedCreateCollectionParentSelectorComponent, - CreateItemParentSelectorComponent, - ThemedCreateItemParentSelectorComponent, - EditCommunitySelectorComponent, - ThemedEditCommunitySelectorComponent, - EditCollectionSelectorComponent, - ThemedEditCollectionSelectorComponent, - EditItemSelectorComponent, - ThemedEditItemSelectorComponent, - CommunitySearchResultListElementComponent, - CollectionSearchResultListElementComponent, - BrowseByComponent, - - CollectionSearchResultGridElementComponent, - CommunitySearchResultGridElementComponent, SearchExportCsvComponent, PageSizeSelectorComponent, ListableObjectComponentLoaderComponent, - CollectionListElementComponent, - CommunityListElementComponent, - CollectionGridElementComponent, - CommunityGridElementComponent, - BrowseByComponent, AbstractTrackableComponent, ComcolMetadataComponent, TypeBadgeComponent, AccessStatusBadgeComponent, - BrowseByComponent, - AbstractTrackableComponent, - ItemSelectComponent, CollectionSelectComponent, MetadataRepresentationLoaderComponent, SelectableListItemControlComponent, - ImportableListItemControlComponent, - - LogInShibbolethComponent, - LogInOidcComponent, - LogInOrcidComponent, - LogInPasswordComponent, LogInContainerComponent, ItemVersionsComponent, - ItemSearchResultListElementComponent, ItemVersionsNoticeComponent, ModifyItemOverviewComponent, ImpersonateNavbarComponent, - FileDownloadLinkComponent, - BitstreamDownloadPageComponent, - BitstreamRequestACopyPageComponent, - CollectionDropdownComponent, EntityDropdownComponent, ExportMetadataSelectorComponent, ImportBatchSelectorComponent, ExportBatchSelectorComponent, ConfirmationModalComponent, AuthorizedCollectionSelectorComponent, - CurationFormComponent, - SearchResultListElementComponent, - SearchResultGridElementComponent, - ItemListElementComponent, - ItemGridElementComponent, - ItemSearchResultGridElementComponent, - BrowseEntryListElementComponent, - SearchResultDetailElementComponent, - PlainTextMetadataListElementComponent, - ItemMetadataListElementComponent, - MetadataRepresentationListElementComponent, - ItemMetadataRepresentationListElementComponent, - BundleListElementComponent, - StartsWithDateComponent, - StartsWithTextComponent, - SidebarSearchListElementComponent, - PublicationSidebarSearchListElementComponent, - CollectionSidebarSearchListElementComponent, - CommunitySidebarSearchListElementComponent, SearchNavbarComponent, - ScopeSelectorModalComponent, ItemPageTitleFieldComponent, ThemedSearchNavbarComponent, ]; @@ -605,6 +544,7 @@ const DIRECTIVES = [ declarations: [ ...PIPES, ...COMPONENTS, + ...ENTRY_COMPONENTS, ...DIRECTIVES, ...SHARED_ITEM_PAGE_COMPONENTS, ItemVersionsSummaryModalComponent, @@ -617,9 +557,10 @@ const DIRECTIVES = [ ...MODULES, ...PIPES, ...COMPONENTS, + ...ENTRY_COMPONENTS, ...SHARED_ITEM_PAGE_COMPONENTS, ...DIRECTIVES, - TranslateModule + TranslateModule, ] }) From 95d5a2ff74c55b99e81d50a390e8209d95c54cbf Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 23 Nov 2022 20:33:20 +0100 Subject: [PATCH 12/14] 96252: Make Klaro lazy-loaded --- .../shared/cookies/browser-klaro.service.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index c6819012d9..2bb9a696bc 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -1,5 +1,4 @@ -import { Injectable } from '@angular/core'; -import * as Klaro from 'klaro'; +import { Inject, Injectable, InjectionToken } from '@angular/core'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { AuthService } from '../../core/auth/auth.service'; import { TranslateService } from '@ngx-translate/core'; @@ -42,6 +41,17 @@ const cookiePurposeMessagePrefix = 'cookies.consent.purpose.'; */ const updateDebounce = 300; +/** + * By using this injection token instead of importing directly we can keep Klaro out of the main bundle + */ +const LAZY_KLARO = new InjectionToken>( + 'Lazily loaded Klaro', + { + providedIn: 'root', + factory: async () => (await import('klaro')), + } +); + /** * Browser implementation for the KlaroService, representing a service for handling Klaro consent preferences and UI */ @@ -64,7 +74,9 @@ export class BrowserKlaroService extends KlaroService { private authService: AuthService, private ePersonService: EPersonDataService, private configService: ConfigurationDataService, - private cookieService: CookieService) { + private cookieService: CookieService, + @Inject(LAZY_KLARO) private lazyKlaro: Promise, + ) { super(); } @@ -134,8 +146,7 @@ export class BrowserKlaroService extends KlaroService { this.translateConfiguration(); this.klaroConfig.services = this.filterConfigServices(servicesToHide); - - Klaro.setup(this.klaroConfig); + this.lazyKlaro.then(({ setup }) => setup(this.klaroConfig)); }); } @@ -219,7 +230,7 @@ export class BrowserKlaroService extends KlaroService { * Show the cookie consent form */ showSettings() { - Klaro.show(this.klaroConfig); + this.lazyKlaro.then(({show}) => show(this.klaroConfig)); } /** From 492344e6bd07adb140560967644e8dd72f91ed4b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 8 Dec 2022 14:32:27 -0600 Subject: [PATCH 13/14] Spin up UI and REST on 127.0.0.1 --- .github/workflows/build.yml | 8 +++++--- docker/docker-compose-ci.yml | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 44dd883f78..f3b7aff689 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,10 +15,12 @@ jobs: env: # 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_HOST: 127.0.0.1 DSPACE_REST_PORT: 8080 DSPACE_REST_NAMESPACE: '/server' DSPACE_REST_SSL: false + # Spin up UI on 127.0.0.1 to avoid host resolution issues in e2e tests with Node 18+ + DSPACE_UI_HOST: 127.0.0.1 # When Chrome version is specified, we pin to a specific version of Chrome # Comment this out to use the latest release #CHROME_VERSION: "90.0.4430.212-1" @@ -147,7 +149,7 @@ jobs: run: | nohup yarn run serve:ssr & printf 'Waiting for app to start' - until curl --output /dev/null --silent --head --fail http://localhost:4000/home; do + until curl --output /dev/null --silent --head --fail http://127.0.0.1:4000/home; do printf '.' sleep 2 done @@ -158,7 +160,7 @@ jobs: # This step also prints entire HTML of homepage for easier debugging if grep fails. - name: Verify SSR (server-side rendering) run: | - result=$(wget -O- -q http://localhost:4000/home) + result=$(wget -O- -q http://127.0.0.1:4000/home) echo "$result" echo "$result" | grep -oE "]*>" | grep DSpace diff --git a/docker/docker-compose-ci.yml b/docker/docker-compose-ci.yml index dbe9500499..ef84c14f43 100644 --- a/docker/docker-compose-ci.yml +++ b/docker/docker-compose-ci.yml @@ -24,8 +24,8 @@ services: # __D__ => "-" (e.g. google__D__metadata => google-metadata) # dspace.dir, dspace.server.url and dspace.ui.url dspace__P__dir: /dspace - dspace__P__server__P__url: http://localhost:8080/server - dspace__P__ui__P__url: http://localhost:4000 + dspace__P__server__P__url: http://127.0.0.1:8080/server + dspace__P__ui__P__url: http://127.0.0.1:4000 # db.url: Ensure we are using the 'dspacedb' image for our database db__P__url: 'jdbc:postgresql://dspacedb:5432/dspace' # solr.server: Ensure we are using the 'dspacesolr' image for Solr From 70d2d20f0603507823864eddc244eec08fa27e66 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 9 Dec 2022 12:14:57 -0600 Subject: [PATCH 14/14] Update Dockerfile to use Node 18 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a7c1640d0b..8eb3582ba3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # This image will be published as dspace/dspace-angular # See https://github.com/DSpace/dspace-angular/tree/main/docker for usage details -FROM node:14-alpine +FROM node:18-alpine WORKDIR /app ADD . /app/ EXPOSE 4000