Skip to content

Commit d2e173b

Browse files
committed
Smart permissions
1 parent e30fee1 commit d2e173b

1 file changed

Lines changed: 116 additions & 89 deletions

File tree

src/components/LanguageTree/node.js

Lines changed: 116 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,72 @@ const LangNode = ({
2929
closeModal,
3030
localPermission
3131
}) => {
32-
const { getTranslation, chooseTranslation } = useTranslations();
33-
const user = useSelector(state => state.user.user);
34-
const [modalCount, setModalCount] = useState(0);
3532

33+
const user = useSelector(state => state.user.user);
3634
const signedIn = user.id !== undefined;
3735
const allowedSync = user.id === 1 || user.allowed_sync;
38-
const publishedStr = getTranslation("Published");
36+
37+
const permissionSet = (perspective) => {
38+
39+
const permissions = new Set();
40+
const perspectiveId = compositeIdToString(perspective.id);
41+
const proxy = config.buildType === "desktop" || config.buildType === "proxy";
42+
const proxyPermissions = proxy ? proxyData?.permission_lists : undefined;
43+
44+
switch (true) {
45+
// Perspective has a twin for synchronization
46+
case allowedSync && perspective.single === "proxy":
47+
permissions.add('proxyPers');
48+
49+
case allowedSync && perspective.single !== "local" && perspective.single !== "proxy":
50+
permissions.add('commonPers');
51+
52+
// Perspective is locally writable
53+
case localPermission && localPermission[perspectiveId] || user.id !== 1:
54+
permissions.add('writable');
55+
56+
// Perspective has no twin for synchronization or proxyPermissions is undefined
57+
case perspective.single === "local" || !proxyPermissions || user.id !== 1:
58+
permissions.add('available');
59+
break;
60+
61+
// Perspective has proxyPermissions for current user and can be shown locally
62+
case !!proxyPermissions?.view.find(p => compositeIdToString(p.id) === perspectiveId):
63+
permissions.add('view').add('available');
64+
65+
case !!proxyPermissions?.edit.find(p => compositeIdToString(p.id) === perspectiveId):
66+
permissions.add('edit').add('available');
67+
68+
case !!proxyPermissions?.publish.find(p => compositeIdToString(p.id) === perspectiveId):
69+
permissions.add('publish').add('available');
70+
71+
case !!proxyPermissions?.limited.find(p => compositeIdToString(p.id) === perspectiveId):
72+
permissions.add('limited').add('available');
73+
}
74+
75+
switch (true) {
76+
case !permissions.has('available'):
77+
break;
78+
79+
case permissions.has('proxyPers'):
80+
permissions.add('canBeAdded');
81+
82+
case permissions.has('commonPers') && permissions.has('writable'):
83+
permissions.add('canBeSynced');
84+
85+
case permissions.has('canBeAdded') || permissions.has('canBeSynced'):
86+
permissions.add('syncable');
87+
}
88+
89+
return permissions;
90+
}
91+
92+
const { getTranslation, chooseTranslation } = useTranslations();
93+
const [modalCount, setModalCount] = useState(0);
3994

4095
const languageId = compositeIdToString(node[0]);
4196
const language = languageMap[languageId];
42-
const proxyLang = language.single === "proxy";
97+
const proxyLang = allowedSync && language.single === "proxy";
4398

4499
let langClass = "lang-name";
45100
if (!language.parent_id) {
@@ -55,11 +110,21 @@ const LangNode = ({
55110
})
56111
: language.dictionaries;
57112

58-
const onSynchronize = ({ id, silentMode, action, refetching=true }) => {
113+
const onSynchronize = ({ perspective, silentMode }) => {
114+
const action = (perspective.single === 'proxy') ? 'create' : 'edit';
115+
const refetching = (action === 'create');
116+
const permissions = permissionSet(perspective);
117+
118+
if (action === 'create' && !permissions.has('canBeAdded') ||
119+
action === 'edit' && !permissions.has('canBeSynced')) {
120+
console.log("Недостаточно прав на загрузку или обновление перспективы!");
121+
return;
122+
}
123+
59124
// +1 or no any change
60125
setModalCount(modalCount + refetching);
61126
openNewModal(SyncModal, {
62-
perspectiveId: id,
127+
perspectiveId: perspective.id,
63128
silentMode,
64129
action,
65130
onClose: () => {
@@ -76,30 +141,27 @@ const LangNode = ({
76141
}
77142
}, [modalCount]);
78143

79-
const proxy = config.buildType === "desktop" || config.buildType === "proxy";
80-
const permissions = proxy ? proxyData?.permission_lists : undefined;
81-
82144
return (
83145
<li className="node_lang" id={`language_${languageId}`}>
84146
<span className={langClass}>
85-
{allowedSync && proxyLang && language.translations && (
147+
{proxyLang && language.translations && (
86148
<span
87149
className="lang-name-remote"
88150
onClick={() =>
89151
openConfirmModal(
90-
`${getTranslation("Language")} "${chooseTranslation(language.translations)}" -> "${chooseTranslation(
91-
language.translations
92-
)}" ${getTranslation("will be downloaded from another server")}?`,
152+
`${getTranslation(
153+
"Language")} "${chooseTranslation(language.translations)}" ${getTranslation(
154+
"with own dictionaries and perspectives")} ${getTranslation(
155+
"will be downloaded from another server")}?`,
93156
() => {
94157
console.log("Загружаем язык");
95158
// Probably we should check every dictionary for permissions
96159
// User can synchronize a dictionary if he has 'edit' permissions
97160
language.dictionaries.forEach(dictionary => {
98161
dictionary.perspectives.forEach(perspective => {
99162
onSynchronize({
100-
id: perspective.id,
101-
silentMode: true,
102-
action: 'create'
163+
perspective,
164+
silentMode: true
103165
});
104166
});
105167
});
@@ -132,8 +194,8 @@ const LangNode = ({
132194
))}
133195
{dictionaries.map((dictionary, index) => {
134196
const dictionaryId = compositeIdToString(dictionary.id);
135-
const proxyDict = dictionary.single === "proxy";
136-
const commonDict = dictionary.single !== "local" && dictionary.single !== "proxy";
197+
const proxyDict = allowedSync && dictionary.single === "proxy";
198+
const commonDict = allowedSync && dictionary.single !== "local" && dictionary.single !== "proxy";
137199

138200
const isDownloaded = proxyData
139201
? proxyData.dictionaries.find(d => d.id.toString() === dictionary.id.toString()) !== undefined
@@ -143,7 +205,7 @@ const LangNode = ({
143205
return (
144206
<li
145207
key={index}
146-
className={`node_dict${allowedSync && proxyDict ? " node_dict_remote" : ""}`}
208+
className={`node_dict${proxyDict ? " node_dict_remote" : ""}`}
147209
>
148210
{/* This elements went from old realization and not actual now */
149211
/*
@@ -165,23 +227,20 @@ const LangNode = ({
165227
{isDownloaded && <Icon name="download" />}
166228
*/}
167229

168-
{allowedSync && proxyDict ? (
230+
{proxyDict ? (
169231
<span
170232
className="dict-name dict-name_link"
171233
onClick={() =>
172234
openConfirmModal(
173-
`${getTranslation("Dictionary")} "${chooseTranslation(
174-
dictionary.translations
175-
)}" -> "${chooseTranslation(dictionary.translations)}" ${getTranslation(
176-
"will be downloaded from another server"
177-
)}?`,
235+
`${getTranslation(
236+
"Dictionary")} "${chooseTranslation(dictionary.translations)}" ${getTranslation(
237+
"with own perspectives")} ${getTranslation("will be downloaded from another server")}?`,
178238
() => {
179239
console.log("Загружаем словарь");
180240
perspectives.forEach(perspective => {
181241
onSynchronize({
182-
id: perspective.id,
183-
silentMode: true,
184-
action: 'create'
242+
perspective,
243+
silentMode: true
185244
});
186245
});
187246
},
@@ -213,57 +272,37 @@ const LangNode = ({
213272
return;
214273
}
215274

216-
const perspectiveId = compositeIdToString(perspective.id);
275+
const permissions = permissionSet(perspective);
276+
const proxyPers = permissions.has('proxyPers');
277+
const commonPers = permissions.has('commonPers');
278+
const canBeSynced = permissions.has('canBeSynced');
217279

218-
const view = !!permissions?.view.find(
219-
p => compositeIdToString(p.id) === perspectiveId
220-
);
221-
const edit = !!permissions?.edit.find(
222-
p => compositeIdToString(p.id) === perspectiveId
223-
);
224-
const publish = !!permissions?.publish.find(
225-
p => compositeIdToString(p.id) === perspectiveId
226-
);
227-
const limited = !!permissions?.limited.find(
228-
p => compositeIdToString(p.id) === perspectiveId
229-
);
230-
231-
const proxyPers = perspective.single === "proxy";
232-
const commonPers = perspective.single !== "local" && perspective.single !== "proxy";
233-
234-
if (
235-
user.id !== 1 && (proxyPers || commonPers) &&
236-
permissions && !(view || edit || publish || limited)
237-
) {
280+
if (!permissions.has('available')) {
238281
return;
239282
}
240283

241284
return (
242285
<Dropdown.Item
243-
key={perspectiveId}
244-
as={allowedSync && proxyPers ? "span" : Link}
286+
key={compositeIdToString(perspective.id)}
287+
as={proxyPers ? "span" : Link}
245288
to={
246289
!proxyPers
247290
? `/dictionary/${dictionary.id.join("/")}/perspective/${perspective.id.join("/")}`
248291
: null
249292
}
250-
className={allowedSync && proxyPers ? "item_remote" : ""}
293+
className={proxyPers ? "item_remote" : ""}
251294
onClick={
252-
(allowedSync && proxyPers &&
253-
perspective.translations &&
295+
(proxyPers && perspective.translations &&
254296
(() =>
255297
openConfirmModal(
256-
`${getTranslation("Perspective")} "${chooseTranslation(
257-
perspective.translations
258-
)}" -> "${chooseTranslation(perspective.translations)}" ${getTranslation(
259-
"will be downloaded from another server"
260-
)}?`,
298+
`${getTranslation(
299+
"Perspective")} "${chooseTranslation(perspective.translations)}" ${getTranslation(
300+
"will be downloaded from another server")}?`,
261301
() => {
262302
console.log("Загружаем перспективу");
263303
onSynchronize({
264-
id: perspective.id,
265-
silentMode: true,
266-
action: 'create'
304+
perspective,
305+
silentMode: true
267306
});
268307
},
269308
getTranslation("Yes"),
@@ -272,14 +311,12 @@ const LangNode = ({
272311
null
273312
}
274313
>
275-
{permissions && (
276-
<span>
277-
{view && <Icon name="book" />}
278-
{edit && <Icon name="edit" />}
279-
{publish && <Icon name="external share" />}
280-
{limited && <Icon name="privacy" />}
281-
</span>
282-
)}
314+
<span>
315+
{permissions.has('view') && <Icon name="book" />}
316+
{permissions.has('edit') && <Icon name="edit" />}
317+
{permissions.has('publish') && <Icon name="external share" />}
318+
{permissions.has('limited') && <Icon name="privacy" />}
319+
</span>
283320

284321
{perspective.translations && (
285322
<>
@@ -288,21 +325,17 @@ const LangNode = ({
288325
</>
289326
)}
290327

291-
{allowedSync && commonPers && (
328+
{commonPers && (
292329
<Button
293330
icon={<i className="lingvo-icon lingvo-icon_refresh" />}
294331
onClick={event => {
295332
console.log("Обновляем перспективу");
296333
onSynchronize({
297-
id: perspective.id,
298-
refetching: false
334+
perspective
299335
});
300336
event.preventDefault();
301337
}}
302-
disabled={
303-
!localPermission ||
304-
!localPermission[compositeIdToString(perspective.id)]
305-
}
338+
disabled={!canBeSynced}
306339
className="lingvo-button-green lingvo-lang-tree-button"
307340
/>
308341
)}
@@ -317,31 +350,25 @@ const LangNode = ({
317350
{config.buildType === "server" && signedIn && dictionary.english_status === "Published" && (
318351
<Popup
319352
trigger={<i className="lingvo-icon lingvo-icon_published" />}
320-
content={publishedStr}
353+
content={getTranslation("Published")}
321354
className="lingvo-popup lingvo-popup_published"
322355
hideOnScroll={true}
323356
/>
324357
)}
325358

326-
{allowedSync && commonDict && (
359+
{commonDict && (
327360
<Button
328361
icon={<i className="lingvo-icon lingvo-icon_refresh" />}
329362
onClick={() => {
330363
console.log("Обновляем словарь");
331364
perspectives.forEach(perspective => {
332365
onSynchronize({
333-
id: perspective.id,
334-
silentMode: true,
335-
refetching: false,
336-
action: perspective.single === "proxy" ? 'create' : 'edit'
366+
perspective,
367+
silentMode: true
337368
});
338369
});
339370
}}
340-
disabled={
341-
!localPermission ||
342-
perspectives.every(
343-
perspective => !localPermission[compositeIdToString(perspective.id)])
344-
}
371+
disabled={!perspectives.some(p => permissionSet(p).has('syncable'))}
345372
className="lingvo-button-green lingvo-lang-tree-button"
346373
/>
347374
)}

0 commit comments

Comments
 (0)