Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c6b0cabcce | |||
| 1764554ce9 | |||
| 5dfeb0abe2 | |||
| ff59ee4c2e | |||
| 61938405e9 | |||
| 5f580fabce | |||
| 5f8b5db415 | |||
| f51c904aa1 | |||
| 5792d55a97 | |||
| 067dbd3b82 | |||
| d805dcd2c6 | |||
| 68e5a72618 |
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
This project is built using [react-admin](https://marmelab.com/react-admin/).
|
This project is built using [react-admin](https://marmelab.com/react-admin/).
|
||||||
|
|
||||||
It needs at least Synapse v1.13.0 for all functions to work as expected!
|
It needs at least Synapse v1.14.0 for all functions to work as expected!
|
||||||
|
|
||||||
## Step-By-Step install:
|
## Step-By-Step install:
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@ import polyglotI18nProvider from "ra-i18n-polyglot";
|
|||||||
import authProvider from "./synapse/authProvider";
|
import authProvider from "./synapse/authProvider";
|
||||||
import dataProvider from "./synapse/dataProvider";
|
import dataProvider from "./synapse/dataProvider";
|
||||||
import { UserList, UserCreate, UserEdit } from "./components/users";
|
import { UserList, UserCreate, UserEdit } from "./components/users";
|
||||||
import { RoomList } from "./components/rooms";
|
import { RoomList, RoomShow } from "./components/rooms";
|
||||||
import LoginPage from "./components/LoginPage";
|
import LoginPage from "./components/LoginPage";
|
||||||
import UserIcon from "@material-ui/icons/Group";
|
import UserIcon from "@material-ui/icons/Group";
|
||||||
import { ViewListIcon as RoomIcon } from "@material-ui/icons/ViewList";
|
import { ViewListIcon as RoomIcon } from "@material-ui/icons/ViewList";
|
||||||
@@ -35,7 +35,7 @@ const App = () => (
|
|||||||
edit={UserEdit}
|
edit={UserEdit}
|
||||||
icon={UserIcon}
|
icon={UserIcon}
|
||||||
/>
|
/>
|
||||||
<Resource name="rooms" list={RoomList} icon={RoomIcon} />
|
<Resource name="rooms" list={RoomList} show={RoomShow} icon={RoomIcon} />
|
||||||
<Resource name="connections" />
|
<Resource name="connections" />
|
||||||
<Resource name="servernotices" />
|
<Resource name="servernotices" />
|
||||||
</Admin>
|
</Admin>
|
||||||
|
|||||||
+169
-13
@@ -1,16 +1,25 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
import {
|
import {
|
||||||
Datagrid,
|
|
||||||
List,
|
|
||||||
TextField,
|
|
||||||
Pagination,
|
|
||||||
BooleanField,
|
BooleanField,
|
||||||
|
Datagrid,
|
||||||
|
Filter,
|
||||||
|
List,
|
||||||
|
Pagination,
|
||||||
|
SelectField,
|
||||||
|
Show,
|
||||||
|
Tab,
|
||||||
|
TabbedShowLayout,
|
||||||
|
TextField,
|
||||||
useTranslate,
|
useTranslate,
|
||||||
} from "react-admin";
|
} from "react-admin";
|
||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import { Tooltip, Typography } from "@material-ui/core";
|
import { Tooltip, Typography, Chip } from "@material-ui/core";
|
||||||
import HttpsIcon from "@material-ui/icons/Https";
|
import HttpsIcon from "@material-ui/icons/Https";
|
||||||
import NoEncryptionIcon from "@material-ui/icons/NoEncryption";
|
import NoEncryptionIcon from "@material-ui/icons/NoEncryption";
|
||||||
|
import PageviewIcon from "@material-ui/icons/Pageview";
|
||||||
|
import ViewListIcon from "@material-ui/icons/ViewList";
|
||||||
|
import VisibilityIcon from "@material-ui/icons/Visibility";
|
||||||
|
|
||||||
const RoomPagination = props => (
|
const RoomPagination = props => (
|
||||||
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
||||||
@@ -42,27 +51,174 @@ const EncryptionField = ({ source, record = {}, emptyText }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RoomList = props => (
|
const RoomTitle = ({ record }) => {
|
||||||
|
const translate = useTranslate();
|
||||||
|
var name = "";
|
||||||
|
if (record) {
|
||||||
|
name = record.name !== "" ? record.name : record.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{translate("resources.rooms.name", 1)} {name}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RoomShow = props => {
|
||||||
|
const translate = useTranslate();
|
||||||
|
return (
|
||||||
|
<Show {...props} title={<RoomTitle />}>
|
||||||
|
<TabbedShowLayout>
|
||||||
|
<Tab label="synapseadmin.rooms.tabs.basic" icon={<ViewListIcon />}>
|
||||||
|
<TextField source="room_id" />
|
||||||
|
<TextField source="name" />
|
||||||
|
<TextField source="canonical_alias" />
|
||||||
|
<TextField source="creator" />
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab
|
||||||
|
label="synapseadmin.rooms.tabs.detail"
|
||||||
|
icon={<PageviewIcon />}
|
||||||
|
path="detail"
|
||||||
|
>
|
||||||
|
<TextField source="joined_members" />
|
||||||
|
<TextField source="joined_local_members" />
|
||||||
|
<TextField source="state_events" />
|
||||||
|
<TextField source="version" />
|
||||||
|
<TextField
|
||||||
|
source="encryption"
|
||||||
|
emptyText={translate("resources.rooms.enums.unencrypted")}
|
||||||
|
/>
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab
|
||||||
|
label="synapseadmin.rooms.tabs.permission"
|
||||||
|
icon={<VisibilityIcon />}
|
||||||
|
path="permission"
|
||||||
|
>
|
||||||
|
<BooleanField source="federatable" />
|
||||||
|
<BooleanField source="public" />
|
||||||
|
<SelectField
|
||||||
|
source="join_rules"
|
||||||
|
choices={[
|
||||||
|
{ id: "public", name: "resources.rooms.enums.join_rules.public" },
|
||||||
|
{ id: "knock", name: "resources.rooms.enums.join_rules.knock" },
|
||||||
|
{ id: "invite", name: "resources.rooms.enums.join_rules.invite" },
|
||||||
|
{
|
||||||
|
id: "private",
|
||||||
|
name: "resources.rooms.enums.join_rules.private",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<SelectField
|
||||||
|
source="guest_access"
|
||||||
|
choices={[
|
||||||
|
{
|
||||||
|
id: "can_join",
|
||||||
|
name: "resources.rooms.enums.guest_access.can_join",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "forbidden",
|
||||||
|
name: "resources.rooms.enums.guest_access.forbidden",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<SelectField
|
||||||
|
source="history_visibility"
|
||||||
|
choices={[
|
||||||
|
{
|
||||||
|
id: "invited",
|
||||||
|
name: "resources.rooms.enums.history_visibility.invited",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "joined",
|
||||||
|
name: "resources.rooms.enums.history_visibility.joined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "shared",
|
||||||
|
name: "resources.rooms.enums.history_visibility.shared",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "world_readable",
|
||||||
|
name: "resources.rooms.enums.history_visibility.world_readable",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Tab>
|
||||||
|
</TabbedShowLayout>
|
||||||
|
</Show>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const RoomFilter = ({ ...props }) => {
|
||||||
|
const translate = useTranslate();
|
||||||
|
return (
|
||||||
|
<Filter {...props}>
|
||||||
|
<Chip
|
||||||
|
label={translate("resources.rooms.fields.joined_local_members")}
|
||||||
|
source="joined_local_members"
|
||||||
|
defaultValue={false}
|
||||||
|
style={{ marginBottom: 8 }}
|
||||||
|
/>
|
||||||
|
<Chip
|
||||||
|
label={translate("resources.rooms.fields.state_events")}
|
||||||
|
source="state_events"
|
||||||
|
defaultValue={false}
|
||||||
|
style={{ marginBottom: 8 }}
|
||||||
|
/>
|
||||||
|
<Chip
|
||||||
|
label={translate("resources.rooms.fields.version")}
|
||||||
|
source="version"
|
||||||
|
defaultValue={false}
|
||||||
|
style={{ marginBottom: 8 }}
|
||||||
|
/>
|
||||||
|
<Chip
|
||||||
|
label={translate("resources.rooms.fields.federatable")}
|
||||||
|
source="federatable"
|
||||||
|
defaultValue={false}
|
||||||
|
style={{ marginBottom: 8 }}
|
||||||
|
/>
|
||||||
|
</Filter>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const FilterableRoomList = ({ ...props }) => {
|
||||||
|
const filter = props.roomFilters;
|
||||||
|
const localMembersFilter =
|
||||||
|
filter && filter.joined_local_members ? true : false;
|
||||||
|
const stateEventsFilter = filter && filter.state_events ? true : false;
|
||||||
|
const versionFilter = filter && filter.version ? true : false;
|
||||||
|
const federateableFilter = filter && filter.federatable ? true : false;
|
||||||
|
|
||||||
|
return (
|
||||||
<List
|
<List
|
||||||
{...props}
|
{...props}
|
||||||
pagination={<RoomPagination />}
|
pagination={<RoomPagination />}
|
||||||
sort={{ field: "name", order: "ASC" }}
|
sort={{ field: "name", order: "ASC" }}
|
||||||
|
filters={<RoomFilter />}
|
||||||
>
|
>
|
||||||
<Datagrid>
|
<Datagrid rowClick="show">
|
||||||
<EncryptionField
|
<EncryptionField
|
||||||
source="is_encrypted"
|
source="is_encrypted"
|
||||||
sortBy="encryption"
|
sortBy="encryption"
|
||||||
label={<HttpsIcon />}
|
label={<HttpsIcon />}
|
||||||
/>
|
/>
|
||||||
<TextField source="room_id" sortable={false} />
|
|
||||||
<TextField source="name" />
|
<TextField source="name" />
|
||||||
<TextField source="canonical_alias" />
|
|
||||||
<TextField source="joined_members" />
|
<TextField source="joined_members" />
|
||||||
<TextField source="joined_local_members" />
|
{localMembersFilter && <TextField source="joined_local_members" />}
|
||||||
<TextField source="state_events" />
|
{stateEventsFilter && <TextField source="state_events" />}
|
||||||
<TextField source="version" />
|
{versionFilter && <TextField source="version" />}
|
||||||
<BooleanField source="federatable" />
|
{federateableFilter && <BooleanField source="federatable" />}
|
||||||
<BooleanField source="public" />
|
<BooleanField source="public" />
|
||||||
</Datagrid>
|
</Datagrid>
|
||||||
</List>
|
</List>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
roomFilters: state.admin.resources.rooms.list.params.displayedFilters,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RoomList = connect(mapStateToProps)(FilterableRoomList);
|
||||||
|
|||||||
+45
-1
@@ -1,4 +1,4 @@
|
|||||||
import React, { 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 PersonPinIcon from "@material-ui/icons/PersonPin";
|
||||||
import ContactMailIcon from "@material-ui/icons/ContactMail";
|
import ContactMailIcon from "@material-ui/icons/ContactMail";
|
||||||
@@ -30,6 +30,10 @@ import {
|
|||||||
regex,
|
regex,
|
||||||
useTranslate,
|
useTranslate,
|
||||||
Pagination,
|
Pagination,
|
||||||
|
CreateButton,
|
||||||
|
ExportButton,
|
||||||
|
TopToolbar,
|
||||||
|
sanitizeListRestProps,
|
||||||
} from "react-admin";
|
} from "react-admin";
|
||||||
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
@@ -46,6 +50,45 @@ const useStyles = makeStyles({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ListActions = ({
|
||||||
|
currentSort,
|
||||||
|
className,
|
||||||
|
resource,
|
||||||
|
filters,
|
||||||
|
displayedFilters,
|
||||||
|
exporter, // you can hide ExportButton if exporter = (null || false)
|
||||||
|
filterValues,
|
||||||
|
permanentFilter,
|
||||||
|
hasCreate, // you can hide CreateButton if hasCreate = false
|
||||||
|
basePath,
|
||||||
|
selectedIds,
|
||||||
|
onUnselectItems,
|
||||||
|
showFilter,
|
||||||
|
maxResults,
|
||||||
|
total,
|
||||||
|
...rest
|
||||||
|
}) => (
|
||||||
|
<TopToolbar className={className} {...sanitizeListRestProps(rest)}>
|
||||||
|
{filters &&
|
||||||
|
cloneElement(filters, {
|
||||||
|
resource,
|
||||||
|
showFilter,
|
||||||
|
displayedFilters,
|
||||||
|
filterValues,
|
||||||
|
context: "button",
|
||||||
|
})}
|
||||||
|
<CreateButton basePath={basePath} />
|
||||||
|
<ExportButton
|
||||||
|
disabled={total === 0}
|
||||||
|
resource={resource}
|
||||||
|
sort={currentSort}
|
||||||
|
filter={{ ...filterValues, ...permanentFilter }}
|
||||||
|
exporter={exporter}
|
||||||
|
maxResults={maxResults}
|
||||||
|
/>
|
||||||
|
</TopToolbar>
|
||||||
|
);
|
||||||
|
|
||||||
const UserPagination = props => (
|
const UserPagination = props => (
|
||||||
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
|
||||||
);
|
);
|
||||||
@@ -86,6 +129,7 @@ export const UserList = props => {
|
|||||||
{...props}
|
{...props}
|
||||||
filters={<UserFilter />}
|
filters={<UserFilter />}
|
||||||
filterDefaultValues={{ guests: true, deactivated: false }}
|
filterDefaultValues={{ guests: true, deactivated: false }}
|
||||||
|
actions={<ListActions maxResults={10000} />}
|
||||||
bulkActionButtons={<UserBulkActionButtons />}
|
bulkActionButtons={<UserBulkActionButtons />}
|
||||||
pagination={<UserPagination />}
|
pagination={<UserPagination />}
|
||||||
>
|
>
|
||||||
|
|||||||
+35
-2
@@ -15,6 +15,15 @@ export default {
|
|||||||
invalid_user_id:
|
invalid_user_id:
|
||||||
"Muss eine vollständige Matrix Benutzer-ID sein, z.B. @benutzer_id:homeserver",
|
"Muss eine vollständige Matrix Benutzer-ID sein, z.B. @benutzer_id:homeserver",
|
||||||
},
|
},
|
||||||
|
rooms: {
|
||||||
|
details: "Raumdetails",
|
||||||
|
tabs: {
|
||||||
|
basic: "Allgemein",
|
||||||
|
members: "Mitglieder",
|
||||||
|
detail: "Details",
|
||||||
|
permission: "Berechtigungen",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
resources: {
|
resources: {
|
||||||
users: {
|
users: {
|
||||||
@@ -58,12 +67,36 @@ export default {
|
|||||||
name: "Name",
|
name: "Name",
|
||||||
canonical_alias: "Alias",
|
canonical_alias: "Alias",
|
||||||
joined_members: "Mitglieder",
|
joined_members: "Mitglieder",
|
||||||
joined_local_members: "lokale Mitglieder",
|
joined_local_members: "Lokale Mitglieder",
|
||||||
state_events: "Ereignisse",
|
state_events: "Ereignisse",
|
||||||
version: "Version",
|
version: "Version",
|
||||||
is_encrypted: "Verschlüsselt",
|
is_encrypted: "Verschlüsselt",
|
||||||
federatable: "Föderiert",
|
encryption: "Verschlüsselungs-Algorithmus",
|
||||||
|
federatable: "Föderierbar",
|
||||||
public: "Öffentlich",
|
public: "Öffentlich",
|
||||||
|
creator: "Ersteller",
|
||||||
|
join_rules: "Beitrittsregeln",
|
||||||
|
guest_access: "Gastzugriff",
|
||||||
|
history_visibility: "Historie-Sichtbarkeit",
|
||||||
|
},
|
||||||
|
enums: {
|
||||||
|
join_rules: {
|
||||||
|
public: "Öffentlich",
|
||||||
|
knock: "Auf Anfrage",
|
||||||
|
invite: "Nur auf Einladung",
|
||||||
|
private: "Privat",
|
||||||
|
},
|
||||||
|
guest_access: {
|
||||||
|
can_join: "Gäste können beitreten",
|
||||||
|
forbidden: "Gäste können nicht beitreten",
|
||||||
|
},
|
||||||
|
history_visibility: {
|
||||||
|
invited: "Ab Einladung",
|
||||||
|
joined: "Ab Beitritt",
|
||||||
|
shared: "Ab Setzen der Einstellung",
|
||||||
|
world_readable: "Jeder",
|
||||||
|
},
|
||||||
|
unencrypted: "Nicht verschlüsselt",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
connections: {
|
connections: {
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ export default {
|
|||||||
invalid_user_id:
|
invalid_user_id:
|
||||||
"Must be a fully qualified Matrix user-id, e.g. @user_id:homeserver",
|
"Must be a fully qualified Matrix user-id, e.g. @user_id:homeserver",
|
||||||
},
|
},
|
||||||
|
rooms: {
|
||||||
|
tabs: {
|
||||||
|
basic: "Basic",
|
||||||
|
members: "Members",
|
||||||
|
detail: "Details",
|
||||||
|
permission: "Permissions",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
resources: {
|
resources: {
|
||||||
users: {
|
users: {
|
||||||
@@ -61,8 +69,32 @@ export default {
|
|||||||
state_events: "State events",
|
state_events: "State events",
|
||||||
version: "Version",
|
version: "Version",
|
||||||
is_encrypted: "Encrypted",
|
is_encrypted: "Encrypted",
|
||||||
|
encryption: "Encryption",
|
||||||
federatable: "Federatable",
|
federatable: "Federatable",
|
||||||
public: "Public",
|
public: "Public",
|
||||||
|
creator: "Creator",
|
||||||
|
join_rules: "Join rules",
|
||||||
|
guest_access: "Guest access",
|
||||||
|
history_visibility: "History visibility",
|
||||||
|
},
|
||||||
|
enums: {
|
||||||
|
join_rules: {
|
||||||
|
public: "Public",
|
||||||
|
knock: "Knock",
|
||||||
|
invite: "Invite",
|
||||||
|
private: "Private",
|
||||||
|
},
|
||||||
|
guest_access: {
|
||||||
|
can_join: "Guests can join",
|
||||||
|
forbidden: "Guests can not join",
|
||||||
|
},
|
||||||
|
history_visibility: {
|
||||||
|
invited: "Since invited",
|
||||||
|
joined: "Since joined",
|
||||||
|
shared: "Since shared",
|
||||||
|
world_readable: "Anyone",
|
||||||
|
},
|
||||||
|
unencrypted: "Unencrypted",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
connections: {
|
connections: {
|
||||||
|
|||||||
Reference in New Issue
Block a user