import AssignmentIndIcon from "@mui/icons-material/AssignmentInd";
import ContactMailIcon from "@mui/icons-material/ContactMail";
import DevicesIcon from "@mui/icons-material/Devices";
import GetAppIcon from "@mui/icons-material/GetApp";
import UserIcon from "@mui/icons-material/Group";
import NotificationsIcon from "@mui/icons-material/Notifications";
import PermMediaIcon from "@mui/icons-material/PermMedia";
import PersonPinIcon from "@mui/icons-material/PersonPin";
import SettingsInputComponentIcon from "@mui/icons-material/SettingsInputComponent";
import ScienceIcon from "@mui/icons-material/Science";
import LockClockIcon from '@mui/icons-material/LockClock';
import ViewListIcon from "@mui/icons-material/ViewList";
import { useEffect, useState } from "react";
import { Alert, Typography } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import {
ArrayInput,
ArrayField,
Button,
Datagrid,
DatagridConfigurable,
DateField,
Create,
CreateProps,
Edit,
EditProps,
List,
ListProps,
SimpleForm,
SimpleFormIterator,
TabbedForm,
FormTab,
BooleanField,
BooleanInput,
PasswordInput,
TextField,
TextInput,
ReferenceField,
ReferenceManyField,
ResourceProps,
SearchInput,
SelectInput,
DeleteButton,
maxLength,
regex,
required,
useRecordContext,
useTranslate,
Pagination,
SaveButton,
CreateButton,
ExportButton,
TopToolbar,
Toolbar,
NumberField,
useListContext,
useNotify,
Identifier,
ToolbarClasses,
ImageInput,
ImageField,
FunctionField,
useDataProvider,
Confirm,
useCreate,
useRedirect,
} from "react-admin";
import { Link } from "react-router-dom";
import AvatarField from "../components/AvatarField";
import DeleteUserButton from "../components/DeleteUserButton";
import { isASManaged } from "../utils/mxid";
import { ServerNoticeButton, ServerNoticeBulkButton } from "../components/ServerNotices";
import { DATE_FORMAT } from "../utils/date";
import DeviceRemoveButton from "../components/DeviceRemoveButton";
import { MediaIDField, ProtectMediaButton, QuarantineMediaButton } from "../components/media";
import { generateRandomPassword } from "../utils/password";
import { useFormContext } from "react-hook-form";
import ExperimentalFeaturesList from "../components/ExperimentalFeatures";
import UserRateLimits from "../components/UserRateLimits";
import { User, UsernameAvailabilityResult } from "../synapse/dataProvider";
import { MakeAdminBtn } from "./rooms";
const choices_medium = [
{ id: "email", name: "resources.users.email" },
{ id: "msisdn", name: "resources.users.msisdn" },
];
const choices_type = [
{ id: "bot", name: "bot" },
{ id: "support", name: "support" },
];
const UserListActions = () => {
const { isLoading, total } = useListContext();
return (
);
};
const UserPagination = () => ;
const userFilters = [
,
,
,
,
];
const UserPreventSelfDelete: React.FC<{ children: React.ReactNode; ownUserIsSelected: boolean; asManagedUserIsSelected: boolean }> = props => {
const ownUserIsSelected = props.ownUserIsSelected;
const asManagedUserIsSelected = props.asManagedUserIsSelected;
const notify = useNotify();
const translate = useTranslate();
const handleDeleteClick = (ev: React.MouseEvent) => {
if (ownUserIsSelected) {
notify({translate("resources.users.helper.erase_admin_error")});
ev.stopPropagation();
} else if (asManagedUserIsSelected) {
notify({translate("resources.users.helper.modify_managed_user_error")});
ev.stopPropagation();
}
};
return {props.children}
;
};
const UserBulkActionButtons = () => {
const record = useListContext();
const [ownUserIsSelected, setOwnUserIsSelected] = useState(false);
const [asManagedUserIsSelected, setAsManagedUserIsSelected] = useState(false);
const selectedIds = record.selectedIds;
const ownUserId = localStorage.getItem("user_id");
useEffect(() => {
setOwnUserIsSelected(selectedIds.includes(ownUserId));
setAsManagedUserIsSelected(selectedIds.some(id => isASManaged(id)));
}, [selectedIds]);
return (
<>
>
);
};
export const UserList = (props: ListProps) => (
}
pagination={}
>
`/${resource}/${id}`}
bulkActionButtons={}
>
);
// https://matrix.org/docs/spec/appendices#user-identifiers
// here only local part of user_id
// maxLength = 255 - "@" - ":" - storage.getItem("home_server").length
// storage.getItem("home_server").length is not valid here
const validateUser = [required(), maxLength(253), regex(/^[a-z0-9._=\-/]+$/, "synapseadmin.users.invalid_user_id")];
const validateAddress = [required(), maxLength(255)];
const UserEditActions = () => {
const record = useRecordContext();
const translate = useTranslate();
const ownUserId = localStorage.getItem("user_id");
let ownUserIsSelected = false;
let asManagedUserIsSelected = false;
if (record && record.id) {
ownUserIsSelected = record.id === ownUserId;
asManagedUserIsSelected = isASManaged(record.id);
}
return (
{!record?.deactivated && }
{record && record.id && (
)}
);
};
export const UserCreate = (props: CreateProps) => {
const dataProvider = useDataProvider();
const translate = useTranslate();
const redirect = useRedirect();
const notify = useNotify();
const theme = useTheme();
const [open, setOpen] = useState(false);
const [userIsAvailable, setUserIsAvailable] = useState();
const [userAvailabilityEl, setUserAvailabilityEl] = useState();
const [formData, setFormData] = useState>({});
const [create] = useCreate();
const checkAvailability = async(event: React.FocusEvent) => {
const username = event.target.value;
const result: UsernameAvailabilityResult = await dataProvider.checkUsernameAvailability(username);
setUserIsAvailable(!!result?.available);
if (result?.available) {
setUserAvailabilityEl(✔️ {translate("resources.users.helper.username_available")});
} else {
setUserAvailabilityEl(⚠️ {result?.error || "unknown error"});
}
};
const postSave = (data: Record) => {
setFormData(data);
if (!userIsAvailable) {
setOpen(true);
return;
}
create("users", { data: data }, {
onSuccess: (resource: User) => {
notify("ra.notification.created", { messageArgs: { smart_count: 1 } });
redirect(() => { return `users/${resource.id}` });
}
});
};
const handleConfirm = () => {
setOpen(false);
updateUser();
};
const handleDialogClose = () => {
setOpen(false);
};
const updateUser = () => {
create("users", { data: formData }, {
onSuccess: (resource: User) => {
notify("ra.notification.updated", { messageArgs: { smart_count: 1 } });
redirect(() => { return `users/${resource.id}` });
}
});
}
return
};
const UserTitle = () => {
const record = useRecordContext();
const translate = useTranslate();
if (!record) {
return null;
}
let username = record ? (record.displayname ? `"${record.displayname}"` : `"${record.name}"`) : ""
return (
{translate("resources.users.name", {
smart_count: 1,
})}{" "}
{username}
);
};
const UserEditToolbar = () => {
const record = useRecordContext();
const ownUserId = localStorage.getItem("user_id");
let ownUserIsSelected = false;
let asManagedUserIsSelected = false;
if (record && record.id) {
ownUserIsSelected = record.id === ownUserId;
asManagedUserIsSelected = isASManaged(record.id);
}
return (
<>
>
);
};
const UserBooleanInput = props => {
const record = useRecordContext();
const ownUserId = localStorage.getItem("user_id");
let ownUserIsSelected = false;
let asManagedUserIsSelected = false;
if (record) {
ownUserIsSelected = record.id === ownUserId;
asManagedUserIsSelected = isASManaged(record.id);
}
return (
);
};
const UserPasswordInput = props => {
const record = useRecordContext();
let asManagedUserIsSelected = false;
// Get form context to update field value
const form = useFormContext();
if (record) {
asManagedUserIsSelected = isASManaged(record.id);
}
const generatePassword = () => {
const password = generateRandomPassword();
form.setValue("password", password, { shouldDirty: true });
};
return (
<>
>
);
};
export const UserEdit = (props: EditProps) => {
const translate = useTranslate();
return (
} actions={} mutationMode="pessimistic" queryOptions={{
meta: {
include: ["features"] // Tell your dataProvider to include features
}
}}>
}>
}>
} path="threepid">
} path="sso">
} path="devices">
} path="connections">
}
path="media"
>
}
perPage={50}
sort={{ field: "created_ts", order: "DESC" }}
>
decodeURIComponent(record.upload_name)} />
} path="rooms">
"/rooms/" + id + "/show"} bulkActionButtons={false}>
}
path="pushers"
>
} path="experimental">
} path="limits">
);
};
const resource: ResourceProps = {
name: "users",
icon: UserIcon,
list: UserList,
edit: UserEdit,
create: UserCreate,
};
export default resource;