mirror of
https://github.com/UA-Fediland/synapse-admin.git
synced 2024-11-26 00:03:17 +00:00
Add buttons to protect and unprotect users' media from quarantine (#150)
This commit is contained in:
parent
32e088ac5a
commit
e6f01f035b
5 changed files with 133 additions and 5 deletions
|
@ -2,6 +2,7 @@ import React, { Fragment, useState } from "react";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
import { Tooltip } from "@material-ui/core";
|
||||||
import {
|
import {
|
||||||
BooleanInput,
|
BooleanInput,
|
||||||
Button,
|
Button,
|
||||||
|
@ -10,16 +11,21 @@ import {
|
||||||
SaveButton,
|
SaveButton,
|
||||||
SimpleForm,
|
SimpleForm,
|
||||||
Toolbar,
|
Toolbar,
|
||||||
|
useCreate,
|
||||||
useDelete,
|
useDelete,
|
||||||
useNotify,
|
useNotify,
|
||||||
|
useRefresh,
|
||||||
useTranslate,
|
useTranslate,
|
||||||
} from "react-admin";
|
} from "react-admin";
|
||||||
import IconCancel from "@material-ui/icons/Cancel";
|
import ClearIcon from "@material-ui/icons/Clear";
|
||||||
|
import DeleteSweepIcon from "@material-ui/icons/DeleteSweep";
|
||||||
import Dialog from "@material-ui/core/Dialog";
|
import Dialog from "@material-ui/core/Dialog";
|
||||||
import DialogContent from "@material-ui/core/DialogContent";
|
import DialogContent from "@material-ui/core/DialogContent";
|
||||||
import DialogContentText from "@material-ui/core/DialogContentText";
|
import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||||
import DeleteSweepIcon from "@material-ui/icons/DeleteSweep";
|
import IconCancel from "@material-ui/icons/Cancel";
|
||||||
|
import LockIcon from "@material-ui/icons/Lock";
|
||||||
|
import LockOpenIcon from "@material-ui/icons/LockOpen";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
|
@ -143,3 +149,95 @@ export const DeleteMediaButton = props => {
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ProtectMediaButton = props => {
|
||||||
|
const { record } = props;
|
||||||
|
const translate = useTranslate();
|
||||||
|
const refresh = useRefresh();
|
||||||
|
const notify = useNotify();
|
||||||
|
const [create, { loading }] = useCreate("protect_media");
|
||||||
|
const [deleteOne] = useDelete("protect_media");
|
||||||
|
|
||||||
|
if (!record) return null;
|
||||||
|
|
||||||
|
const handleProtect = () => {
|
||||||
|
create(
|
||||||
|
{ payload: { data: record } },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
notify("resources.protect_media.action.send_success");
|
||||||
|
refresh();
|
||||||
|
},
|
||||||
|
onFailure: () =>
|
||||||
|
notify("resources.protect_media.action.send_failure", "error"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUnprotect = () => {
|
||||||
|
deleteOne(
|
||||||
|
{ payload: { ...record } },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
notify("resources.protect_media.action.send_success");
|
||||||
|
refresh();
|
||||||
|
},
|
||||||
|
onFailure: () =>
|
||||||
|
notify("resources.protect_media.action.send_failure", "error"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
/*
|
||||||
|
Wrapping Tooltip with <div>
|
||||||
|
https://github.com/marmelab/react-admin/issues/4349#issuecomment-578594735
|
||||||
|
*/
|
||||||
|
<Fragment>
|
||||||
|
{record.quarantined_by && (
|
||||||
|
<Tooltip
|
||||||
|
title={translate("resources.protect_media.action.none", {
|
||||||
|
_: "resources.protect_media.action.none",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{/*
|
||||||
|
Button instead BooleanField for
|
||||||
|
consistent appearance and position in the column
|
||||||
|
*/}
|
||||||
|
<Button disabled={true}>
|
||||||
|
<ClearIcon />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{record.safe_from_quarantine && (
|
||||||
|
<Tooltip
|
||||||
|
title={translate("resources.protect_media.action.delete", {
|
||||||
|
_: "resources.protect_media.action.delete",
|
||||||
|
})}
|
||||||
|
arrow
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<Button onClick={handleUnprotect} disabled={loading}>
|
||||||
|
<LockIcon />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{!record.safe_from_quarantine && !record.quarantined_by && (
|
||||||
|
<Tooltip
|
||||||
|
title={translate("resources.protect_media.action.create", {
|
||||||
|
_: "resources.protect_media.action.create",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<Button onClick={handleProtect} disabled={loading}>
|
||||||
|
<LockOpenIcon />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { cloneElement, Fragment } from "react";
|
import React, { cloneElement, Fragment } from "react";
|
||||||
import Avatar from "@material-ui/core/Avatar";
|
import Avatar from "@material-ui/core/Avatar";
|
||||||
import PersonPinIcon from "@material-ui/icons/PersonPin";
|
|
||||||
import AssignmentIndIcon from "@material-ui/icons/AssignmentInd";
|
import AssignmentIndIcon from "@material-ui/icons/AssignmentInd";
|
||||||
import ContactMailIcon from "@material-ui/icons/ContactMail";
|
import ContactMailIcon from "@material-ui/icons/ContactMail";
|
||||||
import DevicesIcon from "@material-ui/icons/Devices";
|
import DevicesIcon from "@material-ui/icons/Devices";
|
||||||
import GetAppIcon from "@material-ui/icons/GetApp";
|
import GetAppIcon from "@material-ui/icons/GetApp";
|
||||||
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
|
|
||||||
import NotificationsIcon from "@material-ui/icons/Notifications";
|
import NotificationsIcon from "@material-ui/icons/Notifications";
|
||||||
import PermMediaIcon from "@material-ui/icons/PermMedia";
|
import PermMediaIcon from "@material-ui/icons/PermMedia";
|
||||||
|
import PersonPinIcon from "@material-ui/icons/PersonPin";
|
||||||
|
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
|
||||||
import ViewListIcon from "@material-ui/icons/ViewList";
|
import ViewListIcon from "@material-ui/icons/ViewList";
|
||||||
import {
|
import {
|
||||||
ArrayInput,
|
ArrayInput,
|
||||||
|
@ -48,6 +48,7 @@ import {
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
||||||
import { DeviceRemoveButton } from "./devices";
|
import { DeviceRemoveButton } from "./devices";
|
||||||
|
import { ProtectMediaButton } from "./media";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
|
||||||
const redirect = () => {
|
const redirect = () => {
|
||||||
|
@ -465,7 +466,7 @@ export const UserEdit = props => {
|
||||||
<TextField source="media_type" />
|
<TextField source="media_type" />
|
||||||
<TextField source="upload_name" />
|
<TextField source="upload_name" />
|
||||||
<TextField source="quarantined_by" />
|
<TextField source="quarantined_by" />
|
||||||
<BooleanField source="safe_from_quarantine" />
|
<ProtectMediaButton label="resources.users_media.fields.safe_from_quarantine" />
|
||||||
<DeleteButton mutationMode="pessimistic" redirect={false} />
|
<DeleteButton mutationMode="pessimistic" redirect={false} />
|
||||||
</Datagrid>
|
</Datagrid>
|
||||||
</ReferenceManyField>
|
</ReferenceManyField>
|
||||||
|
|
|
@ -263,6 +263,15 @@ const de = {
|
||||||
send: "Diese API löscht die lokalen Medien von der Festplatte des eigenen Servers. Dies umfasst alle lokalen Miniaturbilder und Kopien von Medien. Diese API wirkt sich nicht auf Medien aus, die sich in externen Medien-Repositories befinden.",
|
send: "Diese API löscht die lokalen Medien von der Festplatte des eigenen Servers. Dies umfasst alle lokalen Miniaturbilder und Kopien von Medien. Diese API wirkt sich nicht auf Medien aus, die sich in externen Medien-Repositories befinden.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
protect_media: {
|
||||||
|
action: {
|
||||||
|
create: "Ungeschützt, Schutz erstellen",
|
||||||
|
delete: "Geschützt, Schutz aufheben",
|
||||||
|
none: "In Quarantäne",
|
||||||
|
send_success: "Erfolgreich den Schutz-Status geändert.",
|
||||||
|
send_failure: "Beim Versenden ist ein Fehler aufgetreten.",
|
||||||
|
},
|
||||||
|
},
|
||||||
pushers: {
|
pushers: {
|
||||||
name: "Pusher |||| Pushers",
|
name: "Pusher |||| Pushers",
|
||||||
fields: {
|
fields: {
|
||||||
|
|
|
@ -259,6 +259,15 @@ const en = {
|
||||||
send: "This API deletes the local media from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to external media repositories.",
|
send: "This API deletes the local media from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to external media repositories.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
protect_media: {
|
||||||
|
action: {
|
||||||
|
create: "Unprotected, create protection",
|
||||||
|
delete: "Protected, remove protection",
|
||||||
|
none: "In quarantine",
|
||||||
|
send_success: "Successfully changed the protection status.",
|
||||||
|
send_failure: "An error has occurred.",
|
||||||
|
},
|
||||||
|
},
|
||||||
pushers: {
|
pushers: {
|
||||||
name: "Pusher |||| Pushers",
|
name: "Pusher |||| Pushers",
|
||||||
fields: {
|
fields: {
|
||||||
|
|
|
@ -182,6 +182,17 @@ const resourceMap = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
protect_media: {
|
||||||
|
map: pm => ({ id: pm.media_id }),
|
||||||
|
create: params => ({
|
||||||
|
endpoint: `/_synapse/admin/v1/media/protect/${params.media_id}`,
|
||||||
|
method: "POST",
|
||||||
|
}),
|
||||||
|
delete: params => ({
|
||||||
|
endpoint: `/_synapse/admin/v1/media/unprotect/${params.media_id}`,
|
||||||
|
method: "POST",
|
||||||
|
}),
|
||||||
|
},
|
||||||
servernotices: {
|
servernotices: {
|
||||||
map: n => ({ id: n.event_id }),
|
map: n => ({ id: n.event_id }),
|
||||||
create: data => ({
|
create: data => ({
|
||||||
|
|
Loading…
Reference in a new issue