2020-04-09 11:32:06 +03:00
|
|
|
import React, { Fragment } from "react";
|
2020-03-28 23:25:34 +03:00
|
|
|
import PersonPinIcon from "@material-ui/icons/PersonPin";
|
|
|
|
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
|
2020-02-07 19:44:48 +03:00
|
|
|
import {
|
2020-03-30 11:22:27 +03:00
|
|
|
ArrayInput,
|
2020-03-28 23:25:34 +03:00
|
|
|
ArrayField,
|
2020-02-07 19:44:48 +03:00
|
|
|
Datagrid,
|
2020-03-28 23:25:34 +03:00
|
|
|
DateField,
|
2020-02-07 19:44:48 +03:00
|
|
|
Create,
|
|
|
|
Edit,
|
|
|
|
List,
|
|
|
|
Filter,
|
2020-04-09 11:32:06 +03:00
|
|
|
Toolbar,
|
2020-02-07 19:44:48 +03:00
|
|
|
SimpleForm,
|
2020-03-30 11:22:27 +03:00
|
|
|
SimpleFormIterator,
|
2020-03-28 23:25:34 +03:00
|
|
|
TabbedForm,
|
|
|
|
FormTab,
|
2020-02-07 19:44:48 +03:00
|
|
|
BooleanField,
|
|
|
|
BooleanInput,
|
|
|
|
ImageField,
|
|
|
|
PasswordInput,
|
|
|
|
TextField,
|
|
|
|
TextInput,
|
|
|
|
ReferenceField,
|
2020-03-30 11:22:27 +03:00
|
|
|
SelectInput,
|
2020-04-09 11:32:06 +03:00
|
|
|
BulkDeleteButton,
|
|
|
|
DeleteButton,
|
|
|
|
SaveButton,
|
2020-02-07 19:44:48 +03:00
|
|
|
regex,
|
2020-04-09 11:32:06 +03:00
|
|
|
useTranslate,
|
2020-03-27 23:02:37 +03:00
|
|
|
Pagination,
|
2020-02-07 19:44:48 +03:00
|
|
|
} from "react-admin";
|
2020-05-06 10:03:33 +03:00
|
|
|
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
2020-02-07 19:44:48 +03:00
|
|
|
|
2020-03-27 23:02:37 +03:00
|
|
|
const UserPagination = props => (
|
|
|
|
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
|
|
|
);
|
|
|
|
|
2020-02-07 19:44:48 +03:00
|
|
|
const UserFilter = props => (
|
|
|
|
<Filter {...props}>
|
|
|
|
<BooleanInput source="guests" alwaysOn />
|
|
|
|
<BooleanInput
|
|
|
|
label="resources.users.fields.show_deactivated"
|
|
|
|
source="deactivated"
|
|
|
|
alwaysOn
|
|
|
|
/>
|
|
|
|
</Filter>
|
|
|
|
);
|
|
|
|
|
2020-04-09 11:32:06 +03:00
|
|
|
const UserBulkActionButtons = props => {
|
|
|
|
const translate = useTranslate();
|
|
|
|
return (
|
|
|
|
<Fragment>
|
2020-05-06 10:03:33 +03:00
|
|
|
<ServerNoticeBulkButton {...props} />
|
2020-04-09 11:32:06 +03:00
|
|
|
<BulkDeleteButton
|
|
|
|
{...props}
|
|
|
|
label="resources.users.action.erase"
|
|
|
|
title={translate("resources.users.helper.erase")}
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2020-02-07 19:44:48 +03:00
|
|
|
export const UserList = props => (
|
|
|
|
<List
|
|
|
|
{...props}
|
|
|
|
filters={<UserFilter />}
|
|
|
|
filterDefaultValues={{ guests: true, deactivated: false }}
|
2020-04-09 11:32:06 +03:00
|
|
|
bulkActionButtons={<UserBulkActionButtons />}
|
2020-03-27 23:02:37 +03:00
|
|
|
pagination={<UserPagination />}
|
2020-02-07 19:44:48 +03:00
|
|
|
>
|
|
|
|
<Datagrid rowClick="edit">
|
|
|
|
<ReferenceField
|
|
|
|
source="Avatar"
|
|
|
|
reference="users"
|
|
|
|
link={false}
|
|
|
|
sortable={false}
|
|
|
|
>
|
|
|
|
<ImageField source="avatar_url" title="displayname" />
|
|
|
|
</ReferenceField>
|
|
|
|
<TextField source="id" />
|
|
|
|
{/* Hack since the users endpoint does not give displaynames in the list*/}
|
|
|
|
<ReferenceField
|
|
|
|
source="name"
|
|
|
|
reference="users"
|
|
|
|
link={false}
|
|
|
|
sortable={false}
|
|
|
|
>
|
|
|
|
<TextField source="displayname" />
|
|
|
|
</ReferenceField>
|
|
|
|
<BooleanField source="is_guest" sortable={false} />
|
|
|
|
<BooleanField source="admin" sortable={false} />
|
|
|
|
<BooleanField source="deactivated" sortable={false} />
|
|
|
|
</Datagrid>
|
|
|
|
</List>
|
|
|
|
);
|
|
|
|
|
|
|
|
// https://matrix.org/docs/spec/appendices#user-identifiers
|
|
|
|
const validateUser = regex(
|
|
|
|
/^@[a-z0-9._=\-/]+:.*/,
|
|
|
|
"synapseadmin.users.invalid_user_id"
|
|
|
|
);
|
|
|
|
|
2020-04-09 11:32:06 +03:00
|
|
|
const UserEditToolbar = props => {
|
|
|
|
const translate = useTranslate();
|
|
|
|
return (
|
|
|
|
<Toolbar {...props}>
|
|
|
|
<SaveButton submitOnEnter={true} />
|
|
|
|
<DeleteButton
|
|
|
|
label="resources.users.action.erase"
|
|
|
|
title={translate("resources.users.helper.erase")}
|
|
|
|
/>
|
2020-04-23 11:00:46 +03:00
|
|
|
<ServerNoticeButton />
|
2020-04-09 11:32:06 +03:00
|
|
|
</Toolbar>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2020-02-07 19:44:48 +03:00
|
|
|
export const UserCreate = props => (
|
|
|
|
<Create {...props}>
|
|
|
|
<SimpleForm>
|
|
|
|
<TextInput source="id" autoComplete="off" validate={validateUser} />
|
|
|
|
<TextInput source="displayname" />
|
|
|
|
<PasswordInput source="password" autoComplete="new-password" />
|
|
|
|
<BooleanInput source="admin" />
|
2020-03-30 11:22:27 +03:00
|
|
|
<ArrayInput source="threepids">
|
|
|
|
<SimpleFormIterator>
|
|
|
|
<SelectInput
|
|
|
|
source="medium"
|
|
|
|
choices={[
|
|
|
|
{ id: "email", name: "resources.users.email" },
|
|
|
|
{ id: "msisdn", name: "resources.users.msisdn" },
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
<TextInput source="address" />
|
|
|
|
</SimpleFormIterator>
|
|
|
|
</ArrayInput>
|
2020-02-07 19:44:48 +03:00
|
|
|
</SimpleForm>
|
|
|
|
</Create>
|
|
|
|
);
|
|
|
|
|
2020-04-21 19:39:51 +03:00
|
|
|
const UserTitle = ({ record }) => {
|
|
|
|
const translate = useTranslate();
|
|
|
|
return (
|
|
|
|
<span>
|
|
|
|
{translate("resources.users.name")}{" "}
|
|
|
|
{record ? `"${record.displayname}"` : ""}
|
|
|
|
</span>
|
|
|
|
);
|
|
|
|
};
|
2020-02-07 19:44:48 +03:00
|
|
|
export const UserEdit = props => (
|
2020-04-21 19:39:51 +03:00
|
|
|
<Edit {...props} title={<UserTitle />}>
|
2020-04-09 11:32:06 +03:00
|
|
|
<TabbedForm toolbar={<UserEditToolbar />}>
|
2020-03-28 23:25:34 +03:00
|
|
|
<FormTab label="resources.users.name" icon={<PersonPinIcon />}>
|
|
|
|
<TextInput source="id" disabled />
|
|
|
|
<TextInput source="displayname" />
|
|
|
|
<PasswordInput source="password" autoComplete="new-password" />
|
|
|
|
<BooleanInput source="admin" />
|
2020-04-06 12:13:20 +03:00
|
|
|
<BooleanInput
|
|
|
|
source="deactivated"
|
|
|
|
helperText="resources.users.helper.deactivate"
|
|
|
|
/>
|
2020-03-28 23:25:34 +03:00
|
|
|
<ArrayInput source="threepids">
|
|
|
|
<SimpleFormIterator>
|
|
|
|
<SelectInput
|
|
|
|
source="medium"
|
|
|
|
choices={[
|
|
|
|
{ id: "email", name: "resources.users.email" },
|
|
|
|
{ id: "msisdn", name: "resources.users.msisdn" },
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
<TextInput source="address" />
|
|
|
|
</SimpleFormIterator>
|
|
|
|
</ArrayInput>
|
|
|
|
</FormTab>
|
|
|
|
<FormTab
|
|
|
|
label="resources.connections.name"
|
|
|
|
icon={<SettingsInputComponentIcon />}
|
|
|
|
>
|
|
|
|
<ReferenceField reference="connections" source="id" addLabel={false}>
|
|
|
|
<ArrayField
|
|
|
|
source="devices[].sessions[0].connections"
|
|
|
|
label="resources.connections.name"
|
|
|
|
>
|
|
|
|
<Datagrid style={{ width: "100%" }}>
|
|
|
|
<TextField source="ip" sortable={false} />
|
|
|
|
<DateField
|
|
|
|
source="last_seen"
|
|
|
|
showTime
|
|
|
|
options={{
|
|
|
|
year: "numeric",
|
|
|
|
month: "2-digit",
|
|
|
|
day: "2-digit",
|
|
|
|
hour: "2-digit",
|
|
|
|
minute: "2-digit",
|
|
|
|
second: "2-digit",
|
|
|
|
}}
|
|
|
|
sortable={false}
|
|
|
|
/>
|
|
|
|
<TextField
|
|
|
|
source="user_agent"
|
|
|
|
sortable={false}
|
|
|
|
style={{ width: "100%" }}
|
|
|
|
/>
|
|
|
|
</Datagrid>
|
|
|
|
</ArrayField>
|
|
|
|
</ReferenceField>
|
|
|
|
</FormTab>
|
|
|
|
</TabbedForm>
|
2020-02-07 19:44:48 +03:00
|
|
|
</Edit>
|
|
|
|
);
|