@truedat/core 7.5.7 → 7.5.10
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/package.json +34 -68
- package/src/__tests__/routesTree.spec.js +108 -0
- package/src/api/queries.js +10 -0
- package/src/api.js +3 -0
- package/src/components/AddMemberForm.js +10 -10
- package/src/components/AddResourceMember.js +0 -2
- package/src/components/AdminMenu.js +0 -1
- package/src/components/AiMenu.js +0 -1
- package/src/components/Alert.js +1 -1
- package/src/components/AlertExporter.js +0 -1
- package/src/components/ArrayDecorator.js +0 -1
- package/src/components/Authorized.js +2 -2
- package/src/components/AvailableFilters.js +1 -2
- package/src/components/CSVFileModal.js +1 -1
- package/src/components/CardGroupsAccordion.js +1 -1
- package/src/components/CatalogMenu.js +1 -2
- package/src/components/CommentRow.js +7 -8
- package/src/components/Comments.js +3 -4
- package/src/components/CommentsForm.js +2 -2
- package/src/components/ConfirmModal.js +0 -1
- package/src/components/CursorPagination.js +1 -2
- package/src/components/DashboardMenu.js +0 -1
- package/src/components/Date.js +0 -1
- package/src/components/DateFilter.js +1 -1
- package/src/components/DateRangeFilter.js +1 -1
- package/src/components/DateTime.js +0 -1
- package/src/components/DescriptionInput.js +1 -1
- package/src/components/DomainSelector.js +2 -3
- package/src/components/DropdownMenuItem.js +0 -1
- package/src/components/ErrorBoundary.js +8 -7
- package/src/components/FieldLabel.js +0 -1
- package/src/components/FilterDropdown.js +3 -3
- package/src/components/FilterItem.js +0 -1
- package/src/components/FilterMultilevelDropdown.js +1 -1
- package/src/components/GenericCrumbs.js +3 -4
- package/src/components/GlossaryMenu.js +24 -31
- package/src/components/GrantMenu.js +0 -1
- package/src/components/GroupActions.js +15 -15
- package/src/components/Hierarchy.js +7 -10
- package/src/components/HierarchyFilterDropdown.js +1 -2
- package/src/components/HierarchyNodeFinder.js +4 -4
- package/src/components/HierarchySelector.js +1 -2
- package/src/components/HistoryBackButton.js +6 -6
- package/src/components/IngestMenu.js +0 -1
- package/src/components/LanguagesTabs.js +4 -4
- package/src/components/LineageMenu.js +0 -1
- package/src/components/Loading.js +1 -2
- package/src/components/MembersMenu.js +0 -1
- package/src/components/ModalSaveFilter.js +1 -1
- package/src/components/NodeOpenActions.js +0 -1
- package/src/components/OptionGroup.js +1 -2
- package/src/components/OptionModal.js +0 -1
- package/src/components/Pagination.js +0 -1
- package/src/components/QualityMenu.js +0 -1
- package/src/components/QxMenu.js +0 -1
- package/src/components/Redirector.js +3 -3
- package/src/components/ResourceMember.js +1 -2
- package/src/components/ResourceMembers.js +3 -3
- package/src/components/ResourceMembersActions.js +1 -2
- package/src/components/RichTextEditor.js +7 -8
- package/src/components/RouteListener.js +11 -32
- package/src/components/SafeLink.js +0 -1
- package/src/components/ScrollToTop.js +13 -16
- package/src/components/SearchFilterDropdown.js +1 -1
- package/src/components/SearchInput.js +3 -3
- package/src/components/SearchMenu.js +0 -1
- package/src/components/SelectedFilters.js +1 -2
- package/src/components/SideMenu.js +0 -1
- package/src/components/SidebarToggle.js +2 -2
- package/src/components/StructureFilterItem.js +0 -1
- package/src/components/Submenu.js +8 -7
- package/src/components/SystemsLoader.js +27 -0
- package/src/components/TaxonomyMenu.js +0 -1
- package/src/components/TemplateSelector.js +1 -1
- package/src/components/TemplatesLoader.js +24 -0
- package/src/components/TreeSelector.js +4 -4
- package/src/components/Unauthorized.js +0 -1
- package/src/components/UploadModal.js +152 -176
- package/src/components/UserFilter.js +0 -2
- package/src/components/UserFilters.js +0 -2
- package/src/components/__tests__/AddMemberForm.spec.js +26 -38
- package/src/components/__tests__/AddResourceMember.spec.js +0 -1
- package/src/components/__tests__/AdminMenu.spec.js +0 -1
- package/src/components/__tests__/Alert.spec.js +17 -21
- package/src/components/__tests__/AvailableFilters.spec.js +19 -14
- package/src/components/__tests__/CardGroupsAccordion.spec.js +24 -15
- package/src/components/__tests__/CatalogMenu.spec.js +27 -45
- package/src/components/__tests__/CommentsLoader.spec.js +17 -14
- package/src/components/__tests__/CursorPagination.spec.js +0 -1
- package/src/components/__tests__/DashboardMenu.spec.js +0 -1
- package/src/components/__tests__/DateFilter.spec.js +6 -28
- package/src/components/__tests__/DateTime.spec.js +0 -1
- package/src/components/__tests__/DomainSelector.spec.js +4 -4
- package/src/components/__tests__/DropdownMenuItem.spec.js +0 -1
- package/src/components/__tests__/FilterDropdown.spec.js +28 -27
- package/src/components/__tests__/FilterItem.spec.js +19 -20
- package/src/components/__tests__/FilterMultilevelDropdown.spec.js +16 -16
- package/src/components/__tests__/FiltersLoader.spec.js +25 -20
- package/src/components/__tests__/GenericCrumbs.spec.js +0 -1
- package/src/components/__tests__/GlossaryMenu.spec.js +0 -1
- package/src/components/__tests__/GrantMenu.spec.js +0 -1
- package/src/components/__tests__/GroupActions.spec.js +0 -1
- package/src/components/__tests__/Hierarchy.spec.js +0 -1
- package/src/components/__tests__/HierarchyFilterDropdown.spec.js +16 -14
- package/src/components/__tests__/HierarchyNodeFinder.spec.js +0 -1
- package/src/components/__tests__/HierarchySelector.spec.js +28 -35
- package/src/components/__tests__/HistoryBackButton.spec.js +23 -23
- package/src/components/__tests__/IngestMenu.spec.js +0 -1
- package/src/components/__tests__/LineageMenu.spec.js +0 -1
- package/src/components/__tests__/Loading.spec.js +4 -5
- package/src/components/__tests__/MembersMenu.spec.js +0 -1
- package/src/components/__tests__/ModalSaveFilter.spec.js +0 -1
- package/src/components/__tests__/OptionGroup.spec.js +5 -7
- package/src/components/__tests__/Pagination.spec.js +22 -16
- package/src/components/__tests__/QualityMenu.spec.js +0 -1
- package/src/components/__tests__/Redirector.spec.js +5 -10
- package/src/components/__tests__/ResourceMembers.spec.js +36 -27
- package/src/components/__tests__/ResourceMembersAction.spec.js +1 -2
- package/src/components/__tests__/RouteListener.spec.js +25 -26
- package/src/components/__tests__/SafeLink.spec.js +0 -1
- package/src/components/__tests__/SearchDateFilter.spec.js +0 -1
- package/src/components/__tests__/SearchFilterDropdown.spec.js +32 -24
- package/src/components/__tests__/SearchInput.spec.js +5 -5
- package/src/components/__tests__/SearchMenu.spec.js +0 -1
- package/src/components/__tests__/SelectedFilters.spec.js +50 -47
- package/src/components/__tests__/SideMenu.spec.js +5 -8
- package/src/components/__tests__/StructureFilterItem.spec.js +13 -11
- package/src/components/__tests__/Submenu.spec.js +0 -1
- package/src/components/__tests__/SystemsLoader.spec.js +40 -0
- package/src/components/__tests__/TaxonomyMenu.spec.js +0 -1
- package/src/components/__tests__/TemplateSelector.spec.js +27 -29
- package/src/components/__tests__/TemplatesLoader.spec.js +30 -0
- package/src/components/__tests__/TreeSelector.spec.js +110 -83
- package/src/components/__tests__/UploadModal.spec.js +171 -0
- package/src/components/__tests__/UserFilters.spec.js +44 -37
- package/src/components/__tests__/__snapshots__/AddMemberForm.spec.js.snap +1 -0
- package/src/components/__tests__/__snapshots__/AddResourceMember.spec.js.snap +10 -9
- package/src/components/__tests__/__snapshots__/AdminMenu.spec.js.snap +22 -11
- package/src/components/__tests__/__snapshots__/Alert.spec.js.snap +29 -17
- package/src/components/__tests__/__snapshots__/AvailableFilters.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/CatalogMenu.spec.js.snap +18 -8
- package/src/components/__tests__/__snapshots__/CursorPagination.spec.js.snap +3 -0
- package/src/components/__tests__/__snapshots__/DateFilter.spec.js.snap +165 -107
- package/src/components/__tests__/__snapshots__/DomainSelector.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/FilterItem.spec.js.snap +13 -20
- package/src/components/__tests__/__snapshots__/GlossaryMenu.spec.js.snap +8 -0
- package/src/components/__tests__/__snapshots__/GrantMenu.spec.js.snap +14 -7
- package/src/components/__tests__/__snapshots__/GroupActions.spec.js.snap +0 -1
- package/src/components/__tests__/__snapshots__/Hierarchy.spec.js.snap +0 -1
- package/src/components/__tests__/__snapshots__/HierarchySelector.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/HistoryBackButton.spec.js.snap +10 -20
- package/src/components/__tests__/__snapshots__/IngestMenu.spec.js.snap +3 -1
- package/src/components/__tests__/__snapshots__/LineageMenu.spec.js.snap +6 -3
- package/src/components/__tests__/__snapshots__/Loading.spec.js.snap +5 -4
- package/src/components/__tests__/__snapshots__/MembersMenu.spec.js.snap +6 -3
- package/src/components/__tests__/__snapshots__/OptionGroup.spec.js.snap +38 -28
- package/src/components/__tests__/__snapshots__/Pagination.spec.js.snap +213 -64
- package/src/components/__tests__/__snapshots__/QualityMenu.spec.js.snap +14 -8
- package/src/components/__tests__/__snapshots__/ResourceMembers.spec.js.snap +1 -0
- package/src/components/__tests__/__snapshots__/ResourceMembersAction.spec.js.snap +2 -1
- package/src/components/__tests__/__snapshots__/RouteListener.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/SearchInput.spec.js.snap +10 -12
- package/src/components/__tests__/__snapshots__/SearchMenu.spec.js.snap +3 -1
- package/src/components/__tests__/__snapshots__/SelectedFilters.spec.js.snap +8 -8
- package/src/components/__tests__/__snapshots__/SideMenu.spec.js.snap +112 -50
- package/src/components/__tests__/__snapshots__/Submenu.spec.js.snap +3 -0
- package/src/components/__tests__/__snapshots__/SystemsLoader.spec.js.snap +3 -0
- package/src/components/__tests__/__snapshots__/TaxonomyMenu.spec.js.snap +3 -1
- package/src/components/__tests__/__snapshots__/TemplateSelector.spec.js.snap +7 -7
- package/src/components/common/SearchContextWrapper.js +1 -4
- package/src/hooks/__mocks__/useAuthorized.js +2 -0
- package/src/hooks/__mocks__/useUserFilters.js +17 -0
- package/src/hooks/__tests__/{useAclEntries.spec.js → useAclEntries.spec.js.disabled} +1 -1
- package/src/hooks/__tests__/useAuthorized.spec.js +1 -1
- package/src/hooks/useAclEntries.js +6 -3
- package/src/hooks/useActiveRoute.js +3 -3
- package/src/hooks/useActiveRoutes.js +4 -4
- package/src/hooks/useHierarchies.js +112 -0
- package/src/hooks/useLocales.js +1 -1
- package/src/hooks/useMessages.js +1 -1
- package/src/hooks/usePath.js +4 -4
- package/src/hooks/useUserFilters.js +1 -1
- package/src/i18n/components/EditableCell.js +1 -1
- package/src/i18n/components/I18nRoutes.js +11 -16
- package/src/i18n/components/LangProvider.js +56 -101
- package/src/i18n/components/LangProviderWrapper.js +26 -33
- package/src/i18n/components/Languages.js +8 -7
- package/src/i18n/components/MessageForm.js +9 -23
- package/src/i18n/components/Messages.js +5 -4
- package/src/i18n/components/MessagesTable.js +0 -1
- package/src/i18n/components/NewMessage.js +5 -4
- package/src/i18n/components/__tests__/EditableCell.spec.js +18 -20
- package/src/i18n/components/__tests__/I18nRoutes.spec.js +39 -5
- package/src/i18n/components/__tests__/MessageForm.spec.js +0 -1
- package/src/i18n/components/__tests__/Messages.spec.js +9 -21
- package/src/i18n/components/__tests__/NewMessage.spec.js +0 -1
- package/src/i18n/components/__tests__/__snapshots__/I18nRoutes.spec.js.snap +25 -1
- package/src/i18n/components/__tests__/__snapshots__/MessageForm.spec.js.snap +1 -0
- package/src/i18n/components/__tests__/__snapshots__/Messages.spec.js.snap +5 -13
- package/src/i18n/components/__tests__/__snapshots__/NewMessage.spec.js.snap +2 -0
- package/src/reducers/__tests__/comments.spec.js +9 -6
- package/src/reducers/__tests__/commentsResource.spec.js +5 -2
- package/src/reducers/__tests__/coreMessage.spec.js +1 -1
- package/src/reducers/__tests__/dashboardDomains.spec.js +5 -5
- package/src/reducers/__tests__/systems.spec.js +42 -0
- package/src/reducers/__tests__/systemsLoading.spec.js +22 -0
- package/src/reducers/index.js +5 -1
- package/src/reducers/systems.js +19 -0
- package/src/reducers/systemsLoading.js +14 -0
- package/src/router/Loader.js +10 -0
- package/src/router/ProtectedRoute.js +11 -0
- package/src/router/Unauthorized.js +16 -0
- package/src/router/__tests__/ProtectedRoute.spec.js +49 -0
- package/src/router/__tests__/Unauthorized.spec.js +15 -0
- package/src/router/__tests__/__snapshots__/ProtectedRoute.spec.js.snap +44 -0
- package/src/router/__tests__/__snapshots__/Unauthorized.spec.js.snap +26 -0
- package/src/router/index.js +5 -0
- package/src/routes.js +7 -7
- package/src/routesTree.js +93 -0
- package/src/routines.js +8 -0
- package/src/sagas/__tests__/addComment.spec.js +3 -5
- package/src/sagas/__tests__/fetchComments.spec.js +1 -1
- package/src/sagas/__tests__/fetchSystems.spec.js +69 -0
- package/src/sagas/fetchSystems.js +25 -0
- package/src/sagas/index.js +3 -0
- package/src/search/FilterDropdown.js +0 -1
- package/src/search/FilterItem.js +0 -1
- package/src/search/FilterMultilevelDropdown.js +1 -1
- package/src/search/FilterQueryDropdown.js +38 -42
- package/src/search/HierarchyFilterDropdown.js +3 -4
- package/src/search/ModalSaveFilter.js +1 -1
- package/src/search/Pagination.js +0 -1
- package/src/search/SearchContext.js +9 -11
- package/src/search/SearchDateFilter.js +0 -1
- package/src/search/SearchFilters.js +1 -2
- package/src/search/SearchSelectedFilters.js +4 -4
- package/src/search/SearchWidget.js +0 -4
- package/src/search/UserFilter.js +0 -2
- package/src/search/UserFilters.js +4 -3
- package/src/search/__tests__/FilterDropdown.spec.js +54 -51
- package/src/search/__tests__/FilterItem.spec.js +20 -15
- package/src/search/__tests__/FilterQueryDropdown.spec.js +106 -84
- package/src/search/__tests__/ModalSaveFilter.spec.js +4 -5
- package/src/search/__tests__/SearchContext.spec.js +3 -4
- package/src/search/__tests__/SearchWidget.spec.js +0 -1
- package/src/selectors/__tests__/getConceptSubscope.spec.js +37 -0
- package/src/selectors/__tests__/getDashboardConfig.spec.js +9 -9
- package/src/selectors/__tests__/getMessage.spec.js +1 -1
- package/src/selectors/__tests__/getSidemenuGlossarySubscopes.spec.js +17 -0
- package/src/selectors/__tests__/makeActiveFiltersSelector.spec.js +2 -2
- package/src/selectors/__tests__/makeSearchQuerySelector.spec.js +1 -1
- package/src/selectors/__tests__/makeTagOptionsSelector.spec.js +6 -6
- package/src/selectors/getConceptSubscope.js +19 -0
- package/src/selectors/getMessage.js +2 -2
- package/src/selectors/getRecipients.js +34 -0
- package/src/selectors/getSidemenuGlossarySubscopes.js +8 -0
- package/src/selectors/index.js +5 -0
- package/src/selectors/makeActiveFiltersSelector.js +2 -6
- package/src/selectors/makeSearchQuerySelector.js +4 -11
- package/src/selectors/makeTagOptionsSelector.js +4 -8
- package/src/selectors/subscopedTemplates.js +16 -0
- package/src/selectors/taxonomy.js +170 -0
- package/src/services/__tests__/columnDecorator.spec.js +1 -1
- package/src/services/__tests__/dateFilterFormatter.spec.js +2 -2
- package/src/services/__tests__/fieldType.spec.js +2 -2
- package/src/services/__tests__/filters.spec.js +1 -1
- package/src/services/__tests__/message.spec.js +2 -2
- package/src/services/__tests__/operators.spec.js +5 -5
- package/src/services/__tests__/sort.spec.js +8 -8
- package/src/services/__tests__/storage.spec.js +17 -0
- package/src/services/arrays.js +16 -14
- package/src/services/columnDecoratorComponent.js +2 -2
- package/src/services/columnDecorators.js +0 -1
- package/src/services/fieldType.js +8 -8
- package/src/services/filters.js +5 -5
- package/src/services/message.js +1 -4
- package/src/services/operators.js +1 -1
package/src/reducers/index.js
CHANGED
|
@@ -4,6 +4,8 @@ import { commentsResource } from "./commentsResource";
|
|
|
4
4
|
import { coreMessage } from "./coreMessage";
|
|
5
5
|
import { dashboardDomains } from "./dashboardDomains";
|
|
6
6
|
import { sidebarVisible } from "./sidebarVisible";
|
|
7
|
+
import { systems } from "./systems";
|
|
8
|
+
import { systemsLoading } from "./systemsLoading";
|
|
7
9
|
|
|
8
10
|
export {
|
|
9
11
|
commentsLoading,
|
|
@@ -11,5 +13,7 @@ export {
|
|
|
11
13
|
commentsResource,
|
|
12
14
|
coreMessage,
|
|
13
15
|
dashboardDomains,
|
|
14
|
-
sidebarVisible
|
|
16
|
+
sidebarVisible,
|
|
17
|
+
systems,
|
|
18
|
+
systemsLoading,
|
|
15
19
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { fetchSystems, clearSystems } from "../routines";
|
|
3
|
+
|
|
4
|
+
const initialState = [];
|
|
5
|
+
|
|
6
|
+
const systems = (state = initialState, { type, payload }) => {
|
|
7
|
+
switch (type) {
|
|
8
|
+
case fetchSystems.TRIGGER:
|
|
9
|
+
return initialState;
|
|
10
|
+
case clearSystems.TRIGGER:
|
|
11
|
+
return initialState;
|
|
12
|
+
case fetchSystems.SUCCESS:
|
|
13
|
+
return _.propOr([], "data")(payload);
|
|
14
|
+
default:
|
|
15
|
+
return state;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { systems };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fetchSystems } from "../routines";
|
|
2
|
+
|
|
3
|
+
const systemsLoading = (state = false, { type }) => {
|
|
4
|
+
switch (type) {
|
|
5
|
+
case fetchSystems.TRIGGER:
|
|
6
|
+
return true;
|
|
7
|
+
case fetchSystems.FULFILL:
|
|
8
|
+
return false;
|
|
9
|
+
default:
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { systemsLoading };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Outlet } from "react-router";
|
|
2
|
+
import { useAuthorized } from "@truedat/core/hooks/useAuthorized";
|
|
3
|
+
import Unauthorized from "@truedat/core/router/Unauthorized";
|
|
4
|
+
|
|
5
|
+
export default function ProtectedRoute({ authorization, children }) {
|
|
6
|
+
const isAllowed = useAuthorized(authorization);
|
|
7
|
+
if (!isAllowed) {
|
|
8
|
+
return <Unauthorized />;
|
|
9
|
+
}
|
|
10
|
+
return children ? children : <Outlet />;
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useIntl } from "react-intl";
|
|
2
|
+
import { Message } from "semantic-ui-react";
|
|
3
|
+
|
|
4
|
+
export default function Unauthorized() {
|
|
5
|
+
const { formatMessage } = useIntl();
|
|
6
|
+
return (
|
|
7
|
+
<Message
|
|
8
|
+
icon="warning sign"
|
|
9
|
+
className="center"
|
|
10
|
+
header={formatMessage({ id: "view.unauthorized.head" })}
|
|
11
|
+
content={formatMessage({ id: "view.unauthorized.content" })}
|
|
12
|
+
attached="bottom"
|
|
13
|
+
visible
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { render, waitForLoad } from "@truedat/test/render";
|
|
2
|
+
import ProtectedRoute from "../ProtectedRoute";
|
|
3
|
+
import { useAuthorized } from "@truedat/core/hooks/useAuthorized";
|
|
4
|
+
|
|
5
|
+
// Mock the hooks module
|
|
6
|
+
jest.mock("@truedat/core/hooks/useAuthorized", () => ({
|
|
7
|
+
useAuthorized: jest.fn(() => true),
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
// Mock the Outlet component
|
|
11
|
+
jest.mock("react-router", () => ({
|
|
12
|
+
...jest.requireActual("react-router"),
|
|
13
|
+
Outlet: () => <div data-testid="outlet">Outlet Content</div>,
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
describe("ProtectedRoute", () => {
|
|
17
|
+
it("renders unauthorized message when not authorized", async () => {
|
|
18
|
+
useAuthorized.mockReturnValueOnce(false);
|
|
19
|
+
|
|
20
|
+
const rendered = render(<ProtectedRoute authorization="some_permission" />);
|
|
21
|
+
await waitForLoad(rendered);
|
|
22
|
+
|
|
23
|
+
expect(rendered.getByText(/view.unauthorized.head/i)).toBeInTheDocument();
|
|
24
|
+
expect(
|
|
25
|
+
rendered.getByText(/view.unauthorized.content/i),
|
|
26
|
+
).toBeInTheDocument();
|
|
27
|
+
expect(rendered.container).toMatchSnapshot();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("renders children when authorized and children are provided", async () => {
|
|
31
|
+
const rendered = render(
|
|
32
|
+
<ProtectedRoute authorization="some_permission">
|
|
33
|
+
<div>Protected Content</div>
|
|
34
|
+
</ProtectedRoute>,
|
|
35
|
+
);
|
|
36
|
+
await waitForLoad(rendered);
|
|
37
|
+
|
|
38
|
+
expect(rendered.getByText(/protected content/i)).toBeInTheDocument();
|
|
39
|
+
expect(rendered.container).toMatchSnapshot();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("renders outlet when authorized and no children are provided", async () => {
|
|
43
|
+
const rendered = render(<ProtectedRoute authorization="some_permission" />);
|
|
44
|
+
await waitForLoad(rendered);
|
|
45
|
+
|
|
46
|
+
expect(rendered.getByTestId("outlet")).toBeInTheDocument();
|
|
47
|
+
expect(rendered.container).toMatchSnapshot();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { render, waitForLoad } from "@truedat/test/render";
|
|
2
|
+
import Unauthorized from "../Unauthorized";
|
|
3
|
+
|
|
4
|
+
describe("Unauthorized", () => {
|
|
5
|
+
it("renders unauthorized message", async () => {
|
|
6
|
+
const rendered = render(<Unauthorized />);
|
|
7
|
+
await waitForLoad(rendered);
|
|
8
|
+
|
|
9
|
+
expect(rendered.getByText(/view.unauthorized.head/i)).toBeInTheDocument();
|
|
10
|
+
expect(
|
|
11
|
+
rendered.getByText(/view.unauthorized.content/i),
|
|
12
|
+
).toBeInTheDocument();
|
|
13
|
+
expect(rendered.container).toMatchSnapshot();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`ProtectedRoute renders children when authorized and children are provided 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div>
|
|
6
|
+
Protected Content
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
exports[`ProtectedRoute renders outlet when authorized and no children are provided 1`] = `
|
|
12
|
+
<div>
|
|
13
|
+
<div
|
|
14
|
+
data-testid="outlet"
|
|
15
|
+
>
|
|
16
|
+
Outlet Content
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
exports[`ProtectedRoute renders unauthorized message when not authorized 1`] = `
|
|
22
|
+
<div>
|
|
23
|
+
<div
|
|
24
|
+
class="ui icon visible bottom attached message center"
|
|
25
|
+
>
|
|
26
|
+
<i
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
class="warning sign icon"
|
|
29
|
+
/>
|
|
30
|
+
<div
|
|
31
|
+
class="content"
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
class="header"
|
|
35
|
+
>
|
|
36
|
+
view.unauthorized.head
|
|
37
|
+
</div>
|
|
38
|
+
<p>
|
|
39
|
+
view.unauthorized.content
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Unauthorized renders unauthorized message 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui icon visible bottom attached message center"
|
|
7
|
+
>
|
|
8
|
+
<i
|
|
9
|
+
aria-hidden="true"
|
|
10
|
+
class="warning sign icon"
|
|
11
|
+
/>
|
|
12
|
+
<div
|
|
13
|
+
class="content"
|
|
14
|
+
>
|
|
15
|
+
<div
|
|
16
|
+
class="header"
|
|
17
|
+
>
|
|
18
|
+
view.unauthorized.head
|
|
19
|
+
</div>
|
|
20
|
+
<p>
|
|
21
|
+
view.unauthorized.content
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
`;
|
package/src/routes.js
CHANGED
|
@@ -97,10 +97,10 @@ export const HIERARCHY_CREATE = "/hierarchies/new";
|
|
|
97
97
|
export const I18N = "/i18n";
|
|
98
98
|
export const I18N_MESSAGES = "/i18n/messages";
|
|
99
99
|
export const I18N_MESSAGES_NEW = "/i18n/messages/new";
|
|
100
|
-
export const IMPLEMENTATION = "/implementations/:implementation_id
|
|
100
|
+
export const IMPLEMENTATION = "/implementations/:implementation_id";
|
|
101
101
|
export const IMPLEMENTATIONS = "/implementations";
|
|
102
|
-
export const IMPLEMENTATIONS_DEPRECATED = "/
|
|
103
|
-
export const IMPLEMENTATIONS_PENDING = "/
|
|
102
|
+
export const IMPLEMENTATIONS_DEPRECATED = "/implementations/deprecated";
|
|
103
|
+
export const IMPLEMENTATIONS_PENDING = "/implementations/pending";
|
|
104
104
|
export const IMPLEMENTATION_CLONE = "/implementations/:implementation_id/clone";
|
|
105
105
|
export const IMPLEMENTATION_CONCEPT_LINKS =
|
|
106
106
|
"/implementations/:implementation_id/links/concepts";
|
|
@@ -196,7 +196,7 @@ export const RESOURCE_MAPPINGS = "/resource_mappings";
|
|
|
196
196
|
export const ROLE = "/roles/:id";
|
|
197
197
|
export const ROLES = "/roles";
|
|
198
198
|
export const ROLES_NEW = "/roles/new";
|
|
199
|
-
export const RULE = "/rules/:id
|
|
199
|
+
export const RULE = "/rules/:id";
|
|
200
200
|
export const RULES = "/rules";
|
|
201
201
|
export const RULE_EDIT = "/rules/:id/edit";
|
|
202
202
|
export const RULE_EVENTS = "/rules/:id/events";
|
|
@@ -271,7 +271,6 @@ export const TASK = "/reindex/:id";
|
|
|
271
271
|
export const TEMPLATE = "/templates/:templateId";
|
|
272
272
|
export const TEMPLATES = "/templates";
|
|
273
273
|
export const TEMPLATES_NEW = "/templates/new";
|
|
274
|
-
export const TEMPLATE_EDIT = "/templates/:id/edit";
|
|
275
274
|
export const UNAUTHORIZED = "/unauthorized";
|
|
276
275
|
export const USER = "/users/:id";
|
|
277
276
|
export const USERS = "/users";
|
|
@@ -500,7 +499,6 @@ const routes = {
|
|
|
500
499
|
TEMPLATE,
|
|
501
500
|
TEMPLATES,
|
|
502
501
|
TEMPLATES_NEW,
|
|
503
|
-
TEMPLATE_EDIT,
|
|
504
502
|
UNAUTHORIZED,
|
|
505
503
|
USER,
|
|
506
504
|
USERS,
|
|
@@ -509,5 +507,7 @@ const routes = {
|
|
|
509
507
|
USER_EDIT_PASSWORD,
|
|
510
508
|
};
|
|
511
509
|
|
|
512
|
-
export const linkTo = _.mapValues(
|
|
510
|
+
export const linkTo = _.mapValues(
|
|
511
|
+
(route) => (params) => compile(route)(_.mapValues((x) => `${x}`)(params))
|
|
512
|
+
)(routes);
|
|
513
513
|
export default routes;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
|
|
3
|
+
const routes = [
|
|
4
|
+
"/",
|
|
5
|
+
{
|
|
6
|
+
i18n: [
|
|
7
|
+
"i18n",
|
|
8
|
+
{
|
|
9
|
+
messages: ["messages", { new: ["new"] }],
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
roles: [
|
|
13
|
+
"roles",
|
|
14
|
+
{
|
|
15
|
+
new: ["new"],
|
|
16
|
+
":id": [":id"],
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Returns the path for a given location based on the routes structure
|
|
23
|
+
* @param {string} location - A slash separated string representing the location (e.g. "i18n/messages")
|
|
24
|
+
* @returns {string} The path for the specified location
|
|
25
|
+
*/
|
|
26
|
+
export function path(location) {
|
|
27
|
+
if (!location) return "/";
|
|
28
|
+
|
|
29
|
+
const segments = _.flow(_.split("/"), _.filter(Boolean))(location);
|
|
30
|
+
|
|
31
|
+
if (_.isEmpty(segments)) return "/";
|
|
32
|
+
|
|
33
|
+
return _.flow(
|
|
34
|
+
() => routes[1],
|
|
35
|
+
(routeObj) =>
|
|
36
|
+
_.reduce((acc, segment) => {
|
|
37
|
+
if (acc === null || !acc[segment]) return null;
|
|
38
|
+
|
|
39
|
+
return acc[segment][1];
|
|
40
|
+
}, routeObj)(segments.slice(0, -1)),
|
|
41
|
+
(finalRouteObj) => {
|
|
42
|
+
if (finalRouteObj === null) return undefined;
|
|
43
|
+
const lastSegment = _.last(segments);
|
|
44
|
+
return finalRouteObj[lastSegment]
|
|
45
|
+
? finalRouteObj[lastSegment][0]
|
|
46
|
+
: undefined;
|
|
47
|
+
}
|
|
48
|
+
)();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns the absolute path for a given location based on the routes structure
|
|
52
|
+
* @param {string} location - A slash separated string representing the location (e.g. "i18n/messages")
|
|
53
|
+
* @returns {string} The absolute path for the specified location, including all parent segments
|
|
54
|
+
*/
|
|
55
|
+
export function absolutePath(location) {
|
|
56
|
+
if (!location) return "/";
|
|
57
|
+
|
|
58
|
+
const segments = _.flow(_.split("/"), _.filter(Boolean))(location);
|
|
59
|
+
|
|
60
|
+
if (_.isEmpty(segments)) return "/";
|
|
61
|
+
|
|
62
|
+
let currentPath = "";
|
|
63
|
+
let currentRouteObj = routes[1];
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < segments.length; i++) {
|
|
66
|
+
const segment = segments[i];
|
|
67
|
+
|
|
68
|
+
if (!currentRouteObj[segment]) return undefined;
|
|
69
|
+
|
|
70
|
+
currentPath += `/${currentRouteObj[segment][0]}`;
|
|
71
|
+
|
|
72
|
+
if (i < segments.length - 1) {
|
|
73
|
+
currentRouteObj = currentRouteObj[segment][1];
|
|
74
|
+
if (!currentRouteObj) return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return currentPath;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Returns the relative path for a given location based on the routes structure
|
|
83
|
+
* @param {string} location - A slash separated string representing the location (e.g. "i18n/messages")
|
|
84
|
+
* @returns {string} The relative path for the specified location, without the leading slash
|
|
85
|
+
*/
|
|
86
|
+
export function relativePath(location) {
|
|
87
|
+
const absolute = absolutePath(location);
|
|
88
|
+
|
|
89
|
+
if (!absolute) return undefined;
|
|
90
|
+
if (absolute === "/") return "";
|
|
91
|
+
|
|
92
|
+
return absolute.substring(1); // Remove the leading slash
|
|
93
|
+
}
|
package/src/routines.js
CHANGED
|
@@ -31,3 +31,11 @@ export const logError = createRoutine("LOG_ERROR");
|
|
|
31
31
|
|
|
32
32
|
export const reindexAllGrants = createRoutine("REINDEX_ALL_GRANTS");
|
|
33
33
|
export const reindexAllStructures = createRoutine("REINDEX_ALL_STRUCTURES");
|
|
34
|
+
|
|
35
|
+
export const clearNavFilter = createRoutine("CLEAR_BUCKET_FILTER");
|
|
36
|
+
|
|
37
|
+
export const clearTemplates = createRoutine("CLEAR_TEMPLATES");
|
|
38
|
+
export const fetchTemplates = createRoutine("FETCH_TEMPLATES");
|
|
39
|
+
|
|
40
|
+
export const fetchSystems = createRoutine("FETCH_SYSTEMS");
|
|
41
|
+
export const clearSystems = createRoutine("CLEAR_SYSTEMS");
|
|
@@ -17,9 +17,7 @@ describe("sagas: addCommentRequestSaga", () => {
|
|
|
17
17
|
|
|
18
18
|
it("should throw exception if an unhandled action is received", () => {
|
|
19
19
|
expect(() => {
|
|
20
|
-
testSaga(addCommentRequestSaga)
|
|
21
|
-
.next()
|
|
22
|
-
.takeLatest("FOO", addCommentSaga);
|
|
20
|
+
testSaga(addCommentRequestSaga).next().takeLatest("FOO", addCommentSaga);
|
|
23
21
|
}).toThrow();
|
|
24
22
|
});
|
|
25
23
|
});
|
|
@@ -31,7 +29,7 @@ describe("sagas: addCommentSaga", () => {
|
|
|
31
29
|
const data = {
|
|
32
30
|
resource_id: id,
|
|
33
31
|
resource_type: "business_concept",
|
|
34
|
-
content: comment
|
|
32
|
+
content: comment,
|
|
35
33
|
};
|
|
36
34
|
const payload = { comment: data };
|
|
37
35
|
|
|
@@ -59,7 +57,7 @@ describe("sagas: addCommentSaga", () => {
|
|
|
59
57
|
const data = {
|
|
60
58
|
resource_id: id,
|
|
61
59
|
resource_type: "business_concept",
|
|
62
|
-
content: comment
|
|
60
|
+
content: comment,
|
|
63
61
|
};
|
|
64
62
|
const payload = { comment: data };
|
|
65
63
|
|
|
@@ -31,7 +31,7 @@ describe("sagas: fetchCommentsSaga", () => {
|
|
|
31
31
|
const json_opts = { ...JSON_OPTS, params: payload };
|
|
32
32
|
const data = [
|
|
33
33
|
{ content: "My first comment", resource_id: id },
|
|
34
|
-
{ content: "My second comment", resource_id: id }
|
|
34
|
+
{ content: "My second comment", resource_id: id },
|
|
35
35
|
];
|
|
36
36
|
|
|
37
37
|
it("should put a success action when a response is returned", () => {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { testSaga } from "redux-saga-test-plan";
|
|
2
|
+
import { apiJson, JSON_OPTS } from "@truedat/core/services/api";
|
|
3
|
+
import { fetchSystemsRequestSaga, fetchSystemsSaga } from "../fetchSystems";
|
|
4
|
+
import { fetchSystems } from "../../routines";
|
|
5
|
+
import { API_SYSTEMS } from "../../api";
|
|
6
|
+
|
|
7
|
+
describe("sagas: fetchSystemsRequestSaga", () => {
|
|
8
|
+
it("should invoke fetchSystemsSaga on trigger", () => {
|
|
9
|
+
expect(() => {
|
|
10
|
+
testSaga(fetchSystemsRequestSaga)
|
|
11
|
+
.next()
|
|
12
|
+
.takeLatest(fetchSystems.TRIGGER, fetchSystemsSaga)
|
|
13
|
+
.finish()
|
|
14
|
+
.isDone();
|
|
15
|
+
}).not.toThrow();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should throw exception if an unhandled action is received", () => {
|
|
19
|
+
expect(() => {
|
|
20
|
+
testSaga(fetchSystemsRequestSaga)
|
|
21
|
+
.next()
|
|
22
|
+
.takeLatest("FOO", fetchSystemsSaga);
|
|
23
|
+
}).toThrow();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("sagas: fetchSystemsSaga", () => {
|
|
28
|
+
const data = {
|
|
29
|
+
collection: [
|
|
30
|
+
{ id: 1, name: "Structure 1" },
|
|
31
|
+
{ id: 2, name: "Structure 2" },
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
it("should put a success action when a response is returned", () => {
|
|
36
|
+
expect(() => {
|
|
37
|
+
testSaga(fetchSystemsSaga)
|
|
38
|
+
.next()
|
|
39
|
+
.put(fetchSystems.request())
|
|
40
|
+
.next()
|
|
41
|
+
.call(apiJson, API_SYSTEMS, JSON_OPTS)
|
|
42
|
+
.next({ data })
|
|
43
|
+
.put(fetchSystems.success(data))
|
|
44
|
+
.next()
|
|
45
|
+
.put(fetchSystems.fulfill())
|
|
46
|
+
.next()
|
|
47
|
+
.isDone();
|
|
48
|
+
}).not.toThrow();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("should put a failure action when the call returns an error", () => {
|
|
52
|
+
const message = "Request failed";
|
|
53
|
+
const error = { message };
|
|
54
|
+
|
|
55
|
+
expect(() => {
|
|
56
|
+
testSaga(fetchSystemsSaga)
|
|
57
|
+
.next()
|
|
58
|
+
.put(fetchSystems.request())
|
|
59
|
+
.next()
|
|
60
|
+
.call(apiJson, API_SYSTEMS, JSON_OPTS)
|
|
61
|
+
.throw(error)
|
|
62
|
+
.put(fetchSystems.failure(message))
|
|
63
|
+
.next()
|
|
64
|
+
.put(fetchSystems.fulfill())
|
|
65
|
+
.next()
|
|
66
|
+
.isDone();
|
|
67
|
+
}).not.toThrow();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { call, put, takeLatest } from "redux-saga/effects";
|
|
2
|
+
import { apiJson, JSON_OPTS } from "@truedat/core/services/api";
|
|
3
|
+
import { fetchSystems } from "../routines";
|
|
4
|
+
import { API_SYSTEMS } from "../api";
|
|
5
|
+
|
|
6
|
+
export function* fetchSystemsSaga() {
|
|
7
|
+
try {
|
|
8
|
+
yield put(fetchSystems.request());
|
|
9
|
+
const { data } = yield call(apiJson, API_SYSTEMS, JSON_OPTS);
|
|
10
|
+
yield put(fetchSystems.success(data));
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (error.response) {
|
|
13
|
+
const { status, data } = error.response;
|
|
14
|
+
yield put(fetchSystems.failure({ status, data }));
|
|
15
|
+
} else {
|
|
16
|
+
yield put(fetchSystems.failure(error.message));
|
|
17
|
+
}
|
|
18
|
+
} finally {
|
|
19
|
+
yield put(fetchSystems.fulfill());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function* fetchSystemsRequestSaga() {
|
|
24
|
+
yield takeLatest(fetchSystems.TRIGGER, fetchSystemsSaga);
|
|
25
|
+
}
|
package/src/sagas/index.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { fetchCommentsRequestSaga } from "./fetchComments";
|
|
2
2
|
import { addCommentRequestSaga } from "./addComment";
|
|
3
3
|
import { reindexAllRequestSaga } from "./reindexAll";
|
|
4
|
+
import { fetchSystemsRequestSaga } from "./fetchSystems";
|
|
4
5
|
|
|
5
6
|
export {
|
|
6
7
|
fetchCommentsRequestSaga,
|
|
7
8
|
addCommentRequestSaga,
|
|
8
9
|
reindexAllRequestSaga,
|
|
10
|
+
fetchSystemsRequestSaga,
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
export default [
|
|
12
14
|
fetchCommentsRequestSaga(),
|
|
13
15
|
addCommentRequestSaga(),
|
|
14
16
|
reindexAllRequestSaga(),
|
|
17
|
+
fetchSystemsRequestSaga(),
|
|
15
18
|
];
|
package/src/search/FilterItem.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
3
|
import { FormattedMessage } from "react-intl";
|
|
4
4
|
import {
|
|
5
5
|
Label,
|
|
@@ -88,52 +88,48 @@ export default function FilterQueryDropdown() {
|
|
|
88
88
|
open={!_.isEmpty(options)}
|
|
89
89
|
>
|
|
90
90
|
<Dimmer.Dimmable as={Dropdown.Menu} dimmed={loading}>
|
|
91
|
-
<>
|
|
92
|
-
<>
|
|
93
|
-
<Input
|
|
94
|
-
icon="search"
|
|
95
|
-
iconPosition="left"
|
|
96
|
-
className="search"
|
|
97
|
-
onKeyDown={(e) => {
|
|
98
|
-
if (e.key === " ") {
|
|
99
|
-
e.stopPropagation();
|
|
100
|
-
}
|
|
101
|
-
}}
|
|
102
|
-
onChange={handleSearch}
|
|
103
|
-
value={localQuery}
|
|
104
|
-
onClick={(e) => {
|
|
105
|
-
e.preventDefault();
|
|
106
|
-
e.stopPropagation();
|
|
107
|
-
}}
|
|
108
|
-
/>
|
|
109
|
-
{selected.map((option, i) => (
|
|
110
|
-
<FilterItem
|
|
111
|
-
key={i}
|
|
112
|
-
filter={filter}
|
|
113
|
-
toggleFilterValue={toggleFilterValue}
|
|
114
|
-
option={option}
|
|
115
|
-
active={true}
|
|
116
|
-
/>
|
|
117
|
-
))}
|
|
118
|
-
<Dropdown.Divider />
|
|
119
|
-
{filteredOptions.map((option, i) => (
|
|
120
|
-
<FilterItem
|
|
121
|
-
key={i}
|
|
122
|
-
filter={filter}
|
|
123
|
-
toggleFilterValue={toggleFilterValue}
|
|
124
|
-
option={option}
|
|
125
|
-
active={_.includes(_.prop("value")(option))(
|
|
126
|
-
activeFilterSelectedValues
|
|
127
|
-
)}
|
|
128
|
-
/>
|
|
129
|
-
))}
|
|
130
|
-
</>
|
|
131
|
-
</>
|
|
132
91
|
{loading && (
|
|
133
92
|
<Dimmer active inverted>
|
|
134
93
|
<Loader size="tiny" />
|
|
135
94
|
</Dimmer>
|
|
136
95
|
)}
|
|
96
|
+
<Input
|
|
97
|
+
icon="search"
|
|
98
|
+
iconPosition="left"
|
|
99
|
+
className="search"
|
|
100
|
+
onKeyDown={(e) => {
|
|
101
|
+
if (e.key === " ") {
|
|
102
|
+
e.stopPropagation();
|
|
103
|
+
}
|
|
104
|
+
}}
|
|
105
|
+
onChange={handleSearch}
|
|
106
|
+
value={localQuery}
|
|
107
|
+
onClick={(e) => {
|
|
108
|
+
e.preventDefault();
|
|
109
|
+
e.stopPropagation();
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
{selected.map((option, i) => (
|
|
113
|
+
<FilterItem
|
|
114
|
+
key={i}
|
|
115
|
+
filter={filter}
|
|
116
|
+
toggleFilterValue={toggleFilterValue}
|
|
117
|
+
option={option}
|
|
118
|
+
active={true}
|
|
119
|
+
/>
|
|
120
|
+
))}
|
|
121
|
+
<Dropdown.Divider />
|
|
122
|
+
{filteredOptions.map((option, i) => (
|
|
123
|
+
<FilterItem
|
|
124
|
+
key={i}
|
|
125
|
+
filter={filter}
|
|
126
|
+
toggleFilterValue={toggleFilterValue}
|
|
127
|
+
option={option}
|
|
128
|
+
active={_.includes(_.prop("value")(option))(
|
|
129
|
+
activeFilterSelectedValues
|
|
130
|
+
)}
|
|
131
|
+
/>
|
|
132
|
+
))}
|
|
137
133
|
</Dimmer.Dimmable>
|
|
138
134
|
</Dropdown>
|
|
139
135
|
);
|