permissions for all edit content
This commit is contained in:
parent
5b2dd86e30
commit
cc4c23ad19
@ -4,15 +4,28 @@ import { IconGripVertical } from '@tabler/icons-react';
|
|||||||
import { StrictModeDroppable } from './StrictModeDroppable';
|
import { StrictModeDroppable } from './StrictModeDroppable';
|
||||||
import { ActionIcon, Button, Center, Group, NumberInput, Paper, Text } from '@mantine/core';
|
import { ActionIcon, Button, Center, Group, NumberInput, Paper, Text } from '@mantine/core';
|
||||||
import { IconTrash } from '@tabler/icons-react';
|
import { IconTrash } from '@tabler/icons-react';
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import ModalFileSelector from '../files/file-selector';
|
import ModalFileSelector from '../files/file-selector';
|
||||||
import API from '../../services/api';
|
import API from '../../services/api';
|
||||||
import setNotification from '../errors/error-notification';
|
import setNotification from '../errors/error-notification';
|
||||||
import GrantAccess, { Perm } from '../../tools/grant-access';
|
import GrantAccess, { Perm, checkPerm } from '../../tools/grant-access';
|
||||||
|
import { useAuth } from '../../tools/auth-provider';
|
||||||
|
import { parseTime } from '../../tools/timeUtil';
|
||||||
|
|
||||||
const Content = ({ form, playlistId, playlist }) => {
|
const Content = ({ form, playlistId, playlist }) => {
|
||||||
const [fileSelector, setFileSelector] = useState(false);
|
const [fileSelector, setFileSelector] = useState(false);
|
||||||
const toggleFileSelector = () => setFileSelector(!fileSelector);
|
const toggleFileSelector = () => setFileSelector(!fileSelector);
|
||||||
|
const [canEdit, setCanEdit] = useState(false);
|
||||||
|
const { user } = useAuth();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!user || !playlist) return;
|
||||||
|
const canEditTmp = checkPerm(Perm.EDIT_PLAYLIST, user, playlist);
|
||||||
|
if (canEditTmp != canEdit) {
|
||||||
|
setCanEdit(canEditTmp);
|
||||||
|
}
|
||||||
|
return () => {};
|
||||||
|
}, [playlist, user]);
|
||||||
|
|
||||||
const handleAddFiles = (files) => {
|
const handleAddFiles = (files) => {
|
||||||
let formFiles = form.values.files;
|
let formFiles = form.values.files;
|
||||||
@ -24,7 +37,8 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
file.seconds = 10;
|
file.seconds = 10;
|
||||||
const index = form.values.files.length;
|
const index = form.values.files.length;
|
||||||
form.insertListItem('files', file);
|
form.insertListItem('files', file);
|
||||||
API.playlists.addFile(playlistId, { position: file.position, file_id: file.id, seconds: file.seconds })
|
API.playlists
|
||||||
|
.addFile(playlistId, { position: file.position, file_id: file.id, seconds: file.seconds })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
setNotification(true, `Error when adding file (${res.status})`);
|
setNotification(true, `Error when adding file (${res.status})`);
|
||||||
@ -55,7 +69,8 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
let newPosition = (below_position + above_position) / 2;
|
let newPosition = (below_position + above_position) / 2;
|
||||||
|
|
||||||
// sending modification to server
|
// sending modification to server
|
||||||
API.playlists.changeOrder(playlistId, { file_id: formFiles[from].id, position: newPosition })
|
API.playlists
|
||||||
|
.changeOrder(playlistId, { file_id: formFiles[from].id, position: newPosition })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
@ -95,7 +110,8 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
|
|
||||||
const changeSeconds = (seconds, index) => {
|
const changeSeconds = (seconds, index) => {
|
||||||
const fileId = form.values.files[index].id;
|
const fileId = form.values.files[index].id;
|
||||||
API.playlists.changeSeconds(playlistId, { file_id: fileId, seconds: seconds })
|
API.playlists
|
||||||
|
.changeSeconds(playlistId, { file_id: fileId, seconds: seconds })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
setOriginSecs();
|
setOriginSecs();
|
||||||
@ -111,7 +127,8 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (index) => {
|
const handleDelete = (index) => {
|
||||||
API.playlists.removeFile(playlistId, { file_id: form.values.files[index].pfid })
|
API.playlists
|
||||||
|
.removeFile(playlistId, { file_id: form.values.files[index].pfid })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
form.removeListItem('files', index);
|
form.removeListItem('files', index);
|
||||||
@ -132,6 +149,7 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
<Flex direction="row" align="center" gap="lg" justify="flex-end">
|
<Flex direction="row" align="center" gap="lg" justify="flex-end">
|
||||||
<Text>{form.getInputProps(`files.${index}.name`).value}</Text>
|
<Text>{form.getInputProps(`files.${index}.name`).value}</Text>
|
||||||
<Image width={150} src={'/api/file/' + form.getInputProps(`files.${index}.id`).value} />
|
<Image width={150} src={'/api/file/' + form.getInputProps(`files.${index}.id`).value} />
|
||||||
|
{ canEdit ?
|
||||||
<NumberInput
|
<NumberInput
|
||||||
required
|
required
|
||||||
hideControls
|
hideControls
|
||||||
@ -140,14 +158,24 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
onChange={(secs) => handleChangeSeconds(secs, index)}
|
onChange={(secs) => handleChangeSeconds(secs, index)}
|
||||||
error={form.getInputProps(`files.${index}.seconds`).errors && 'This field is required'}
|
error={form.getInputProps(`files.${index}.seconds`).errors && 'This field is required'}
|
||||||
/>
|
/>
|
||||||
<ActionIcon color="red" variant="light" size="lg" onClick={() => handleDelete(index)}>
|
: <Text>Display time: {parseTime(form.getInputProps(`files.${index}.seconds`).value)}</Text>
|
||||||
<IconTrash size="1rem" />
|
}
|
||||||
</ActionIcon>
|
{canEdit ? (
|
||||||
|
<ActionIcon color="red" variant="light" size="lg" onClick={() => handleDelete(index)}>
|
||||||
|
<IconTrash size="1rem" />
|
||||||
|
</ActionIcon>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Paper>
|
</Paper>
|
||||||
<Center {...provided.dragHandleProps}>
|
{canEdit ? (
|
||||||
<IconGripVertical size="1.2rem" />
|
<Center {...provided.dragHandleProps}>
|
||||||
</Center>
|
<IconGripVertical size="1.2rem" />
|
||||||
|
</Center>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
)}
|
)}
|
||||||
</Draggable>
|
</Draggable>
|
||||||
@ -175,25 +203,23 @@ const Content = ({ form, playlistId, playlist }) => {
|
|||||||
</StrictModeDroppable>
|
</StrictModeDroppable>
|
||||||
</DragDropContext>
|
</DragDropContext>
|
||||||
|
|
||||||
<GrantAccess
|
{canEdit ? (
|
||||||
role={Perm.EDIT_PLAYLIST}
|
<>
|
||||||
item={playlist}
|
<Group position="center" mt="md">
|
||||||
children={
|
<Button vairant="light" onClick={toggleFileSelector}>
|
||||||
<>
|
Select File(s)
|
||||||
<Group position="center" mt="md">
|
</Button>
|
||||||
<Button vairant="light" onClick={toggleFileSelector}>
|
</Group>
|
||||||
Select File(s)
|
<ModalFileSelector
|
||||||
</Button>
|
opened={fileSelector}
|
||||||
</Group>
|
multi
|
||||||
<ModalFileSelector
|
handleClose={toggleFileSelector}
|
||||||
opened={fileSelector}
|
handleSubmit={(files) => handleAddFiles(files)}
|
||||||
multi
|
/>
|
||||||
handleClose={toggleFileSelector}
|
</>
|
||||||
handleSubmit={(files) => handleAddFiles(files)}
|
) : (
|
||||||
/>
|
<></>
|
||||||
</>
|
)}
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,6 @@ const PlaylistViewEditor = ({ item, handler, buttonText, APICall }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
console.log(item);
|
|
||||||
const [rolesView, setRolesView] = useState(item?.view.map((role) => role.id.toString()) ?? []);
|
const [rolesView, setRolesView] = useState(item?.view.map((role) => role.id.toString()) ?? []);
|
||||||
const [rolesEdit, setRolesEdit] = useState(item?.edit.map((role) => role.id.toString()) ?? []);
|
const [rolesEdit, setRolesEdit] = useState(item?.edit.map((role) => role.id.toString()) ?? []);
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ const PlaylistViewEditor = ({ item, handler, buttonText, APICall }) => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
if (item) {
|
if (item) {
|
||||||
await APICall(item?.id, { name: form.values.name });
|
await APICall(item?.id, { name: form.values.name });
|
||||||
// todo permissions
|
// todo permissions update
|
||||||
item.name = form.values.name;
|
item.name = form.values.name;
|
||||||
handleClose(item);
|
handleClose(item);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
export const parseTime = (preparationTime) => {
|
export const parseTime = (timeInSecs) => {
|
||||||
let res = '';
|
let res = '';
|
||||||
let hours = Math.floor(preparationTime / 3600);
|
let hours = Math.floor(timeInSecs / 3600);
|
||||||
res += hours > 0 ? `${hours}h` : '';
|
res += hours > 0 ? `${hours}h` : '';
|
||||||
|
|
||||||
let min = Math.floor((preparationTime % 3600) / 60);
|
let min = Math.floor((timeInSecs % 3600) / 60);
|
||||||
if (min > 0 && res !== '') res += ' ';
|
if (min > 0 && res !== '') res += ' ';
|
||||||
res += min > 0 ? `${min}m` : '';
|
res += min > 0 ? `${min}m` : '';
|
||||||
|
|
||||||
let sec = Math.floor((preparationTime % 3600) % 60);
|
let sec = Math.floor((timeInSecs % 3600) % 60);
|
||||||
if (sec > 0 && res !== '') res += ' ';
|
if (sec > 0 && res !== '') res += ' ';
|
||||||
res += sec > 0 ? `${sec}s` : '';
|
res += sec > 0 ? `${sec}s` : '';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user