diff --git a/app/scenes/Settings/Members.tsx b/app/scenes/Settings/Members.tsx index 2d8e4aac3..01ac6845f 100644 --- a/app/scenes/Settings/Members.tsx +++ b/app/scenes/Settings/Members.tsx @@ -22,6 +22,7 @@ import usePolicy from "~/hooks/usePolicy"; import useQuery from "~/hooks/useQuery"; import useStores from "~/hooks/useStores"; import PeopleTable from "./components/PeopleTable"; +import UserRoleFilter from "./components/UserRoleFilter"; import UserStatusFilter from "./components/UserStatusFilter"; function Members() { @@ -39,6 +40,7 @@ function Members() { const can = usePolicy(team); const query = params.get("query") || undefined; const filter = params.get("filter") || undefined; + const role = params.get("role") || undefined; const sort = params.get("sort") || "name"; const direction = (params.get("direction") || "asc").toUpperCase() as | "ASC" @@ -58,6 +60,7 @@ function Members() { direction, query, filter, + role, }); setTotalPages(Math.ceil(response[PAGINATION_SYMBOL].total / limit)); setUserIds(response.map((u: User) => u.id)); @@ -67,7 +70,7 @@ function Members() { }; void fetchData(); - }, [query, sort, filter, page, direction, users, users.counts.all]); + }, [query, sort, filter, role, page, direction, users, users.counts.all]); React.useEffect(() => { let filtered = users.orderedData; @@ -76,36 +79,32 @@ function Members() { filtered = users.active.filter((u) => userIds.includes(u.id)); } else if (filter === "all") { filtered = users.orderedData.filter((u) => userIds.includes(u.id)); - } else if (filter === "admins") { - filtered = users.admins.filter((u) => userIds.includes(u.id)); - } else if (filter === "members") { - filtered = users.members.filter((u) => userIds.includes(u.id)); } else if (filter === "suspended") { filtered = users.suspended.filter((u) => userIds.includes(u.id)); } else if (filter === "invited") { filtered = users.invited.filter((u) => userIds.includes(u.id)); - } else if (filter === "viewers") { - filtered = users.viewers.filter((u) => userIds.includes(u.id)); + } + + if (role) { + filtered = filtered.filter((u) => u.role === role); } // sort the resulting data by the original order from the server setData(sortBy(filtered, (item) => userIds.indexOf(item.id))); }, [ filter, + role, users.active, - users.admins, - users.members, users.orderedData, users.suspended, users.invited, - users.viewers, userIds, ]); - const handleFilter = React.useCallback( - (filter) => { - if (filter) { - params.set("filter", filter); + const handleStatusFilter = React.useCallback( + (f) => { + if (f) { + params.set("filter", f); params.delete("page"); } else { params.delete("filter"); @@ -119,6 +118,23 @@ function Members() { [params, history, location.pathname] ); + const handleRoleFilter = React.useCallback( + (r) => { + if (r) { + params.set("role", r); + params.delete("page"); + } else { + params.delete("role"); + } + + history.replace({ + pathname: location.pathname, + search: params.toString(), + }); + }, + [params, history, location.pathname] + ); + const handleSearch = React.useCallback( (event) => { const { value } = event.target; @@ -182,7 +198,11 @@ function Members() { /> + void; +}; + +const UserRoleFilter = ({ activeKey, onSelect, ...rest }: Props) => { + const { t } = useTranslation(); + + const options = React.useMemo( + () => + compact([ + { + key: "", + label: t("All roles"), + }, + { + key: UserRole.Admin, + label: t("Admins"), + }, + { + key: UserRole.Member, + label: t("Editors"), + }, + { + key: UserRole.Viewer, + label: t("Viewers"), + }, + ]), + [t] + ); + + return ( + + ); +}; + +export default observer(UserRoleFilter); diff --git a/app/scenes/Settings/components/UserStatusFilter.tsx b/app/scenes/Settings/components/UserStatusFilter.tsx index ac1665ed3..eabdf3c77 100644 --- a/app/scenes/Settings/components/UserStatusFilter.tsx +++ b/app/scenes/Settings/components/UserStatusFilter.tsx @@ -17,22 +17,14 @@ const UserStatusFilter = ({ activeKey, onSelect, ...rest }: Props) => { const options = React.useMemo( () => compact([ + { + key: "all", + label: t("All status"), + }, { key: "", label: t("Active"), }, - { - key: "all", - label: t("Everyone"), - }, - { - key: "members", - label: t("Members"), - }, - { - key: "admins", - label: t("Admins"), - }, ...(user.isAdmin ? [ { @@ -45,10 +37,6 @@ const UserStatusFilter = ({ activeKey, onSelect, ...rest }: Props) => { key: "invited", label: t("Invited"), }, - { - key: "viewers", - label: t("Viewers"), - }, ]), [t, user.isAdmin] ); diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json index 110744bdd..b7d87d5ee 100644 --- a/shared/i18n/locales/en_US/translation.json +++ b/shared/i18n/locales/en_US/translation.json @@ -806,8 +806,10 @@ "Date shared": "Date shared", "Domain": "Domain", "Views": "Views", - "Everyone": "Everyone", + "All roles": "All roles", "Admins": "Admins", + "Editors": "Editors", + "All status": "All status", "Settings saved": "Settings saved", "Logo updated": "Logo updated", "Unable to upload new logo": "Unable to upload new logo",