@eeacms/volto-bise-policy 1.0.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.
- package/.coverage.babel.config.js +9 -0
- package/.i18n.babel.config.js +1 -0
- package/.project.eslintrc.js +47 -0
- package/.release-it.json +17 -0
- package/CHANGELOG.md +27 -0
- package/DEVELOP.md +53 -0
- package/LICENSE.md +9 -0
- package/README.md +84 -0
- package/RELEASE.md +74 -0
- package/babel.config.js +17 -0
- package/bootstrap +41 -0
- package/cypress.config.js +27 -0
- package/jest-addon.config.js +36 -0
- package/locales/bg/LC_MESSAGES/volto.po +14 -0
- package/locales/bg.json +1 -0
- package/locales/bs/LC_MESSAGES/volto.po +14 -0
- package/locales/bs.json +1 -0
- package/locales/cs/LC_MESSAGES/volto.po +14 -0
- package/locales/cs.json +1 -0
- package/locales/da/LC_MESSAGES/volto.po +14 -0
- package/locales/da.json +1 -0
- package/locales/de/LC_MESSAGES/volto.po +29 -0
- package/locales/de.json +1 -0
- package/locales/el/LC_MESSAGES/volto.po +14 -0
- package/locales/el.json +1 -0
- package/locales/en/LC_MESSAGES/volto.po +14 -0
- package/locales/en.json +1 -0
- package/locales/es/LC_MESSAGES/volto.po +24 -0
- package/locales/es.json +1 -0
- package/locales/et/LC_MESSAGES/volto.po +14 -0
- package/locales/et.json +1 -0
- package/locales/eu/LC_MESSAGES/volto.po +19 -0
- package/locales/eu.json +1 -0
- package/locales/fi/LC_MESSAGES/volto.po +14 -0
- package/locales/fi.json +1 -0
- package/locales/fr/LC_MESSAGES/volto.po +29 -0
- package/locales/fr.json +1 -0
- package/locales/ga/LC_MESSAGES/volto.po +14 -0
- package/locales/ga.json +1 -0
- package/locales/hr/LC_MESSAGES/volto.po +14 -0
- package/locales/hr.json +1 -0
- package/locales/hu/LC_MESSAGES/volto.po +14 -0
- package/locales/hu.json +1 -0
- package/locales/is/LC_MESSAGES/volto.po +14 -0
- package/locales/is.json +1 -0
- package/locales/it/LC_MESSAGES/volto.po +14 -0
- package/locales/it.json +1 -0
- package/locales/ja/LC_MESSAGES/volto.po +21 -0
- package/locales/ja.json +1 -0
- package/locales/lt/LC_MESSAGES/volto.po +14 -0
- package/locales/lt.json +1 -0
- package/locales/lv/LC_MESSAGES/volto.po +14 -0
- package/locales/lv.json +1 -0
- package/locales/mk/LC_MESSAGES/volto.po +14 -0
- package/locales/mk.json +1 -0
- package/locales/mt/LC_MESSAGES/volto.po +14 -0
- package/locales/mt.json +1 -0
- package/locales/nl/LC_MESSAGES/volto.po +33 -0
- package/locales/nl.json +1 -0
- package/locales/no/LC_MESSAGES/volto.po +14 -0
- package/locales/no.json +1 -0
- package/locales/pl/LC_MESSAGES/volto.po +14 -0
- package/locales/pl.json +1 -0
- package/locales/pt/LC_MESSAGES/volto.po +22 -0
- package/locales/pt.json +1 -0
- package/locales/pt_BR/LC_MESSAGES/volto.po +20 -0
- package/locales/pt_BR.json +1 -0
- package/locales/ro/LC_MESSAGES/volto.po +20 -0
- package/locales/ro.json +1 -0
- package/locales/sh/LC_MESSAGES/volto.po +14 -0
- package/locales/sh.json +1 -0
- package/locales/sk/LC_MESSAGES/volto.po +14 -0
- package/locales/sk.json +1 -0
- package/locales/sl/LC_MESSAGES/volto.po +14 -0
- package/locales/sl.json +1 -0
- package/locales/sq/LC_MESSAGES/volto.po +14 -0
- package/locales/sq.json +1 -0
- package/locales/sv/LC_MESSAGES/volto.po +14 -0
- package/locales/sv.json +1 -0
- package/locales/tr/LC_MESSAGES/volto.po +14 -0
- package/locales/tr.json +1 -0
- package/locales/volto.pot +16 -0
- package/package.json +57 -0
- package/razzle.extend.js +29 -0
- package/src/components/manage/Blocks/BodyClass/Edit.jsx +30 -0
- package/src/components/manage/Blocks/BodyClass/View.jsx +12 -0
- package/src/components/manage/Blocks/BodyClass/index.js +24 -0
- package/src/components/manage/Blocks/BodyClass/schema.js +20 -0
- package/src/components/manage/Blocks/FactsheetsListing/FactsheetsListingEdit.jsx +32 -0
- package/src/components/manage/Blocks/FactsheetsListing/FactsheetsListingView.jsx +81 -0
- package/src/components/manage/Blocks/FactsheetsListing/index.js +24 -0
- package/src/components/manage/Blocks/FactsheetsListing/schema.js +20 -0
- package/src/components/manage/Blocks/KeyFacts/KeyFactsEdit.jsx +34 -0
- package/src/components/manage/Blocks/KeyFacts/KeyFactsView.jsx +68 -0
- package/src/components/manage/Blocks/KeyFacts/index.js +22 -0
- package/src/components/manage/Blocks/KeyFacts/schema.jsx +74 -0
- package/src/components/manage/Blocks/MaesViewer/MaesViewerEdit.jsx +64 -0
- package/src/components/manage/Blocks/MaesViewer/MaesViewerView.jsx +136 -0
- package/src/components/manage/Blocks/MaesViewer/constants.js +1 -0
- package/src/components/manage/Blocks/MaesViewer/index.js +22 -0
- package/src/components/manage/Blocks/MaesViewer/schema.js +60 -0
- package/src/components/manage/Blocks/MaesViewer/style.css +64 -0
- package/src/components/manage/Blocks/MaesViewer/utils.js +473 -0
- package/src/components/manage/Blocks/Navigation/Edit.jsx +27 -0
- package/src/components/manage/Blocks/Navigation/View.jsx +43 -0
- package/src/components/manage/Blocks/Navigation/index.js +22 -0
- package/src/components/manage/Blocks/Navigation/schema.js +43 -0
- package/src/components/manage/Blocks/Navigation/styles.less +42 -0
- package/src/components/manage/Blocks/Redirect/Edit.jsx +29 -0
- package/src/components/manage/Blocks/Redirect/View.jsx +13 -0
- package/src/components/manage/Blocks/Redirect/index.js +24 -0
- package/src/components/manage/Blocks/Redirect/schema.js +20 -0
- package/src/components/manage/Blocks/index.js +17 -0
- package/src/components/manage/Styles/index.js +163 -0
- package/src/customizations/@eeacms/volto-block-style/StyleWrapper/schema.js +206 -0
- package/src/customizations/volto/components/manage/Toolbar/More.jsx +547 -0
- package/src/customizations/volto/components/theme/Footer/Footer.jsx +25 -0
- package/src/customizations/volto/components/theme/Header/Header.jsx +301 -0
- package/src/index.js +77 -0
- package/theme/assets/icons/plus.png +0 -0
- package/theme/assets/icons/plus.svg +6 -0
- package/theme/assets/icons/search.svg +3 -0
- package/theme/assets/images/Header/bise-logo-white.svg +47 -0
- package/theme/assets/images/Header/bise-logo.svg +132 -0
- package/theme/collections/table.variables +17 -0
- package/theme/extras/banner.variables +5 -0
- package/theme/extras/factsheets.less +76 -0
- package/theme/extras/footer.variables +6 -0
- package/theme/extras/header.overrides +30 -0
- package/theme/extras/header.variables +7 -0
- package/theme/extras/hero.overrides +4 -0
- package/theme/extras/inpageNavigation.variables +5 -0
- package/theme/extras/keyfacts.less +202 -0
- package/theme/extras/pluggables.less +191 -0
- package/theme/extras/stylemenu.less +48 -0
- package/theme/extras/tocnav.less +158 -0
- package/theme/globals/site.overrides +78 -0
- package/theme/globals/site.variables +22 -0
- package/theme/theme.config +135 -0
- package/theme/tokens/colors.less +15 -0
- package/theme/tokens/tokens.less +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.maes-viewer-grid {
|
|
2
|
+
display: grid;
|
|
3
|
+
margin: 3em 0;
|
|
4
|
+
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.maes-viewer-grid .js-plotly-plot {
|
|
8
|
+
/* this would have been overriden by inline CSS inside the react-plotly.js
|
|
9
|
+
component if it was not marked !important */
|
|
10
|
+
/* this rule is needed to make the small charts inside the MAES Viewer
|
|
11
|
+
responsive */
|
|
12
|
+
display: block !important;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.maes-select-label {
|
|
16
|
+
display: inline-block;
|
|
17
|
+
margin-bottom: 1rem;
|
|
18
|
+
font-size: 19px;
|
|
19
|
+
font-weight: bold;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@media only screen and (min-width: 1440px) {
|
|
23
|
+
.maes-viewer-grid {
|
|
24
|
+
column-gap: 2rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.maes-viewer-select {
|
|
28
|
+
grid-column: 9/13;
|
|
29
|
+
grid-row: 1/2;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.maes-viewer-charts {
|
|
33
|
+
grid-column: 1/9;
|
|
34
|
+
grid-row: 1/2;
|
|
35
|
+
overflow-x: hidden;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media only screen and (max-width: 1440px) {
|
|
40
|
+
.maes-viewer-grid {
|
|
41
|
+
grid-template-rows: auto auto;
|
|
42
|
+
/* grid-template-columns: 1fr; */
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.maes-viewer-select {
|
|
46
|
+
margin-bottom: 3em;
|
|
47
|
+
grid-column: 1/5;
|
|
48
|
+
grid-row: 1/2;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.maes-viewer-charts {
|
|
52
|
+
grid-column: 1/13;
|
|
53
|
+
grid-row: 2/3;
|
|
54
|
+
overflow-x: hidden;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@media only screen and (max-width: 1282px) {
|
|
59
|
+
.maes-viewer-select {
|
|
60
|
+
width: 100%;
|
|
61
|
+
max-width: 320px;
|
|
62
|
+
grid-column: 1/13;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { defaultHoverTemplate } from './constants';
|
|
3
|
+
|
|
4
|
+
export const colorscale = [
|
|
5
|
+
'rgb(166,206,227)',
|
|
6
|
+
'rgb(31,120,180)',
|
|
7
|
+
'rgb(178,223,138)',
|
|
8
|
+
'rgb(51,160,44)',
|
|
9
|
+
'rgb(251,154,153)',
|
|
10
|
+
'rgb(227,26,28)',
|
|
11
|
+
'rgb(160,26,51)',
|
|
12
|
+
'rgb(227,178,223)',
|
|
13
|
+
'rgb(31,227,28)',
|
|
14
|
+
'rgb(227,120,180)',
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const mapLongLevelNameToShort = (x) => {
|
|
18
|
+
const obj = {
|
|
19
|
+
'A - Marine habitats': 'Marine habitats',
|
|
20
|
+
'B - Coastal habitats': 'Coastal habitats',
|
|
21
|
+
'C - Inland surface waters': 'Inland waters',
|
|
22
|
+
'D - Mires, bogs and fens': 'Mires, bogs and fens',
|
|
23
|
+
'E - Grasslands and land dominated by forbs, mosses or lichens':
|
|
24
|
+
'Grassland',
|
|
25
|
+
'F - Heathland, scrub and tundra': 'Heathland',
|
|
26
|
+
'G - Woodland, forest and other wooded land': 'Woodlands',
|
|
27
|
+
'H - Inland unvegetated or sparsely vegetated habitats':
|
|
28
|
+
'Inland unvegetated or sparsely vegetated habitats',
|
|
29
|
+
'I - Arable land and market gardens': 'Cropland',
|
|
30
|
+
'J - constructed, industrial and other artificial habitats': 'Urban',
|
|
31
|
+
};
|
|
32
|
+
return obj[x] || x;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const filterGettingOriginalIndices = (a, fn) => {
|
|
36
|
+
return a
|
|
37
|
+
.map((c, i) => [c, i])
|
|
38
|
+
.filter(([c, i]) => fn(c, i))
|
|
39
|
+
.map(([, i]) => i);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
class ProviderData {
|
|
43
|
+
static ecosystemColumnName = 'Ecosystem_level2';
|
|
44
|
+
static countryColumnName = 'Country_name';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Takes an object like:
|
|
48
|
+
*
|
|
49
|
+
* { Area: [...], Source: [...] }
|
|
50
|
+
*
|
|
51
|
+
* where each item in the lists represents a table column value.
|
|
52
|
+
*/
|
|
53
|
+
constructor(data) {
|
|
54
|
+
this.data = data;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getColumnData(name) {
|
|
58
|
+
return this.data[name];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
getUniqueColumnData(name) {
|
|
62
|
+
return _.uniq(this.data[name]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getEcosystems() {
|
|
66
|
+
return this.getUniqueColumnData(ProviderData.ecosystemColumnName);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getCountries() {
|
|
70
|
+
return this.getUniqueColumnData(ProviderData.countryColumnName).concat(
|
|
71
|
+
'EU',
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getCountriesColumn() {
|
|
76
|
+
return this.getColumnData(ProviderData.countryColumnName);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
forEachCountryAndLevel(fn) {
|
|
80
|
+
const c = this.getCountries();
|
|
81
|
+
const e = this.getEcosystems();
|
|
82
|
+
c.forEach((country) => {
|
|
83
|
+
e.forEach((level) => {
|
|
84
|
+
fn(country, level);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getEcosystemForRowIndex(i) {
|
|
90
|
+
return this.data[ProviderData.ecosystemColumnName][i];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
hasEcosystemAtRowIndex(i, ecosystem) {
|
|
94
|
+
return this.getEcosystemForRowIndex(i) === ecosystem;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getColumnNames() {
|
|
98
|
+
return _.keys(this.data);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getCellValue(columnName, rowIndex) {
|
|
102
|
+
return this.getColumnData(columnName)[rowIndex];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
createRowObject(rowIndex) {
|
|
106
|
+
const obj = {};
|
|
107
|
+
this.getColumnNames().forEach((cn) => {
|
|
108
|
+
obj[cn] = this.getCellValue(cn, rowIndex);
|
|
109
|
+
});
|
|
110
|
+
return obj;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
rowSatisfiesFilters(index, filters) {
|
|
114
|
+
const filtersResults = filters.map((f) => f(this.data, index));
|
|
115
|
+
return filtersResults.every((t) => t);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Filters the data. Given a country name and an array of filter functions
|
|
120
|
+
* which receive two parameters, provider_data and rowIndex, returns an array
|
|
121
|
+
* of objects containing the data for each matching row in the DataProvider.
|
|
122
|
+
*/
|
|
123
|
+
query(country, filters) {
|
|
124
|
+
const countriesColumn = this.getCountriesColumn();
|
|
125
|
+
const filteredIndices = filterGettingOriginalIndices(
|
|
126
|
+
countriesColumn,
|
|
127
|
+
(c, i) => {
|
|
128
|
+
return c === country && this.rowSatisfiesFilters(i, filters);
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
const rowObjects = filteredIndices.map((i) => this.createRowObject(i));
|
|
132
|
+
return rowObjects;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function mapByLevel(provider_data) {
|
|
137
|
+
const pd = new ProviderData(provider_data);
|
|
138
|
+
|
|
139
|
+
const byLevel = _.fromPairs(pd.getEcosystems().map((l) => [l, {}]));
|
|
140
|
+
|
|
141
|
+
pd.forEachCountryAndLevel((country, level) => {
|
|
142
|
+
const filters = [
|
|
143
|
+
(provider_data, index) => pd.hasEcosystemAtRowIndex(index, level),
|
|
144
|
+
];
|
|
145
|
+
const country_data = pd.query(country, filters);
|
|
146
|
+
byLevel[level][country] = country_data;
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return byLevel;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function mapToAllEU(provider_data, byLevel) {
|
|
153
|
+
const level2 = new Set(provider_data['Ecosystem_level2']);
|
|
154
|
+
const countries = new Set(provider_data['Country_name']);
|
|
155
|
+
const EUByLevel = Object.fromEntries(Array.from(level2).map((l) => [l, {}]));
|
|
156
|
+
|
|
157
|
+
let totalArea = 0;
|
|
158
|
+
|
|
159
|
+
level2.forEach((level) => {
|
|
160
|
+
EUByLevel[level] = 0;
|
|
161
|
+
|
|
162
|
+
countries.forEach((country) => {
|
|
163
|
+
byLevel[level][country].forEach((x) => {
|
|
164
|
+
EUByLevel[level] += parseFloat(x['Area (m2)']);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
totalArea += EUByLevel[level];
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const EUByLevelPercents = _.fromPairs(
|
|
172
|
+
_.map(Array.from(level2), (l) => {
|
|
173
|
+
return [l, (EUByLevel[l] / totalArea) * 100];
|
|
174
|
+
}),
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
return { EUByLevel, EUByLevelPercents };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function makeTrace(
|
|
181
|
+
level,
|
|
182
|
+
levelData,
|
|
183
|
+
index,
|
|
184
|
+
focusOn,
|
|
185
|
+
{ hoverTemplate = defaultHoverTemplate },
|
|
186
|
+
) {
|
|
187
|
+
const data = [
|
|
188
|
+
...Object.entries(levelData).filter(([k, v]) => k !== focusOn),
|
|
189
|
+
[focusOn, levelData[focusOn]],
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
const x = [...data.map(([k, v]) => v)];
|
|
193
|
+
const y = [];
|
|
194
|
+
y.length = x.length;
|
|
195
|
+
y.fill(0);
|
|
196
|
+
y[y.length - 1] = 0.25; // we "lift" this value to "highlight" it
|
|
197
|
+
|
|
198
|
+
// first element: country name
|
|
199
|
+
// second element: square kilometers (km2)
|
|
200
|
+
// third element: square megameters (Mm2)
|
|
201
|
+
const hovertext = _.map(data, (x) => [x[0], x[1] / 100, x[1] / 10000]);
|
|
202
|
+
|
|
203
|
+
const text = [
|
|
204
|
+
...data.slice(0, data.length - 1).map((_) => null),
|
|
205
|
+
`<b>${focusOn}</b>`,
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
const marker = {
|
|
209
|
+
symbol: [
|
|
210
|
+
...data.slice(0, data.length - 1).map((_) => null),
|
|
211
|
+
'big-dot',
|
|
212
|
+
// 'triangle-down',
|
|
213
|
+
],
|
|
214
|
+
// See https://plotly.com/javascript/reference/scatter/#scatter-marker
|
|
215
|
+
size: [...data.slice(0, data.length - 1).map((_) => 10), 10],
|
|
216
|
+
opacity: [...data.slice(0, data.length - 1).map((_) => 0.8), 1],
|
|
217
|
+
color: [
|
|
218
|
+
...data.slice(0, data.length - 1).map((_) => colorscale[index]),
|
|
219
|
+
'#182844',
|
|
220
|
+
],
|
|
221
|
+
};
|
|
222
|
+
const ht = hoverTemplate
|
|
223
|
+
.replace(/\{(.*?)country(.*?)\}/, '{$1customdata[0]$2}')
|
|
224
|
+
.replace(/\{(.*?)km2(.*?)\}/, '{$1customdata[1]$2}')
|
|
225
|
+
.replace(/\{(.*?)mm2(.*?)\}/, '{$1customdata[2]$2}');
|
|
226
|
+
const res = {
|
|
227
|
+
x,
|
|
228
|
+
y,
|
|
229
|
+
// hovertext,
|
|
230
|
+
// See
|
|
231
|
+
// https://plotly.com/javascript/reference/scatter/#scatter-hovertemplate
|
|
232
|
+
hovertemplate: ht,
|
|
233
|
+
hoverinfo: 'y',
|
|
234
|
+
customdata: hovertext,
|
|
235
|
+
name: level,
|
|
236
|
+
type: 'scatter',
|
|
237
|
+
// needed for subplots!!
|
|
238
|
+
// xaxis: `x${index > 0 ? index + 1 : ''}`,
|
|
239
|
+
// yaxis: `y${index > 0 ? index + 1 : ''}`,
|
|
240
|
+
mode: 'markers+text',
|
|
241
|
+
text,
|
|
242
|
+
marker,
|
|
243
|
+
textposition: 'top center',
|
|
244
|
+
};
|
|
245
|
+
return res;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function axesFromTemplate(prefix, count, tpl, getTitle) {
|
|
249
|
+
const res = {};
|
|
250
|
+
for (let x = 0; x < count; x++) {
|
|
251
|
+
const rec = `${prefix}${x > 0 ? x + 1 : x}`;
|
|
252
|
+
res[rec] = JSON.parse(JSON.stringify(tpl));
|
|
253
|
+
// res[rec].title = { text: getTitle(x) };
|
|
254
|
+
}
|
|
255
|
+
res[prefix] = JSON.parse(JSON.stringify(tpl));
|
|
256
|
+
return res;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @param {number} index
|
|
261
|
+
* @param {number} finalPercent
|
|
262
|
+
*/
|
|
263
|
+
export function chartTileLayout(index, finalPercent) {
|
|
264
|
+
return {
|
|
265
|
+
height: 60,
|
|
266
|
+
showlegend: false,
|
|
267
|
+
margin: {
|
|
268
|
+
l: 0,
|
|
269
|
+
r: 0,
|
|
270
|
+
t: 0,
|
|
271
|
+
b: 0,
|
|
272
|
+
},
|
|
273
|
+
pad: 0,
|
|
274
|
+
xaxis: {
|
|
275
|
+
visible: true,
|
|
276
|
+
showline: false,
|
|
277
|
+
showgrid: false,
|
|
278
|
+
zeroline: false,
|
|
279
|
+
autorange: true,
|
|
280
|
+
|
|
281
|
+
// showticklabels: true,
|
|
282
|
+
// automargin: true,
|
|
283
|
+
// tickvals: [10000000000],
|
|
284
|
+
// tickmode: 'array',
|
|
285
|
+
// ticktext: ['0%'],
|
|
286
|
+
// ticks: 'outside',
|
|
287
|
+
},
|
|
288
|
+
yaxis: {
|
|
289
|
+
type: 'linear',
|
|
290
|
+
range: [-0.3, 1], // needed to show the current country as a dot above the line
|
|
291
|
+
visible: true,
|
|
292
|
+
ticks: '',
|
|
293
|
+
showgrid: false,
|
|
294
|
+
gridwidth: 2,
|
|
295
|
+
gridcolor: '#000',
|
|
296
|
+
showline: true,
|
|
297
|
+
zeroline: true,
|
|
298
|
+
zerolinewidth: 2,
|
|
299
|
+
zerolinecolor: '#000',
|
|
300
|
+
showticklabels: false,
|
|
301
|
+
// showdividers: true,
|
|
302
|
+
},
|
|
303
|
+
annotations: [
|
|
304
|
+
{
|
|
305
|
+
xref: 'x',
|
|
306
|
+
yref: 'paper',
|
|
307
|
+
x: 0,
|
|
308
|
+
y: 0.3,
|
|
309
|
+
xanchor: 'right',
|
|
310
|
+
yanchor: 'bottom',
|
|
311
|
+
text: '0%',
|
|
312
|
+
showarrow: false,
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
xref: 'paper',
|
|
316
|
+
yref: 'paper',
|
|
317
|
+
x: 1,
|
|
318
|
+
y: 0.3,
|
|
319
|
+
xanchor: 'right',
|
|
320
|
+
yanchor: 'bottom',
|
|
321
|
+
text: `${Math.round(finalPercent).toFixed(0)}%`,
|
|
322
|
+
showarrow: false,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function makeChartTiles(
|
|
329
|
+
provider_data,
|
|
330
|
+
focusOn,
|
|
331
|
+
focusEcosystem,
|
|
332
|
+
{ hoverTemplate },
|
|
333
|
+
) {
|
|
334
|
+
if (!provider_data) return;
|
|
335
|
+
const byLevel = mapByLevel(provider_data);
|
|
336
|
+
const { EUByLevel, EUByLevelPercents } = mapToAllEU(provider_data, byLevel);
|
|
337
|
+
|
|
338
|
+
const ecosystems = _.uniq(provider_data['Ecosystem_level2']);
|
|
339
|
+
const countries = _.uniq(provider_data['Country_name']);
|
|
340
|
+
|
|
341
|
+
const byArea = Object.fromEntries(ecosystems.map((l) => [l, {}]));
|
|
342
|
+
ecosystems.forEach((level) => {
|
|
343
|
+
countries.forEach((country) => {
|
|
344
|
+
const recs = byLevel[level][country];
|
|
345
|
+
const total = recs.reduce(
|
|
346
|
+
(acc, rec) => acc + parseInt(rec['Area (m2)']),
|
|
347
|
+
0,
|
|
348
|
+
);
|
|
349
|
+
byArea[level][country] = total;
|
|
350
|
+
});
|
|
351
|
+
byArea[level]['EU'] = EUByLevel[level];
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const tiles = ecosystems
|
|
355
|
+
.map((level, index) => {
|
|
356
|
+
if (focusEcosystem && level !== focusEcosystem) return null;
|
|
357
|
+
return {
|
|
358
|
+
layout: chartTileLayout(index, EUByLevelPercents[level]),
|
|
359
|
+
data: [
|
|
360
|
+
makeTrace(level, byArea[level], index, focusOn, { hoverTemplate }),
|
|
361
|
+
],
|
|
362
|
+
title: mapLongLevelNameToShort(level),
|
|
363
|
+
};
|
|
364
|
+
})
|
|
365
|
+
.filter((c) => !!c);
|
|
366
|
+
|
|
367
|
+
return tiles;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// unused, old version
|
|
371
|
+
// export function makeSubplotsChart(provider_data) {
|
|
372
|
+
// if (!provider_data) return;
|
|
373
|
+
// const byLevel = mapByLevel(provider_data);
|
|
374
|
+
//
|
|
375
|
+
// const level2 = new Set(provider_data['Ecosystem_level2']);
|
|
376
|
+
// const countries = new Set(provider_data['Country_name']);
|
|
377
|
+
//
|
|
378
|
+
// const byArea = Object.fromEntries(Array.from(level2).map((l) => [l, {}]));
|
|
379
|
+
// level2.forEach((level) => {
|
|
380
|
+
// countries.forEach((country) => {
|
|
381
|
+
// const recs = byLevel[level][country];
|
|
382
|
+
// const total = recs.reduce(
|
|
383
|
+
// (acc, rec) => acc + parseInt(rec['Area (m2)']),
|
|
384
|
+
// 0,
|
|
385
|
+
// );
|
|
386
|
+
// byArea[level][country] = total;
|
|
387
|
+
// });
|
|
388
|
+
// });
|
|
389
|
+
//
|
|
390
|
+
// let layout = {
|
|
391
|
+
// height: 560,
|
|
392
|
+
// showlegend: false,
|
|
393
|
+
// margin: {
|
|
394
|
+
// l: 400,
|
|
395
|
+
// r: 0,
|
|
396
|
+
// t: 0,
|
|
397
|
+
// b: 0,
|
|
398
|
+
// },
|
|
399
|
+
// pad: 10,
|
|
400
|
+
// grid: {
|
|
401
|
+
// xside: 'bottom',
|
|
402
|
+
// yside: 'left',
|
|
403
|
+
// rows: Object.keys(byLevel).length,
|
|
404
|
+
// columns: 1,
|
|
405
|
+
// ygap: 0.2,
|
|
406
|
+
// roworder: 'bottom to top',
|
|
407
|
+
// yaxes: Object.keys(byLevel).map(
|
|
408
|
+
// (l, index) => `y${index > 0 ? index + 1 : ''}`,
|
|
409
|
+
// ),
|
|
410
|
+
// xaxes: Object.keys(byLevel).map(
|
|
411
|
+
// (l, index) => `x${index > 0 ? index + 1 : ''}`,
|
|
412
|
+
// ),
|
|
413
|
+
// pattern: 'independent',
|
|
414
|
+
// },
|
|
415
|
+
// ...axesFromTemplate(
|
|
416
|
+
// 'xaxis',
|
|
417
|
+
// Object.keys(byLevel).length,
|
|
418
|
+
// {
|
|
419
|
+
// // this axis is shared
|
|
420
|
+
// visible: true,
|
|
421
|
+
// ticks: '',
|
|
422
|
+
// showline: false,
|
|
423
|
+
// showgrid: false,
|
|
424
|
+
// zeroline: false,
|
|
425
|
+
// autorange: true,
|
|
426
|
+
// // fixedrange: true,
|
|
427
|
+
// showticklabels: false,
|
|
428
|
+
// },
|
|
429
|
+
// (index) => '',
|
|
430
|
+
// ),
|
|
431
|
+
// ...axesFromTemplate(
|
|
432
|
+
// 'yaxis',
|
|
433
|
+
// Object.keys(byLevel).length,
|
|
434
|
+
// {
|
|
435
|
+
// type: 'category',
|
|
436
|
+
// visible: true,
|
|
437
|
+
// ticks: '',
|
|
438
|
+
// showline: false,
|
|
439
|
+
// showgrid: true,
|
|
440
|
+
// gridwidth: 2,
|
|
441
|
+
// zeroline: false,
|
|
442
|
+
// gridcolor: '#000',
|
|
443
|
+
// showticklabels: false,
|
|
444
|
+
// },
|
|
445
|
+
// (index) => Object.keys(byLevel)[index],
|
|
446
|
+
// ),
|
|
447
|
+
// annotations: [...makeAnnotations(byLevel)],
|
|
448
|
+
// };
|
|
449
|
+
//
|
|
450
|
+
// const traces = Array.from(level2).map((level, index) =>
|
|
451
|
+
// makeTrace(level, byArea[level], index),
|
|
452
|
+
// );
|
|
453
|
+
//
|
|
454
|
+
// return { layout, data: traces };
|
|
455
|
+
// }
|
|
456
|
+
// export function makeAnnotations(byLabel) {
|
|
457
|
+
// const len = Object.keys(byLabel).length;
|
|
458
|
+
// return Object.keys(byLabel).map((label, index) => {
|
|
459
|
+
// return {
|
|
460
|
+
// xref: 'paper',
|
|
461
|
+
// yref: 'paper',
|
|
462
|
+
// x: -0.06,
|
|
463
|
+
// // y: 0,
|
|
464
|
+
// y: (1 / (len - 1)) * index,
|
|
465
|
+
// xanchor: 'right',
|
|
466
|
+
// // yanchor: 'bottom',
|
|
467
|
+
// text: label,
|
|
468
|
+
// showarrow: false,
|
|
469
|
+
// // ay: (10 * index) / 2,
|
|
470
|
+
// };
|
|
471
|
+
// });
|
|
472
|
+
// }
|
|
473
|
+
//
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SidebarPortal } from '@plone/volto/components';
|
|
3
|
+
import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
|
|
4
|
+
import schema from './schema';
|
|
5
|
+
import View from './View';
|
|
6
|
+
|
|
7
|
+
const Edit = (props) => (
|
|
8
|
+
<>
|
|
9
|
+
<View {...props} mode="edit" />
|
|
10
|
+
|
|
11
|
+
<SidebarPortal selected={props.selected}>
|
|
12
|
+
<InlineForm
|
|
13
|
+
schema={schema}
|
|
14
|
+
title={schema.title}
|
|
15
|
+
onChangeField={(id, value) => {
|
|
16
|
+
props.onChangeBlock(props.block, {
|
|
17
|
+
...props.data,
|
|
18
|
+
[id]: value,
|
|
19
|
+
});
|
|
20
|
+
}}
|
|
21
|
+
formData={props.data}
|
|
22
|
+
/>
|
|
23
|
+
</SidebarPortal>
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export default Edit;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { connect } from 'react-redux';
|
|
3
|
+
import { Menu } from 'semantic-ui-react';
|
|
4
|
+
import { UniversalLink } from '@plone/volto/components';
|
|
5
|
+
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
6
|
+
|
|
7
|
+
import './styles.less';
|
|
8
|
+
|
|
9
|
+
const View = ({ history, data, navigation, ...props }) => {
|
|
10
|
+
const search = history?.location?.search || '';
|
|
11
|
+
const pathname = props.path || props.pathname;
|
|
12
|
+
const pages = data.pages || [];
|
|
13
|
+
const items = useMemo(() => {
|
|
14
|
+
return [
|
|
15
|
+
...(navigation.filter(
|
|
16
|
+
(item) => flattenToAppURL(item.url) === flattenToAppURL(data.parent),
|
|
17
|
+
)[0]?.items || []),
|
|
18
|
+
...pages,
|
|
19
|
+
];
|
|
20
|
+
}, [navigation, pages, data.parent]);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Menu className="navigation-block">
|
|
24
|
+
{items.map((item) => (
|
|
25
|
+
<Menu.Item
|
|
26
|
+
key={item.url}
|
|
27
|
+
active={
|
|
28
|
+
item.url &&
|
|
29
|
+
pathname?.replace('/edit', '') === flattenToAppURL(item.url)
|
|
30
|
+
}
|
|
31
|
+
>
|
|
32
|
+
<UniversalLink href={`${item.url}${search}`}>
|
|
33
|
+
{item.title}
|
|
34
|
+
</UniversalLink>
|
|
35
|
+
</Menu.Item>
|
|
36
|
+
))}
|
|
37
|
+
</Menu>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default connect((state) => ({
|
|
42
|
+
navigation: state.navigation.items,
|
|
43
|
+
}))(View);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import imageSVG from '@plone/volto/icons/image.svg';
|
|
2
|
+
import NavigationBlockView from './View';
|
|
3
|
+
import NavigationBlockEdit from './Edit';
|
|
4
|
+
|
|
5
|
+
export default (config) => {
|
|
6
|
+
config.blocks.blocksConfig.navigationBlock = {
|
|
7
|
+
id: 'navigationBlock',
|
|
8
|
+
title: 'Navigation Block',
|
|
9
|
+
icon: imageSVG,
|
|
10
|
+
group: 'common',
|
|
11
|
+
view: NavigationBlockView,
|
|
12
|
+
edit: NavigationBlockEdit,
|
|
13
|
+
restricted: false,
|
|
14
|
+
mostUsed: false,
|
|
15
|
+
sidebarTab: 1,
|
|
16
|
+
security: {
|
|
17
|
+
addPermission: [],
|
|
18
|
+
view: [],
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
return config;
|
|
22
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const pagesSchema = {
|
|
2
|
+
title: 'Page',
|
|
3
|
+
fieldsets: [
|
|
4
|
+
{
|
|
5
|
+
id: 'default',
|
|
6
|
+
title: 'Default',
|
|
7
|
+
fields: ['title', 'url'],
|
|
8
|
+
},
|
|
9
|
+
],
|
|
10
|
+
properties: {
|
|
11
|
+
title: {
|
|
12
|
+
title: 'Title',
|
|
13
|
+
},
|
|
14
|
+
url: {
|
|
15
|
+
title: 'Url',
|
|
16
|
+
widget: 'url',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: [],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
title: 'Navigation block',
|
|
24
|
+
fieldsets: [
|
|
25
|
+
{
|
|
26
|
+
id: 'default',
|
|
27
|
+
title: 'Default',
|
|
28
|
+
fields: ['parent', 'pages'],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
properties: {
|
|
32
|
+
parent: {
|
|
33
|
+
title: 'Parent',
|
|
34
|
+
widget: 'url',
|
|
35
|
+
},
|
|
36
|
+
pages: {
|
|
37
|
+
title: 'Pages',
|
|
38
|
+
schema: pagesSchema,
|
|
39
|
+
widget: 'object_list',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: [],
|
|
43
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@import (multiple, reference, optional) '../../theme.config';
|
|
2
|
+
|
|
3
|
+
@type: extra;
|
|
4
|
+
@element: custom;
|
|
5
|
+
|
|
6
|
+
.ui.menu.navigation-block {
|
|
7
|
+
flex-wrap: wrap;
|
|
8
|
+
border: none;
|
|
9
|
+
box-shadow: unset;
|
|
10
|
+
|
|
11
|
+
.item {
|
|
12
|
+
padding: 0;
|
|
13
|
+
border: none;
|
|
14
|
+
|
|
15
|
+
&.active {
|
|
16
|
+
a {
|
|
17
|
+
color: @primaryColor;
|
|
18
|
+
// text-decoration: none;
|
|
19
|
+
// border-bottom: 1px solid @secondaryColor;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&:hover,
|
|
24
|
+
&.active:hover {
|
|
25
|
+
background-color: unset;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&::before {
|
|
29
|
+
content: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:not(:last-child)::after {
|
|
33
|
+
top: 0%;
|
|
34
|
+
right: 0px;
|
|
35
|
+
width: 1px;
|
|
36
|
+
height: 80%;
|
|
37
|
+
margin: 0 0.3rem;
|
|
38
|
+
background: @secondaryColor;
|
|
39
|
+
content: '';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|