mirror of
https://github.com/UA-Fediland/synapse-admin.git
synced 2024-11-25 07:45:23 +00:00
Get avatar_url and displayname from v2/users API
API was added by synapse v1.13.0. Change-Id: I927b81882fa20e5b3de3d9fc216e2136f7036bba
This commit is contained in:
parent
8282a3caf8
commit
ab04db5baf
4 changed files with 149 additions and 122 deletions
|
@ -1,4 +1,5 @@
|
||||||
import React, { Fragment } from "react";
|
import React, { Fragment } from "react";
|
||||||
|
import Avatar from "@material-ui/core/Avatar";
|
||||||
import PersonPinIcon from "@material-ui/icons/PersonPin";
|
import PersonPinIcon from "@material-ui/icons/PersonPin";
|
||||||
import ContactMailIcon from "@material-ui/icons/ContactMail";
|
import ContactMailIcon from "@material-ui/icons/ContactMail";
|
||||||
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
|
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
|
||||||
|
@ -18,7 +19,6 @@ import {
|
||||||
FormTab,
|
FormTab,
|
||||||
BooleanField,
|
BooleanField,
|
||||||
BooleanInput,
|
BooleanInput,
|
||||||
ImageField,
|
|
||||||
PasswordInput,
|
PasswordInput,
|
||||||
TextField,
|
TextField,
|
||||||
TextInput,
|
TextInput,
|
||||||
|
@ -32,6 +32,19 @@ import {
|
||||||
Pagination,
|
Pagination,
|
||||||
} from "react-admin";
|
} from "react-admin";
|
||||||
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
||||||
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
small: {
|
||||||
|
height: "40px",
|
||||||
|
width: "40px",
|
||||||
|
},
|
||||||
|
large: {
|
||||||
|
height: "120px",
|
||||||
|
width: "120px",
|
||||||
|
float: "right",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const UserPagination = props => (
|
const UserPagination = props => (
|
||||||
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
||||||
|
@ -62,7 +75,13 @@ const UserBulkActionButtons = props => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserList = props => (
|
const AvatarField = ({ source, className, record = {} }) => (
|
||||||
|
<Avatar src={record[source]} className={className} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const UserList = props => {
|
||||||
|
const classes = useStyles();
|
||||||
|
return (
|
||||||
<List
|
<List
|
||||||
{...props}
|
{...props}
|
||||||
filters={<UserFilter />}
|
filters={<UserFilter />}
|
||||||
|
@ -71,30 +90,20 @@ export const UserList = props => (
|
||||||
pagination={<UserPagination />}
|
pagination={<UserPagination />}
|
||||||
>
|
>
|
||||||
<Datagrid rowClick="edit">
|
<Datagrid rowClick="edit">
|
||||||
<ReferenceField
|
<AvatarField
|
||||||
source="Avatar"
|
source="avatar_src"
|
||||||
reference="users"
|
|
||||||
link={false}
|
|
||||||
sortable={false}
|
sortable={false}
|
||||||
>
|
className={classes.small}
|
||||||
<ImageField source="avatar_url" title="displayname" />
|
/>
|
||||||
</ReferenceField>
|
|
||||||
<TextField source="id" sortable={false} />
|
<TextField source="id" sortable={false} />
|
||||||
{/* Hack since the users endpoint does not give displaynames in the list*/}
|
<TextField source="displayname" sortable={false} />
|
||||||
<ReferenceField
|
|
||||||
source="name"
|
|
||||||
reference="users"
|
|
||||||
link={false}
|
|
||||||
sortable={false}
|
|
||||||
>
|
|
||||||
<TextField source="displayname" />
|
|
||||||
</ReferenceField>
|
|
||||||
<BooleanField source="is_guest" sortable={false} />
|
<BooleanField source="is_guest" sortable={false} />
|
||||||
<BooleanField source="admin" sortable={false} />
|
<BooleanField source="admin" sortable={false} />
|
||||||
<BooleanField source="deactivated" sortable={false} />
|
<BooleanField source="deactivated" sortable={false} />
|
||||||
</Datagrid>
|
</Datagrid>
|
||||||
</List>
|
</List>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// https://matrix.org/docs/spec/appendices#user-identifiers
|
// https://matrix.org/docs/spec/appendices#user-identifiers
|
||||||
const validateUser = regex(
|
const validateUser = regex(
|
||||||
|
@ -148,10 +157,17 @@ const UserTitle = ({ record }) => {
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export const UserEdit = props => (
|
export const UserEdit = props => {
|
||||||
|
const classes = useStyles();
|
||||||
|
return (
|
||||||
<Edit {...props} title={<UserTitle />}>
|
<Edit {...props} title={<UserTitle />}>
|
||||||
<TabbedForm toolbar={<UserEditToolbar />}>
|
<TabbedForm toolbar={<UserEditToolbar />}>
|
||||||
<FormTab label="resources.users.name" icon={<PersonPinIcon />}>
|
<FormTab label="resources.users.name" icon={<PersonPinIcon />}>
|
||||||
|
<AvatarField
|
||||||
|
source="avatar_src"
|
||||||
|
sortable={false}
|
||||||
|
className={classes.large}
|
||||||
|
/>
|
||||||
<TextInput source="id" disabled />
|
<TextInput source="id" disabled />
|
||||||
<TextInput source="displayname" />
|
<TextInput source="displayname" />
|
||||||
<PasswordInput source="password" autoComplete="new-password" />
|
<PasswordInput source="password" autoComplete="new-password" />
|
||||||
|
@ -234,3 +250,4 @@ export const UserEdit = props => (
|
||||||
</TabbedForm>
|
</TabbedForm>
|
||||||
</Edit>
|
</Edit>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -36,6 +36,7 @@ export default {
|
||||||
displayname: "Anzeigename",
|
displayname: "Anzeigename",
|
||||||
password: "Passwort",
|
password: "Passwort",
|
||||||
avatar_url: "Avatar URL",
|
avatar_url: "Avatar URL",
|
||||||
|
avatar_src: "Avatar",
|
||||||
medium: "Medium",
|
medium: "Medium",
|
||||||
threepids: "3PIDs",
|
threepids: "3PIDs",
|
||||||
address: "Adresse",
|
address: "Adresse",
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default {
|
||||||
displayname: "Displayname",
|
displayname: "Displayname",
|
||||||
password: "Password",
|
password: "Password",
|
||||||
avatar_url: "Avatar URL",
|
avatar_url: "Avatar URL",
|
||||||
|
avatar_src: "Avatar",
|
||||||
medium: "Medium",
|
medium: "Medium",
|
||||||
threepids: "3PIDs",
|
threepids: "3PIDs",
|
||||||
address: "Address",
|
address: "Address",
|
||||||
|
|
|
@ -14,12 +14,24 @@ const jsonClient = (url, options = {}) => {
|
||||||
return fetchUtils.fetchJson(url, options);
|
return fetchUtils.fetchJson(url, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mxcUrlToHttp = mxcUrl => {
|
||||||
|
const homeserver = localStorage.getItem("base_url");
|
||||||
|
const re = /^mxc:\/\/([^/]+)\/(\w+)/;
|
||||||
|
var ret = re.exec(mxcUrl);
|
||||||
|
console.log("mxcClient " + ret);
|
||||||
|
if (ret == null) return null;
|
||||||
|
const serverName = ret[1];
|
||||||
|
const mediaId = ret[2];
|
||||||
|
return `${homeserver}/_matrix/media/r0/thumbnail/${serverName}/${mediaId}?width=24&height=24&method=scale`;
|
||||||
|
};
|
||||||
|
|
||||||
const resourceMap = {
|
const resourceMap = {
|
||||||
users: {
|
users: {
|
||||||
path: "/_synapse/admin/v2/users",
|
path: "/_synapse/admin/v2/users",
|
||||||
map: u => ({
|
map: u => ({
|
||||||
...u,
|
...u,
|
||||||
id: u.name,
|
id: u.name,
|
||||||
|
avatar_src: mxcUrlToHttp(u.avatar_url),
|
||||||
is_guest: !!u.is_guest,
|
is_guest: !!u.is_guest,
|
||||||
admin: !!u.admin,
|
admin: !!u.admin,
|
||||||
deactivated: !!u.deactivated,
|
deactivated: !!u.deactivated,
|
||||||
|
@ -27,11 +39,7 @@ const resourceMap = {
|
||||||
creation_ts_ms: u.creation_ts * 1000,
|
creation_ts_ms: u.creation_ts * 1000,
|
||||||
}),
|
}),
|
||||||
data: "users",
|
data: "users",
|
||||||
total: (json, from, perPage) => {
|
total: json => json.total,
|
||||||
return json.next_token
|
|
||||||
? parseInt(json.next_token, 10) + perPage
|
|
||||||
: from + json.users.length;
|
|
||||||
},
|
|
||||||
create: data => ({
|
create: data => ({
|
||||||
endpoint: `/_synapse/admin/v2/users/${data.id}`,
|
endpoint: `/_synapse/admin/v2/users/${data.id}`,
|
||||||
body: data,
|
body: data,
|
||||||
|
|
Loading…
Reference in a new issue