@eeacms/volto-cca-policy 1.0.25 → 1.0.27
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/CHANGELOG.md +26 -0
- package/package.json +1 -1
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.jsx +16 -24
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.test.jsx +21 -2
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.jsx +9 -6
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.test.jsx +50 -0
- package/src/components/Search/NavigatorCatalogue/utils.js +22 -0
- package/src/components/Search/NavigatorGuide/NavigatorGuideContentView.jsx +153 -135
- package/src/components/Search/NavigatorGuide/NavigatorGuideContentView.test.jsx +108 -2
- package/src/components/Search/NavigatorGuide/utils.js +15 -0
- package/src/components/Search/NavigatorGuide/utils.test.js +18 -1
- package/src/components/index.js +2 -0
- package/src/components/manage/Blocks/ChatbotCatalogue/astUtils.js +129 -3
- package/src/components/manage/Blocks/ChatbotCatalogue/astUtils.test.js +207 -0
- package/src/components/manage/Blocks/ChatbotCatalogue/docCards.js +8 -0
- package/src/components/manage/Blocks/ChatbotCatalogue/docCards.test.js +72 -0
- package/src/components/manage/Blocks/ChatbotCatalogue/nextSteps.js +4 -0
- package/src/components/manage/Blocks/ChatbotCatalogue/nextSteps.test.js +48 -0
- package/src/components/theme/CompareTools/CompareToolsPanel.jsx +1 -1
- package/src/components/theme/CompareTools/CompareToolsView.jsx +1 -1
- package/src/components/theme/Content/Sections/MetadataItemList.jsx +7 -24
- package/src/components/theme/TagOverflowPopup.jsx +28 -0
- package/src/components/theme/Views/RelatedTools.jsx +7 -25
- package/src/search/navigator_guide/facets.js +1 -0
- package/src/search/navigator_guide/guideSteps.js +1 -1
- package/theme/globals/navigator.less +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [1.0.27](https://github.com/eea/volto-cca-policy/compare/1.0.26...1.0.27) - 21 September 2026
|
|
8
|
+
|
|
9
|
+
#### :bug: Bug Fixes
|
|
10
|
+
|
|
11
|
+
- fix(navigator): country filtering on map view - refs #304610 [kreafox - [`2b8c52d`](https://github.com/eea/volto-cca-policy/commit/2b8c52dee15ed7a43a90eb2214db6557d7d3c964)]
|
|
12
|
+
|
|
13
|
+
### [1.0.26](https://github.com/eea/volto-cca-policy/compare/1.0.25...1.0.26) - 21 September 2026
|
|
14
|
+
|
|
15
|
+
#### :rocket: New Features
|
|
16
|
+
|
|
17
|
+
- feat(navigator): implement TagOverflowPopup component and replace Popup in navigator [kreafox - [`42a66c8`](https://github.com/eea/volto-cca-policy/commit/42a66c826f2e19ebd0102fc05a2df5ccd1648f14)]
|
|
18
|
+
|
|
19
|
+
#### :bug: Bug Fixes
|
|
20
|
+
|
|
21
|
+
- fix(navigator): rename adaptation support cycle step and improve guide me layout [kreafox - [`2806e1b`](https://github.com/eea/volto-cca-policy/commit/2806e1b258dc3b1172c21a567f5d76328d855bb9)]
|
|
22
|
+
- fix(navigator): update climate impacts to climate hazards - refs #304609 [kreafox - [`cf2af49`](https://github.com/eea/volto-cca-policy/commit/cf2af49836f3b5a1b33621ae29650b14fb38c078)]
|
|
23
|
+
|
|
24
|
+
#### :nail_care: Enhancements
|
|
25
|
+
|
|
26
|
+
- refactor: update import paths for ToolThumbnail and TagOverflowPopup components [kreafox - [`c174abe`](https://github.com/eea/volto-cca-policy/commit/c174abeafcfb8040e43cb496a3f0b10747c057a8)]
|
|
27
|
+
- refactor(navigator): consolidate ToolThumbnail import paths and update related components [kreafox - [`5996b0b`](https://github.com/eea/volto-cca-policy/commit/5996b0b28814cb24c4167d9eb72cf6c632eb2a36)]
|
|
28
|
+
|
|
29
|
+
#### :house: Internal changes
|
|
30
|
+
|
|
31
|
+
- style: Automated code fix [eea-jenkins - [`851dcd2`](https://github.com/eea/volto-cca-policy/commit/851dcd27a6fd162e723b2e6e8fe542d8ab3bc8d1)]
|
|
32
|
+
|
|
7
33
|
### [1.0.25](https://github.com/eea/volto-cca-policy/compare/1.0.24...1.0.25) - 17 September 2026
|
|
8
34
|
|
|
9
35
|
#### :rocket: New Features
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Checkbox, Icon
|
|
2
|
+
import { Checkbox, Icon } from 'semantic-ui-react';
|
|
3
3
|
import { defineMessages, useIntl } from 'react-intl';
|
|
4
4
|
import ExternalLink from '@eeacms/search/components/Result/ExternalLink';
|
|
5
5
|
import ResultContext from '@eeacms/search/components/Result/ResultContext';
|
|
6
|
-
import
|
|
6
|
+
import TagOverflowPopup from '@eeacms/volto-cca-policy/components/theme/TagOverflowPopup';
|
|
7
|
+
import ToolThumbnail from '@eeacms/volto-cca-policy/components/theme/ToolThumbnail/ToolThumbnail';
|
|
7
8
|
import { getToolThumbnailUrl } from '../../theme/ToolThumbnail/utils';
|
|
8
9
|
import {
|
|
9
10
|
getCompareToolTitle,
|
|
@@ -78,27 +79,10 @@ const TagGroup = ({ typeLabel, values, type, maxItems }) => {
|
|
|
78
79
|
</span>
|
|
79
80
|
))}
|
|
80
81
|
{remaining > 0 && (
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<ul>
|
|
86
|
-
{hidden.map((value) => (
|
|
87
|
-
<li key={`${type}-hidden-${value}`}>{value}</li>
|
|
88
|
-
))}
|
|
89
|
-
</ul>
|
|
90
|
-
</div>
|
|
91
|
-
}
|
|
92
|
-
position="bottom left"
|
|
93
|
-
trigger={
|
|
94
|
-
<button
|
|
95
|
-
type="button"
|
|
96
|
-
className={`navigator-tag ${type} more`}
|
|
97
|
-
aria-label={`${typeLabel}: ${hidden.join(', ')}`}
|
|
98
|
-
>
|
|
99
|
-
+ {remaining}
|
|
100
|
-
</button>
|
|
101
|
-
}
|
|
82
|
+
<TagOverflowPopup
|
|
83
|
+
items={hidden}
|
|
84
|
+
className={`navigator-tag ${type} more`}
|
|
85
|
+
ariaLabel={`${typeLabel}: ${hidden.join(', ')}`}
|
|
102
86
|
/>
|
|
103
87
|
)}
|
|
104
88
|
</div>
|
|
@@ -107,6 +91,7 @@ const TagGroup = ({ typeLabel, values, type, maxItems }) => {
|
|
|
107
91
|
|
|
108
92
|
const CycleElements = ({ intl, values }) => {
|
|
109
93
|
const visible = values.slice(0, 3);
|
|
94
|
+
const hidden = values.slice(3);
|
|
110
95
|
|
|
111
96
|
if (!visible.length) return null;
|
|
112
97
|
|
|
@@ -123,6 +108,13 @@ const CycleElements = ({ intl, values }) => {
|
|
|
123
108
|
{value}
|
|
124
109
|
</span>
|
|
125
110
|
))}
|
|
111
|
+
{hidden.length > 0 && (
|
|
112
|
+
<TagOverflowPopup
|
|
113
|
+
items={hidden}
|
|
114
|
+
className="navigator-tag cycle-element more"
|
|
115
|
+
ariaLabel={`${intl.formatMessage(messages.cycle)}: ${hidden.join(', ')}`}
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
126
118
|
</div>
|
|
127
119
|
);
|
|
128
120
|
};
|
|
@@ -141,7 +133,7 @@ const NavigatorCatalogueCardItem = (props) => {
|
|
|
141
133
|
.join(', ');
|
|
142
134
|
const toolProvider = result?._result?.tool_provider?.raw;
|
|
143
135
|
const adaptationSupportCycleSteps = rawValueAsArray(
|
|
144
|
-
result.
|
|
136
|
+
result.cca_adaptation_support_cycle_step,
|
|
145
137
|
)
|
|
146
138
|
.map((value) => {
|
|
147
139
|
const title = value?.title || value;
|
|
@@ -94,7 +94,7 @@ describe('NavigatorCatalogueCardItem', () => {
|
|
|
94
94
|
'Datasets and indicators',
|
|
95
95
|
],
|
|
96
96
|
},
|
|
97
|
-
|
|
97
|
+
cca_adaptation_support_cycle_step: {
|
|
98
98
|
raw: [
|
|
99
99
|
{ title: 'Step 1: Preparing the ground' },
|
|
100
100
|
{ title: 'Step 2: Assessing risks' },
|
|
@@ -131,7 +131,10 @@ describe('NavigatorCatalogueCardItem', () => {
|
|
|
131
131
|
expect(screen.getByText('Resilience')).toBeInTheDocument();
|
|
132
132
|
expect(screen.getByText('Adaptation')).toBeInTheDocument();
|
|
133
133
|
expect(screen.getByText('Step 1')).toBeInTheDocument();
|
|
134
|
-
expect(
|
|
134
|
+
expect(
|
|
135
|
+
screen.getByRole('button', { name: 'Cycle: Step 4' }),
|
|
136
|
+
).toHaveTextContent('+ 1');
|
|
137
|
+
expect(screen.getByText('Step 4')).toBeInTheDocument();
|
|
135
138
|
expect(
|
|
136
139
|
screen.getByTitle(
|
|
137
140
|
'Maps and graphs, Reports and decision support, Datasets and indicators',
|
|
@@ -152,6 +155,22 @@ describe('NavigatorCatalogueCardItem', () => {
|
|
|
152
155
|
});
|
|
153
156
|
});
|
|
154
157
|
|
|
158
|
+
it('shows the cycle steps from the field used by the catalogue filter', () => {
|
|
159
|
+
renderCard({
|
|
160
|
+
title: 'Climate planning tool',
|
|
161
|
+
href: 'https://example.com/tool',
|
|
162
|
+
cca_adaptation_support_cycle_step: {
|
|
163
|
+
raw: ['Step 2: Assessing risks'],
|
|
164
|
+
},
|
|
165
|
+
adaptation_support_cycle_step: {
|
|
166
|
+
raw: [{ title: 'Step 1: Preparing the ground' }],
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
expect(screen.getByText('Step 2')).toBeInTheDocument();
|
|
171
|
+
expect(screen.queryByText('Step 1')).not.toBeInTheDocument();
|
|
172
|
+
});
|
|
173
|
+
|
|
155
174
|
it('renders sparse results and disables comparison without a UID', () => {
|
|
156
175
|
useCompareTools.mockReturnValue({
|
|
157
176
|
isSelected: true,
|
|
@@ -22,7 +22,9 @@ import {
|
|
|
22
22
|
getColorForCount,
|
|
23
23
|
normalizeCountryName,
|
|
24
24
|
buildCountryCounts,
|
|
25
|
+
filterCountryCounts,
|
|
25
26
|
mapLegendItems,
|
|
27
|
+
setCountryFilter,
|
|
26
28
|
} from './utils';
|
|
27
29
|
|
|
28
30
|
const messages = defineMessages({
|
|
@@ -147,10 +149,7 @@ const NavigatorCatalogueMapViewInner = (props) => {
|
|
|
147
149
|
// Handler: replace country filter + switch to list view
|
|
148
150
|
const handleExploreTools = React.useCallback(
|
|
149
151
|
(countryName) => {
|
|
150
|
-
|
|
151
|
-
// Clear existing country filter, then set the new one
|
|
152
|
-
searchContext?.removeFilter(field);
|
|
153
|
-
searchContext?.addFilter(field, countryName, 'any');
|
|
152
|
+
setCountryFilter(searchContext, countryName);
|
|
154
153
|
// Switch to listing view
|
|
155
154
|
views.setActiveViewId('listing');
|
|
156
155
|
},
|
|
@@ -159,8 +158,12 @@ const NavigatorCatalogueMapViewInner = (props) => {
|
|
|
159
158
|
|
|
160
159
|
// Build lookup: countryName -> count
|
|
161
160
|
const countryCounts = React.useMemo(
|
|
162
|
-
() =>
|
|
163
|
-
|
|
161
|
+
() =>
|
|
162
|
+
filterCountryCounts(
|
|
163
|
+
buildCountryCounts(searchContext?.facets),
|
|
164
|
+
searchContext?.filters,
|
|
165
|
+
),
|
|
166
|
+
[searchContext?.facets, searchContext?.filters],
|
|
164
167
|
);
|
|
165
168
|
|
|
166
169
|
const [tileWMSSources, setTileWMSSources] = React.useState(null);
|
|
@@ -3,7 +3,9 @@ import {
|
|
|
3
3
|
getColorForCount,
|
|
4
4
|
normalizeCountryName,
|
|
5
5
|
buildCountryCounts,
|
|
6
|
+
filterCountryCounts,
|
|
6
7
|
mapLegendItems,
|
|
8
|
+
setCountryFilter,
|
|
7
9
|
} from './utils';
|
|
8
10
|
|
|
9
11
|
describe('getColorForCount', () => {
|
|
@@ -135,6 +137,54 @@ describe('buildCountryCounts', () => {
|
|
|
135
137
|
});
|
|
136
138
|
});
|
|
137
139
|
|
|
140
|
+
describe('setCountryFilter', () => {
|
|
141
|
+
it('replaces the current country selection', () => {
|
|
142
|
+
const searchContext = {
|
|
143
|
+
setFilter: jest.fn(),
|
|
144
|
+
addFilter: jest.fn(),
|
|
145
|
+
removeFilter: jest.fn(),
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
setCountryFilter(searchContext, 'Germany');
|
|
149
|
+
|
|
150
|
+
expect(searchContext.setFilter).toHaveBeenCalledWith(
|
|
151
|
+
'cca_geographic_countries.keyword',
|
|
152
|
+
'Germany',
|
|
153
|
+
'any',
|
|
154
|
+
);
|
|
155
|
+
expect(searchContext.addFilter).not.toHaveBeenCalled();
|
|
156
|
+
expect(searchContext.removeFilter).not.toHaveBeenCalled();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('filterCountryCounts', () => {
|
|
161
|
+
const countryCounts = { Spain: 3, France: 7, Germany: 5 };
|
|
162
|
+
|
|
163
|
+
it('shows all country counts without a country filter', () => {
|
|
164
|
+
expect(filterCountryCounts(countryCounts, [])).toEqual(countryCounts);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('shows only countries selected in the country filter', () => {
|
|
168
|
+
expect(
|
|
169
|
+
filterCountryCounts(countryCounts, [
|
|
170
|
+
{
|
|
171
|
+
field: 'cca_geographic_countries.keyword',
|
|
172
|
+
values: ['Spain'],
|
|
173
|
+
type: 'any',
|
|
174
|
+
},
|
|
175
|
+
]),
|
|
176
|
+
).toEqual({ Spain: 3 });
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('ignores filters for other fields', () => {
|
|
180
|
+
expect(
|
|
181
|
+
filterCountryCounts(countryCounts, [
|
|
182
|
+
{ field: 'cca_climate_impacts.keyword', values: ['Flooding'] },
|
|
183
|
+
]),
|
|
184
|
+
).toEqual(countryCounts);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
138
188
|
describe('mapLegendItems', () => {
|
|
139
189
|
it('has 5 legend items', () => {
|
|
140
190
|
expect(mapLegendItems).toHaveLength(5);
|
|
@@ -47,6 +47,28 @@ export const buildCountryCounts = (facets) => {
|
|
|
47
47
|
return counts;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
export const filterCountryCounts = (countryCounts, filters) => {
|
|
51
|
+
const selectedCountries =
|
|
52
|
+
filters?.find(({ field }) => field === 'cca_geographic_countries.keyword')
|
|
53
|
+
?.values || [];
|
|
54
|
+
|
|
55
|
+
if (!selectedCountries.length) return countryCounts;
|
|
56
|
+
|
|
57
|
+
return Object.fromEntries(
|
|
58
|
+
selectedCountries
|
|
59
|
+
.filter((country) => countryCounts[country] !== undefined)
|
|
60
|
+
.map((country) => [country, countryCounts[country]]),
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const setCountryFilter = (searchContext, countryName) => {
|
|
65
|
+
searchContext?.setFilter(
|
|
66
|
+
'cca_geographic_countries.keyword',
|
|
67
|
+
countryName,
|
|
68
|
+
'any',
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
50
72
|
/**
|
|
51
73
|
* Legend items for the map view
|
|
52
74
|
*/
|
|
@@ -6,10 +6,11 @@ import { defineMessages, useIntl } from 'react-intl';
|
|
|
6
6
|
import { Button, Checkbox, Icon, Loader, Message } from 'semantic-ui-react';
|
|
7
7
|
import URLManager from '@elastic/search-ui/lib/cjs/URLManager';
|
|
8
8
|
import { useSearchContext } from '@eeacms/search/lib/hocs';
|
|
9
|
-
import ToolThumbnail from '
|
|
9
|
+
import ToolThumbnail from '@eeacms/volto-cca-policy/components/theme/ToolThumbnail/ToolThumbnail';
|
|
10
10
|
import guideSteps from '../../../search/navigator_guide/guideSteps';
|
|
11
11
|
import { navigatorGuideStepAtom } from '../../../state';
|
|
12
|
-
import { mergeGuideOptions } from './utils';
|
|
12
|
+
import { mergeGuideOptions, sortAdaptationSteps } from './utils';
|
|
13
|
+
import { rawValueAsArray } from '../NavigatorCatalogue/utils';
|
|
13
14
|
import useGuideFacetOptions from './useGuideFacetOptions';
|
|
14
15
|
import { getNavigatorCataloguePageURL } from '../../Search/NavigatorCatalogue/utils';
|
|
15
16
|
|
|
@@ -95,7 +96,7 @@ const isStepSelected = (filters, field) =>
|
|
|
95
96
|
|
|
96
97
|
const previewTagTypes = {
|
|
97
98
|
adaptationSectors: 'sector',
|
|
98
|
-
|
|
99
|
+
climateHazards: 'hazard',
|
|
99
100
|
adaptationStage: 'adaptation-stage',
|
|
100
101
|
coverage: 'coverage',
|
|
101
102
|
};
|
|
@@ -130,31 +131,39 @@ const NavigatorGuideContentView = ({ appConfig }) => {
|
|
|
130
131
|
const hasSelections = steps.some(({ field }) =>
|
|
131
132
|
isStepSelected(filters, field),
|
|
132
133
|
);
|
|
133
|
-
const
|
|
134
|
+
const mergedOptions = mergeGuideOptions(
|
|
134
135
|
allFacetOptions?.[step?.field],
|
|
135
136
|
getFacetOptions(facets, step?.field),
|
|
136
137
|
selectedValues,
|
|
137
138
|
hasSelections,
|
|
138
139
|
);
|
|
140
|
+
const options =
|
|
141
|
+
step?.id === 'adaptationStage'
|
|
142
|
+
? sortAdaptationSteps(mergedOptions)
|
|
143
|
+
: mergedOptions;
|
|
139
144
|
const isLastStep = activeStep === steps.length - 1;
|
|
140
145
|
const selectedStepLabels = steps
|
|
141
146
|
.filter(({ field }) => isStepSelected(filters, field))
|
|
142
147
|
.map(({ label }) =>
|
|
143
148
|
intl.formatMessage(label).toLocaleLowerCase(currentLang),
|
|
144
149
|
);
|
|
145
|
-
const selectedPreviewTags =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
const selectedPreviewTags = (result) =>
|
|
151
|
+
steps.flatMap((item) => {
|
|
152
|
+
const values =
|
|
153
|
+
(filters || []).find((filter) => filter.field === item.field)?.values ||
|
|
154
|
+
[];
|
|
149
155
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
const resultValues = rawValueAsArray(
|
|
157
|
+
result[item.field.replace('.keyword', '')],
|
|
158
|
+
).map((value) => value?.title || value);
|
|
159
|
+
|
|
160
|
+
return values
|
|
161
|
+
.filter((value) => resultValues.includes(value))
|
|
162
|
+
.map((value) => ({
|
|
163
|
+
label: item.id === 'adaptationStage' ? value.split(':')[0] : value,
|
|
164
|
+
type: previewTagTypes[item.id],
|
|
165
|
+
}));
|
|
166
|
+
});
|
|
158
167
|
|
|
159
168
|
React.useEffect(() => {
|
|
160
169
|
if (storedActiveStep !== activeStep) {
|
|
@@ -204,88 +213,94 @@ const NavigatorGuideContentView = ({ appConfig }) => {
|
|
|
204
213
|
|
|
205
214
|
<div className="navigator-guide-layout">
|
|
206
215
|
<section className="navigator-guide-wizard">
|
|
207
|
-
<div className="navigator-guide-
|
|
208
|
-
|
|
209
|
-
<
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
<div className="navigator-guide-wizard-content">
|
|
217
|
+
<div className="navigator-guide-progress-wrapper">
|
|
218
|
+
<div className="navigator-guide-progress">
|
|
219
|
+
{steps.map((item, index) => (
|
|
220
|
+
<React.Fragment key={item.id}>
|
|
221
|
+
<Button
|
|
222
|
+
className={`navigator-guide-progress-step${
|
|
223
|
+
index === activeStep ? ' active' : ''
|
|
224
|
+
}${index < activeStep ? ' completed' : ''}`}
|
|
225
|
+
aria-current={index === activeStep ? 'step' : undefined}
|
|
226
|
+
onClick={() => setActiveStep(index)}
|
|
227
|
+
>
|
|
228
|
+
<span>
|
|
229
|
+
{isStepSelected(filters, item.field) ? (
|
|
230
|
+
<Icon className="ri-check-line" />
|
|
231
|
+
) : (
|
|
232
|
+
index + 1
|
|
233
|
+
)}
|
|
234
|
+
</span>
|
|
235
|
+
{intl.formatMessage(item.label)}
|
|
236
|
+
</Button>
|
|
237
|
+
{index < steps.length - 1 && (
|
|
238
|
+
<span
|
|
239
|
+
className={`navigator-guide-progress-connector${
|
|
240
|
+
index < activeStep ? ' completed' : ''
|
|
241
|
+
}`}
|
|
242
|
+
aria-hidden="true"
|
|
243
|
+
/>
|
|
222
244
|
)}
|
|
223
|
-
</
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
</React.Fragment>
|
|
246
|
+
))}
|
|
247
|
+
</div>
|
|
248
|
+
<div
|
|
249
|
+
className="navigator-guide-progress-bar"
|
|
250
|
+
role="progressbar"
|
|
251
|
+
aria-valuemin="1"
|
|
252
|
+
aria-valuemax={steps.length}
|
|
253
|
+
aria-valuenow={activeStep + 1}
|
|
254
|
+
>
|
|
255
|
+
<div
|
|
256
|
+
className="navigator-guide-progress-bar-fill"
|
|
257
|
+
style={{
|
|
258
|
+
width: `${((activeStep + 1) / steps.length) * 100}%`,
|
|
259
|
+
}}
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
<div className="navigator-guide-step-meta">
|
|
263
|
+
<span className="navigator-guide-step-number">
|
|
264
|
+
{intl.formatMessage(messages.stepProgress, {
|
|
265
|
+
current: activeStep + 1,
|
|
266
|
+
total: steps.length,
|
|
267
|
+
})}
|
|
268
|
+
</span>
|
|
269
|
+
<span>{intl.formatMessage(messages.selectAllThatApply)}</span>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
249
272
|
|
|
250
|
-
|
|
251
|
-
<
|
|
252
|
-
{intl.formatMessage(messages.stepProgress, {
|
|
253
|
-
current: activeStep + 1,
|
|
254
|
-
total: steps.length,
|
|
255
|
-
})}
|
|
256
|
-
</span>
|
|
257
|
-
<span>{intl.formatMessage(messages.selectAllThatApply)}</span>
|
|
258
|
-
</div>
|
|
259
|
-
<h3>{intl.formatMessage(step.title)}</h3>
|
|
260
|
-
{step.description && <p>{intl.formatMessage(step.description)}</p>}
|
|
273
|
+
<h3>{intl.formatMessage(step.title)}</h3>
|
|
274
|
+
{step.description && <p>{intl.formatMessage(step.description)}</p>}
|
|
261
275
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
276
|
+
{isLoading ? (
|
|
277
|
+
<div className="navigator-guide-options-loading">
|
|
278
|
+
<Loader active inline />
|
|
279
|
+
</div>
|
|
280
|
+
) : options.length > 0 ? (
|
|
281
|
+
<div className="navigator-guide-options">
|
|
282
|
+
{options.map((option) => (
|
|
283
|
+
<label
|
|
284
|
+
key={option.value}
|
|
285
|
+
className={`navigator-guide-option${
|
|
286
|
+
selectedValues.includes(option.value) ? ' selected' : ''
|
|
287
|
+
}${option.disabled ? ' disabled' : ''}`}
|
|
288
|
+
aria-disabled={option.disabled || undefined}
|
|
289
|
+
>
|
|
290
|
+
<Checkbox
|
|
291
|
+
checked={selectedValues.includes(option.value)}
|
|
292
|
+
disabled={option.disabled}
|
|
293
|
+
onChange={() => toggleValue(option.value)}
|
|
294
|
+
/>
|
|
295
|
+
<span>{option.value}</span>
|
|
296
|
+
<small>{option.count}</small>
|
|
297
|
+
</label>
|
|
298
|
+
))}
|
|
299
|
+
</div>
|
|
300
|
+
) : (
|
|
301
|
+
<Message>{intl.formatMessage(messages.noOptions)}</Message>
|
|
302
|
+
)}
|
|
303
|
+
</div>
|
|
289
304
|
|
|
290
305
|
<div className="navigator-guide-actions">
|
|
291
306
|
<Button
|
|
@@ -346,53 +361,56 @@ const NavigatorGuideContentView = ({ appConfig }) => {
|
|
|
346
361
|
<div className="navigator-guide-preview-results">
|
|
347
362
|
{(results || [])
|
|
348
363
|
.slice(0, appConfig.previewResultsLimit)
|
|
349
|
-
.map((result) =>
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
<
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
>
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
{
|
|
377
|
-
|
|
364
|
+
.map((result) => {
|
|
365
|
+
const tags = selectedPreviewTags(result);
|
|
366
|
+
const visibleTags = tags.slice(0, 3);
|
|
367
|
+
const remainingTags = tags.length - visibleTags.length;
|
|
368
|
+
return (
|
|
369
|
+
<div
|
|
370
|
+
className="navigator-guide-preview-result"
|
|
371
|
+
key={result._original?._id || result.href}
|
|
372
|
+
>
|
|
373
|
+
<ToolThumbnail
|
|
374
|
+
result={result}
|
|
375
|
+
fallbackIcon="ri-stack-line"
|
|
376
|
+
/>
|
|
377
|
+
<div className="navigator-guide-preview-result-content">
|
|
378
|
+
<small
|
|
379
|
+
className="navigator-tool-provider"
|
|
380
|
+
title={result?._result?.tool_provider?.raw}
|
|
381
|
+
>
|
|
382
|
+
{result?._result?.tool_provider?.raw}
|
|
383
|
+
</small>
|
|
384
|
+
<a
|
|
385
|
+
href={result.href}
|
|
386
|
+
target="_blank"
|
|
387
|
+
rel="noopener noreferrer"
|
|
388
|
+
className="navigator-guide-preview-result-title"
|
|
389
|
+
title={result.title}
|
|
390
|
+
>
|
|
391
|
+
<h5>{result.title}</h5>
|
|
392
|
+
</a>
|
|
393
|
+
{tags.length > 0 && (
|
|
394
|
+
<div className="navigator-guide-preview-tags">
|
|
395
|
+
{visibleTags.map(({ label, type }, index) => (
|
|
378
396
|
<span
|
|
379
397
|
className={`navigator-tag ${type}`}
|
|
380
398
|
key={`${type}-${label}-${index}`}
|
|
381
399
|
>
|
|
382
400
|
{label}
|
|
383
401
|
</span>
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
402
|
+
))}
|
|
403
|
+
{remainingTags > 0 && (
|
|
404
|
+
<span className="navigator-guide-preview-tag-more">
|
|
405
|
+
+ {remainingTags}
|
|
406
|
+
</span>
|
|
407
|
+
)}
|
|
408
|
+
</div>
|
|
409
|
+
)}
|
|
410
|
+
</div>
|
|
393
411
|
</div>
|
|
394
|
-
|
|
395
|
-
)
|
|
412
|
+
);
|
|
413
|
+
})}
|
|
396
414
|
</div>
|
|
397
415
|
<Button
|
|
398
416
|
labelPosition="right"
|