@eeacms/volto-globalsearch 0.1.0

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.
Files changed (60) hide show
  1. package/.coverage.babel.config.js +9 -0
  2. package/.eslintignore +1 -0
  3. package/.project.eslintrc.js +46 -0
  4. package/.release-it.json +17 -0
  5. package/CHANGELOG.md +26 -0
  6. package/DEVELOP.md +52 -0
  7. package/LICENSE.md +9 -0
  8. package/README.md +106 -0
  9. package/RELEASE.md +74 -0
  10. package/babel.config.js +17 -0
  11. package/bootstrap +41 -0
  12. package/cypress.json +17 -0
  13. package/jest-addon.config.js +36 -0
  14. package/locales/volto.pot +0 -0
  15. package/package.json +47 -0
  16. package/src/components/LogoImage.jsx +16 -0
  17. package/src/components/MasonryLandingPage.jsx +277 -0
  18. package/src/components/WebsiteFilterListComponent.jsx +14 -0
  19. package/src/components/img/content-types-bg.png +0 -0
  20. package/src/components/img/countries-bg.png +0 -0
  21. package/src/components/img/organisations-bg.png +0 -0
  22. package/src/components/img/search-album-slideshow-bg.png +0 -0
  23. package/src/components/img/topics-bg.png +0 -0
  24. package/src/config/clusters.js +172 -0
  25. package/src/config/download.js +20 -0
  26. package/src/config/facets.js +298 -0
  27. package/src/config/filters.js +15 -0
  28. package/src/config/global-search-config.js +118 -0
  29. package/src/config/index.js +92 -0
  30. package/src/config/json/contentTypeNormalize.json +56 -0
  31. package/src/config/json/objectProvidesWhitelist.json +56 -0
  32. package/src/config/json/placesBlacklist.json +268 -0
  33. package/src/config/json/spatialWhitelist.json +264 -0
  34. package/src/config/json/topicsBlacklist.json +1 -0
  35. package/src/config/json/typesWhitelist.json +49 -0
  36. package/src/config/query.js +44 -0
  37. package/src/config/views.js +157 -0
  38. package/src/config/vocabulary.js +59 -0
  39. package/src/index.js +13 -0
  40. package/src/static/bise-logo.png +0 -0
  41. package/src/static/climate-adapt-logo.png +0 -0
  42. package/src/static/eea-logo.png +0 -0
  43. package/src/static/eionet-logo.png +0 -0
  44. package/src/static/energy-logo.png +0 -0
  45. package/src/static/etc-atni.png +0 -0
  46. package/src/static/etc-bd.jpg +0 -0
  47. package/src/static/etc-cca.jpeg +0 -0
  48. package/src/static/etc-cme.png +0 -0
  49. package/src/static/etc-icm.jpg +0 -0
  50. package/src/static/etc-uls.png +0 -0
  51. package/src/static/etc-wmge.png +0 -0
  52. package/src/static/forest-logo.png +0 -0
  53. package/src/static/ias-logo.png +0 -0
  54. package/src/static/industry-logo.png +0 -0
  55. package/src/static/water-logo.png +0 -0
  56. package/src/static/website-logo.png +0 -0
  57. package/src/static/wise-logo.png +0 -0
  58. package/src/styles/masonry-landing-page.less +145 -0
  59. package/src/styles/tiles-landing-page.less +0 -0
  60. package/src/utils.js +250 -0
@@ -0,0 +1,298 @@
1
+ import {
2
+ booleanFacet,
3
+ dateRangeFacet,
4
+ fixedRangeFacet,
5
+ histogramFacet,
6
+ makeRange,
7
+ multiTermFacet,
8
+ } from '@eeacms/search';
9
+ import spatialWhitelist from './json/spatialWhitelist.json';
10
+ import placesBlacklist from './json/placesBlacklist.json';
11
+ import topicsBlacklist from './json/topicsBlacklist.json';
12
+ import { getTodayWithTime } from '../utils';
13
+
14
+ const facets = [
15
+ booleanFacet(() => ({
16
+ field: 'IncludeArchived',
17
+ label: 'Include archived content',
18
+ id: 'archived-facet',
19
+ showInFacetsList: false,
20
+ showInSecondaryFacetsList: true,
21
+ isFilter: true, // filters don't need facet options to show up
22
+
23
+ // we want this to be applied by default
24
+ // when the facet is checked, then apply the `on` key:
25
+ off: {
26
+ constant_score: {
27
+ filter: {
28
+ bool: {
29
+ should: [
30
+ { bool: { must_not: { exists: { field: 'expires' } } } },
31
+ // Functions should be supported in the buildFilters
32
+ { range: { expires: { gte: getTodayWithTime() } } },
33
+ ],
34
+ },
35
+ },
36
+ },
37
+ },
38
+ on: null,
39
+ })),
40
+ multiTermFacet({
41
+ field: 'moreLikeThis',
42
+ isFilterable: true,
43
+ isMulti: false,
44
+ label: 'More like this',
45
+ showInFacetsList: false,
46
+ filterListComponent: 'MoreLikeThisEntry',
47
+ factory: 'MoreLikeThis',
48
+ condition: 'like',
49
+ queryParams: {
50
+ fields: ['title', 'text'],
51
+ min_term_freq: 1,
52
+ max_query_terms: 12,
53
+ },
54
+
55
+ // registryConfig: 'MoreLikeThis',
56
+ }),
57
+ multiTermFacet({
58
+ field: 'topic',
59
+ isFilterable: true,
60
+ isMulti: true,
61
+ label: 'Topics',
62
+ blacklist: topicsBlacklist,
63
+ factory: 'MultiTermListFacet',
64
+ wrapper: 'ModalFacetWrapper',
65
+ show: 10000,
66
+ showAllOptions: true, // show all options (even if 0) in modal facet
67
+ // factory: 'sui.Facet',
68
+ }),
69
+ multiTermFacet({
70
+ field: 'spatial',
71
+ isFilterable: true,
72
+ isMulti: true,
73
+ label: 'Countries',
74
+ whitelist: spatialWhitelist,
75
+ wrapper: 'ModalFacetWrapper',
76
+ show: 10000,
77
+ factory: 'MultiTermListFacet',
78
+ iconsFamily: 'Countries',
79
+ enableExact: true,
80
+ sortOn: 'value',
81
+ }),
82
+ multiTermFacet({
83
+ field: 'op_cluster',
84
+ isFilterable: true,
85
+ isMulti: true,
86
+ label: 'Section',
87
+ wrapper: 'ModalFacetWrapper',
88
+ show: 10000,
89
+ factory: 'MultiTermListFacet',
90
+ showInFacetsList: false,
91
+ }),
92
+
93
+ multiTermFacet({
94
+ field: 'places',
95
+ isFilterable: true,
96
+ isMulti: true,
97
+ label: 'Regions/Places/Cities/Seas...',
98
+ blacklist: placesBlacklist,
99
+ wrapper: 'ModalFacetWrapper',
100
+ show: 10000,
101
+ factory: 'MultiTermListFacet',
102
+ showAllOptions: true, // show all options (even if 0) in modal facet
103
+ }),
104
+ multiTermFacet({
105
+ field: 'objectProvides',
106
+ isFilterable: false,
107
+ isMulti: true,
108
+ label: 'Content types',
109
+ iconsFamily: 'Content types',
110
+ //whitelist: objectProvidesWhitelist,
111
+ wrapper: 'ModalFacetWrapper',
112
+ factory: 'MultiTermListFacet',
113
+ optionsFilter: 'typesForClustersOptionsFilter',
114
+ }),
115
+ multiTermFacet({
116
+ field: 'cluster_name',
117
+ isFilterable: false,
118
+ isMulti: true,
119
+ label: 'Sources',
120
+ wrapper: 'ModalFacetWrapper',
121
+ factory: 'MultiTermListFacet',
122
+ iconsFamily: 'Sources',
123
+ }),
124
+ histogramFacet({
125
+ wrapper: 'ModalFacetWrapper',
126
+ field: 'year',
127
+ // isFilterable: false,
128
+ isMulti: true,
129
+ label: 'Publishing year',
130
+ // TODO: implement split in buckets
131
+ ranges: makeRange({
132
+ step: 1,
133
+ normalRange: [1994, 2022],
134
+ includeOutlierStart: false,
135
+ includeOutlierEnd: false,
136
+ }),
137
+ step: 10,
138
+ // [
139
+ // {
140
+ // to: 1900,
141
+ // },
142
+ // {
143
+ // key: '2001-2010',
144
+ // from: 2001,
145
+ // to: 2010,
146
+ // },
147
+ // {
148
+ // from: 2011,
149
+ // },
150
+ // ]
151
+ // min_max_script:
152
+ //
153
+ //"def vals = doc['year']; if (vals.length == 0){return 2000} else {def ret = [];for (val in vals){def tmp_val = val.substring(0,4);ret.add(tmp_val.toLowerCase() == tmp_val.toUpperCase() ? Integer.parseInt(tmp_val) : 2000);}return ret;}",
154
+
155
+ aggs_script:
156
+ "def vals = doc['year']; if (vals.length == 0){return 2500} else {def ret = [];for (val in vals){def tmp_val = val.substring(0,4);ret.add(tmp_val.toLowerCase() == tmp_val.toUpperCase() ? Integer.parseInt(tmp_val) : 2500);}return ret;}",
157
+ }),
158
+
159
+ histogramFacet({
160
+ wrapper: 'ModalFacetWrapper',
161
+ field: 'time_coverage',
162
+ // isFilterable: false,
163
+ isMulti: true,
164
+ label: 'Time coverage',
165
+ // TODO: implement split in buckets
166
+ ranges: makeRange({
167
+ step: 10,
168
+ normalRange: [1700, 2210],
169
+ includeOutlierStart: false,
170
+ includeOutlierEnd: false,
171
+ }),
172
+ step: 10,
173
+ // [
174
+ // {
175
+ // to: 1900,
176
+ // },
177
+ // {
178
+ // key: '2001-2010',
179
+ // from: 2001,
180
+ // to: 2010,
181
+ // },
182
+ // {
183
+ // from: 2011,
184
+ // },
185
+ // ]
186
+ // min_max_script:
187
+ //
188
+ //"def vals = doc['year']; if (vals.length == 0){return 2000} else {def ret = [];for (val in vals){def tmp_val = val.substring(0,4);ret.add(tmp_val.toLowerCase() == tmp_val.toUpperCase() ? Integer.parseInt(tmp_val) : 2000);}return ret;}",
189
+
190
+ aggs_script:
191
+ "def vals = doc['time_coverage']; if (vals.length == 0){return 2500} else {def ret = [];for (val in vals){def tmp_val = val.substring(0,4);ret.add(tmp_val.toLowerCase() == tmp_val.toUpperCase() ? Integer.parseInt(tmp_val) : 2500);}return ret;}",
192
+ }),
193
+
194
+ fixedRangeFacet({
195
+ wrapper: 'ModalFacetWrapper',
196
+ field: 'readingTime',
197
+ label: 'Reading time (minutes)',
198
+ rangeType: 'fixed',
199
+ isMulti: true,
200
+ ranges: [
201
+ { key: 'All' },
202
+ { from: 0, to: 4.99999, key: 'Short (<5 minutes)' },
203
+ { from: 5, to: 24.9999, key: 'Medium (5-25 minutes)' },
204
+ { from: 25, to: 10000, key: 'Large (25+ minutes)' },
205
+ // { to: -0.0001, key: 'Unknown' },
206
+ ],
207
+ factory: 'ModalFixedRangeFacet',
208
+ default: {
209
+ values: [{ name: 'All', rangeType: 'fixed' }],
210
+ type: 'any',
211
+ },
212
+ }),
213
+ dateRangeFacet({
214
+ field: 'issued.date',
215
+ label: ' ',
216
+ isFilter: true, // filters don't need facet options to show up
217
+ showInFacetsList: false,
218
+ showInSecondaryFacetsList: true,
219
+ // rangeType: 'dateRange',
220
+ isMulti: false,
221
+ ranges: [
222
+ { key: 'All time' },
223
+ { key: 'Last week', from: 'now-1w', to: 'now' },
224
+ { key: 'Last month', from: 'now-1m', to: 'now' },
225
+ { key: 'Last 3 months', from: 'now-3m', to: 'now' },
226
+ { key: 'Last year', from: 'now-1y', to: 'now' },
227
+ { key: 'Last 2 years', from: 'now-2y', to: 'now' },
228
+ ],
229
+ factory: 'DropdownRangeFilter',
230
+ default: {
231
+ values: ['All time'],
232
+ type: 'any',
233
+ },
234
+ }),
235
+ multiTermFacet({
236
+ wrapper: 'ModalFacetWrapper',
237
+ field: 'language',
238
+ isFilterable: false,
239
+ isMulti: true,
240
+ label: 'Language',
241
+ default: {
242
+ values: ['en'],
243
+ type: 'any',
244
+ },
245
+ factory: 'MultiTermListFacet',
246
+ facetValues: [
247
+ 'ar',
248
+ 'sr',
249
+ 'sq',
250
+ 'bg',
251
+ 'bs',
252
+ 'cs',
253
+ 'hr',
254
+ 'da',
255
+ 'nl',
256
+ 'el',
257
+ 'en',
258
+ 'et',
259
+ 'fi',
260
+ 'fr',
261
+ 'ga',
262
+ 'de',
263
+ 'hu',
264
+ 'is',
265
+ 'it',
266
+ 'lv',
267
+ 'lt',
268
+ 'mk',
269
+ 'mt',
270
+ 'no',
271
+ 'pl',
272
+ 'pt',
273
+ 'ro',
274
+ 'ru',
275
+ 'sh',
276
+ 'sk',
277
+ 'sl',
278
+ 'es',
279
+ 'sv',
280
+ 'tr',
281
+ ],
282
+ sortOn: 'custom',
283
+ sortOnCustomLabel: 'Alphabetical',
284
+ }),
285
+ ];
286
+
287
+ export default {
288
+ facets,
289
+ };
290
+
291
+ // default filter values
292
+ // TODO: this needs to be removed and the configuration plugged into each of
293
+ // the facets
294
+ // readingTime: {
295
+ // value: { name: 'All', rangeType: 'fixed' },
296
+ // type: 'any',
297
+ // },
298
+ // },
@@ -0,0 +1,15 @@
1
+ import { getTodayWithTime } from '../utils';
2
+
3
+ export default {
4
+ // filter values that are always added to the ES requests
5
+ permanentFilters: [
6
+ { term: { hasWorkflowState: 'published' } },
7
+ () => ({
8
+ constant_score: {
9
+ filter: {
10
+ range: { 'issued.date': { lte: getTodayWithTime() } },
11
+ },
12
+ },
13
+ }),
14
+ ],
15
+ };
@@ -0,0 +1,118 @@
1
+ import { build_runtime_mappings } from '../utils';
2
+ import clusterParams, { clusters } from './clusters';
3
+
4
+ import facets from './facets';
5
+ import views from './views';
6
+ import query from './query';
7
+ import filters from './filters';
8
+ import download from './download';
9
+ import vocabs from './vocabulary';
10
+
11
+ import objectProvidesWhitelist from './json/objectProvidesWhitelist.json';
12
+ import spatialWhitelist from './json/spatialWhitelist.json';
13
+ import placesBlacklist from './json/placesBlacklist.json';
14
+ import typesWhitelist from './json/typesWhitelist.json';
15
+
16
+ const globalSearchConfig = {
17
+ title: 'Global search and catalogue',
18
+ layoutComponent: 'FilterAsideLayout',
19
+ contentBodyComponent: 'FilterAsideContentView',
20
+ enableNLP: true, // enables NLP capabilities
21
+ facetsListComponent: 'VerticalCardsModalFacets',
22
+ runtime_mappings: build_runtime_mappings(clusters),
23
+ useSearchPhrases: false,
24
+ searchAsYouType: false,
25
+
26
+ ...vocabs,
27
+ ...facets,
28
+ ...views,
29
+ ...query,
30
+ ...filters,
31
+ ...download,
32
+ ...clusterParams,
33
+
34
+ sourceExcludedFields: ['embedding'], // don't need these in results
35
+ // 'fulltext',
36
+
37
+ // these are used to "clean" the values in the results.
38
+ field_filters: {
39
+ type: {
40
+ whitelist: typesWhitelist,
41
+ },
42
+ objectProvides: {
43
+ whitelist: objectProvidesWhitelist,
44
+ },
45
+ spatial: {
46
+ whitelist: spatialWhitelist,
47
+ },
48
+ places: {
49
+ blacklist: placesBlacklist,
50
+ },
51
+ },
52
+
53
+ highlight: {
54
+ queryParams: {
55
+ fragment_size: 200,
56
+ number_of_fragments: 3,
57
+ },
58
+ fields: ['description.highlight'],
59
+ queryBuilder: {
60
+ factory: 'highlightQueryBuilder',
61
+ },
62
+ },
63
+
64
+ sortOptions: [
65
+ {
66
+ name: 'Title a-z',
67
+ value: 'title.index',
68
+ direction: 'asc',
69
+ },
70
+ {
71
+ name: 'Title z-a',
72
+ value: 'title.index',
73
+ direction: 'desc',
74
+ },
75
+ {
76
+ name: 'Oldest',
77
+ value: 'issued.date',
78
+ direction: 'asc',
79
+ },
80
+ {
81
+ name: 'Newest',
82
+ value: 'issued.date',
83
+ direction: 'desc',
84
+ },
85
+ ],
86
+
87
+ defaultPromptQueries: [
88
+ 'what is the status of our forests',
89
+ 'what is PFAS?',
90
+ 'how does PFAS get into human?',
91
+ 'what is the cumulative surface area of the Natura 2000?',
92
+ 'what percentage of europe population is connected to waste water treatement?',
93
+ 'How is the status of fish species in Europe?',
94
+ 'What is the BISE?',
95
+ 'how much does transport contributes to GHG emissions in EU?',
96
+ 'Which cities in Europe have the worst air quality?',
97
+ 'What car is best for the environment?',
98
+ 'What transport mode is best for the environment?',
99
+ 'What EU legislation safeguards our water?',
100
+ 'What is land accounting?',
101
+ 'What countries had the highest land take in the EEA-39 between 2000 and 2018?',
102
+ 'Why is urban sprawl bad?',
103
+ 'what are controlled substances',
104
+ 'what is plastic',
105
+ 'What year did car manufacturers meet their binding emissions target?',
106
+ 'What is the percentage of surface water bodies with less than good status?',
107
+ 'What is the most common pollutant in water bodies in Europe?',
108
+ 'Where can I access greenhouse gas data',
109
+ 'What is the trend on greenhouse gas emissions from transport',
110
+ 'what is the best transport mode',
111
+ 'what are ecosystem services',
112
+ 'bathing water quality',
113
+ 'greenhouse gas emissions trends',
114
+ 'waste generation trends',
115
+ ],
116
+ };
117
+
118
+ export default globalSearchConfig;
@@ -0,0 +1,92 @@
1
+ import { suiFacet, mergeConfig } from '@eeacms/search';
2
+ import { getGlobalsearchThumbUrl, getGlobalsearchIconUrl } from './../utils';
3
+ import { typesForClustersOptionsFilter } from './clusters';
4
+
5
+ // import WebsiteFilterListComponent from './../components/WebsiteFilterListComponent';
6
+
7
+ import contentTypeNormalize from './json/contentTypeNormalize.json';
8
+ import globalSearchConfig from './global-search-config.js';
9
+
10
+ const getClientProxyAddress = () => {
11
+ const url = new URL(window.location);
12
+ url.pathname = '';
13
+ url.search = '';
14
+ return url.toString();
15
+ };
16
+
17
+ export default function install(config) {
18
+ // console.log(process.env.RAZZLE_ENV_CONFIG);
19
+ const envConfig = process.env.RAZZLE_ENV_CONFIG
20
+ ? JSON.parse(process.env.RAZZLE_ENV_CONFIG)
21
+ : globalSearchConfig;
22
+
23
+ const pjson = require('../../package.json');
24
+ envConfig.app_name = pjson.name;
25
+ envConfig.app_version = pjson.version;
26
+
27
+ config.searchui.globalsearch = {
28
+ ...mergeConfig(envConfig, config.searchui.default),
29
+ elastic_index: 'es',
30
+ host: process.env.RAZZLE_ES_PROXY_ADDR || 'http://localhost:3000',
31
+ };
32
+
33
+ if (typeof window !== 'undefined') {
34
+ config.searchui.globalsearch.host =
35
+ process.env.RAZZLE_ES_PROXY_ADDR || getClientProxyAddress();
36
+ }
37
+
38
+ config.searchui.standalone = {
39
+ ...mergeConfig(envConfig, config.searchui.default),
40
+ host: process.env.RAZZLE_ES_PROXY_ADDR,
41
+ elastic_index: 'es',
42
+ facets: [],
43
+ highlight: {},
44
+ sortOptions: [],
45
+ tableViewParams: {
46
+ columns: [
47
+ {
48
+ title: 'Title',
49
+ field: 'title',
50
+ },
51
+ ],
52
+ },
53
+ listingViewParams: {
54
+ titleField: 'title',
55
+ extraFields: [],
56
+ details: {
57
+ titleField: 'title',
58
+ extraFields: [],
59
+ },
60
+ sections: [],
61
+ },
62
+ };
63
+
64
+ config.resolve.getGlobalsearchIconUrl = getGlobalsearchIconUrl(
65
+ contentTypeNormalize,
66
+ );
67
+ config.resolve.getGlobalsearchThumbUrl = getGlobalsearchThumbUrl(
68
+ contentTypeNormalize,
69
+ );
70
+
71
+ config.resolve.typesForClustersOptionsFilter = typesForClustersOptionsFilter;
72
+ // config.resolve.WebsiteFilterListComponent = {
73
+ // component: WebsiteFilterListComponent,
74
+ // };
75
+ // config.resolve.FreshnessRangeFacet = {
76
+ // ...config.resolve.FixedRangeFacet,
77
+ // component: (props) => <div>Mumu</div>,
78
+ // };
79
+
80
+ // config.resolve.LandingPage = { component: LandingPage };
81
+
82
+ config.searchui.minimal = mergeConfig(config.searchui.default, envConfig);
83
+ config.searchui.minimal.facets = [
84
+ suiFacet({ field: 'Sector' }),
85
+ suiFacet({
86
+ field: 'Origin_of_the_measure',
87
+ label: 'Origin of the measure',
88
+ }),
89
+ ];
90
+
91
+ return config;
92
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "highlight": "highlight",
3
+ "press-release": "pressrelease",
4
+ "news": "highlight",
5
+ "news-item": "news-item",
6
+ "event": "event",
7
+ "promotion": "generic",
8
+ "article": "article",
9
+ "eco-tip": "ecotip",
10
+ "image": "generic",
11
+ "video": "cloudvideo",
12
+ "report": "report",
13
+ "publication": "report",
14
+ "dataset": "data",
15
+ "data-(rdf)": "data",
16
+ "data": "data",
17
+ "data-visualization": "davizvisualization",
18
+ "indicator-specification": "specification",
19
+ "indicator-factsheet": "assessment",
20
+ "indicator-assessment": "assessment",
21
+ "infographic": "interactive-data",
22
+ "briefing": "fiche",
23
+ "page": "document",
24
+ "link": "link",
25
+ "data-file": "datafile",
26
+ "assessment-part": "assessmentpart",
27
+ "file": "file",
28
+ "eea-job-vacancy": "eeavacancy",
29
+ "epub-file": "epubfile",
30
+ "external-data-reference": "externaldataspec",
31
+ "eyewitness-story": "generic",
32
+ "figure": "eeafigure",
33
+ "figure-file": "eeafigurefile",
34
+ "folder": "folder",
35
+ "gis-map-application": "gis-application",
36
+ "methodology-reference": "generic",
37
+ "organization": "organisation",
38
+ "organisation": "organisation",
39
+ "policy-question": "policyquestion",
40
+ "policy-document": "policydocumentreference",
41
+ "rationale-reference": "rationalereference",
42
+ "soer-key-fact": "soerkeyfact",
43
+ "soer-message": "soermessage",
44
+ "sparql": "sparql",
45
+ "data-table-via-sparql": "sparql",
46
+ "speech": "news-item",
47
+ "text": "document",
48
+ "work-item": "generic",
49
+ "collection---old-style ": "topic",
50
+ "Catalogue---listing": "topic",
51
+ "legislation-instrument": "legislation-instrument",
52
+ "legislation": "legislation-instrument",
53
+ "legislation-data-reporting": "legislation-instrument",
54
+ "reporting-obligation": "reporting-obligation",
55
+ "country-country": "country-profile"
56
+ }
@@ -0,0 +1,56 @@
1
+ [
2
+ "Article",
3
+ "EEA Job Vacancy",
4
+ "Briefing (all)",
5
+ "Briefing (Country)",
6
+ "News",
7
+ "Video",
8
+ "Web page",
9
+ "Map (interactive)",
10
+ "Infographic",
11
+ "Data receiver (Reportnet client)",
12
+ "Data visualisation",
13
+ "Data (at EEA)",
14
+ "Data table (via SPARQL)",
15
+ "Dashboard",
16
+ "Topic/subtopic site",
17
+ "Graph (image)",
18
+ "Map (image)",
19
+ "Publication / Report",
20
+ "Microdata (file)",
21
+ "Data provider (organisation)",
22
+ "Catalogue / listing",
23
+ "Indicator assessment",
24
+ "Data (external links)",
25
+ "Key message",
26
+ "Website main section",
27
+ "Organisation",
28
+ "Legislation Instrument",
29
+ "Legislation",
30
+ "Legislation (Data reporting)",
31
+ "References and links",
32
+ "Environmental question",
33
+ "Reporting obligation",
34
+ "Contract opportunity",
35
+ "Glossary term",
36
+ "Country profile",
37
+ "Country fact sheet",
38
+ "Webpage",
39
+ "File",
40
+ "Figure (chart/map)",
41
+ "Report",
42
+ "Indicator",
43
+ "Chart (interactive)",
44
+ "External data reference",
45
+ "Research and knowledge project",
46
+ "FAQ",
47
+ "Briefing",
48
+ "Information portal",
49
+ "Guidance",
50
+ "Case study",
51
+ "Tool",
52
+ "Topic page",
53
+ "Adaptation option",
54
+ "Collection",
55
+ "Data set"
56
+ ]