geonetwork-ui 2.4.0-dev.6c8dcba0 → 2.4.0-dev.9c5250ea
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/index.mjs +2 -1
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.mjs +2 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +1 -1
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.mjs +1 -1
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +1 -1
- package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +14 -5
- package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.mjs +11 -3
- package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +34 -14
- package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
- package/esm2022/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.mjs +1 -1
- package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
- package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
- package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +4 -4
- package/esm2022/libs/feature/dataviz/src/lib/feature-dataviz.module.mjs +7 -4
- package/esm2022/libs/feature/dataviz/src/lib/table-view/table-view.component.mjs +1 -1
- package/esm2022/libs/feature/editor/src/lib/+state/editor.actions.mjs +2 -1
- package/esm2022/libs/feature/editor/src/lib/+state/editor.effects.mjs +6 -4
- package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +2 -1
- package/esm2022/libs/feature/editor/src/lib/+state/editor.selectors.mjs +2 -2
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.mjs +57 -0
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +64 -50
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +17 -35
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/index.mjs +2 -1
- package/esm2022/libs/feature/editor/src/lib/feature-editor.module.mjs +4 -3
- package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +8 -1
- package/esm2022/libs/feature/editor/src/lib/services/editor.service.mjs +12 -6
- package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +7 -4
- package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +3 -3
- package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +4 -11
- package/esm2022/libs/feature/search/src/index.mjs +2 -2
- package/esm2022/libs/feature/search/src/lib/feature-search.module.mjs +7 -4
- package/esm2022/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.mjs +3 -3
- package/esm2022/libs/feature/search/src/lib/results-table/results-table-container.component.mjs +49 -0
- package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +4 -4
- package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +3 -3
- package/esm2022/libs/ui/inputs/src/index.mjs +2 -1
- package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +59 -26
- package/esm2022/libs/ui/inputs/src/lib/badge/badge.component.mjs +28 -0
- package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +11 -10
- package/esm2022/libs/ui/search/src/index.mjs +2 -1
- package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +120 -0
- package/esm2022/libs/ui/widgets/src/index.mjs +1 -2
- package/esm2022/libs/ui/widgets/src/lib/popup-alert/popup-alert.component.mjs +5 -3
- package/esm2022/libs/ui/widgets/src/lib/ui-widgets.module.mjs +1 -6
- package/esm2022/translations/de.json +8 -1
- package/esm2022/translations/en.json +8 -1
- package/esm2022/translations/es.json +8 -1
- package/esm2022/translations/fr.json +8 -1
- package/esm2022/translations/it.json +8 -1
- package/esm2022/translations/nl.json +8 -1
- package/esm2022/translations/pt.json +8 -1
- package/fesm2022/geonetwork-ui.mjs +702 -494
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/api/metadata-converter/src/lib/gn4/types/index.d.ts +1 -0
- package/libs/api/metadata-converter/src/lib/gn4/types/index.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.d.ts +31 -0
- package/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +3 -2
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.d.ts +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +3 -2
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
- package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +1 -0
- package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
- package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts +3 -3
- package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts.map +1 -1
- package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +8 -5
- package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +4 -7
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
- package/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.d.ts +12 -5
- package/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.d.ts.map +1 -1
- package/libs/common/domain/src/lib/platform.service.interface.d.ts +3 -3
- package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
- package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +3 -1
- package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/feature-dataviz.module.d.ts +2 -1
- package/libs/feature/dataviz/src/lib/feature-dataviz.module.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/+state/editor.actions.d.ts +1 -0
- package/libs/feature/editor/src/lib/+state/editor.actions.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/+state/editor.effects.d.ts +1 -1
- package/libs/feature/editor/src/lib/+state/editor.effects.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +1 -0
- package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.d.ts +25 -0
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.d.ts.map +1 -0
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +6 -6
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +6 -10
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/index.d.ts +1 -0
- package/libs/feature/editor/src/lib/components/record-form/form-field/index.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/feature-editor.module.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/services/editor.service.d.ts +1 -1
- package/libs/feature/editor/src/lib/services/editor.service.d.ts.map +1 -1
- package/libs/feature/record/src/lib/feature-record.module.d.ts +2 -1
- package/libs/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
- package/libs/feature/search/src/index.d.ts +1 -1
- package/libs/feature/search/src/index.d.ts.map +1 -1
- package/libs/feature/search/src/lib/feature-search.module.d.ts +2 -1
- package/libs/feature/search/src/lib/feature-search.module.d.ts.map +1 -1
- package/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.d.ts.map +1 -1
- package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts +25 -0
- package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts.map +1 -0
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts +1 -1
- package/libs/ui/inputs/src/index.d.ts +1 -0
- package/libs/ui/inputs/src/index.d.ts.map +1 -1
- package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts +7 -4
- package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts.map +1 -1
- package/libs/ui/inputs/src/lib/badge/badge.component.d.ts +11 -0
- package/libs/ui/inputs/src/lib/badge/badge.component.d.ts.map +1 -0
- package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +35 -35
- package/libs/ui/search/src/index.d.ts +1 -0
- package/libs/ui/search/src/index.d.ts.map +1 -1
- package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +30 -0
- package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -0
- package/libs/ui/widgets/src/index.d.ts +0 -1
- package/libs/ui/widgets/src/index.d.ts.map +1 -1
- package/libs/ui/widgets/src/lib/popup-alert/popup-alert.component.d.ts +1 -1
- package/libs/ui/widgets/src/lib/popup-alert/popup-alert.component.d.ts.map +1 -1
- package/libs/ui/widgets/src/lib/ui-widgets.module.d.ts +10 -11
- package/libs/ui/widgets/src/lib/ui-widgets.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/libs/api/metadata-converter/src/lib/gn4/types/index.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.ts +31 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +2 -2
- package/src/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.ts +1 -1
- package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +2 -2
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +21 -8
- package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts +24 -3
- package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +70 -21
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +4 -9
- package/src/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.ts +13 -6
- package/src/libs/common/domain/src/lib/platform.service.interface.ts +3 -3
- package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +4 -1
- package/src/libs/common/fixtures/src/lib/records.fixtures.ts +8 -0
- package/src/libs/feature/dataviz/src/lib/feature-dataviz.module.ts +2 -1
- package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +2 -0
- package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +35 -29
- package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +1 -0
- package/src/libs/feature/editor/src/lib/+state/editor.selectors.ts +1 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.html +19 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.ts +77 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +95 -86
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +7 -22
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +16 -44
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/index.ts +1 -1
- package/src/libs/feature/editor/src/lib/feature-editor.module.ts +2 -1
- package/src/libs/feature/editor/src/lib/fields.config.ts +7 -0
- package/src/libs/feature/editor/src/lib/services/editor.service.ts +20 -6
- package/src/libs/feature/record/src/lib/feature-record.module.ts +3 -2
- package/src/libs/feature/record/src/lib/state/mdview.facade.ts +38 -31
- package/src/libs/feature/search/src/index.ts +1 -1
- package/src/libs/feature/search/src/lib/feature-search.module.ts +2 -1
- package/src/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.ts +2 -2
- package/src/libs/feature/search/src/lib/results-table/results-table-container.component.html +9 -0
- package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +49 -0
- package/src/libs/ui/elements/src/lib/ui-elements.module.ts +2 -2
- package/src/libs/ui/inputs/src/index.ts +1 -0
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.css +0 -1
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +23 -19
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +79 -27
- package/src/libs/ui/inputs/src/lib/badge/badge.component.css +0 -0
- package/src/libs/ui/inputs/src/lib/badge/badge.component.html +18 -0
- package/src/libs/ui/inputs/src/lib/badge/badge.component.ts +27 -0
- package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +3 -3
- package/src/libs/ui/search/src/index.ts +1 -0
- package/src/libs/ui/search/src/lib/results-table/results-table.component.css +0 -0
- package/src/libs/{feature → ui}/search/src/lib/results-table/results-table.component.html +8 -8
- package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +138 -0
- package/src/libs/ui/widgets/src/index.ts +0 -1
- package/src/libs/ui/widgets/src/lib/popup-alert/popup-alert.component.ts +4 -0
- package/src/libs/ui/widgets/src/lib/ui-widgets.module.ts +0 -3
- package/translations/de.json +8 -1
- package/translations/en.json +8 -1
- package/translations/es.json +8 -1
- package/translations/fr.json +8 -1
- package/translations/it.json +8 -1
- package/translations/nl.json +8 -1
- package/translations/pt.json +8 -1
- package/translations/sk.json +8 -1
- package/esm2022/libs/feature/search/src/lib/results-table/results-table.component.mjs +0 -136
- package/esm2022/libs/ui/widgets/src/lib/badge/badge.component.mjs +0 -18
- package/libs/feature/search/src/lib/results-table/results-table.component.d.ts +0 -36
- package/libs/feature/search/src/lib/results-table/results-table.component.d.ts.map +0 -1
- package/libs/ui/widgets/src/lib/badge/badge.component.d.ts +0 -7
- package/libs/ui/widgets/src/lib/badge/badge.component.d.ts.map +0 -1
- package/src/libs/feature/search/src/lib/results-table/results-table.component.ts +0 -172
- package/src/libs/ui/widgets/src/lib/badge/badge.component.html +0 -10
- package/src/libs/ui/widgets/src/lib/badge/badge.component.ts +0 -14
- /package/src/libs/feature/{search/src/lib/results-table/results-table.component.css → editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.css} +0 -0
- /package/src/libs/{ui/widgets/src/lib/badge/badge.component.css → feature/search/src/lib/results-table/results-table-container.component.css} +0 -0
|
@@ -8,11 +8,16 @@ import { Injectable } from '@angular/core'
|
|
|
8
8
|
import { AvatarServiceInterface } from '../auth'
|
|
9
9
|
import { map } from 'rxjs/operators'
|
|
10
10
|
import { Observable, of } from 'rxjs'
|
|
11
|
-
import { ThesaurusModel } from '../../../../../../../libs/common/domain/src/lib/model/thesaurus/thesaurus.model'
|
|
12
11
|
import {
|
|
12
|
+
Keyword,
|
|
13
13
|
UserFeedback,
|
|
14
14
|
UserFeedbackViewModel,
|
|
15
15
|
} from '../../../../../../../libs/common/domain/src/lib/model/record'
|
|
16
|
+
import {
|
|
17
|
+
KeywordApiResponse,
|
|
18
|
+
ThesaurusApiResponse,
|
|
19
|
+
} from '../../../../../../../libs/api/metadata-converter/src'
|
|
20
|
+
import { KeywordType } from '../../../../../../../libs/common/domain/src/lib/model/thesaurus'
|
|
16
21
|
|
|
17
22
|
@Injectable()
|
|
18
23
|
export class Gn4PlatformMapper {
|
|
@@ -52,8 +57,12 @@ export class Gn4PlatformMapper {
|
|
|
52
57
|
return { ...apiUser, id: id.toString() } as UserModel
|
|
53
58
|
}
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
keywordsFromApi(
|
|
61
|
+
keywords: KeywordApiResponse[],
|
|
62
|
+
thesaurus: ThesaurusApiResponse[],
|
|
63
|
+
lang3?: string
|
|
64
|
+
): Keyword[] {
|
|
65
|
+
return keywords.map((keyword): Keyword => {
|
|
57
66
|
let key = keyword.uri
|
|
58
67
|
// sometines GN can prefix an URI with an "all thesaurus" URI; only keep the last one
|
|
59
68
|
if (key.indexOf('@@@') > -1) {
|
|
@@ -65,10 +74,22 @@ export class Gn4PlatformMapper {
|
|
|
65
74
|
lang3 && lang3 in keyword.definitions
|
|
66
75
|
? keyword.definitions[lang3]
|
|
67
76
|
: keyword.definition
|
|
77
|
+
|
|
78
|
+
const matchedThesaurus = thesaurus.find(
|
|
79
|
+
(thes) => keyword.thesaurusKey === thes.key
|
|
80
|
+
)
|
|
81
|
+
|
|
68
82
|
return {
|
|
69
83
|
key,
|
|
70
84
|
label,
|
|
71
85
|
description,
|
|
86
|
+
type: matchedThesaurus?.dname as KeywordType,
|
|
87
|
+
thesaurus: {
|
|
88
|
+
id: matchedThesaurus?.key,
|
|
89
|
+
name: matchedThesaurus?.title,
|
|
90
|
+
url: new URL(matchedThesaurus?.url),
|
|
91
|
+
type: matchedThesaurus?.dname as KeywordType,
|
|
92
|
+
},
|
|
72
93
|
}
|
|
73
94
|
})
|
|
74
95
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core'
|
|
2
|
-
import { Observable, of, switchMap } from 'rxjs'
|
|
2
|
+
import { Observable, combineLatest, of, switchMap } from 'rxjs'
|
|
3
3
|
import { catchError, map, shareReplay, tap } from 'rxjs/operators'
|
|
4
4
|
import {
|
|
5
5
|
MeApiService,
|
|
6
6
|
RegistriesApiService,
|
|
7
7
|
SiteApiService,
|
|
8
|
+
ThesaurusInfoApiModel,
|
|
8
9
|
ToolsApiService,
|
|
9
10
|
UserfeedbackApiService,
|
|
10
11
|
UsersApiService,
|
|
@@ -12,13 +13,18 @@ import {
|
|
|
12
13
|
import { PlatformServiceInterface } from '../../../../../../../libs/common/domain/src/lib/platform.service.interface'
|
|
13
14
|
import { UserModel } from '../../../../../../../libs/common/domain/src/lib/model/user/user.model'
|
|
14
15
|
import {
|
|
16
|
+
Keyword,
|
|
15
17
|
Organization,
|
|
16
18
|
UserFeedback,
|
|
17
19
|
} from '../../../../../../../libs/common/domain/src/lib/model/record'
|
|
18
20
|
import { Gn4PlatformMapper } from './gn4-platform.mapper'
|
|
19
21
|
import { ltr } from 'semver'
|
|
20
|
-
import { ThesaurusModel } from '../../../../../../../libs/common/domain/src/lib/model/thesaurus/thesaurus.model'
|
|
21
22
|
import { LangService } from '../../../../../../../libs/util/i18n/src'
|
|
23
|
+
import { HttpClient } from '@angular/common/http'
|
|
24
|
+
import {
|
|
25
|
+
KeywordApiResponse,
|
|
26
|
+
ThesaurusApiResponse,
|
|
27
|
+
} from '../../../../../../../libs/api/metadata-converter/src'
|
|
22
28
|
|
|
23
29
|
const minApiVersion = '4.2.2'
|
|
24
30
|
|
|
@@ -60,7 +66,7 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
60
66
|
* A map of already loaded thesauri (groups of keywords); the key is a URI
|
|
61
67
|
* @private
|
|
62
68
|
*/
|
|
63
|
-
private
|
|
69
|
+
private keywordsByThesauri: Record<string, Observable<Keyword[]>> = {}
|
|
64
70
|
|
|
65
71
|
constructor(
|
|
66
72
|
private siteApiService: SiteApiService,
|
|
@@ -70,7 +76,8 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
70
76
|
private toolsApiService: ToolsApiService,
|
|
71
77
|
private registriesApiService: RegistriesApiService,
|
|
72
78
|
private langService: LangService,
|
|
73
|
-
private userfeedbackApiService: UserfeedbackApiService
|
|
79
|
+
private userfeedbackApiService: UserfeedbackApiService,
|
|
80
|
+
private httpClient: HttpClient
|
|
74
81
|
) {
|
|
75
82
|
this.me$ = this.meApi.getMe().pipe(
|
|
76
83
|
switchMap((apiUser) => this.mapper.userFromMeApi(apiUser)),
|
|
@@ -121,7 +128,7 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
121
128
|
// the thesaurus URI is inferred by removing a part of the keyword URI
|
|
122
129
|
// this is not exact science but it's OK, we'll still end up loading a bunch of keywords at once anyway
|
|
123
130
|
const thesaurusUri = key.replace(/\/([^/]+)$/, '/')
|
|
124
|
-
return this.
|
|
131
|
+
return this.getKeywordsByUri(thesaurusUri).pipe(
|
|
125
132
|
map((thesaurus) => {
|
|
126
133
|
for (const item of thesaurus) {
|
|
127
134
|
if (item.key === key) return item.label
|
|
@@ -133,12 +140,49 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
133
140
|
return this.keyTranslations$.pipe(map((translations) => translations[key]))
|
|
134
141
|
}
|
|
135
142
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
private allThesaurus$ = this.httpClient
|
|
144
|
+
.get(
|
|
145
|
+
`${this.registriesApiService.configuration.basePath}/thesaurus?_content_type=json`
|
|
146
|
+
)
|
|
147
|
+
.pipe(
|
|
148
|
+
map((thesaurus) => {
|
|
149
|
+
// FIXME: find a better way to exclude place keywords
|
|
150
|
+
// thesaurus[0].filter((thes) => thes.dname !== 'place')
|
|
151
|
+
return thesaurus[0] as ThesaurusApiResponse[]
|
|
152
|
+
}),
|
|
153
|
+
shareReplay(1)
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
searchKeywords(query: string): Observable<Keyword[]> {
|
|
157
|
+
const keywords$: Observable<KeywordApiResponse[]> =
|
|
158
|
+
this.registriesApiService.searchKeywords(
|
|
159
|
+
query,
|
|
160
|
+
this.langService.iso3,
|
|
161
|
+
10,
|
|
162
|
+
0,
|
|
163
|
+
null,
|
|
164
|
+
null,
|
|
165
|
+
null,
|
|
166
|
+
`*${query}*`
|
|
167
|
+
) as Observable<KeywordApiResponse[]>
|
|
168
|
+
|
|
169
|
+
return combineLatest([keywords$, this.allThesaurus$]).pipe(
|
|
170
|
+
map(([keywords, thesaurus]) => {
|
|
171
|
+
return this.mapper.keywordsFromApi(
|
|
172
|
+
keywords,
|
|
173
|
+
thesaurus,
|
|
174
|
+
this.langService.iso3
|
|
175
|
+
)
|
|
176
|
+
})
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
getKeywordsByUri(uri: string): Observable<Keyword[]> {
|
|
181
|
+
if (this.keywordsByThesauri[uri]) {
|
|
182
|
+
return this.keywordsByThesauri[uri]
|
|
139
183
|
}
|
|
140
|
-
|
|
141
|
-
.searchKeywords(
|
|
184
|
+
const keywords$: Observable<KeywordApiResponse[]> =
|
|
185
|
+
this.registriesApiService.searchKeywords(
|
|
142
186
|
null,
|
|
143
187
|
this.langService.iso3,
|
|
144
188
|
1000,
|
|
@@ -147,18 +191,23 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
147
191
|
null,
|
|
148
192
|
null,
|
|
149
193
|
`${uri}*`
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
194
|
+
) as Observable<KeywordApiResponse[]>
|
|
195
|
+
|
|
196
|
+
this.keywordsByThesauri[uri] = combineLatest([
|
|
197
|
+
keywords$,
|
|
198
|
+
this.allThesaurus$,
|
|
199
|
+
]).pipe(
|
|
200
|
+
map(([keywords, thesaurus]) => {
|
|
201
|
+
return this.mapper.keywordsFromApi(
|
|
202
|
+
keywords,
|
|
203
|
+
thesaurus,
|
|
204
|
+
this.langService.iso3
|
|
205
|
+
)
|
|
206
|
+
}),
|
|
207
|
+
shareReplay(1)
|
|
208
|
+
)
|
|
160
209
|
|
|
161
|
-
return this.
|
|
210
|
+
return this.keywordsByThesauri[uri]
|
|
162
211
|
}
|
|
163
212
|
|
|
164
213
|
getUserFeedbacks(uuid: string): Observable<UserFeedback[]> {
|
|
@@ -2,6 +2,7 @@ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
|
|
|
2
2
|
import type { Individual } from './contact.model'
|
|
3
3
|
import type { Organization } from './organization.model'
|
|
4
4
|
import type { Geometry } from 'geojson'
|
|
5
|
+
import { KeywordType, ThesaurusModel } from '../thesaurus'
|
|
5
6
|
|
|
6
7
|
type Uuid = string
|
|
7
8
|
|
|
@@ -60,18 +61,12 @@ export type SpatialRepresentationType =
|
|
|
60
61
|
| 'table'
|
|
61
62
|
| 'point'
|
|
62
63
|
|
|
63
|
-
export type KeywordType = 'place' | 'temporal' | 'theme' | 'other'
|
|
64
|
-
|
|
65
|
-
export type KeywordThesaurus = {
|
|
66
|
-
id: string
|
|
67
|
-
name?: string
|
|
68
|
-
url?: URL
|
|
69
|
-
}
|
|
70
|
-
|
|
71
64
|
export interface Keyword {
|
|
65
|
+
key?: string
|
|
72
66
|
label: string
|
|
67
|
+
description?: string
|
|
73
68
|
type: KeywordType
|
|
74
|
-
thesaurus?:
|
|
69
|
+
thesaurus?: ThesaurusModel
|
|
75
70
|
}
|
|
76
71
|
// languages should be expressed using two-letters ISO 639-1 codes
|
|
77
72
|
export type LanguageCode = string
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
export
|
|
2
|
-
key: string
|
|
3
|
-
label: string
|
|
4
|
-
description?: string
|
|
5
|
-
}
|
|
1
|
+
export type KeywordType = 'place' | 'temporal' | 'theme' | 'other'
|
|
6
2
|
|
|
7
|
-
export
|
|
3
|
+
export interface ThesaurusModel {
|
|
4
|
+
id: string
|
|
5
|
+
name?: string
|
|
6
|
+
url?: URL
|
|
7
|
+
thesaurusKey?: string
|
|
8
|
+
definition?: string
|
|
9
|
+
definitions?: object
|
|
10
|
+
uri?: string
|
|
11
|
+
value?: string
|
|
12
|
+
values?: object
|
|
13
|
+
type?: KeywordType
|
|
14
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { Observable } from 'rxjs'
|
|
2
2
|
import type { UserModel } from './model/user/user.model'
|
|
3
3
|
import type { Organization } from './model/record/organization.model'
|
|
4
|
-
import
|
|
5
|
-
import { UserFeedback } from './model/record'
|
|
4
|
+
import { Keyword, UserFeedback } from './model/record'
|
|
6
5
|
|
|
7
6
|
export abstract class PlatformServiceInterface {
|
|
8
7
|
abstract getType(): string
|
|
@@ -16,7 +15,8 @@ export abstract class PlatformServiceInterface {
|
|
|
16
15
|
): Observable<UserModel[]>
|
|
17
16
|
abstract getOrganizations(): Observable<Organization[]>
|
|
18
17
|
abstract translateKey(key: string): Observable<string>
|
|
19
|
-
abstract
|
|
18
|
+
abstract searchKeywords(query: string): Observable<Keyword[]>
|
|
19
|
+
abstract getKeywordsByUri(uri: string): Observable<Keyword[]>
|
|
20
20
|
abstract getUserFeedbacks(recordUuid: string): Observable<UserFeedback[]>
|
|
21
21
|
abstract postUserFeedbacks(recordUuid: UserFeedback): Observable<void>
|
|
22
22
|
}
|
|
@@ -33,7 +33,7 @@ export abstract class RecordsRepositoryInterface {
|
|
|
33
33
|
/**
|
|
34
34
|
* @param record
|
|
35
35
|
* @param referenceRecordSource
|
|
36
|
-
* @returns Observable<string> Returns the
|
|
36
|
+
* @returns Observable<string> Returns the unique identifier of the record as it was when saved
|
|
37
37
|
*/
|
|
38
38
|
abstract saveRecord(
|
|
39
39
|
record: CatalogRecord,
|
|
@@ -52,4 +52,7 @@ export abstract class RecordsRepositoryInterface {
|
|
|
52
52
|
|
|
53
53
|
abstract clearRecordDraft(uniqueIdentifier: string): void
|
|
54
54
|
abstract recordHasDraft(uniqueIdentifier: string): boolean
|
|
55
|
+
|
|
56
|
+
/** will return all pending drafts, both published and not published */
|
|
57
|
+
abstract getAllDrafts(): Observable<CatalogRecord[]>
|
|
55
58
|
}
|
|
@@ -233,6 +233,14 @@ Malgré l'attention portée à la création de ces données, il est rappelé que
|
|
|
233
233
|
description: 'Téléchargement du fichier',
|
|
234
234
|
mimeType: 'x-gis/x-shapefile',
|
|
235
235
|
},
|
|
236
|
+
{
|
|
237
|
+
type: 'service',
|
|
238
|
+
url: new URL('https://my-org.net/ogc'),
|
|
239
|
+
accessServiceProtocol: 'ogcFeatures',
|
|
240
|
+
name: 'ogcFeaturesSecondRecord',
|
|
241
|
+
description: 'This OGC service is the second part of the download',
|
|
242
|
+
identifierInService: 'my:featuretype',
|
|
243
|
+
},
|
|
236
244
|
],
|
|
237
245
|
lineage: `Document d’urbanisme numérisé conformément aux prescriptions nationales du CNIG par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.
|
|
238
246
|
Ce lot de données produit en 2019, a été numérisé à partir du PCI Vecteur de 2019 et contrôlé par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.`,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import { TableViewComponent } from './table-view/table-view.component'
|
|
13
13
|
import { ChartViewComponent } from './chart-view/chart-view.component'
|
|
14
14
|
import { TranslateModule } from '@ngx-translate/core'
|
|
15
|
-
import { UiWidgetsModule } from '../../../../../libs/ui/widgets/src'
|
|
15
|
+
import { PopupAlertComponent, UiWidgetsModule } from '../../../../../libs/ui/widgets/src'
|
|
16
16
|
import { UiInputsModule } from '../../../../../libs/ui/inputs/src'
|
|
17
17
|
|
|
18
18
|
@NgModule({
|
|
@@ -26,6 +26,7 @@ import { UiInputsModule } from '../../../../../libs/ui/inputs/src'
|
|
|
26
26
|
TranslateModule,
|
|
27
27
|
ChartComponent,
|
|
28
28
|
UiInputsModule,
|
|
29
|
+
PopupAlertComponent,
|
|
29
30
|
],
|
|
30
31
|
declarations: [
|
|
31
32
|
GeoTableViewComponent,
|
|
@@ -5,7 +5,11 @@ import { catchError, map, switchMap } from 'rxjs/operators'
|
|
|
5
5
|
import * as EditorActions from './editor.actions'
|
|
6
6
|
import { EditorService } from '../services/editor.service'
|
|
7
7
|
import { Store } from '@ngrx/store'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
selectRecord,
|
|
10
|
+
selectRecordAlreadySavedOnce,
|
|
11
|
+
selectRecordFieldsConfig,
|
|
12
|
+
} from './editor.selectors'
|
|
9
13
|
import { RecordsRepositoryInterface } from '../../../../../../libs/common/domain/src/lib/repository/records-repository.interface'
|
|
10
14
|
|
|
11
15
|
@Injectable()
|
|
@@ -20,28 +24,31 @@ export class EditorEffects {
|
|
|
20
24
|
ofType(EditorActions.saveRecord),
|
|
21
25
|
withLatestFrom(
|
|
22
26
|
this.store.select(selectRecord),
|
|
23
|
-
this.store.select(selectRecordFieldsConfig)
|
|
27
|
+
this.store.select(selectRecordFieldsConfig),
|
|
28
|
+
this.store.select(selectRecordAlreadySavedOnce)
|
|
24
29
|
),
|
|
25
|
-
switchMap(([, record, fieldsConfig]) =>
|
|
26
|
-
this.editorService
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
switchMap(([, record, fieldsConfig, alreadySavedOnce]) =>
|
|
31
|
+
this.editorService
|
|
32
|
+
.saveRecord(record, fieldsConfig, !alreadySavedOnce)
|
|
33
|
+
.pipe(
|
|
34
|
+
switchMap(([record, recordSource]) =>
|
|
35
|
+
of(
|
|
36
|
+
EditorActions.saveRecordSuccess(),
|
|
37
|
+
EditorActions.openRecord({
|
|
38
|
+
record,
|
|
39
|
+
alreadySavedOnce: true,
|
|
40
|
+
recordSource,
|
|
41
|
+
})
|
|
42
|
+
)
|
|
43
|
+
),
|
|
44
|
+
catchError((error) =>
|
|
45
|
+
of(
|
|
46
|
+
EditorActions.saveRecordFailure({
|
|
47
|
+
error: error.message,
|
|
48
|
+
})
|
|
49
|
+
)
|
|
42
50
|
)
|
|
43
51
|
)
|
|
44
|
-
)
|
|
45
52
|
)
|
|
46
53
|
)
|
|
47
54
|
)
|
|
@@ -53,15 +60,14 @@ export class EditorEffects {
|
|
|
53
60
|
)
|
|
54
61
|
)
|
|
55
62
|
|
|
56
|
-
saveRecordDraft$ = createEffect(
|
|
57
|
-
(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
{ dispatch: false }
|
|
63
|
+
saveRecordDraft$ = createEffect(() =>
|
|
64
|
+
this.actions$.pipe(
|
|
65
|
+
ofType(EditorActions.updateRecordField),
|
|
66
|
+
debounceTime(1000),
|
|
67
|
+
withLatestFrom(this.store.select(selectRecord)),
|
|
68
|
+
switchMap(([, record]) => this.editorService.saveRecordAsDraft(record)),
|
|
69
|
+
map(() => EditorActions.draftSaveSuccess())
|
|
70
|
+
)
|
|
65
71
|
)
|
|
66
72
|
|
|
67
73
|
checkHasChangesOnOpen$ = createEffect(() =>
|
|
@@ -26,6 +26,7 @@ export class EditorFacade {
|
|
|
26
26
|
select(EditorSelectors.selectRecordChangedSinceSave)
|
|
27
27
|
)
|
|
28
28
|
recordFields$ = this.store.pipe(select(EditorSelectors.selectRecordFields))
|
|
29
|
+
draftSaveSuccess$ = this.actions$.pipe(ofType(EditorActions.draftSaveSuccess))
|
|
29
30
|
|
|
30
31
|
openRecord(
|
|
31
32
|
record: CatalogRecord,
|
|
@@ -44,6 +44,6 @@ export const selectRecordFields = createSelector(
|
|
|
44
44
|
(state: EditorState) =>
|
|
45
45
|
state.fieldsConfig.map((fieldConfig) => ({
|
|
46
46
|
config: fieldConfig,
|
|
47
|
-
value: state.record?.[fieldConfig.model]
|
|
47
|
+
value: state.record?.[fieldConfig.model] ?? null,
|
|
48
48
|
}))
|
|
49
49
|
)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div class="flex flex-col gap-3">
|
|
2
|
+
<gn-ui-autocomplete
|
|
3
|
+
[placeholder]="'Search for keywords in all thesaurus'"
|
|
4
|
+
[displayWithFn]="displayWithFn"
|
|
5
|
+
[action]="autoCompleteAction"
|
|
6
|
+
(itemSelected)="handleItemSelection($event)"
|
|
7
|
+
[clearOnSelection]="true"
|
|
8
|
+
[minCharacterCount]="0"
|
|
9
|
+
[allowSubmit]="false"
|
|
10
|
+
></gn-ui-autocomplete>
|
|
11
|
+
<div class="flex gap-2 flex-wrap">
|
|
12
|
+
<gn-ui-badge
|
|
13
|
+
*ngFor="let keyword of control.value; let index = index"
|
|
14
|
+
[removable]="true"
|
|
15
|
+
(badgeRemoveClicked)="removeKeyword(index)"
|
|
16
|
+
>{{ keyword.label }}</gn-ui-badge
|
|
17
|
+
>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common'
|
|
2
|
+
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
|
3
|
+
import { FormControl } from '@angular/forms'
|
|
4
|
+
import { PlatformServiceInterface } from '../../../../../../../../../libs/common/domain/src/lib/platform.service.interface'
|
|
5
|
+
import {
|
|
6
|
+
AutocompleteComponent,
|
|
7
|
+
DropdownSelectorComponent,
|
|
8
|
+
UiInputsModule,
|
|
9
|
+
} from '../../../../../../../../../libs/ui/inputs/src'
|
|
10
|
+
import { UiWidgetsModule } from '../../../../../../../../../libs/ui/widgets/src'
|
|
11
|
+
import { map } from 'rxjs'
|
|
12
|
+
import { Keyword } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
|
|
13
|
+
|
|
14
|
+
type AutocompleteItem = { title: string; value: Keyword }
|
|
15
|
+
|
|
16
|
+
@Component({
|
|
17
|
+
selector: 'gn-ui-form-field-keywords',
|
|
18
|
+
templateUrl: './form-field-keywords.component.html',
|
|
19
|
+
styleUrls: ['./form-field-keywords.component.css'],
|
|
20
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21
|
+
standalone: true,
|
|
22
|
+
imports: [
|
|
23
|
+
DropdownSelectorComponent,
|
|
24
|
+
UiInputsModule,
|
|
25
|
+
CommonModule,
|
|
26
|
+
UiWidgetsModule,
|
|
27
|
+
AutocompleteComponent,
|
|
28
|
+
],
|
|
29
|
+
})
|
|
30
|
+
export class FormFieldKeywordsComponent {
|
|
31
|
+
@Input() control: FormControl<Keyword[]>
|
|
32
|
+
|
|
33
|
+
displayWithFn = (item: AutocompleteItem) => {
|
|
34
|
+
return `${item.title} (${item.value.thesaurus?.name})`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
autoCompleteAction = (query: string) => {
|
|
38
|
+
return this.platformService.searchKeywords(query).pipe(
|
|
39
|
+
map((keywords) =>
|
|
40
|
+
keywords.map((keyword) => {
|
|
41
|
+
return { title: keyword.label, value: keyword }
|
|
42
|
+
})
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
constructor(private platformService: PlatformServiceInterface) {}
|
|
48
|
+
|
|
49
|
+
handleItemSelection(item: AutocompleteItem) {
|
|
50
|
+
this.addKeyword(item.value)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
addKeyword(keyword: Keyword) {
|
|
54
|
+
const addedKeywords = [...this.control.value, keyword]
|
|
55
|
+
|
|
56
|
+
// remove duplicates from keyword
|
|
57
|
+
const filteredKeywords = addedKeywords.filter((value, index, self) => {
|
|
58
|
+
return (
|
|
59
|
+
index ===
|
|
60
|
+
self.findIndex(
|
|
61
|
+
(t) =>
|
|
62
|
+
t?.label === value?.label &&
|
|
63
|
+
t?.thesaurus?.id === value?.thesaurus?.id &&
|
|
64
|
+
t?.type === value?.type
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
this.control.setValue(filteredKeywords)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
removeKeyword(index: number) {
|
|
73
|
+
const removeKeywords = this.control.value.filter((_, i) => i !== index)
|
|
74
|
+
|
|
75
|
+
this.control.setValue(removeKeywords)
|
|
76
|
+
}
|
|
77
|
+
}
|