@truedat/core 8.6.7 → 8.7.1
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 +3 -3
- package/src/components/AddMemberForm.js +3 -3
- package/src/components/Alert.js +3 -3
- package/src/components/AlertExporter.js +4 -4
- package/src/components/AvailableFilters.js +5 -5
- package/src/components/CSVFileModal.js +1 -1
- package/src/components/CardGroupsAccordion.js +4 -4
- package/src/components/CatalogMenu.js +2 -2
- package/src/components/CommentsForm.js +1 -1
- package/src/components/DomainSearchFilter.js +9 -9
- package/src/components/DomainSelector.js +1 -1
- package/src/components/FilterDropdown.js +5 -5
- package/src/components/FilterMultilevelDropdown.js +9 -9
- package/src/components/GlossaryMenu.js +10 -7
- package/src/components/Graph.js +199 -127
- package/src/components/GroupActions.js +2 -2
- package/src/components/Hierarchy.js +1 -1
- package/src/components/HierarchyFilterDropdown.js +7 -7
- package/src/components/HierarchySelector.js +1 -1
- package/src/components/LanguagesTabs.js +2 -2
- package/src/components/OptionGroup.js +8 -9
- package/src/components/QualityMenu.js +6 -8
- package/src/components/ResourceMembers.js +3 -3
- package/src/components/SearchFilterDropdown.js +3 -3
- package/src/components/SidebarToggle.js +1 -1
- package/src/components/Submenu.js +46 -27
- package/src/components/SystemsLoader.js +1 -1
- package/src/components/TemplatesLoader.js +1 -1
- package/src/components/TreeSelector.js +2 -2
- package/src/components/UploadJob.js +3 -3
- package/src/components/UploadJobBreadcrumbs.js +4 -1
- package/src/components/UploadJobParser.js +4 -3
- package/src/components/UploadModal.js +1 -1
- package/src/components/UserFilter.js +1 -1
- package/src/components/UserFilters.js +2 -2
- package/src/components/__tests__/ArrayDecorator.spec.js +2 -2
- package/src/components/__tests__/CardGroupsAccordion.spec.js +6 -6
- package/src/components/__tests__/CatalogMenu.spec.js +1 -1
- package/src/components/__tests__/DateTime.spec.js +1 -1
- package/src/components/__tests__/DomainSearchFilter.spec.js +2 -2
- package/src/components/__tests__/DomainSearchFilterItem.spec.js +7 -7
- package/src/components/__tests__/DomainSelector.spec.js +3 -3
- package/src/components/__tests__/DropdownMenuItem.spec.js +3 -3
- package/src/components/__tests__/FilterDropdown.spec.js +11 -11
- package/src/components/__tests__/FilterMultilevelDropdown.spec.js +2 -2
- package/src/components/__tests__/GlossaryMenu.spec.js +2 -2
- package/src/components/__tests__/Graph.spec.js +12 -4
- package/src/components/__tests__/GroupActions.spec.js +4 -4
- package/src/components/__tests__/Hierarchy.spec.js +1 -1
- package/src/components/__tests__/HierarchyFilterDropdown.spec.js +5 -5
- package/src/components/__tests__/HierarchyNodeFinder.spec.js +4 -4
- package/src/components/__tests__/HierarchySelector.spec.js +7 -5
- package/src/components/__tests__/Markdown.spec.js +22 -8
- package/src/components/__tests__/ModalSaveFilter.spec.js +1 -1
- package/src/components/__tests__/Pagination.spec.js +2 -2
- package/src/components/__tests__/ResourceMembers.spec.js +4 -4
- package/src/components/__tests__/SearchDateFilter.spec.js +10 -5
- package/src/components/__tests__/SearchFilterDropdown.spec.js +1 -1
- package/src/components/__tests__/SelectedFilters.spec.js +7 -7
- package/src/components/__tests__/SideMenu.spec.js +1 -1
- package/src/components/__tests__/Submenu.spec.js +1 -1
- package/src/components/__tests__/TemplateSelector.spec.js +5 -5
- package/src/components/__tests__/TreeSelector.spec.js +23 -24
- package/src/components/__tests__/UploadJob.spec.js +1 -3
- package/src/components/__tests__/UploadJobBreadcrumbs.spec.js +4 -4
- package/src/components/__tests__/UploadJobParser.spec.js +42 -38
- package/src/components/__tests__/UploadModal.spec.js +9 -9
- package/src/components/__tests__/UserFilters.spec.js +1 -1
- package/src/components/graph/ColoredEdge.js +29 -23
- package/src/components/graph/edgeLayout.js +4 -1
- package/src/hooks/__tests__/useActiveRoutes.spec.js +32 -18
- package/src/hooks/useAclEntries.js +2 -2
- package/src/hooks/useActiveRoutes.js +14 -6
- package/src/hooks/useAuthorized.js +3 -3
- package/src/hooks/useHierarchies.js +8 -8
- package/src/hooks/useLocales.js +3 -3
- package/src/hooks/useMessages.js +1 -1
- package/src/hooks/useOnScreen.js +1 -1
- package/src/hooks/useUploadJobs.js +2 -8
- package/src/hooks/useUserFilters.js +1 -1
- package/src/i18n/components/LangProvider.js +6 -6
- package/src/i18n/components/Languages.js +4 -4
- package/src/i18n/components/MessageForm.js +24 -13
- package/src/i18n/components/Messages.js +5 -5
- package/src/i18n/components/__tests__/I18nRoutes.spec.js +1 -1
- package/src/messages/index.js +1 -1
- package/src/reducers/comments.js +3 -3
- package/src/router/__tests__/ProtectedRoute.spec.js +1 -1
- package/src/routes.js +1 -1
- package/src/routesTree.js +6 -1
- package/src/routines.js +2 -2
- package/src/search/FilterDropdown.js +1 -1
- package/src/search/FilterMultilevelDropdown.js +10 -10
- package/src/search/FilterQueryDropdown.js +4 -4
- package/src/search/HierarchyFilterDropdown.js +7 -7
- package/src/search/SearchContext.js +19 -19
- package/src/search/SearchDateFilter.js +12 -2
- package/src/search/SearchFilters.js +1 -1
- package/src/search/SearchSelectedFilters.js +1 -1
- package/src/search/SearchWidget.js +6 -2
- package/src/search/UserFilter.js +1 -1
- package/src/search/UserFilters.js +4 -4
- package/src/search/__tests__/FilterDropdown.spec.js +3 -3
- package/src/search/__tests__/FilterQueryDropdown.spec.js +20 -18
- package/src/search/__tests__/ModalSaveFilter.spec.js +2 -2
- package/src/search/__tests__/SearchContext.spec.js +42 -42
- package/src/search/__tests__/SearchSelectedFilters.spec.js +21 -17
- package/src/search/__tests__/SearchWidget.spec.js +4 -4
- package/src/selectors/__tests__/getRiSubscopes.spec.js +1 -1
- package/src/selectors/__tests__/makeSearchQuerySelector.spec.js +2 -2
- package/src/selectors/getConceptSubscope.js +1 -1
- package/src/selectors/getDashboardConfig.js +3 -3
- package/src/selectors/getMessage.js +3 -3
- package/src/selectors/getRecipients.js +3 -3
- package/src/selectors/getRiSubscopes.js +2 -2
- package/src/selectors/getSidemenuGlossarySubscopes.js +1 -1
- package/src/selectors/makeActiveFiltersSelector.js +2 -2
- package/src/selectors/makeDateFiltersSelector.js +1 -1
- package/src/selectors/makeSearchQuerySelector.js +10 -10
- package/src/selectors/makeTagOptionsSelector.js +1 -4
- package/src/selectors/subscopedTemplates.js +2 -2
- package/src/services/columnPredicate.js +1 -1
- package/src/services/dateFilterFormatter.js +1 -1
- package/src/services/fieldType.js +1 -1
- package/src/services/formRules.js +16 -13
- package/src/services/getHierarchyOptions.js +2 -2
- package/src/services/message.js +7 -8
- package/src/services/operators.js +5 -5
- package/src/services/sort.js +2 -2
- package/src/services/swr.js +1 -1
- package/src/services/tree.js +2 -2
|
@@ -8,9 +8,13 @@ jest.mock("react-router", () => ({
|
|
|
8
8
|
jest.mock("lodash/fp", () => ({
|
|
9
9
|
prop: jest.fn((key) => (obj) => obj[key]),
|
|
10
10
|
orderBy: jest.fn((iteratees, orders, collection) => collection.sort()),
|
|
11
|
-
castArray: jest.fn((val) => Array.isArray(val) ? val : [val]),
|
|
12
|
-
size: jest.fn((val) => typeof val ===
|
|
13
|
-
flow: jest.fn(
|
|
11
|
+
castArray: jest.fn((val) => (Array.isArray(val) ? val : [val])),
|
|
12
|
+
size: jest.fn((val) => (typeof val === "string" ? val.length : 0)),
|
|
13
|
+
flow: jest.fn(
|
|
14
|
+
(...funcs) =>
|
|
15
|
+
(...args) =>
|
|
16
|
+
funcs.reduceRight((arg, fn) => fn(arg), args),
|
|
17
|
+
),
|
|
14
18
|
map: jest.fn((fn) => (arr) => arr.map(fn)),
|
|
15
19
|
head: jest.fn((arr) => arr[0]),
|
|
16
20
|
}));
|
|
@@ -26,34 +30,42 @@ jest.mock("react-router", () => ({
|
|
|
26
30
|
describe("hooks: useActiveRoutes", () => {
|
|
27
31
|
beforeEach(() => {
|
|
28
32
|
jest.clearAllMocks();
|
|
29
|
-
|
|
33
|
+
|
|
30
34
|
// Setup default mocks
|
|
31
35
|
require("lodash/fp").prop.mockImplementation((key) => (obj) => obj[key]);
|
|
32
|
-
require("lodash/fp").orderBy.mockImplementation(
|
|
33
|
-
|
|
36
|
+
require("lodash/fp").orderBy.mockImplementation(
|
|
37
|
+
(iteratees, orders, collection) => collection,
|
|
38
|
+
);
|
|
39
|
+
require("lodash/fp").castArray.mockImplementation((val) =>
|
|
40
|
+
Array.isArray(val) ? val : [val],
|
|
41
|
+
);
|
|
34
42
|
require("react-router").useLocation = () => ({ pathname: "/test" });
|
|
35
43
|
});
|
|
36
44
|
|
|
37
45
|
it("should return the most specific route when multiple routes match", () => {
|
|
38
46
|
const mockUseLocation = jest.spyOn(require("react-router"), "useLocation");
|
|
39
|
-
mockUseLocation.mockReturnValue({
|
|
47
|
+
mockUseLocation.mockReturnValue({
|
|
48
|
+
pathname: "/implementations/subscope/test",
|
|
49
|
+
});
|
|
40
50
|
|
|
41
51
|
const mockRoutes = ["/implementations", "/implementations/subscope/test"];
|
|
42
|
-
|
|
52
|
+
|
|
43
53
|
const result = useActiveRoutes(mockRoutes, null);
|
|
44
|
-
|
|
54
|
+
|
|
45
55
|
// Should return the more specific route
|
|
46
56
|
expect(result).toBe("/implementations/subscope/test");
|
|
47
57
|
});
|
|
48
58
|
|
|
49
59
|
it("should handle subscope path detection correctly", () => {
|
|
50
60
|
const mockUseLocation = jest.spyOn(require("react-router"), "useLocation");
|
|
51
|
-
mockUseLocation.mockReturnValue({
|
|
61
|
+
mockUseLocation.mockReturnValue({
|
|
62
|
+
pathname: "/concepts/subscope/AI_Initiative",
|
|
63
|
+
});
|
|
52
64
|
|
|
53
65
|
const mockRoutes = ["/concepts", "/concepts/subscope/AI_Initiative"];
|
|
54
|
-
|
|
66
|
+
|
|
55
67
|
const result = useActiveRoutes(mockRoutes, null);
|
|
56
|
-
|
|
68
|
+
|
|
57
69
|
// Should return the more specific route
|
|
58
70
|
expect(result).toBe("/concepts/subscope/AI_Initiative");
|
|
59
71
|
});
|
|
@@ -63,21 +75,23 @@ describe("hooks: useActiveRoutes", () => {
|
|
|
63
75
|
mockUseLocation.mockReturnValue({ pathname: "/other" });
|
|
64
76
|
|
|
65
77
|
const mockRoutes = ["/implementations", "/concepts"];
|
|
66
|
-
|
|
78
|
+
|
|
67
79
|
const result = useActiveRoutes(mockRoutes, null);
|
|
68
|
-
|
|
80
|
+
|
|
69
81
|
expect(result).toBeNull();
|
|
70
82
|
});
|
|
71
83
|
|
|
72
84
|
it("should handle URL decoding properly", () => {
|
|
73
85
|
const mockUseLocation = jest.spyOn(require("react-router"), "useLocation");
|
|
74
|
-
mockUseLocation.mockReturnValue({
|
|
86
|
+
mockUseLocation.mockReturnValue({
|
|
87
|
+
pathname: "/concepts/subscope/AI%20Initiative",
|
|
88
|
+
});
|
|
75
89
|
|
|
76
90
|
const mockRoutes = ["/concepts", "/concepts/subscope/AI Initiative"];
|
|
77
|
-
|
|
91
|
+
|
|
78
92
|
const result = useActiveRoutes(mockRoutes, null);
|
|
79
|
-
|
|
93
|
+
|
|
80
94
|
// Should match the decoded route
|
|
81
95
|
expect(result).toBe("/concepts/subscope/AI Initiative");
|
|
82
96
|
});
|
|
83
|
-
});
|
|
97
|
+
});
|
|
@@ -20,12 +20,12 @@ export const useAclEntries = (resource) => {
|
|
|
20
20
|
const { data, error, loading, mutate } = useSWR(url, apiJson);
|
|
21
21
|
const aclEntries = _.flow(
|
|
22
22
|
_.pathOr([], "_embedded.acl_entries"),
|
|
23
|
-
_.sortBy(accentInsensitivePathOrder("user_name"))
|
|
23
|
+
_.sortBy(accentInsensitivePathOrder("user_name")),
|
|
24
24
|
)(data?.data);
|
|
25
25
|
const actions = {
|
|
26
26
|
canCreate: _.flow(
|
|
27
27
|
_.pathOr([], "_links.self.methods"),
|
|
28
|
-
_.includes("POST")
|
|
28
|
+
_.includes("POST"),
|
|
29
29
|
)(data?.data),
|
|
30
30
|
};
|
|
31
31
|
return { data: { aclEntries, actions }, error, loading, mutate };
|
|
@@ -7,7 +7,7 @@ export const useActiveRoutes = (route, navFilter) => {
|
|
|
7
7
|
const location = useLocation();
|
|
8
8
|
const pathname = _.prop("pathname")(location);
|
|
9
9
|
const decodedPathname = decodeURIComponent(pathname);
|
|
10
|
-
const routes = _.orderBy([_.size], [
|
|
10
|
+
const routes = _.orderBy([_.size], ["desc"], _.castArray(route)); // Sort routes by length in descending order to prioritize more specific routes
|
|
11
11
|
|
|
12
12
|
for (const routeObj of _.map((route) => ({
|
|
13
13
|
route,
|
|
@@ -15,9 +15,11 @@ export const useActiveRoutes = (route, navFilter) => {
|
|
|
15
15
|
}))(routes)) {
|
|
16
16
|
const { route, filterMatch } = routeObj;
|
|
17
17
|
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if (
|
|
19
|
+
navFilter &&
|
|
20
|
+
filterMatch?.params?.propertyPath &&
|
|
21
|
+
_.includes(filterMatch?.params?.propertyPath, Object.keys(navFilter))
|
|
22
|
+
) {
|
|
21
23
|
return route;
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -25,11 +27,17 @@ export const useActiveRoutes = (route, navFilter) => {
|
|
|
25
27
|
return route;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
if (
|
|
30
|
+
if (
|
|
31
|
+
_.startsWith(`${route}/`)(pathname) ||
|
|
32
|
+
_.startsWith(`${route}/`)(decodedPathname)
|
|
33
|
+
) {
|
|
29
34
|
return route;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
if (
|
|
37
|
+
if (
|
|
38
|
+
matchPath({ path: route }, pathname) ||
|
|
39
|
+
matchPath({ path: route }, decodedPathname)
|
|
40
|
+
) {
|
|
33
41
|
return route;
|
|
34
42
|
}
|
|
35
43
|
}
|
|
@@ -9,7 +9,7 @@ export const useAuthorized = (allowedRoles) => {
|
|
|
9
9
|
: _.flow(
|
|
10
10
|
_.defaultTo([]),
|
|
11
11
|
_.castArray,
|
|
12
|
-
_.some((r) => _.includes(r)(groups))
|
|
12
|
+
_.some((r) => _.includes(r)(groups)),
|
|
13
13
|
)(allowedRoles);
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -26,7 +26,7 @@ export const useAuthorizedItems = (items) => {
|
|
|
26
26
|
_.defaultTo([]),
|
|
27
27
|
_.castArray,
|
|
28
28
|
_.filter((i) =>
|
|
29
|
-
_.flow(_.pathOr([], "groups"), filterByGroups(groups))(i)
|
|
30
|
-
)
|
|
29
|
+
_.flow(_.pathOr([], "groups"), filterByGroups(groups))(i),
|
|
30
|
+
),
|
|
31
31
|
)(items);
|
|
32
32
|
};
|
|
@@ -47,16 +47,16 @@ export const useHierarchyPatch = (id, callback) => {
|
|
|
47
47
|
return useSWRMutations(url, (url, { arg }) =>
|
|
48
48
|
apiJsonPatch(url, toBack(arg)).then(
|
|
49
49
|
({ data }) =>
|
|
50
|
-
mutate(API_HIERARCHIES) && mutate(url, data) && callback(data?.data)
|
|
51
|
-
)
|
|
50
|
+
mutate(API_HIERARCHIES) && mutate(url, data) && callback(data?.data),
|
|
51
|
+
),
|
|
52
52
|
);
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
export const useHierarchyPost = (callback) => {
|
|
56
56
|
return useSWRMutations(API_HIERARCHIES, (url, { arg }) =>
|
|
57
57
|
apiJsonPost(url, toBack(arg)).then(
|
|
58
|
-
({ data }) => mutate(API_HIERARCHIES) && callback(data?.data)
|
|
59
|
-
)
|
|
58
|
+
({ data }) => mutate(API_HIERARCHIES) && callback(data?.data),
|
|
59
|
+
),
|
|
60
60
|
);
|
|
61
61
|
};
|
|
62
62
|
|
|
@@ -65,8 +65,8 @@ export const useHierarchyDelete = (id, callback) => {
|
|
|
65
65
|
const url = toApiPath({ id: `${id}` });
|
|
66
66
|
return useSWRMutations(url, (url, { arg }) =>
|
|
67
67
|
apiJsonDelete(url, toBack(arg)).then(
|
|
68
|
-
({ data }) => mutate(API_HIERARCHIES) && callback(data?.data)
|
|
69
|
-
)
|
|
68
|
+
({ data }) => mutate(API_HIERARCHIES) && callback(data?.data),
|
|
69
|
+
),
|
|
70
70
|
);
|
|
71
71
|
};
|
|
72
72
|
|
|
@@ -84,7 +84,7 @@ const toFront = (hierarchy) => {
|
|
|
84
84
|
name: node.name,
|
|
85
85
|
description: node.description,
|
|
86
86
|
};
|
|
87
|
-
})
|
|
87
|
+
}),
|
|
88
88
|
)(hierarchy),
|
|
89
89
|
}
|
|
90
90
|
: hierarchy;
|
|
@@ -104,7 +104,7 @@ const toBack = (hierarchy) => {
|
|
|
104
104
|
name: node.name,
|
|
105
105
|
description: node.description,
|
|
106
106
|
};
|
|
107
|
-
})
|
|
107
|
+
}),
|
|
108
108
|
)(hierarchy),
|
|
109
109
|
},
|
|
110
110
|
}
|
package/src/hooks/useLocales.js
CHANGED
|
@@ -15,15 +15,15 @@ export const useLocales = (includeMessages = true) => {
|
|
|
15
15
|
apiJson,
|
|
16
16
|
{
|
|
17
17
|
revalidateOnFocus: false,
|
|
18
|
-
}
|
|
18
|
+
},
|
|
19
19
|
);
|
|
20
20
|
const locales = data?.data?.data;
|
|
21
21
|
const orderedLocales = locales
|
|
22
22
|
? _.flow(
|
|
23
23
|
_.orderBy(
|
|
24
24
|
["is_default", "is_required", "lang"],
|
|
25
|
-
["desc", "desc", "asc"]
|
|
26
|
-
)
|
|
25
|
+
["desc", "desc", "asc"],
|
|
26
|
+
),
|
|
27
27
|
)(locales)
|
|
28
28
|
: data?.data?.data;
|
|
29
29
|
return {
|
package/src/hooks/useMessages.js
CHANGED
|
@@ -22,7 +22,7 @@ export const useMessages = (lang) => {
|
|
|
22
22
|
export const useMessagePatch = (id) => {
|
|
23
23
|
const url = toApiMessagePath({ id: `${id}` });
|
|
24
24
|
return useSWRMutations(url, (url, { arg }) =>
|
|
25
|
-
apiJsonPatch(url, arg).then(() => mutate(API_LOCALES))
|
|
25
|
+
apiJsonPatch(url, arg).then(() => mutate(API_LOCALES)),
|
|
26
26
|
);
|
|
27
27
|
};
|
|
28
28
|
|
package/src/hooks/useOnScreen.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { compile } from "path-to-regexp";
|
|
2
2
|
import useSWR from "swr";
|
|
3
3
|
import { apiJson } from "@truedat/core/services/api";
|
|
4
|
-
import {
|
|
5
|
-
API_UPLOAD_JOBS,
|
|
6
|
-
API_UPLOAD_JOB,
|
|
7
|
-
} from "../api";
|
|
4
|
+
import { API_UPLOAD_JOBS, API_UPLOAD_JOB } from "../api";
|
|
8
5
|
|
|
9
6
|
export const useUploadJobs = (scope) => {
|
|
10
7
|
const url = scope ? `${API_UPLOAD_JOBS}?scope=${scope}` : API_UPLOAD_JOBS;
|
|
11
|
-
const { data, error, mutate } = useSWR(
|
|
12
|
-
url,
|
|
13
|
-
apiJson
|
|
14
|
-
);
|
|
8
|
+
const { data, error, mutate } = useSWR(url, apiJson);
|
|
15
9
|
return { data: data?.data, error, loading: !error && !data, mutate };
|
|
16
10
|
};
|
|
17
11
|
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
const buildUrl = (type, scope) =>
|
|
19
19
|
_.flow(
|
|
20
20
|
() => compile(API_GET_USER_FILTERS)({ type }),
|
|
21
|
-
(baseUrl) => `${baseUrl}${scope ? `?scope=${scope}` : ""}
|
|
21
|
+
(baseUrl) => `${baseUrl}${scope ? `?scope=${scope}` : ""}`,
|
|
22
22
|
)("");
|
|
23
23
|
|
|
24
24
|
export const mutateUserFilters = (type, scope) => {
|
|
@@ -47,34 +47,34 @@ const LanguageContextProvider = ({ children, defaultMessages }) => {
|
|
|
47
47
|
const langsOf = _.map(({ lang }) => lang);
|
|
48
48
|
const enabledLangs = _.flow(
|
|
49
49
|
_.filter(({ is_enabled }) => is_enabled),
|
|
50
|
-
langsOf
|
|
50
|
+
langsOf,
|
|
51
51
|
)(locales);
|
|
52
52
|
|
|
53
53
|
const altLangs = _.flow(
|
|
54
54
|
_.filter(({ is_enabled, is_default }) => is_enabled && !is_default),
|
|
55
55
|
_.orderBy(["is_required", "lang"], ["desc", "asc"]),
|
|
56
|
-
langsOf
|
|
56
|
+
langsOf,
|
|
57
57
|
)(locales);
|
|
58
58
|
|
|
59
59
|
const requiredLangs = _.flow(
|
|
60
60
|
_.filter(({ is_required }) => is_required),
|
|
61
|
-
langsOf
|
|
61
|
+
langsOf,
|
|
62
62
|
)(locales);
|
|
63
63
|
|
|
64
64
|
const defaultLang = _.flow(
|
|
65
65
|
_.find(({ is_default }) => is_default),
|
|
66
66
|
_.prop("lang"),
|
|
67
|
-
_.defaultTo("en")
|
|
67
|
+
_.defaultTo("en"),
|
|
68
68
|
)(locales);
|
|
69
69
|
|
|
70
70
|
const mapMessages = _.flow(
|
|
71
71
|
_.map(({ message_id, definition }) => [message_id, definition]),
|
|
72
|
-
_.fromPairs
|
|
72
|
+
_.fromPairs,
|
|
73
73
|
);
|
|
74
74
|
|
|
75
75
|
const messages = _.flow(
|
|
76
76
|
_.map(({ lang, messages }) => [lang, mapMessages(messages)]),
|
|
77
|
-
_.fromPairs
|
|
77
|
+
_.fromPairs,
|
|
78
78
|
)(locales);
|
|
79
79
|
|
|
80
80
|
const [lang, setLang] = useState(defaultLang);
|
|
@@ -77,7 +77,7 @@ const LanguageRow = ({
|
|
|
77
77
|
{
|
|
78
78
|
id: "i18n.messages.locale.setDefault.confirmation.content",
|
|
79
79
|
},
|
|
80
|
-
{ lang: local_name }
|
|
80
|
+
{ lang: local_name },
|
|
81
81
|
)}
|
|
82
82
|
onConfirm={() => handleChange({ id, locale: { is_default: true } })}
|
|
83
83
|
/>
|
|
@@ -134,7 +134,7 @@ const Languages = () => {
|
|
|
134
134
|
_.orderBy("lang", "asc"),
|
|
135
135
|
_.map(({ id, name, local_name }) => {
|
|
136
136
|
return { text: `${name} ( ${local_name} )`, value: id };
|
|
137
|
-
})
|
|
137
|
+
}),
|
|
138
138
|
)(locales);
|
|
139
139
|
|
|
140
140
|
const handleOnChange = ({ value }) => {
|
|
@@ -215,7 +215,7 @@ const Languages = () => {
|
|
|
215
215
|
_.filter("is_enabled"),
|
|
216
216
|
_.orderBy(
|
|
217
217
|
["is_default", "is_required", "lang"],
|
|
218
|
-
["desc", "desc", "asc"]
|
|
218
|
+
["desc", "desc", "asc"],
|
|
219
219
|
),
|
|
220
220
|
_.map((locale) => (
|
|
221
221
|
<LanguageRow
|
|
@@ -223,7 +223,7 @@ const Languages = () => {
|
|
|
223
223
|
locale={locale}
|
|
224
224
|
anyDefault={anyDefault}
|
|
225
225
|
/>
|
|
226
|
-
))
|
|
226
|
+
)),
|
|
227
227
|
)(locales)}
|
|
228
228
|
</TableBody>
|
|
229
229
|
</Table>
|
|
@@ -13,19 +13,21 @@ export const LangForm = ({
|
|
|
13
13
|
formatMessage,
|
|
14
14
|
}) => {
|
|
15
15
|
return (
|
|
16
|
-
|
|
16
|
+
<Segment>
|
|
17
|
+
<Header
|
|
17
18
|
as="h4"
|
|
18
19
|
content={formatMessage({
|
|
19
20
|
id: `i18n.messages.locale.${lang}`,
|
|
20
21
|
defaultMessage: `${name} ( ${local_name} )`,
|
|
21
22
|
})}
|
|
22
|
-
|
|
23
|
+
/>
|
|
24
|
+
<Controller
|
|
23
25
|
control={control}
|
|
24
26
|
name={`langs.${id}.definition`}
|
|
25
27
|
rules={{
|
|
26
28
|
required: formatMessage(
|
|
27
29
|
{ id: "form.validation.required" },
|
|
28
|
-
{ prop: formatMessage({ id: "i18n.message.props.definition" }) }
|
|
30
|
+
{ prop: formatMessage({ id: "i18n.message.props.definition" }) },
|
|
29
31
|
),
|
|
30
32
|
}}
|
|
31
33
|
render={({ field: { onBlur, onChange, value } }) => (
|
|
@@ -42,7 +44,8 @@ export const LangForm = ({
|
|
|
42
44
|
required
|
|
43
45
|
/>
|
|
44
46
|
)}
|
|
45
|
-
|
|
47
|
+
/>
|
|
48
|
+
<Controller
|
|
46
49
|
control={control}
|
|
47
50
|
name={`langs.${id}.description`}
|
|
48
51
|
render={({ field: { onBlur, onChange, value } }) => (
|
|
@@ -57,7 +60,8 @@ export const LangForm = ({
|
|
|
57
60
|
value={value || ""}
|
|
58
61
|
/>
|
|
59
62
|
)}
|
|
60
|
-
|
|
63
|
+
/>
|
|
64
|
+
</Segment>
|
|
61
65
|
);
|
|
62
66
|
};
|
|
63
67
|
|
|
@@ -81,13 +85,14 @@ export const MessageForm = ({ onSubmit, isSubmitting }) => {
|
|
|
81
85
|
const { errors, isDirty, isValid } = formState;
|
|
82
86
|
|
|
83
87
|
return (
|
|
84
|
-
|
|
88
|
+
<Form onSubmit={handleSubmit(onSubmit)}>
|
|
89
|
+
<Controller
|
|
85
90
|
control={control}
|
|
86
91
|
name="message_id"
|
|
87
92
|
rules={{
|
|
88
93
|
required: formatMessage(
|
|
89
94
|
{ id: "form.validation.required" },
|
|
90
|
-
{ prop: formatMessage({ id: "i18n.message.props.messageId" }) }
|
|
95
|
+
{ prop: formatMessage({ id: "i18n.message.props.messageId" }) },
|
|
91
96
|
),
|
|
92
97
|
}}
|
|
93
98
|
render={({ field: { onBlur, onChange, value } }) => (
|
|
@@ -104,11 +109,12 @@ export const MessageForm = ({ onSubmit, isSubmitting }) => {
|
|
|
104
109
|
required
|
|
105
110
|
/>
|
|
106
111
|
)}
|
|
107
|
-
/>
|
|
112
|
+
/>
|
|
113
|
+
{_.flow(
|
|
108
114
|
_.filter("is_enabled"),
|
|
109
115
|
_.orderBy(
|
|
110
116
|
["is_default", "is_required", "lang"],
|
|
111
|
-
["desc", "desc", "asc"]
|
|
117
|
+
["desc", "desc", "asc"],
|
|
112
118
|
),
|
|
113
119
|
_.map((locale) => (
|
|
114
120
|
<LangForm
|
|
@@ -118,18 +124,23 @@ export const MessageForm = ({ onSubmit, isSubmitting }) => {
|
|
|
118
124
|
errors={errors}
|
|
119
125
|
formatMessage={formatMessage}
|
|
120
126
|
/>
|
|
121
|
-
))
|
|
122
|
-
)(locales)}
|
|
127
|
+
)),
|
|
128
|
+
)(locales)}
|
|
129
|
+
<div className="actions">
|
|
130
|
+
<Button
|
|
123
131
|
floated="right"
|
|
124
132
|
type="submit"
|
|
125
133
|
primary
|
|
126
134
|
loading={isSubmitting}
|
|
127
135
|
disabled={isSubmitting || !isDirty || !isValid}
|
|
128
136
|
content={formatMessage({ id: "actions.save" })}
|
|
129
|
-
|
|
137
|
+
/>
|
|
138
|
+
<HistoryBackButton
|
|
130
139
|
content={formatMessage({ id: "actions.cancel" })}
|
|
131
140
|
disabled={isSubmitting}
|
|
132
|
-
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
</Form>
|
|
133
144
|
);
|
|
134
145
|
};
|
|
135
146
|
|
|
@@ -35,7 +35,7 @@ export function MessagesContent() {
|
|
|
35
35
|
_.toPairs,
|
|
36
36
|
_.filter(([_, value]) => value),
|
|
37
37
|
_.fromPairs,
|
|
38
|
-
(params) => new URLSearchParams(params)
|
|
38
|
+
(params) => new URLSearchParams(params),
|
|
39
39
|
)({
|
|
40
40
|
lang: selectedLang,
|
|
41
41
|
filter,
|
|
@@ -67,14 +67,14 @@ export function MessagesContent() {
|
|
|
67
67
|
lowerDeburrTrim(definition).includes(deburrFilter) ||
|
|
68
68
|
lowerDeburrTrim(description).includes(deburrFilter)
|
|
69
69
|
);
|
|
70
|
-
})
|
|
70
|
+
}),
|
|
71
71
|
)(locales)
|
|
72
72
|
: [];
|
|
73
73
|
|
|
74
74
|
const totalPages = Math.ceil(messages.length / ITEMS_PER_PAGE);
|
|
75
75
|
const paginatedMessages = _.flow(
|
|
76
76
|
_.drop((page - 1) * ITEMS_PER_PAGE),
|
|
77
|
-
_.take(ITEMS_PER_PAGE)
|
|
77
|
+
_.take(ITEMS_PER_PAGE),
|
|
78
78
|
)(messages);
|
|
79
79
|
|
|
80
80
|
return (
|
|
@@ -92,7 +92,7 @@ export function MessagesContent() {
|
|
|
92
92
|
_.filter("is_enabled"),
|
|
93
93
|
_.orderBy(
|
|
94
94
|
["is_default", "is_required", "lang"],
|
|
95
|
-
["desc", "desc", "asc"]
|
|
95
|
+
["desc", "desc", "asc"],
|
|
96
96
|
),
|
|
97
97
|
_.map(({ lang, name, local_name }) => (
|
|
98
98
|
<Menu.Item
|
|
@@ -106,7 +106,7 @@ export function MessagesContent() {
|
|
|
106
106
|
defaultMessage={`${name} ( ${local_name} )`}
|
|
107
107
|
/>
|
|
108
108
|
</Menu.Item>
|
|
109
|
-
))
|
|
109
|
+
)),
|
|
110
110
|
)(locales)}
|
|
111
111
|
</Menu>
|
|
112
112
|
<Divider hidden />
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
-
import I18nRoutes from "../I18nRoutes";
|
|
4
3
|
import { useAuthorized } from "@truedat/core/hooks/useAuthorized";
|
|
4
|
+
import I18nRoutes from "../I18nRoutes";
|
|
5
5
|
|
|
6
6
|
jest.mock("@truedat/core/hooks/useAuthorized", () => ({
|
|
7
7
|
useAuthorized: jest.fn(() => true),
|
package/src/messages/index.js
CHANGED
package/src/reducers/comments.js
CHANGED
|
@@ -6,7 +6,7 @@ const pickFields = _.pick([
|
|
|
6
6
|
"resource_type",
|
|
7
7
|
"content",
|
|
8
8
|
"user",
|
|
9
|
-
"created_at"
|
|
9
|
+
"created_at",
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
12
|
export const initialState = [];
|
|
@@ -22,8 +22,8 @@ export const comments = (state = initialState, { type, payload }) => {
|
|
|
22
22
|
case createComment.SUCCESS:
|
|
23
23
|
return _.flow(
|
|
24
24
|
_.propOr(initialState, "data"),
|
|
25
|
-
comment => [comment, ...state],
|
|
26
|
-
_.map(pickFields)
|
|
25
|
+
(comment) => [comment, ...state],
|
|
26
|
+
_.map(pickFields),
|
|
27
27
|
)(payload);
|
|
28
28
|
default:
|
|
29
29
|
return state;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { render, waitForLoad } from "@truedat/test/render";
|
|
2
|
-
import ProtectedRoute from "../ProtectedRoute";
|
|
3
2
|
import { useAuthorized } from "@truedat/core/hooks/useAuthorized";
|
|
3
|
+
import ProtectedRoute from "../ProtectedRoute";
|
|
4
4
|
|
|
5
5
|
// Mock the hooks module
|
|
6
6
|
jest.mock("@truedat/core/hooks/useAuthorized", () => ({
|
package/src/routes.js
CHANGED
|
@@ -545,6 +545,6 @@ const routes = {
|
|
|
545
545
|
};
|
|
546
546
|
|
|
547
547
|
export const linkTo = _.mapValues(
|
|
548
|
-
(route) => (params) => compile(route)(_.mapValues((x) => `${x}`)(params))
|
|
548
|
+
(route) => (params) => compile(route)(_.mapValues((x) => `${x}`)(params)),
|
|
549
549
|
)(routes);
|
|
550
550
|
export default routes;
|
package/src/routesTree.js
CHANGED
|
@@ -44,7 +44,7 @@ export function path(location) {
|
|
|
44
44
|
return finalRouteObj[lastSegment]
|
|
45
45
|
? finalRouteObj[lastSegment][0]
|
|
46
46
|
: undefined;
|
|
47
|
-
}
|
|
47
|
+
},
|
|
48
48
|
)();
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
@@ -59,17 +59,22 @@ export function absolutePath(location) {
|
|
|
59
59
|
|
|
60
60
|
if (_.isEmpty(segments)) return "/";
|
|
61
61
|
|
|
62
|
+
// eslint-disable-next-line fp/no-let
|
|
62
63
|
let currentPath = "";
|
|
64
|
+
// eslint-disable-next-line fp/no-let
|
|
63
65
|
let currentRouteObj = routes[1];
|
|
64
66
|
|
|
67
|
+
// eslint-disable-next-line fp/no-let, fp/no-mutation
|
|
65
68
|
for (let i = 0; i < segments.length; i++) {
|
|
66
69
|
const segment = segments[i];
|
|
67
70
|
|
|
68
71
|
if (!currentRouteObj[segment]) return undefined;
|
|
69
72
|
|
|
73
|
+
// eslint-disable-next-line fp/no-mutation
|
|
70
74
|
currentPath += `/${currentRouteObj[segment][0]}`;
|
|
71
75
|
|
|
72
76
|
if (i < segments.length - 1) {
|
|
77
|
+
// eslint-disable-next-line fp/no-mutation
|
|
73
78
|
currentRouteObj = currentRouteObj[segment][1];
|
|
74
79
|
if (!currentRouteObj) return undefined;
|
|
75
80
|
}
|
package/src/routines.js
CHANGED
|
@@ -12,12 +12,12 @@ export const dismissAlert = createRoutine("DISMISS_ALERT");
|
|
|
12
12
|
export const createRelation = createRoutine("CREATE_RELATION");
|
|
13
13
|
export const deleteRelation = createRoutine("DELETE_RELATION");
|
|
14
14
|
export const clearSelectedRelationTags = createRoutine(
|
|
15
|
-
"CLEAR_SELECTED_RELATION_TAGS"
|
|
15
|
+
"CLEAR_SELECTED_RELATION_TAGS",
|
|
16
16
|
);
|
|
17
17
|
|
|
18
18
|
// Defined here instead of in audit to avoid cyclical dependencies
|
|
19
19
|
export const clearSubscriptionsSearch = createRoutine(
|
|
20
|
-
"CLEAR_SUBSCRIPTIONS_SEARCH"
|
|
20
|
+
"CLEAR_SUBSCRIPTIONS_SEARCH",
|
|
21
21
|
);
|
|
22
22
|
export const createSubscription = createRoutine("CREATE_SUBSCRIPTION");
|
|
23
23
|
export const deleteSubscription = createRoutine("DELETE_SUBSCRIPTION");
|