mirror of
https://github.com/docmost/docmost.git
synced 2026-05-20 00:14:10 +08:00
fix: bug fixes (#1000)
* sort by groups first * add scroll area * fix group members pagination * move pagination to the right
This commit is contained in:
@@ -21,7 +21,7 @@ export default function Paginate({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group mt="md">
|
<Group mt="md" justify="flex-end">
|
||||||
<Button
|
<Button
|
||||||
variant="default"
|
variant="default"
|
||||||
size="compact-sm"
|
size="compact-sm"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export async function getGroupMembers(
|
|||||||
groupId: string,
|
groupId: string,
|
||||||
params?: QueryParams,
|
params?: QueryParams,
|
||||||
): Promise<IPagination<IUser>> {
|
): Promise<IPagination<IUser>> {
|
||||||
const req = await api.post("/groups/members", { groupId, params });
|
const req = await api.post("/groups/members", { groupId, ...params });
|
||||||
return req.data;
|
return req.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import { Group, Table, Text, Menu, ActionIcon } from "@mantine/core";
|
import {
|
||||||
|
Group,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
Menu,
|
||||||
|
ActionIcon,
|
||||||
|
ScrollArea,
|
||||||
|
} from "@mantine/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { IconDots } from "@tabler/icons-react";
|
import { IconDots } from "@tabler/icons-react";
|
||||||
import { modals } from "@mantine/modals";
|
import { modals } from "@mantine/modals";
|
||||||
@@ -106,93 +113,95 @@ export default function SpaceMembersList({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SearchInput onSearch={handleSearch} />
|
<SearchInput onSearch={handleSearch} />
|
||||||
<Table.ScrollContainer minWidth={500}>
|
<ScrollArea h={400}>
|
||||||
<Table highlightOnHover verticalSpacing={8}>
|
<Table.ScrollContainer minWidth={500}>
|
||||||
<Table.Thead>
|
<Table highlightOnHover verticalSpacing={8}>
|
||||||
<Table.Tr>
|
<Table.Thead>
|
||||||
<Table.Th>{t("Member")}</Table.Th>
|
<Table.Tr>
|
||||||
<Table.Th>{t("Role")}</Table.Th>
|
<Table.Th>{t("Member")}</Table.Th>
|
||||||
<Table.Th></Table.Th>
|
<Table.Th>{t("Role")}</Table.Th>
|
||||||
</Table.Tr>
|
<Table.Th></Table.Th>
|
||||||
</Table.Thead>
|
|
||||||
|
|
||||||
<Table.Tbody>
|
|
||||||
{data?.items.map((member, index) => (
|
|
||||||
<Table.Tr key={index}>
|
|
||||||
<Table.Td>
|
|
||||||
<Group gap="sm" wrap="nowrap">
|
|
||||||
{member.type === "user" && (
|
|
||||||
<CustomAvatar
|
|
||||||
avatarUrl={member?.avatarUrl}
|
|
||||||
name={member.name}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{member.type === "group" && <IconGroupCircle />}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Text fz="sm" fw={500} lineClamp={1}>
|
|
||||||
{member?.name}
|
|
||||||
</Text>
|
|
||||||
<Text fz="xs" c="dimmed">
|
|
||||||
{member.type == "user" && member?.email}
|
|
||||||
|
|
||||||
{member.type == "group" &&
|
|
||||||
`${t("Group")} - ${formatMemberCount(member?.memberCount, t)}`}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</Group>
|
|
||||||
</Table.Td>
|
|
||||||
|
|
||||||
<Table.Td>
|
|
||||||
<RoleSelectMenu
|
|
||||||
roles={spaceRoleData}
|
|
||||||
roleName={getSpaceRoleLabel(member.role)}
|
|
||||||
onChange={(newRole) =>
|
|
||||||
handleRoleChange(
|
|
||||||
member.id,
|
|
||||||
member.type,
|
|
||||||
newRole,
|
|
||||||
member.role,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
disabled={readOnly}
|
|
||||||
/>
|
|
||||||
</Table.Td>
|
|
||||||
|
|
||||||
<Table.Td>
|
|
||||||
{!readOnly && (
|
|
||||||
<Menu
|
|
||||||
shadow="xl"
|
|
||||||
position="bottom-end"
|
|
||||||
offset={20}
|
|
||||||
width={200}
|
|
||||||
withArrow
|
|
||||||
arrowPosition="center"
|
|
||||||
>
|
|
||||||
<Menu.Target>
|
|
||||||
<ActionIcon variant="subtle" c="gray">
|
|
||||||
<IconDots size={20} stroke={2} />
|
|
||||||
</ActionIcon>
|
|
||||||
</Menu.Target>
|
|
||||||
|
|
||||||
<Menu.Dropdown>
|
|
||||||
<Menu.Item
|
|
||||||
onClick={() =>
|
|
||||||
openRemoveModal(member.id, member.type)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("Remove space member")}
|
|
||||||
</Menu.Item>
|
|
||||||
</Menu.Dropdown>
|
|
||||||
</Menu>
|
|
||||||
)}
|
|
||||||
</Table.Td>
|
|
||||||
</Table.Tr>
|
</Table.Tr>
|
||||||
))}
|
</Table.Thead>
|
||||||
</Table.Tbody>
|
|
||||||
</Table>
|
<Table.Tbody>
|
||||||
</Table.ScrollContainer>
|
{data?.items.map((member, index) => (
|
||||||
|
<Table.Tr key={index}>
|
||||||
|
<Table.Td>
|
||||||
|
<Group gap="sm" wrap="nowrap">
|
||||||
|
{member.type === "user" && (
|
||||||
|
<CustomAvatar
|
||||||
|
avatarUrl={member?.avatarUrl}
|
||||||
|
name={member.name}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{member.type === "group" && <IconGroupCircle />}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Text fz="sm" fw={500} lineClamp={1}>
|
||||||
|
{member?.name}
|
||||||
|
</Text>
|
||||||
|
<Text fz="xs" c="dimmed">
|
||||||
|
{member.type == "user" && member?.email}
|
||||||
|
|
||||||
|
{member.type == "group" &&
|
||||||
|
`${t("Group")} - ${formatMemberCount(member?.memberCount, t)}`}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</Group>
|
||||||
|
</Table.Td>
|
||||||
|
|
||||||
|
<Table.Td>
|
||||||
|
<RoleSelectMenu
|
||||||
|
roles={spaceRoleData}
|
||||||
|
roleName={getSpaceRoleLabel(member.role)}
|
||||||
|
onChange={(newRole) =>
|
||||||
|
handleRoleChange(
|
||||||
|
member.id,
|
||||||
|
member.type,
|
||||||
|
newRole,
|
||||||
|
member.role,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={readOnly}
|
||||||
|
/>
|
||||||
|
</Table.Td>
|
||||||
|
|
||||||
|
<Table.Td>
|
||||||
|
{!readOnly && (
|
||||||
|
<Menu
|
||||||
|
shadow="xl"
|
||||||
|
position="bottom-end"
|
||||||
|
offset={20}
|
||||||
|
width={200}
|
||||||
|
withArrow
|
||||||
|
arrowPosition="center"
|
||||||
|
>
|
||||||
|
<Menu.Target>
|
||||||
|
<ActionIcon variant="subtle" c="gray">
|
||||||
|
<IconDots size={20} stroke={2} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Menu.Target>
|
||||||
|
|
||||||
|
<Menu.Dropdown>
|
||||||
|
<Menu.Item
|
||||||
|
onClick={() =>
|
||||||
|
openRemoveModal(member.id, member.type)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("Remove space member")}
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.Dropdown>
|
||||||
|
</Menu>
|
||||||
|
)}
|
||||||
|
</Table.Td>
|
||||||
|
</Table.Tr>
|
||||||
|
))}
|
||||||
|
</Table.Tbody>
|
||||||
|
</Table>
|
||||||
|
</Table.ScrollContainer>
|
||||||
|
</ScrollArea>
|
||||||
|
|
||||||
{data?.items.length > 0 && (
|
{data?.items.length > 0 && (
|
||||||
<Paginate
|
<Paginate
|
||||||
|
|||||||
-1
@@ -17,7 +17,6 @@ import Paginate from "@/components/common/paginate.tsx";
|
|||||||
import { SearchInput } from "@/components/common/search-input.tsx";
|
import { SearchInput } from "@/components/common/search-input.tsx";
|
||||||
import NoTableResults from "@/components/common/no-table-results.tsx";
|
import NoTableResults from "@/components/common/no-table-results.tsx";
|
||||||
import { usePaginateAndSearch } from "@/hooks/use-paginate-and-search.tsx";
|
import { usePaginateAndSearch } from "@/hooks/use-paginate-and-search.tsx";
|
||||||
import InviteActionMenu from "@/features/workspace/components/members/components/invite-action-menu.tsx";
|
|
||||||
import MemberActionMenu from "@/features/workspace/components/members/components/members-action-menu.tsx";
|
import MemberActionMenu from "@/features/workspace/components/members/components/members-action-menu.tsx";
|
||||||
|
|
||||||
export default function WorkspaceMembersTable() {
|
export default function WorkspaceMembersTable() {
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ export class SpaceMemberRepo {
|
|||||||
])
|
])
|
||||||
.select((eb) => this.groupRepo.withMemberCount(eb))
|
.select((eb) => this.groupRepo.withMemberCount(eb))
|
||||||
.where('spaceId', '=', spaceId)
|
.where('spaceId', '=', spaceId)
|
||||||
|
.orderBy((eb) => eb('groups.id', 'is not', null), 'desc')
|
||||||
.orderBy('spaceMembers.createdAt', 'asc');
|
.orderBy('spaceMembers.createdAt', 'asc');
|
||||||
|
|
||||||
if (pagination.query) {
|
if (pagination.query) {
|
||||||
|
|||||||
Reference in New Issue
Block a user