From 6363e3d32ef1275315e80d634764a82759718b90 Mon Sep 17 00:00:00 2001 From: Manuel Stahl Date: Mon, 5 Feb 2024 10:18:25 +0100 Subject: [PATCH 1/6] Use icon as loading spinner in login page Change-Id: Ie0e8d0a9e1242849fb8b18875d752dd15facaaf9 --- src/components/LoginPage.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/LoginPage.js b/src/components/LoginPage.js index 33eb6be..8585f69 100644 --- a/src/components/LoginPage.js +++ b/src/components/LoginPage.js @@ -307,9 +307,13 @@ const LoginPage = () => { - - - + {loading ? ( + + ) : ( + + + + )} {translate("synapseadmin.auth.welcome")} @@ -339,7 +343,6 @@ const LoginPage = () => { disabled={loading || !supportPassAuth} fullWidth > - {loading && } {translate("ra.auth.sign_in")} From 51def5775dc8ffc97686f590438671ec4d946069 Mon Sep 17 00:00:00 2001 From: Manuel Stahl Date: Sat, 3 Feb 2024 13:56:33 +0100 Subject: [PATCH 2/6] Replace `Fragment` with short form https://legacy.reactjs.org/docs/fragments.html#short-syntax Change-Id: Ib1af57fc5e87ded8c1fee38dcbd60fae8621cb07 --- src/components/RoomDirectory.js | 8 ++------ src/components/ServerNotices.js | 10 +++++----- src/components/devices.js | 6 +++--- src/components/media.js | 14 +++++++------- src/components/rooms.js | 6 +++--- src/components/users.js | 6 +++--- 6 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/components/RoomDirectory.js b/src/components/RoomDirectory.js index aac42df..84d4027 100644 --- a/src/components/RoomDirectory.js +++ b/src/components/RoomDirectory.js @@ -1,4 +1,4 @@ -import React, { Fragment } from "react"; +import React from "react"; import FolderSharedIcon from "@mui/icons-material/FolderShared"; import { BooleanField, @@ -130,11 +130,7 @@ export const RoomDirectorySaveButton = () => { ); }; -const RoomDirectoryBulkActionButtons = () => ( - - - -); +const RoomDirectoryBulkActionButtons = () => ; const RoomDirectoryListActions = () => ( diff --git a/src/components/ServerNotices.js b/src/components/ServerNotices.js index 631a849..751bada 100644 --- a/src/components/ServerNotices.js +++ b/src/components/ServerNotices.js @@ -1,4 +1,4 @@ -import React, { Fragment, useState } from "react"; +import React, { useState } from "react"; import { Button, SaveButton, @@ -93,7 +93,7 @@ export const ServerNoticeButton = () => { }; return ( - + <> @@ -232,7 +235,7 @@ export const ProtectMediaButton = props => { })} >
-
@@ -247,14 +250,15 @@ export const QuarantineMediaButton = props => { const translate = useTranslate(); const refresh = useRefresh(); const notify = useNotify(); - const [create, { loading }] = useCreate("quarantine_media"); - const [deleteOne] = useDelete("quarantine_media"); + const [create, { isLoading }] = useCreate(); + const [deleteOne] = useDelete(); if (!record) return null; const handleQuarantaine = () => { create( - { payload: { data: record } }, + "quarantine_media", + { data: record }, { onSuccess: () => { notify("resources.quarantine_media.action.send_success"); @@ -270,7 +274,8 @@ export const QuarantineMediaButton = props => { const handleRemoveQuarantaine = () => { deleteOne( - { payload: { ...record } }, + "quarantine_media", + { id: record.id }, { onSuccess: () => { notify("resources.quarantine_media.action.send_success"); @@ -306,7 +311,7 @@ export const QuarantineMediaButton = props => { })} >
-
@@ -319,7 +324,7 @@ export const QuarantineMediaButton = props => { })} >
-
diff --git a/src/synapse/dataProvider.js b/src/synapse/dataProvider.js index db57ec7..39e099a 100644 --- a/src/synapse/dataProvider.js +++ b/src/synapse/dataProvider.js @@ -98,7 +98,7 @@ const resourceMap = { }), delete: params => ({ endpoint: `/_synapse/admin/v2/users/${encodeURIComponent( - params.user_id + params.meta.user_id )}/devices/${params.id}`, }), }, @@ -184,9 +184,9 @@ const resourceMap = { delete: params => ({ endpoint: `/_synapse/admin/v1/media/${localStorage.getItem( "home_server" - )}/delete?before_ts=${params.before_ts}&size_gt=${ - params.size_gt - }&keep_profiles=${params.keep_profiles}`, + )}/delete?before_ts=${params.meta.before_ts}&size_gt=${ + params.meta.size_gt + }&keep_profiles=${params.meta.keep_profiles}`, method: "POST", }), }, @@ -197,7 +197,7 @@ const resourceMap = { method: "POST", }), delete: params => ({ - endpoint: `/_synapse/admin/v1/media/unprotect/${params.media_id}`, + endpoint: `/_synapse/admin/v1/media/unprotect/${params.id}`, method: "POST", }), }, @@ -212,7 +212,7 @@ const resourceMap = { delete: params => ({ endpoint: `/_synapse/admin/v1/media/unquarantine/${localStorage.getItem( "home_server" - )}/${params.media_id}`, + )}/${params.id}`, method: "POST", }), }, From 78d1d34a843fd2dd6c974b7646a8c0bdc5b136e8 Mon Sep 17 00:00:00 2001 From: Manuel Stahl Date: Sat, 3 Feb 2024 13:46:33 +0100 Subject: [PATCH 4/6] Simplify filters Change-Id: I3e4cb7134a92c949bfb62d753c682a6c8fca6736 --- src/components/RegistrationTokens.js | 9 ++------- src/components/destinations.js | 11 ++--------- src/components/rooms.js | 9 ++------- src/components/statistics.js | 9 ++------- src/components/users.js | 23 ++++++++++------------- 5 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/components/RegistrationTokens.js b/src/components/RegistrationTokens.js index 28213e5..97a2581 100644 --- a/src/components/RegistrationTokens.js +++ b/src/components/RegistrationTokens.js @@ -6,7 +6,6 @@ import { DateField, DateTimeInput, Edit, - Filter, List, maxValue, number, @@ -53,17 +52,13 @@ const dateFormatter = v => { return `${year}-${month}-${day}T${hour}:${minute}`; }; -const RegistrationTokenFilter = props => ( - - - -); +const registrationTokenFilters = []; export const RegistrationTokenList = props => { return ( } + filters={registrationTokenFilters} filterDefaultValues={{ valid: true }} pagination={false} perPage={500} diff --git a/src/components/destinations.js b/src/components/destinations.js index 0190375..6027258 100644 --- a/src/components/destinations.js +++ b/src/components/destinations.js @@ -3,7 +3,6 @@ import { Button, Datagrid, DateField, - Filter, List, Pagination, ReferenceField, @@ -41,13 +40,7 @@ const destinationRowSx = (record, _index) => ({ backgroundColor: record.retry_last_ts > 0 ? "#ffcccc" : "white", }); -const DestinationFilter = props => { - return ( - - - - ); -}; +const destinationFilters = []; export const DestinationReconnectButton = props => { const record = useRecordContext(); @@ -110,7 +103,7 @@ export const DestinationList = props => { return ( } + filters={destinationFilters} pagination={} sort={{ field: "destination", order: "ASC" }} > diff --git a/src/components/rooms.js b/src/components/rooms.js index 7d46538..23d2000 100644 --- a/src/components/rooms.js +++ b/src/components/rooms.js @@ -7,7 +7,6 @@ import { DatagridConfigurable, DeleteButton, ExportButton, - Filter, FunctionField, List, NumberField, @@ -290,11 +289,7 @@ const RoomBulkActionButtons = () => ( ); -const RoomFilter = props => ( - - - -); +const roomFilters = []; const RoomListActions = () => ( @@ -310,7 +305,7 @@ export const RoomList = () => { } sort={{ field: "name", order: "ASC" }} - filters={} + filters={roomFilters} actions={} > ( ); -const UserMediaStatsFilter = props => ( - - - -); +const userMediaStatsFilters = []; export const UserMediaStatsList = props => { return ( } - filters={} + filters={userMediaStatsFilters} pagination={} sort={{ field: "media_length", order: "DESC" }} > diff --git a/src/components/users.js b/src/components/users.js index 26853ac..53d0e5a 100644 --- a/src/components/users.js +++ b/src/components/users.js @@ -17,7 +17,6 @@ import { Create, Edit, List, - Filter, Toolbar, SimpleForm, SimpleFormIterator, @@ -125,17 +124,15 @@ const UserPagination = props => ( ); -const UserFilter = props => ( - - - - - -); +const userFilters = [ + , + , + , +]; const UserBulkActionButtons = props => ( <> @@ -153,7 +150,7 @@ export const UserList = props => { return ( } + filters={userFilters} filterDefaultValues={{ guests: true, deactivated: false }} sort={{ field: "name", order: "ASC" }} actions={} From af453eea71edccd6cd1905d8f06d6cccadd1a465 Mon Sep 17 00:00:00 2001 From: Manuel Stahl Date: Mon, 5 Feb 2024 13:06:47 +0100 Subject: [PATCH 5/6] Remove/mark unused parameters All top level components should pass props to the generic react-admin component to be more versatile. Change-Id: I25dd099cde1aefacbc748dc4716a8b0a3db9ab93 --- src/components/EventReports.js | 43 +++++++------- src/components/ImportFeature.js | 8 +-- src/components/RegistrationTokens.js | 86 +++++++++++++--------------- src/components/RoomDirectory.js | 6 +- src/components/destinations.js | 6 +- src/components/devices.js | 1 + src/components/media.js | 9 ++- src/components/rooms.js | 19 +++--- src/components/statistics.js | 44 +++++++------- src/components/users.js | 67 +++++++++++----------- 10 files changed, 142 insertions(+), 147 deletions(-) diff --git a/src/components/EventReports.js b/src/components/EventReports.js index 7e9c2a3..8185960 100644 --- a/src/components/EventReports.js +++ b/src/components/EventReports.js @@ -98,26 +98,23 @@ export const ReportShow = props => { ); }; -export const ReportList = ({ ...props }) => { - return ( - } - sort={{ field: "received_ts", order: "DESC" }} - bulkActionButtons={false} - > - - - - - - - - - ); -}; +export const ReportList = props => ( + } + sort={{ field: "received_ts", order: "DESC" }} + > + + + + + + + + +); diff --git a/src/components/ImportFeature.js b/src/components/ImportFeature.js index d30d302..c0066fe 100644 --- a/src/components/ImportFeature.js +++ b/src/components/ImportFeature.js @@ -32,7 +32,7 @@ function TranslatableOption({ value, text }) { return ; } -const FilePicker = props => { +const FilePicker = () => { const [values, setValues] = useState(null); const [error, setError] = useState(null); const [stats, setStats] = useState(null); @@ -191,7 +191,7 @@ const FilePicker = props => { return true; }; - const runImport = async e => { + const runImport = async _e => { if (progress !== null) { notify("import_users.errors.already_in_progress"); return; @@ -307,7 +307,7 @@ const FilePicker = props => { let retries = 0; const submitRecord = recordData => { return dataProvider.getOne("users", { id: recordData.id }).then( - async alreadyExists => { + async _alreadyExists => { if (LOGGING) console.log("already existed"); if (useridMode === "update" || conflictMode === "skip") { @@ -332,7 +332,7 @@ const FilePicker = props => { } } }, - async okToSubmit => { + async _okToSubmit => { if (LOGGING) console.log( "OK to create record " + diff --git a/src/components/RegistrationTokens.js b/src/components/RegistrationTokens.js index 97a2581..779feec 100644 --- a/src/components/RegistrationTokens.js +++ b/src/components/RegistrationTokens.js @@ -54,30 +54,28 @@ const dateFormatter = v => { const registrationTokenFilters = []; -export const RegistrationTokenList = props => { - return ( - - - - - - - - - - ); -}; +export const RegistrationTokenList = props => ( + + + + + + + + + +); export const RegistrationTokenCreate = props => ( @@ -104,24 +102,22 @@ export const RegistrationTokenCreate = props => ( ); -export const RegistrationTokenEdit = props => { - return ( - - - - - - - - - - ); -}; +export const RegistrationTokenEdit = props => ( + + + + + + + + + +); diff --git a/src/components/RoomDirectory.js b/src/components/RoomDirectory.js index 84d4027..4fbcca7 100644 --- a/src/components/RoomDirectory.js +++ b/src/components/RoomDirectory.js @@ -102,16 +102,16 @@ export const RoomDirectorySaveButton = () => { const refresh = useRefresh(); const [create, { isloading }] = useCreate(); - const handleSend = values => { + const handleSend = () => { create( "room_directory", { data: { id: record.id } }, { - onSuccess: data => { + onSuccess: _data => { notify("resources.room_directory.action.send_success"); refresh(); }, - onError: error => + onError: _error => notify("resources.room_directory.action.send_failure", { type: "error", }), diff --git a/src/components/destinations.js b/src/components/destinations.js index 6027258..cdd9e99 100644 --- a/src/components/destinations.js +++ b/src/components/destinations.js @@ -42,7 +42,7 @@ const destinationRowSx = (record, _index) => ({ const destinationFilters = []; -export const DestinationReconnectButton = props => { +export const DestinationReconnectButton = () => { const record = useRecordContext(); const refresh = useRefresh(); const notify = useNotify(); @@ -83,13 +83,13 @@ export const DestinationReconnectButton = props => { ); }; -const DestinationShowActions = props => ( +const DestinationShowActions = () => ( ); -const DestinationTitle = props => { +const DestinationTitle = () => { const record = useRecordContext(); const translate = useTranslate(); return ( diff --git a/src/components/devices.js b/src/components/devices.js index e467c39..313bb47 100644 --- a/src/components/devices.js +++ b/src/components/devices.js @@ -44,6 +44,7 @@ export const DeviceRemoveButton = props => { return ( <> @@ -311,7 +312,11 @@ export const QuarantineMediaButton = props => { })} >
-
diff --git a/src/components/rooms.js b/src/components/rooms.js index 23d2000..deedfb1 100644 --- a/src/components/rooms.js +++ b/src/components/rooms.js @@ -54,7 +54,7 @@ const RoomPagination = props => ( ); -const RoomTitle = props => { +const RoomTitle = () => { const record = useRecordContext(); const translate = useTranslate(); var name = ""; @@ -69,23 +69,23 @@ const RoomTitle = props => { ); }; -const RoomShowActions = ({ data, resource }) => { +const RoomShowActions = () => { + const record = useRecordContext(); var roomDirectoryStatus = ""; - if (data) { - roomDirectoryStatus = data.public; + if (record) { + roomDirectoryStatus = record.public; } return ( {roomDirectoryStatus === false && ( - + )} {roomDirectoryStatus === true && ( - + )} ( ); -export const RoomList = () => { +export const RoomList = props => { const theme = useTheme(); return ( } sort={{ field: "name", order: "ASC" }} filters={roomFilters} diff --git a/src/components/statistics.js b/src/components/statistics.js index 9dca38b..1cadac6 100644 --- a/src/components/statistics.js +++ b/src/components/statistics.js @@ -52,27 +52,25 @@ const UserMediaStatsPagination = props => ( const userMediaStatsFilters = []; -export const UserMediaStatsList = props => { - return ( - } - filters={userMediaStatsFilters} - pagination={} - sort={{ field: "media_length", order: "DESC" }} +export const UserMediaStatsList = props => ( + } + filters={userMediaStatsFilters} + pagination={} + sort={{ field: "media_length", order: "DESC" }} + > + "/users/" + id + "/media"} + bulkActionButtons={false} > - "/users/" + id + "/media"} - bulkActionButtons={false} - > - - - - - - - ); -}; + + + + + + +); diff --git a/src/components/users.js b/src/components/users.js index 53d0e5a..a2e240f 100644 --- a/src/components/users.js +++ b/src/components/users.js @@ -134,11 +134,10 @@ const userFilters = [ />, ]; -const UserBulkActionButtons = props => ( +const UserBulkActionButtons = () => ( <> - + ( ); -export const UserList = props => { - return ( - } - pagination={} - > - }> - - - - - - - - - - ); -}; +export const UserList = props => ( + } + pagination={} + > + }> + + + + + + + + + +); // https://matrix.org/docs/spec/appendices#user-identifiers // here only local part of user_id @@ -300,7 +297,7 @@ export const UserCreate = props => ( ); -const UserTitle = props => { +const UserTitle = () => { const record = useRecordContext(); const translate = useTranslate(); return ( From d520c6d61852171b0aea2a39fc306a8f6cb9763e Mon Sep 17 00:00:00 2001 From: Manuel Stahl Date: Mon, 5 Feb 2024 13:44:00 +0100 Subject: [PATCH 6/6] Export resources as objects Change-Id: I3c501369abf27fa21293c0434c56a00aaf8a64cd --- src/App.js | 69 ++++++---------------------- src/components/EventReports.js | 10 ++++ src/components/RegistrationTokens.js | 11 +++++ src/components/RoomDirectory.js | 18 ++++++-- src/components/destinations.js | 10 ++++ src/components/rooms.js | 10 ++++ src/components/statistics.js | 9 ++++ src/components/users.js | 11 +++++ 8 files changed, 88 insertions(+), 60 deletions(-) diff --git a/src/App.js b/src/App.js index 58cdb22..1d61d84 100644 --- a/src/App.js +++ b/src/App.js @@ -8,26 +8,15 @@ import { import polyglotI18nProvider from "ra-i18n-polyglot"; import authProvider from "./synapse/authProvider"; import dataProvider from "./synapse/dataProvider"; -import { UserList, UserCreate, UserEdit } from "./components/users"; -import { RoomList, RoomShow } from "./components/rooms"; -import { ReportList, ReportShow } from "./components/EventReports"; +import users from "./components/users"; +import rooms from "./components/rooms"; +import userMediaStats from "./components/statistics"; +import reports from "./components/EventReports"; +import roomDirectory from "./components/RoomDirectory"; +import destinations from "./components/destinations"; +import registrationToken from "./components/RegistrationTokens"; import LoginPage from "./components/LoginPage"; -import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber"; -import CloudQueueIcon from "@mui/icons-material/CloudQueue"; -import EqualizerIcon from "@mui/icons-material/Equalizer"; -import UserIcon from "@mui/icons-material/Group"; -import { UserMediaStatsList } from "./components/statistics"; -import RoomIcon from "@mui/icons-material/ViewList"; -import ReportIcon from "@mui/icons-material/Warning"; -import FolderSharedIcon from "@mui/icons-material/FolderShared"; -import { DestinationList, DestinationShow } from "./components/destinations"; import { ImportFeature } from "./components/ImportFeature"; -import { - RegistrationTokenCreate, - RegistrationTokenEdit, - RegistrationTokenList, -} from "./components/RegistrationTokens"; -import { RoomDirectoryList } from "./components/RoomDirectory"; import { Route } from "react-router-dom"; import germanMessages from "./i18n/de"; import englishMessages from "./i18n/en"; @@ -59,43 +48,13 @@ const App = () => ( } /> - - - - - - - + + + + + + + diff --git a/src/components/EventReports.js b/src/components/EventReports.js index 8185960..7e67eb7 100644 --- a/src/components/EventReports.js +++ b/src/components/EventReports.js @@ -13,6 +13,7 @@ import { useTranslate, } from "react-admin"; import PageviewIcon from "@mui/icons-material/Pageview"; +import ReportIcon from "@mui/icons-material/Warning"; import ViewListIcon from "@mui/icons-material/ViewList"; const date_format = { @@ -118,3 +119,12 @@ export const ReportList = props => ( ); + +const resource = { + name: "reports", + icon: ReportIcon, + list: ReportList, + show: ReportShow, +}; + +export default resource; diff --git a/src/components/RegistrationTokens.js b/src/components/RegistrationTokens.js index 779feec..483d1d8 100644 --- a/src/components/RegistrationTokens.js +++ b/src/components/RegistrationTokens.js @@ -17,6 +17,7 @@ import { TextField, Toolbar, } from "react-admin"; +import RegistrationTokenIcon from "@mui/icons-material/ConfirmationNumber"; const date_format = { year: "numeric", @@ -121,3 +122,13 @@ export const RegistrationTokenEdit = props => ( ); + +const resource = { + name: "users", + icon: RegistrationTokenIcon, + list: RegistrationTokenList, + edit: RegistrationTokenEdit, + create: RegistrationTokenCreate, +}; + +export default resource; diff --git a/src/components/RoomDirectory.js b/src/components/RoomDirectory.js index 4fbcca7..6981889 100644 --- a/src/components/RoomDirectory.js +++ b/src/components/RoomDirectory.js @@ -1,5 +1,4 @@ import React from "react"; -import FolderSharedIcon from "@mui/icons-material/FolderShared"; import { BooleanField, BulkDeleteButton, @@ -22,6 +21,7 @@ import { useUnselectAll, } from "react-admin"; import { useMutation } from "react-query"; +import RoomDirectoryIcon from "@mui/icons-material/FolderShared"; import AvatarField from "./AvatarField"; const RoomDirectoryPagination = props => ( @@ -44,7 +44,7 @@ export const RoomDirectoryDeleteButton = props => { smart_count: 1, })} resource="room_directory" - icon={} + icon={} /> ); }; @@ -57,7 +57,7 @@ export const RoomDirectoryBulkDeleteButton = props => ( confirmTitle="resources.room_directory.action.title" confirmContent="resources.room_directory.action.content" resource="room_directory" - icon={} + icon={} /> ); @@ -91,7 +91,7 @@ export const RoomDirectoryBulkSaveButton = () => { onClick={handleSend} disabled={isloading} > - + ); }; @@ -125,7 +125,7 @@ export const RoomDirectorySaveButton = () => { onClick={handleSend} disabled={isloading} > - + ); }; @@ -194,3 +194,11 @@ export const RoomDirectoryList = () => (
); + +const resource = { + name: "room_directory", + icon: RoomDirectoryIcon, + list: RoomDirectoryList, +}; + +export default resource; diff --git a/src/components/destinations.js b/src/components/destinations.js index cdd9e99..7f6ee02 100644 --- a/src/components/destinations.js +++ b/src/components/destinations.js @@ -20,6 +20,7 @@ import { useTranslate, } from "react-admin"; import AutorenewIcon from "@mui/icons-material/Autorenew"; +import DestinationsIcon from "@mui/icons-material/CloudQueue"; import FolderSharedIcon from "@mui/icons-material/FolderShared"; import ViewListIcon from "@mui/icons-material/ViewList"; @@ -177,3 +178,12 @@ export const DestinationShow = props => { ); }; + +const resource = { + name: "destinations", + icon: DestinationsIcon, + list: DestinationList, + show: DestinationShow, +}; + +export default resource; diff --git a/src/components/rooms.js b/src/components/rooms.js index deedfb1..8cfa793 100644 --- a/src/components/rooms.js +++ b/src/components/rooms.js @@ -34,6 +34,7 @@ import UserIcon from "@mui/icons-material/Group"; import ViewListIcon from "@mui/icons-material/ViewList"; import VisibilityIcon from "@mui/icons-material/Visibility"; import EventIcon from "@mui/icons-material/Event"; +import RoomIcon from "@mui/icons-material/ViewList"; import { RoomDirectoryBulkDeleteButton, RoomDirectoryBulkSaveButton, @@ -346,3 +347,12 @@ export const RoomList = props => {
); }; + +const resource = { + name: "rooms", + icon: RoomIcon, + list: RoomList, + show: RoomShow, +}; + +export default resource; diff --git a/src/components/statistics.js b/src/components/statistics.js index 1cadac6..90fd2fa 100644 --- a/src/components/statistics.js +++ b/src/components/statistics.js @@ -12,6 +12,7 @@ import { TopToolbar, useListContext, } from "react-admin"; +import EqualizerIcon from "@mui/icons-material/Equalizer"; import { DeleteMediaButton } from "./media"; const ListActions = props => { @@ -74,3 +75,11 @@ export const UserMediaStatsList = props => (
); + +const resource = { + name: "user_media_statistics", + icon: EqualizerIcon, + list: UserMediaStatsList, +}; + +export default resource; diff --git a/src/components/users.js b/src/components/users.js index a2e240f..dcd3b87 100644 --- a/src/components/users.js +++ b/src/components/users.js @@ -7,6 +7,7 @@ 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 UserIcon from "@mui/icons-material/Group"; import ViewListIcon from "@mui/icons-material/ViewList"; import { ArrayInput, @@ -524,3 +525,13 @@ export const UserEdit = props => { ); }; + +const resource = { + name: "users", + icon: UserIcon, + list: UserList, + edit: UserEdit, + create: UserCreate, +}; + +export default resource;