@truedat/core 5.20.0 → 5.20.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 +2 -2
- package/src/api.js +2 -0
- package/src/hooks/useAllLocales.js +9 -0
- package/src/hooks/useLocales.js +37 -2
- package/src/hooks/useMessages.js +1 -2
- package/src/i18n/components/Languages.js +205 -0
- package/src/i18n/components/MessageForm.js +11 -9
- package/src/i18n/components/Messages.js +59 -27
- package/src/i18n/components/__tests__/Messages.spec.js +4 -2
- package/src/i18n/components/__tests__/__snapshots__/Messages.spec.js.snap +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/core",
|
|
3
|
-
"version": "5.20.
|
|
3
|
+
"version": "5.20.1",
|
|
4
4
|
"description": "Truedat Web Core",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"react-dom": ">= 16.8.6 < 17",
|
|
118
118
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "a7197e02a1b1a88c375fe044dee65c7e96ccd618"
|
|
121
121
|
}
|
package/src/api.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const API_COMMENTS = "/api/business_concepts/comments";
|
|
2
|
+
export const API_LOCALE = "/api/locales/:id";
|
|
2
3
|
export const API_LOCALE_MESSAGES = "/api/locales/:lang/messages";
|
|
3
4
|
export const API_LOCALES = "/api/locales";
|
|
5
|
+
export const API_ALL_LOCALES = "/api/locales/all_locales";
|
|
4
6
|
export const API_MESSAGE = "/api/messages/:id";
|
|
5
7
|
export const API_MESSAGES = "/api/messages";
|
|
6
8
|
export const API_REINDEX_GRANTS = "/api/grants/search/reindex_all";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import useSWR from "swr";
|
|
2
|
+
import { API_ALL_LOCALES } from "../api";
|
|
3
|
+
import { apiJson } from "../services/api";
|
|
4
|
+
|
|
5
|
+
export const useAllLocales = () => {
|
|
6
|
+
const { data, loading, error, mutate } = useSWR(API_ALL_LOCALES, apiJson);
|
|
7
|
+
const all_locales = data?.data?.data;
|
|
8
|
+
return { all_locales, error, loading, mutate };
|
|
9
|
+
};
|
package/src/hooks/useLocales.js
CHANGED
|
@@ -1,9 +1,44 @@
|
|
|
1
|
+
import { compile } from "path-to-regexp";
|
|
1
2
|
import useSWR from "swr";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
3
|
+
import useSWRMutations from "swr/mutation";
|
|
4
|
+
import { API_LOCALES, API_LOCALE } from "../api";
|
|
5
|
+
import {
|
|
6
|
+
apiJson,
|
|
7
|
+
apiJsonDelete,
|
|
8
|
+
apiJsonPatch,
|
|
9
|
+
apiJsonPost,
|
|
10
|
+
} from "../services/api";
|
|
11
|
+
import _ from "lodash/fp";
|
|
4
12
|
|
|
5
13
|
export const useLocales = () => {
|
|
6
14
|
const { data, error, mutate } = useSWR(API_LOCALES, apiJson);
|
|
7
15
|
const locales = data?.data?.data;
|
|
8
16
|
return { locales, error, loading: !error && !data, mutate };
|
|
9
17
|
};
|
|
18
|
+
|
|
19
|
+
export const useLocalesUpdate = (id) => {
|
|
20
|
+
const toApiPath = compile(API_LOCALE);
|
|
21
|
+
const url = toApiPath({ id });
|
|
22
|
+
return useSWRMutations(url, (url, { arg }) => {
|
|
23
|
+
const { mutateData } = arg;
|
|
24
|
+
const payload = { id: arg.id, locale: arg };
|
|
25
|
+
apiJsonPatch(url, payload).then(() => mutateData());
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const useLocalesCreate = () => {
|
|
30
|
+
const url = API_LOCALES;
|
|
31
|
+
|
|
32
|
+
return useSWRMutations(url, (url, { arg }) => {
|
|
33
|
+
apiJsonPost(url, arg);
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const useLocalesDelete = (id) => {
|
|
38
|
+
const toApiPath = compile(API_LOCALE);
|
|
39
|
+
const url = toApiPath({ id });
|
|
40
|
+
return useSWRMutations(url, (url, { arg }) => {
|
|
41
|
+
const payload = { id: arg.id };
|
|
42
|
+
apiJsonDelete(url, payload);
|
|
43
|
+
});
|
|
44
|
+
};
|
package/src/hooks/useMessages.js
CHANGED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { useIntl, FormattedMessage } from "react-intl";
|
|
4
|
+
import _ from "lodash/fp";
|
|
5
|
+
import {
|
|
6
|
+
Button,
|
|
7
|
+
Dropdown,
|
|
8
|
+
Form,
|
|
9
|
+
Icon,
|
|
10
|
+
Input,
|
|
11
|
+
Table,
|
|
12
|
+
TableBody,
|
|
13
|
+
TableCell,
|
|
14
|
+
TableHeader,
|
|
15
|
+
TableRow,
|
|
16
|
+
} from "semantic-ui-react";
|
|
17
|
+
import { ConfirmModal } from "@truedat/core/components";
|
|
18
|
+
import { useAllLocales } from "../../hooks/useAllLocales";
|
|
19
|
+
import {
|
|
20
|
+
useLocalesCreate,
|
|
21
|
+
useLocalesDelete,
|
|
22
|
+
useLocalesUpdate,
|
|
23
|
+
} from "../../hooks/useLocales";
|
|
24
|
+
|
|
25
|
+
const LanguajeRow = ({ code, local, name, config, mutate }) => {
|
|
26
|
+
const { formatMessage } = useIntl();
|
|
27
|
+
const { trigger } = useLocalesUpdate(config.id);
|
|
28
|
+
const { trigger: triggerDelete } = useLocalesDelete(config.id);
|
|
29
|
+
|
|
30
|
+
const handleChange = (data) => {
|
|
31
|
+
const { name, checked } = data;
|
|
32
|
+
const newConfig = {
|
|
33
|
+
...config,
|
|
34
|
+
[name]: !checked,
|
|
35
|
+
};
|
|
36
|
+
trigger({ ...newConfig, mutateData: mutate });
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const handleDelete = () => {
|
|
40
|
+
triggerDelete(config).then(() => {
|
|
41
|
+
mutate();
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<TableRow>
|
|
47
|
+
<TableCell>
|
|
48
|
+
{_.upperCase(code)} | {local} ( {name} )
|
|
49
|
+
</TableCell>
|
|
50
|
+
<TableCell textAlign="center">
|
|
51
|
+
<Input
|
|
52
|
+
type="checkbox"
|
|
53
|
+
name="is_required"
|
|
54
|
+
checked={config.is_required}
|
|
55
|
+
disabled={config.is_default}
|
|
56
|
+
onChange={(_e, data) => handleChange(data)}
|
|
57
|
+
/>
|
|
58
|
+
</TableCell>
|
|
59
|
+
<TableCell textAlign="center">
|
|
60
|
+
<Input
|
|
61
|
+
id={`radio-${code}`}
|
|
62
|
+
type="radio"
|
|
63
|
+
name="is_default"
|
|
64
|
+
checked={config.is_default}
|
|
65
|
+
onChange={(_e, data) => handleChange(data)}
|
|
66
|
+
/>
|
|
67
|
+
</TableCell>
|
|
68
|
+
<TableCell>
|
|
69
|
+
<ConfirmModal
|
|
70
|
+
icon="trash"
|
|
71
|
+
trigger={
|
|
72
|
+
<Icon
|
|
73
|
+
className="lang-manager-delete"
|
|
74
|
+
name="trash alternate outline"
|
|
75
|
+
color="red"
|
|
76
|
+
disabled={config.is_default || ["es", "en"].includes(code)}
|
|
77
|
+
/>
|
|
78
|
+
}
|
|
79
|
+
header={formatMessage({
|
|
80
|
+
id: "i18n.messages.locale.delete.confirmation.header",
|
|
81
|
+
})}
|
|
82
|
+
content={formatMessage({
|
|
83
|
+
id: "i18n.messages.locale.delete.confirmation.content",
|
|
84
|
+
})}
|
|
85
|
+
onConfirm={() => handleDelete()}
|
|
86
|
+
/>
|
|
87
|
+
</TableCell>
|
|
88
|
+
</TableRow>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
LanguajeRow.propTypes = {
|
|
93
|
+
code: PropTypes.string,
|
|
94
|
+
local: PropTypes.string,
|
|
95
|
+
name: PropTypes.string,
|
|
96
|
+
config: PropTypes.object,
|
|
97
|
+
mutate: PropTypes.func,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const Languages = ({ config, langs, mutate }) => {
|
|
101
|
+
const { formatMessage } = useIntl();
|
|
102
|
+
const { all_locales, loading, error } = useAllLocales();
|
|
103
|
+
const [newLocales, setNewLocales] = useState([]);
|
|
104
|
+
const { trigger } = useLocalesCreate();
|
|
105
|
+
|
|
106
|
+
const options = _.flow(
|
|
107
|
+
_.filter(({ code }) => {
|
|
108
|
+
return !langs.includes(code);
|
|
109
|
+
}),
|
|
110
|
+
_.map(({ code, name, local }) => {
|
|
111
|
+
return { text: `${local} (${name} | ${code})`, value: code };
|
|
112
|
+
})
|
|
113
|
+
)(all_locales);
|
|
114
|
+
|
|
115
|
+
const handleOnChange = ({ value }) => {
|
|
116
|
+
setNewLocales(value);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const handleSubmit = () => {
|
|
120
|
+
setNewLocales([]);
|
|
121
|
+
trigger({ locales: newLocales }).then(() => {
|
|
122
|
+
mutate();
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<>
|
|
128
|
+
<Form
|
|
129
|
+
onSubmit={() => {
|
|
130
|
+
handleSubmit();
|
|
131
|
+
}}
|
|
132
|
+
>
|
|
133
|
+
<Dropdown
|
|
134
|
+
className="lang-manager-dropdown"
|
|
135
|
+
placeholder={formatMessage({
|
|
136
|
+
id: "i18n.messages.locale.lang_select",
|
|
137
|
+
defaultMessage: "Select languaje",
|
|
138
|
+
})}
|
|
139
|
+
name="add-locales"
|
|
140
|
+
multiple={true}
|
|
141
|
+
search={true}
|
|
142
|
+
selection={true}
|
|
143
|
+
options={options}
|
|
144
|
+
clearable={true}
|
|
145
|
+
value={newLocales}
|
|
146
|
+
onChange={(_e, data) => {
|
|
147
|
+
handleOnChange(data);
|
|
148
|
+
}}
|
|
149
|
+
/>
|
|
150
|
+
<Button
|
|
151
|
+
type="submit"
|
|
152
|
+
className="lang-manager-button"
|
|
153
|
+
disabled={_.isEmpty(newLocales)}
|
|
154
|
+
>
|
|
155
|
+
{formatMessage({
|
|
156
|
+
id: "i18n.messages.locale.add_lang",
|
|
157
|
+
})}
|
|
158
|
+
</Button>
|
|
159
|
+
</Form>
|
|
160
|
+
<Table collapsing striped>
|
|
161
|
+
<TableHeader>
|
|
162
|
+
<TableRow>
|
|
163
|
+
<TableCell></TableCell>
|
|
164
|
+
<TableCell textAlign="center">
|
|
165
|
+
{formatMessage({
|
|
166
|
+
id: "i18n.messages.locale.required",
|
|
167
|
+
})}
|
|
168
|
+
</TableCell>
|
|
169
|
+
<TableCell textAlign="center">
|
|
170
|
+
{formatMessage({
|
|
171
|
+
id: "i18n.messages.locale.default",
|
|
172
|
+
})}
|
|
173
|
+
</TableCell>
|
|
174
|
+
<TableCell></TableCell>
|
|
175
|
+
</TableRow>
|
|
176
|
+
</TableHeader>
|
|
177
|
+
<TableBody>
|
|
178
|
+
{_.flow(
|
|
179
|
+
_.filter((locale) => _.includes(locale.code)(langs)),
|
|
180
|
+
_.map(({ code, local, name }) => {
|
|
181
|
+
return (
|
|
182
|
+
<LanguajeRow
|
|
183
|
+
key={code}
|
|
184
|
+
code={code}
|
|
185
|
+
local={local}
|
|
186
|
+
name={name}
|
|
187
|
+
config={config[code]}
|
|
188
|
+
mutate={mutate}
|
|
189
|
+
/>
|
|
190
|
+
);
|
|
191
|
+
})
|
|
192
|
+
)(all_locales)}
|
|
193
|
+
</TableBody>
|
|
194
|
+
</Table>
|
|
195
|
+
</>
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
Languages.propTypes = {
|
|
200
|
+
config: PropTypes.array,
|
|
201
|
+
langs: PropTypes.object,
|
|
202
|
+
mutate: PropTypes.func,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export default Languages;
|
|
@@ -104,15 +104,17 @@ export const MessageForm = ({ onSubmit, isSubmitting }) => {
|
|
|
104
104
|
)}
|
|
105
105
|
/>
|
|
106
106
|
|
|
107
|
-
{locales
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
107
|
+
{locales
|
|
108
|
+
.filter(({ lang }) => lang === "en" || lang === "es")
|
|
109
|
+
.map((lang, i) => (
|
|
110
|
+
<LangForm
|
|
111
|
+
key={i}
|
|
112
|
+
control={control}
|
|
113
|
+
lang={lang}
|
|
114
|
+
errors={errors}
|
|
115
|
+
formatMessage={formatMessage}
|
|
116
|
+
/>
|
|
117
|
+
))}
|
|
116
118
|
|
|
117
119
|
<div className="actions">
|
|
118
120
|
<Button
|
|
@@ -18,12 +18,20 @@ import { useLocales } from "@truedat/core/hooks";
|
|
|
18
18
|
import { I18N_MESSAGES_NEW } from "@truedat/core/routes";
|
|
19
19
|
import { Pagination } from "@truedat/core/components";
|
|
20
20
|
import MessagesTable from "./MessagesTable";
|
|
21
|
+
import Languages from "./Languages";
|
|
21
22
|
|
|
22
23
|
const ITEMS_PER_PAGE = 30;
|
|
23
24
|
|
|
24
|
-
export function MessagesContent({ locales, loading }) {
|
|
25
|
+
export function MessagesContent({ locales, loading, mutate }) {
|
|
25
26
|
const langs = _.map("lang")(locales);
|
|
27
|
+
|
|
28
|
+
const langsConfig = _.flow(
|
|
29
|
+
_.map((locale) => _.omit("messages")(locale)),
|
|
30
|
+
_.groupBy("lang"),
|
|
31
|
+
_.mapValues(_.first)
|
|
32
|
+
)(locales);
|
|
26
33
|
const [selectedLang, setSelectedLang] = useState(_.head(langs));
|
|
34
|
+
const [selectedManageView, setSelectedManageView] = useState(false);
|
|
27
35
|
const [page, setPage] = useState(1);
|
|
28
36
|
const [filter, setFilter] = useState("");
|
|
29
37
|
const { formatMessage } = useIntl();
|
|
@@ -56,39 +64,59 @@ export function MessagesContent({ locales, loading }) {
|
|
|
56
64
|
return (
|
|
57
65
|
<>
|
|
58
66
|
<Menu attached="top" secondary pointing tabular>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
<Menu.Item
|
|
68
|
+
key={0}
|
|
69
|
+
active={selectedManageView}
|
|
70
|
+
onClick={() => setSelectedManageView(true)}
|
|
71
|
+
>
|
|
72
|
+
<FormattedMessage id="i18n.messages.locale.manage" />
|
|
73
|
+
</Menu.Item>
|
|
74
|
+
{langs
|
|
75
|
+
.filter((lang) => lang === "en" || lang === "es")
|
|
76
|
+
.map((lang, i) => (
|
|
77
|
+
<Menu.Item
|
|
78
|
+
key={i}
|
|
79
|
+
active={lang === selectedLang && !selectedManageView}
|
|
80
|
+
onClick={() => {
|
|
81
|
+
setSelectedLang(lang);
|
|
82
|
+
setSelectedManageView(false);
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
<FormattedMessage id={`i18n.messages.locale.${lang}`} />
|
|
86
|
+
</Menu.Item>
|
|
87
|
+
))}
|
|
68
88
|
</Menu>
|
|
69
89
|
<Divider hidden />
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
{!selectedManageView ? (
|
|
91
|
+
<>
|
|
92
|
+
<SearchInput
|
|
93
|
+
onChange={handleSearch}
|
|
94
|
+
placeholder={formatMessage({
|
|
95
|
+
id: "i18n.messages.search.placeholder",
|
|
96
|
+
})}
|
|
97
|
+
value={filter}
|
|
98
|
+
/>
|
|
99
|
+
<MessagesTable
|
|
100
|
+
messages={paginatedMessages}
|
|
101
|
+
locales={locales}
|
|
102
|
+
loading={loading}
|
|
103
|
+
/>
|
|
104
|
+
<Pagination
|
|
105
|
+
totalPages={totalPages}
|
|
106
|
+
activePage={page}
|
|
107
|
+
selectPage={({ activePage }) => setPage(activePage)}
|
|
108
|
+
/>
|
|
109
|
+
</>
|
|
110
|
+
) : (
|
|
111
|
+
<Languages langs={langs} config={langsConfig} mutate={mutate} />
|
|
112
|
+
)}
|
|
85
113
|
</>
|
|
86
114
|
);
|
|
87
115
|
}
|
|
88
116
|
|
|
89
117
|
export default function Messages() {
|
|
90
118
|
const { formatMessage } = useIntl();
|
|
91
|
-
const { locales, loading } = useLocales();
|
|
119
|
+
const { locales, loading, mutate } = useLocales();
|
|
92
120
|
|
|
93
121
|
return (
|
|
94
122
|
<Segment>
|
|
@@ -116,7 +144,11 @@ export default function Messages() {
|
|
|
116
144
|
to={I18N_MESSAGES_NEW}
|
|
117
145
|
/>
|
|
118
146
|
{!loading ? (
|
|
119
|
-
<MessagesContent
|
|
147
|
+
<MessagesContent
|
|
148
|
+
locales={locales}
|
|
149
|
+
loading={loading}
|
|
150
|
+
mutate={mutate}
|
|
151
|
+
/>
|
|
120
152
|
) : null}
|
|
121
153
|
</Segment>
|
|
122
154
|
</Segment>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render } from "@truedat/test/render";
|
|
3
|
-
import
|
|
3
|
+
import en from "@truedat/core/messages/en";
|
|
4
4
|
import Messages from "../Messages";
|
|
5
5
|
|
|
6
|
-
const renderOpts = {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: { en: { ...en, "i18n.messages.locale.manage": "manage" } },
|
|
8
|
+
};
|
|
7
9
|
|
|
8
10
|
jest.mock("@truedat/core/hooks", () => ({
|
|
9
11
|
useLocales: jest.fn(() => ({
|