Compare commits

7 Commits

Author SHA1 Message Date
Aine
7da5265575 update version in package.json 2025-05-20 22:05:51 +03:00
Aine
62fc97a417 Sync with upstream 2025-05-20 22:02:51 +03:00
dependabot[bot]
fa3f2437a3 Bump softprops/action-gh-release from 2.0.8 to 2.2.2 (#660)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.8 to 2.2.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](c062e08bd5...da05d55257)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:35:55 +02:00
dependabot[bot]
8dc5238fcb Bump JamesIves/github-pages-deploy-action from 4.6.8 to 4.7.3 (#659)
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.8 to 4.7.3.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.8...v4.7.3)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-version: 4.7.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:35:45 +02:00
dependabot[bot]
238350b940 Bump typescript-eslint from 8.32.0 to 8.32.1 (#661)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.32.0 to 8.32.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.32.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.32.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:35:26 +02:00
dependabot[bot]
99bf7b1889 Bump vite from 5.4.19 to 6.3.5 (#664)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.19 to 6.3.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.5
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:30:15 +02:00
dependabot[bot]
d72c91644d Bump ra-language-english from 5.2.3 to 5.8.2 (#667)
Bumps [ra-language-english](https://github.com/marmelab/react-admin) from 5.2.3 to 5.8.2.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.2.3...v5.8.2)

---
updated-dependencies:
- dependency-name: ra-language-english
  dependency-version: 5.8.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 17:09:09 +02:00
6 changed files with 98 additions and 145 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "synapse-admin", "name": "synapse-admin",
"version": "0.10.3", "version": "0.11.0",
"description": "Admin GUI for the Matrix.org server Synapse", "description": "Admin GUI for the Matrix.org server Synapse",
"type": "module", "type": "module",
"author": "etke.cc (originally by Awesome Technologies Innovationslabor GmbH)", "author": "etke.cc (originally by Awesome Technologies Innovationslabor GmbH)",

View File

@@ -1,7 +1,7 @@
import ActionCheck from "@mui/icons-material/CheckCircle"; import ActionCheck from "@mui/icons-material/CheckCircle";
import ActionDelete from "@mui/icons-material/Delete"; import ActionDelete from "@mui/icons-material/Delete";
import AlertError from "@mui/icons-material/ErrorOutline"; import AlertError from "@mui/icons-material/ErrorOutline";
import { Button, Tooltip, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
import { Fragment, useState } from "react"; import { Fragment, useState } from "react";
import { import {
SimpleForm, SimpleForm,
@@ -63,24 +63,22 @@ const DeleteRoomButton: React.FC<DeleteRoomButtonProps> = props => {
return ( return (
<Fragment> <Fragment>
<Tooltip title={translate("ra.action.delete")}> <Button
<Button onClick={handleDialogOpen}
onClick={handleDialogOpen} disabled={isLoading}
disabled={isLoading} className={"ra-delete-button"}
className={"ra-delete-button"} key="button"
key="button" size="small"
size="small" sx={{
sx={{ "&.MuiButton-sizeSmall": {
"&.MuiButton-sizeSmall": { lineHeight: 1.5,
lineHeight: 1.5, },
}, }}
}} color={"error"}
color={"error"} startIcon={<ActionDelete />}
startIcon={<ActionDelete />} >
> {translate("ra.action.delete")}
{translate("ra.action.delete")} </Button>
</Button>
</Tooltip>
<Dialog open={open} onClose={handleDialogClose}> <Dialog open={open} onClose={handleDialogClose}>
<DialogTitle>{translate(props.confirmTitle)}</DialogTitle> <DialogTitle>{translate(props.confirmTitle)}</DialogTitle>
<DialogContent> <DialogContent>

View File

@@ -1,7 +1,7 @@
import ActionCheck from "@mui/icons-material/CheckCircle"; import ActionCheck from "@mui/icons-material/CheckCircle";
import ActionDelete from "@mui/icons-material/Delete"; import ActionDelete from "@mui/icons-material/Delete";
import AlertError from "@mui/icons-material/ErrorOutline"; import AlertError from "@mui/icons-material/ErrorOutline";
import { Tooltip, Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
import { Fragment, useState } from "react"; import { Fragment, useState } from "react";
import { import {
SimpleForm, SimpleForm,
@@ -69,24 +69,22 @@ const DeleteUserButton: React.FC<DeleteUserButtonProps> = props => {
return ( return (
<Fragment> <Fragment>
<Tooltip title={translate("ra.action.delete")}> <Button
<Button onClick={handleDialogOpen}
onClick={handleDialogOpen} disabled={isLoading}
disabled={isLoading} className={"ra-delete-button"}
className={"ra-delete-button"} key="button"
key="button" size="small"
size="small" sx={{
sx={{ "&.MuiButton-sizeSmall": {
"&.MuiButton-sizeSmall": { lineHeight: 1.5,
lineHeight: 1.5, },
}, }}
}} color={"error"}
color={"error"} startIcon={<ActionDelete />}
startIcon={<ActionDelete />} >
> {translate("ra.action.delete")}
{translate("ra.action.delete")} </Button>
</Button>
</Tooltip>
<Dialog open={open} onClose={handleDialogClose}> <Dialog open={open} onClose={handleDialogClose}>
<DialogTitle>{translate(props.confirmTitle)}</DialogTitle> <DialogTitle>{translate(props.confirmTitle)}</DialogTitle>
<DialogContent> <DialogContent>

View File

@@ -1,11 +1,8 @@
import { Tooltip } from "@mui/material";
import { DeleteWithConfirmButton, DeleteWithConfirmButtonProps, useRecordContext } from "react-admin"; import { DeleteWithConfirmButton, DeleteWithConfirmButtonProps, useRecordContext } from "react-admin";
import { useTranslate } from "react-admin";
import { isASManaged } from "../utils/mxid"; import { isASManaged } from "../utils/mxid";
export const DeviceRemoveButton = (props: DeleteWithConfirmButtonProps) => { export const DeviceRemoveButton = (props: DeleteWithConfirmButtonProps) => {
const translate = useTranslate();
const record = useRecordContext(); const record = useRecordContext();
if (!record) return null; if (!record) return null;
@@ -15,23 +12,19 @@ export const DeviceRemoveButton = (props: DeleteWithConfirmButtonProps) => {
} }
return ( return (
<Tooltip <DeleteWithConfirmButton
title={isASManagedUser ? translate("resources.devices.action.erase.disabled") : translate("ra.action.delete")} {...props}
> label="ra.action.remove"
<DeleteWithConfirmButton confirmTitle="resources.devices.action.erase.title"
{...props} confirmContent="resources.devices.action.erase.content"
label="ra.action.remove" mutationMode="pessimistic"
confirmTitle="resources.devices.action.erase.title" redirect={false}
confirmContent="resources.devices.action.erase.content" disabled={isASManagedUser}
mutationMode="pessimistic" translateOptions={{
redirect={false} id: record.id,
disabled={isASManagedUser} name: record.display_name ? record.display_name : record.id,
translateOptions={{ }}
id: record.id, />
name: record.display_name ? record.display_name : record.id,
}}
/>
</Tooltip>
); );
}; };

View File

@@ -1,6 +1,8 @@
import { Tooltip, Stack, Switch, Typography } from "@mui/material"; import { Stack, Switch, Typography } from "@mui/material";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { useRecordContext, useTranslate, useNotify, useDataProvider } from "react-admin"; import { useRecordContext } from "react-admin";
import { useNotify } from "react-admin";
import { useDataProvider } from "react-admin";
import { ExperimentalFeaturesModel, SynapseDataProvider } from "../synapse/dataProvider"; import { ExperimentalFeaturesModel, SynapseDataProvider } from "../synapse/dataProvider";
@@ -13,7 +15,6 @@ const ExperimentalFeatureRow = (props: {
featureValue: boolean; featureValue: boolean;
updateFeature: (feature_name: string, feature_value: boolean) => void; updateFeature: (feature_name: string, feature_value: boolean) => void;
}) => { }) => {
const translate = useTranslate();
const featureKey = props.featureKey; const featureKey = props.featureKey;
const featureValue = props.featureValue; const featureValue = props.featureValue;
const featureDescription = experimentalFeaturesMap[featureKey] ?? ""; const featureDescription = experimentalFeaturesMap[featureKey] ?? "";
@@ -33,9 +34,7 @@ const ExperimentalFeatureRow = (props: {
padding: 2, padding: 2,
}} }}
> >
<Tooltip title={translate("resources.experimental_features.action.toggle")}> <Switch checked={checked} onChange={handleChange} />
<Switch checked={checked} onChange={handleChange} />
</Tooltip>
<Stack> <Stack>
<Typography <Typography
variant="subtitle1" variant="subtitle1"

View File

@@ -50,14 +50,10 @@ const DeleteMediaDialog = ({ open, onClose, onSubmit }) => {
const DeleteMediaToolbar = (props: ToolbarProps) => ( const DeleteMediaToolbar = (props: ToolbarProps) => (
<Toolbar {...props}> <Toolbar {...props}>
<Tooltip title={translate("delete_media.helper.send")}> <SaveButton label="delete_media.action.send" icon={<DeleteSweepIcon />} />
<SaveButton label="delete_media.action.send" icon={<DeleteSweepIcon />} /> <Button label="ra.action.cancel" onClick={onClose}>
</Tooltip> <IconCancel />
<Tooltip title={translate("ra.action.cancel")}> </Button>
<Button label="ra.action.cancel" onClick={onClose}>
<IconCancel />
</Button>
</Tooltip>
</Toolbar> </Toolbar>
); );
@@ -67,20 +63,9 @@ const DeleteMediaDialog = ({ open, onClose, onSubmit }) => {
<DialogContent> <DialogContent>
<DialogContentText>{translate("delete_media.helper.send")}</DialogContentText> <DialogContentText>{translate("delete_media.helper.send")}</DialogContentText>
<SimpleForm toolbar={<DeleteMediaToolbar />} onSubmit={onSubmit}> <SimpleForm toolbar={<DeleteMediaToolbar />} onSubmit={onSubmit}>
<Tooltip title={translate("delete_media.helper.before_ts")}> <DateTimeInput source="before_ts" label="delete_media.fields.before_ts" defaultValue={0} parse={dateParser} />
<DateTimeInput <NumberInput source="size_gt" label="delete_media.fields.size_gt" defaultValue={0} min={0} step={1024} />
source="before_ts" <BooleanInput source="keep_profiles" label="delete_media.fields.keep_profiles" defaultValue={true} />
label="delete_media.fields.before_ts"
defaultValue={0}
parse={dateParser}
/>
</Tooltip>
<Tooltip title={translate("delete_media.helper.size_gt")}>
<NumberInput source="size_gt" label="delete_media.fields.size_gt" defaultValue={0} min={0} step={1024} />
</Tooltip>
<Tooltip title={translate("delete_media.helper.keep_profiles")}>
<BooleanInput source="keep_profiles" label="delete_media.fields.keep_profiles" defaultValue={true} />
</Tooltip>
</SimpleForm> </SimpleForm>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
@@ -91,7 +76,6 @@ export const DeleteMediaButton = (props: ButtonProps) => {
const theme = useTheme(); const theme = useTheme();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const notify = useNotify(); const notify = useNotify();
const translate = useTranslate();
const dataProvider = useDataProvider<SynapseDataProvider>(); const dataProvider = useDataProvider<SynapseDataProvider>();
const { mutate: deleteMedia, isPending } = useMutation({ const { mutate: deleteMedia, isPending } = useMutation({
mutationFn: (values: DeleteMediaParams) => dataProvider.deleteMedia(values), mutationFn: (values: DeleteMediaParams) => dataProvider.deleteMedia(values),
@@ -111,26 +95,24 @@ export const DeleteMediaButton = (props: ButtonProps) => {
return ( return (
<> <>
<Tooltip title={translate("delete_media.helper.send")}> <Button
<Button {...props}
{...props} label="delete_media.action.send"
label="delete_media.action.send" onClick={openDialog}
onClick={openDialog} disabled={isPending}
disabled={isPending} sx={{
sx={{ color: theme.palette.error.main,
color: theme.palette.error.main, "&:hover": {
"&:hover": { backgroundColor: alpha(theme.palette.error.main, 0.12),
backgroundColor: alpha(theme.palette.error.main, 0.12), // Reset on mouse devices
// Reset on mouse devices "@media (hover: none)": {
"@media (hover: none)": { backgroundColor: "transparent",
backgroundColor: "transparent",
},
}, },
}} },
> }}
<DeleteSweepIcon /> >
</Button> <DeleteSweepIcon />
</Tooltip> </Button>
<DeleteMediaDialog open={open} onClose={closeDialog} onSubmit={deleteMedia} /> <DeleteMediaDialog open={open} onClose={closeDialog} onSubmit={deleteMedia} />
</> </>
); );
@@ -141,14 +123,10 @@ const PurgeRemoteMediaDialog = ({ open, onClose, onSubmit }) => {
const PurgeRemoteMediaToolbar = (props: ToolbarProps) => ( const PurgeRemoteMediaToolbar = (props: ToolbarProps) => (
<Toolbar {...props}> <Toolbar {...props}>
<Tooltip title={translate("purge_remote_media.helper.send")}> <SaveButton label="purge_remote_media.action.send" icon={<DeleteSweepIcon />} />
<SaveButton label="purge_remote_media.action.send" icon={<DeleteSweepIcon />} /> <Button label="ra.action.cancel" onClick={onClose}>
</Tooltip> <IconCancel />
<Tooltip title={translate("ra.action.cancel")}> </Button>
<Button label="ra.action.cancel" onClick={onClose}>
<IconCancel />
</Button>
</Tooltip>
</Toolbar> </Toolbar>
); );
@@ -174,7 +152,6 @@ export const PurgeRemoteMediaButton = (props: ButtonProps) => {
const theme = useTheme(); const theme = useTheme();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const notify = useNotify(); const notify = useNotify();
const translate = useTranslate();
const dataProvider = useDataProvider<SynapseDataProvider>(); const dataProvider = useDataProvider<SynapseDataProvider>();
const { mutate: purgeRemoteMedia, isPending } = useMutation({ const { mutate: purgeRemoteMedia, isPending } = useMutation({
mutationFn: (values: DeleteMediaParams) => dataProvider.purgeRemoteMedia(values), mutationFn: (values: DeleteMediaParams) => dataProvider.purgeRemoteMedia(values),
@@ -194,24 +171,22 @@ export const PurgeRemoteMediaButton = (props: ButtonProps) => {
return ( return (
<> <>
<Tooltip title={translate("purge_remote_media.helper.send")}> <Button
<Button {...props}
{...props} label="purge_remote_media.action.send"
label="purge_remote_media.action.send" onClick={openDialog}
onClick={openDialog} disabled={isPending}
disabled={isPending} sx={{
sx={{ "&:hover": {
"&:hover": { // Reset on mouse devices
// Reset on mouse devices "@media (hover: none)": {
"@media (hover: none)": { backgroundColor: "transparent",
backgroundColor: "transparent",
},
}, },
}} },
> }}
<DeleteSweepIcon /> >
</Button> <DeleteSweepIcon />
</Tooltip> </Button>
<PurgeRemoteMediaDialog open={open} onClose={closeDialog} onSubmit={purgeRemoteMedia} /> <PurgeRemoteMediaDialog open={open} onClose={closeDialog} onSubmit={purgeRemoteMedia} />
</> </>
); );
@@ -487,7 +462,6 @@ export const ViewMediaButton = ({ mxcURL, label, uploadName, mimetype }) => {
}; };
export const MediaIDField = ({ source }) => { export const MediaIDField = ({ source }) => {
const translate = useTranslate();
const record = useRecordContext(); const record = useRecordContext();
if (!record) { if (!record) {
return null; return null;
@@ -510,15 +484,10 @@ export const MediaIDField = ({ source }) => {
mxcURL = `mxc://${homeserver}/${mediaID}`; mxcURL = `mxc://${homeserver}/${mediaID}`;
} }
return ( return <ViewMediaButton mxcURL={mxcURL} label={mediaID} uploadName={uploadName} mimetype={record.media_type} />;
<Tooltip title={translate("resources.users_media.action.open")}>
<ViewMediaButton mxcURL={mxcURL} label={mediaID} uploadName={uploadName} mimetype={record.media_type} />
</Tooltip>
);
}; };
export const ReportMediaContent = ({ source }) => { export const ReportMediaContent = ({ source }) => {
const translate = useTranslate();
const record = useRecordContext(); const record = useRecordContext();
if (!record) { if (!record) {
return null; return null;
@@ -534,9 +503,5 @@ export const ReportMediaContent = ({ source }) => {
uploadName = decodeURLComponent(get(record, "event_json.content.body")?.toString()); uploadName = decodeURLComponent(get(record, "event_json.content.body")?.toString());
} }
return ( return <ViewMediaButton mxcURL={mxcURL} label={mxcURL} uploadName={uploadName} mimetype={record.media_type} />;
<Tooltip title={translate("resources.users_media.action.open")}>
<ViewMediaButton mxcURL={mxcURL} label={mxcURL} uploadName={uploadName} mimetype={record.media_type} />
</Tooltip>
);
}; };