From b75f2e3b49b005b405347c45482326e374113e99 Mon Sep 17 00:00:00 2001 From: grimhilt Date: Wed, 30 Aug 2023 14:39:09 +0200 Subject: [PATCH] global changes and test --- public/robots.txt | 3 + src/components/ModalEditor.jsx | 25 +++++++++ src/components/media-player.jsx | 4 +- src/pages/files/add.jsx | 1 - src/pages/playlist/content.jsx | 19 +++++-- src/pages/roles/create.jsx | 38 +++++++++++++ src/pages/roles/role-selector.jsx | 82 ++++++++++++++++++++++++++++ src/pages/roles/role-view-editor.jsx | 64 ++++++++++++++++++++++ src/tools/fileUtil.js | 10 ++++ 9 files changed, 239 insertions(+), 7 deletions(-) create mode 100644 public/robots.txt create mode 100644 src/components/ModalEditor.jsx create mode 100644 src/pages/roles/create.jsx create mode 100644 src/pages/roles/role-selector.jsx create mode 100644 src/pages/roles/role-view-editor.jsx create mode 100644 src/tools/fileUtil.js diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/src/components/ModalEditor.jsx b/src/components/ModalEditor.jsx new file mode 100644 index 0000000..4c6b6a1 --- /dev/null +++ b/src/components/ModalEditor.jsx @@ -0,0 +1,25 @@ +import { Modal, Text } from '@mantine/core'; + +const ModalEditor = ({ title, opened, handlerClose }) => { + + return ( + + + + + + + {title} + + + + + + {content} + + + + ); +}; + +export default ModalEditor; diff --git a/src/components/media-player.jsx b/src/components/media-player.jsx index 7300773..1e273cc 100644 --- a/src/components/media-player.jsx +++ b/src/components/media-player.jsx @@ -1,8 +1,8 @@ import { Image } from '@mantine/core'; +import { isImage } from '../tools/fileUtil'; const MediaPlayer = ({ file, fileId, shouldContain }) => { - const isImage = () => file.type.split('/')[0] === 'image'; - return isImage() ? ( + return isImage(file.type) ? ( {file?.name { const handleSubmit = () => { setIsLoading(true); const formData = new FormData(); - const CHUNK_SIZE = 1 * 1024 * 1024; // 1MB chunks files.forEach((file) => formData.append(`${file.name}`, file, file.name)); diff --git a/src/pages/playlist/content.jsx b/src/pages/playlist/content.jsx index d7934cd..6c1145b 100644 --- a/src/pages/playlist/content.jsx +++ b/src/pages/playlist/content.jsx @@ -12,6 +12,9 @@ import { Perm, checkPerm } from '../../tools/grant-access'; import { useAuth } from '../../tools/auth-provider'; import { parseTime } from '../../tools/timeUtil'; import MediaPlayer from '../../components/media-player'; +import { isVideo } from '../../tools/fileUtil'; + +const DEFAULT_FILE_TIME = 2; const Content = ({ form, playlistId, playlist }) => { const [fileSelector, setFileSelector] = useState(false); @@ -36,7 +39,7 @@ const Content = ({ form, playlistId, playlist }) => { max_position++; file.position = max_position; - file.seconds = 10; + file.seconds = DEFAULT_FILE_TIME; const index = form.values.files.length; form.insertListItem('files', file); API.playlists @@ -154,10 +157,18 @@ const Content = ({ form, playlistId, playlist }) => { handleChangeSeconds(secs, index), + })} hideControls - description="Seconds to display" - value={form.getInputProps(`files.${index}.seconds`).value} - onChange={(secs) => handleChangeSeconds(secs, index)} + label="Seconds to display" error={ form.getInputProps(`files.${index}.seconds`).errors && 'This field is required' } diff --git a/src/pages/roles/create.jsx b/src/pages/roles/create.jsx new file mode 100644 index 0000000..dfdff03 --- /dev/null +++ b/src/pages/roles/create.jsx @@ -0,0 +1,38 @@ +import { Modal, Text } from '@mantine/core'; +import API from '../../services/api'; +import RoleViewEditor from './role-view-editor'; + +const ModalCreateRole = ({ opened, handler, addRole, item }) => { + const validate = (role) => { + if (role) { + addRole(role); + } + handler(); + }; + + return ( + + + + + + + Create Role + + + + + + validate(role)} + /> + + + + ); +}; + +export default ModalCreateRole; diff --git a/src/pages/roles/role-selector.jsx b/src/pages/roles/role-selector.jsx new file mode 100644 index 0000000..564e0ff --- /dev/null +++ b/src/pages/roles/role-selector.jsx @@ -0,0 +1,82 @@ +import { MultiSelect } from '@mantine/core'; +import { useEffect, useState } from 'react'; +import setNotification from '../errors/error-notification'; +import API from '../../services/api'; +import { Perm, checkPerm } from '../../tools/grant-access'; +import { useAuth } from '../../tools/auth-provider'; +import ModalCreateRole from './create'; + +const RoleSelector = ({ defaultRoles, label, value, setValue }) => { + const [data, setData] = useState([]); + const [search, setSearch] = useState(); + const [showCreateRole, setShowCreateRole] = useState(false); + const toggleCreateRole = () => setShowCreateRole(!showCreateRole); + const [query, setQuery] = useState(''); + + const { user } = useAuth(); + const canCreateRole = checkPerm(Perm.CREATE_ROLE, user); + + const addRoles = (roles) => { + if (!roles) return; + for (let i = 0; i < roles.length; i++) { + const role = roles[i]; + if (!data.find((r) => r.id === role.id)) { + role.label = role.name; + role.value = role.id.toString(); + setData((prev) => [...prev, role]); + } + } + }; + + useEffect(() => { + API.roles + .search(search) + .then((res) => { + if (res.status === 200) { + addRoles(res.data); + } else { + setNotification(true, res); + } + }) + .catch((err) => { + setNotification(true, err); + }); + // eslint-disable-next-line + }, [search]); + + useEffect(() => { + addRoles(defaultRoles); + // eslint-disable-next-line + }, [defaultRoles]); + + return ( + <> + `+ Create ${query}`} + onCreate={(query) => { + setQuery(query); + setShowCreateRole(true); + }} + /> + {canCreateRole && ( + addRoles([role])} + handler={toggleCreateRole} + /> + )} + + ); +}; + +export default RoleSelector; diff --git a/src/pages/roles/role-view-editor.jsx b/src/pages/roles/role-view-editor.jsx new file mode 100644 index 0000000..1928d38 --- /dev/null +++ b/src/pages/roles/role-view-editor.jsx @@ -0,0 +1,64 @@ +import { Button, TextInput, Group, Stack } from '@mantine/core'; +import { useForm, isNotEmpty } from '@mantine/form'; +import { useEffect, useState } from 'react'; +import setNotification from '../errors/error-notification'; + +const RoleViewEditor = ({ item, handler, buttonText, APICall }) => { + const handleClose = (role) => { + form.reset(); + handler(role); + }; + + const [isLoading, setIsLoading] = useState(false); + + const form = useForm({ + initialValues: { + name: item?.name ?? '', + }, + validate: { + name: isNotEmpty('Name is required'), + }, + }); + + useEffect(() => { + form.setFieldValue('name', item?.name); + return () => {}; + }, [item]); + + const handleSubmit = async (event) => { + event.preventDefault(); + if (form.validate().hasErrors) return; + try { + setIsLoading(true); + if (item?.id) { + const res = await APICall(item?.id, { name: form.values.name }); + handleClose(res.data); + } else { + const res = await APICall({ name: form.values.name }); + handleClose(res.data); + } + setIsLoading(false); + } catch (err) { + setIsLoading(false); + setNotification(true, err); + } + }; + + return ( +
+ + todo parent id + users + + + + + + ); +}; + +export default RoleViewEditor; diff --git a/src/tools/fileUtil.js b/src/tools/fileUtil.js new file mode 100644 index 0000000..e26e92c --- /dev/null +++ b/src/tools/fileUtil.js @@ -0,0 +1,10 @@ +export const isImage = (type) => { + if (!type) return false; + return type.split('/')[0] === 'image'; +}; + +export const isVideo = (type) => { + if (!type) return false; + return type.split('/')[0] === 'video'; +}; +