Compare commits

..

12 Commits

Author SHA1 Message Date
Michael Albert c6b0cabcce Merge pull request #27 from dklimpel/increase_export
Increase export of users up to 10000
2020-07-10 15:31:25 +02:00
Michael Albert 1764554ce9 Update users.js 2020-07-10 15:29:58 +02:00
Michael Albert 5dfeb0abe2 Merge branch 'master' into increase_export 2020-07-10 15:26:14 +02:00
Michael Albert ff59ee4c2e Hide some room list information by default
Change-Id: Ic6fbf0d941d2ffcc87fb5b7793517b96792ce16d
2020-07-08 11:19:09 +02:00
Manuel Stahl 61938405e9 Add room detail view
Needs Synapse v1.14.0 or later

Change-Id: I6e3956a1e02fad5ba2f847458cd184af6aaedef0
2020-07-08 10:46:49 +02:00
Michael Albert 5f580fabce Merge branch 'master' into increase_export 2020-05-25 08:19:42 +02:00
Dirk Klimpel 5f8b5db415 Update user.js to fix error in resolve conflict 2020-04-06 12:56:34 +02:00
Dirk Klimpel f51c904aa1 Merge branch 'master' into increase_export 2020-04-06 12:44:54 +02:00
Dirk Klimpel 5792d55a97 Merge branch 'master' into increase_export 2020-03-30 11:42:34 +02:00
dklimpel 067dbd3b82 Fix coding style 2020-03-29 21:13:23 +02:00
dklimpel d805dcd2c6 Fix coding style 2020-03-29 20:59:54 +02:00
dklimpel 68e5a72618 Increase export of users up to 5000 2020-03-28 22:31:59 +01:00
6 changed files with 299 additions and 34 deletions
+1 -1
View File
@@ -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
View File
@@ -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>
+184 -28
View File
@@ -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 }) => {
<List const translate = useTranslate();
{...props} var name = "";
pagination={<RoomPagination />} if (record) {
sort={{ field: "name", order: "ASC" }} name = record.name !== "" ? record.name : record.id;
> }
<Datagrid>
<EncryptionField return (
source="is_encrypted" <span>
sortBy="encryption" {translate("resources.rooms.name", 1)} {name}
label={<HttpsIcon />} </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 }}
/> />
<TextField source="room_id" sortable={false} /> <Chip
<TextField source="name" /> label={translate("resources.rooms.fields.state_events")}
<TextField source="canonical_alias" /> source="state_events"
<TextField source="joined_members" /> defaultValue={false}
<TextField source="joined_local_members" /> style={{ marginBottom: 8 }}
<TextField source="state_events" /> />
<TextField source="version" /> <Chip
<BooleanField source="federatable" /> label={translate("resources.rooms.fields.version")}
<BooleanField source="public" /> source="version"
</Datagrid> defaultValue={false}
</List> 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
{...props}
pagination={<RoomPagination />}
sort={{ field: "name", order: "ASC" }}
filters={<RoomFilter />}
>
<Datagrid rowClick="show">
<EncryptionField
source="is_encrypted"
sortBy="encryption"
label={<HttpsIcon />}
/>
<TextField source="name" />
<TextField source="joined_members" />
{localMembersFilter && <TextField source="joined_local_members" />}
{stateEventsFilter && <TextField source="state_events" />}
{versionFilter && <TextField source="version" />}
{federateableFilter && <BooleanField source="federatable" />}
<BooleanField source="public" />
</Datagrid>
</List>
);
};
function mapStateToProps(state) {
return {
roomFilters: state.admin.resources.rooms.list.params.displayedFilters,
};
}
export const RoomList = connect(mapStateToProps)(FilterableRoomList);
+45 -1
View File
@@ -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
View File
@@ -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ö­de­riert", encryption: "Verschlüsselungs-Algorithmus",
federatable: "Fö­de­rierbar",
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: {
+32
View File
@@ -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: {