global changes and test

This commit is contained in:
grimhilt 2023-08-30 14:39:09 +02:00
parent 44cdba6b7d
commit b75f2e3b49
9 changed files with 239 additions and 7 deletions

3
public/robots.txt Normal file
View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@ -0,0 +1,25 @@
import { Modal, Text } from '@mantine/core';
const ModalEditor = ({ title, opened, handlerClose }) => {
return (
<Modal.Root opened={opened} onClose={handlerClose}>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>
<Modal.Title>
<Text fw={700} fz="lg">
{title}
</Text>
</Modal.Title>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body>
{content}
</Modal.Body>
</Modal.Content>
</Modal.Root>
);
};
export default ModalEditor;

View File

@ -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) ? (
<Image
src={'/api/files/' + (fileId ?? file.id)}
alt={file?.name ?? ''}

View File

@ -25,7 +25,6 @@ const ModalAddFile = ({ opened, handler, addFiles }) => {
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));

View File

@ -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 }) => {
<MediaPlayer file={form.getInputProps(`files.${index}`).value} />
<NumberInput
required
{...(isVideo(form.getInputProps(`files.${index}.type`).value)
? {
disabled: true,
value: 0,
description: 'Default to video duration',
}
: {
value: form.getInputProps(`files.${index}.seconds`).value,
onChange: (secs) => 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'
}

View File

@ -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 (
<Modal.Root opened={opened} onClose={handler}>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>
<Modal.Title>
<Text fw={700} fz="lg">
Create Role
</Text>
</Modal.Title>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body>
<RoleViewEditor
buttonText="Create"
item={item}
APICall={API.roles.create}
handler={(role) => validate(role)}
/>
</Modal.Body>
</Modal.Content>
</Modal.Root>
);
};
export default ModalCreateRole;

View File

@ -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 (
<>
<MultiSelect
label={label}
data={data}
searchable
searchValue={search}
onSearchChange={setSearch}
value={value}
onChange={setValue}
maxDropdownHeight={160}
creatable={canCreateRole}
getCreateLabel={(query) => `+ Create ${query}`}
onCreate={(query) => {
setQuery(query);
setShowCreateRole(true);
}}
/>
{canCreateRole && (
<ModalCreateRole
opened={showCreateRole}
item={{ name: query }}
addRole={(role) => addRoles([role])}
handler={toggleCreateRole}
/>
)}
</>
);
};
export default RoleSelector;

View File

@ -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 (
<form onSubmit={handleSubmit}>
<TextInput label="Name" placeholder="Name" withAsterisk {...form.getInputProps('name')} mb="sm" />
todo parent id
users
<Group position="right" mt="md">
<Button variant="light" color="red" onClick={() => handler()}>
Cancel
</Button>
<Button type="submit" variant="light" color="green" loading={isLoading}>
{buttonText}
</Button>
</Group>
</form>
);
};
export default RoleViewEditor;

10
src/tools/fileUtil.js Normal file
View File

@ -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';
};