mirror of https://github.com/buster-so/buster.git
add additional bulk popup menus
Co-Authored-By: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
This commit is contained in:
parent
58fa171a8e
commit
db7d98ec9a
|
@ -19,7 +19,7 @@ export const PermissionDatasetGroupSelectedPopup: React.FC<{
|
|||
onSelectChange={onSelectChange}
|
||||
buttons={[
|
||||
<PermissionDatasetGroupAssignButton
|
||||
key="delete"
|
||||
key="assign"
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={onSelectChange}
|
||||
datasetId={datasetId}
|
||||
|
|
|
@ -6,12 +6,12 @@ import { Select } from 'antd';
|
|||
import { createStyles } from 'antd-style';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { PermissionDatasetGroupSelectedPopup } from './PermissionDatasetGroupSelectedPopup';
|
||||
import { PermissionListContainer } from '../_components';
|
||||
|
||||
export const PermissionListDatasetGroupContainer: React.FC<{
|
||||
filteredPermissionGroups: ListDatasetGroupsResponse[];
|
||||
datasetId: string;
|
||||
}> = ({ filteredPermissionGroups, datasetId }) => {
|
||||
const { styles, cx } = useStyles();
|
||||
const { mutateAsync: updateDatasetGroups } = useDatasetUpdateDatasetGroups(datasetId);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
const numberOfPermissionGroups = filteredPermissionGroups.length;
|
||||
|
@ -107,36 +107,28 @@ export const PermissionListDatasetGroupContainer: React.FC<{
|
|||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={cx('', styles.container)}>
|
||||
<BusterInfiniteList
|
||||
columns={columns}
|
||||
rows={rows}
|
||||
showHeader={false}
|
||||
showSelectAll={false}
|
||||
<PermissionListContainer
|
||||
popupNode={
|
||||
<PermissionDatasetGroupSelectedPopup
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
emptyState={<div className="py-12">No dataset groups found</div>}
|
||||
datasetId={datasetId}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PermissionDatasetGroupSelectedPopup
|
||||
}>
|
||||
<BusterInfiniteList
|
||||
columns={columns}
|
||||
rows={rows}
|
||||
showHeader={false}
|
||||
showSelectAll={false}
|
||||
useRowClickSelectChange={true}
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
datasetId={datasetId}
|
||||
emptyState={<div className="py-12">No dataset groups found</div>}
|
||||
/>
|
||||
</>
|
||||
</PermissionListContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
container: css`
|
||||
border: 0.5px solid ${token.colorBorder};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
overflow: hidden;
|
||||
`
|
||||
}));
|
||||
|
||||
const DatasetGroupInfoCell: React.FC<{ name: string }> = ({ name }) => {
|
||||
return <div>{name}</div>;
|
||||
};
|
||||
|
@ -165,6 +157,10 @@ const DatasetGroupAssignedCell: React.FC<{
|
|||
onSelect={(value) => {
|
||||
onSelect({ id, assigned: value });
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,18 +5,17 @@ import {
|
|||
import { BusterListColumn, BusterListRowItem } from '@/components/list';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Select } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Text } from '@/components/text';
|
||||
import { PermissionGroupSelectedPopup } from './PermissionGroupSelectedPopup';
|
||||
import { BusterInfiniteList } from '@/components/list/BusterInfiniteList';
|
||||
import { PERMISSION_GROUP_ASSIGNED_OPTIONS } from './config';
|
||||
import { PermissionListContainer } from '../_components/PermissionListContainer';
|
||||
|
||||
export const PermissionListPermissionGroupContainer: React.FC<{
|
||||
filteredPermissionGroups: ListPermissionGroupsResponse[];
|
||||
datasetId: string;
|
||||
}> = React.memo(({ filteredPermissionGroups, datasetId }) => {
|
||||
const { styles, cx } = useStyles();
|
||||
const { mutateAsync: updatePermissionGroups } = useDatasetUpdatePermissionGroups(datasetId);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
|
||||
|
@ -113,7 +112,14 @@ export const PermissionListPermissionGroupContainer: React.FC<{
|
|||
);
|
||||
|
||||
return (
|
||||
<div className={cx('min-h-fit overflow-hidden', styles.container)}>
|
||||
<PermissionListContainer
|
||||
popupNode={
|
||||
<PermissionGroupSelectedPopup
|
||||
datasetId={datasetId}
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
/>
|
||||
}>
|
||||
<BusterInfiniteList
|
||||
columns={columns}
|
||||
rows={rows}
|
||||
|
@ -124,29 +130,12 @@ export const PermissionListPermissionGroupContainer: React.FC<{
|
|||
emptyState={<EmptyState />}
|
||||
useRowClickSelectChange={true}
|
||||
/>
|
||||
|
||||
<div className="fixed bottom-0 left-0 right-0 w-full">
|
||||
<div className="relative ml-[220px] mr-[55px]">
|
||||
<PermissionGroupSelectedPopup
|
||||
datasetId={datasetId}
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PermissionListContainer>
|
||||
);
|
||||
});
|
||||
|
||||
PermissionListPermissionGroupContainer.displayName = 'PermissionListTeamContainer';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
container: css`
|
||||
border: 0.5px solid ${token.colorBorder};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
`
|
||||
}));
|
||||
|
||||
const PermissionGroupInfoCell = React.memo(({ name }: { name: string }) => {
|
||||
return <div>{name}</div>;
|
||||
});
|
||||
|
@ -165,7 +154,7 @@ export const PermissionGroupAssignedCell = React.memo(
|
|||
return (
|
||||
<Select
|
||||
options={PERMISSION_GROUP_ASSIGNED_OPTIONS}
|
||||
defaultValue={assigned}
|
||||
value={assigned}
|
||||
popupMatchSelectWidth
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
|
|
@ -11,12 +11,14 @@ import { Select } from 'antd';
|
|||
import { createStyles } from 'antd-style';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Text } from '@/components/text';
|
||||
import { PermissionListContainer } from '../_components';
|
||||
import { PermissionUsersSelectedPopup } from './PermissionUsersSelectedPopup';
|
||||
import { PERMISSION_USERS_OPTIONS } from './config';
|
||||
|
||||
export const PermissionListUsersContainer: React.FC<{
|
||||
filteredPermissionUsers: ListPermissionUsersResponse[];
|
||||
datasetId: string;
|
||||
}> = React.memo(({ filteredPermissionUsers, datasetId }) => {
|
||||
const { styles, cx } = useStyles();
|
||||
const { mutateAsync: updatePermissionUsers } = useDatasetUpdatePermissionUsers(datasetId);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
|
||||
|
@ -113,7 +115,14 @@ export const PermissionListUsersContainer: React.FC<{
|
|||
);
|
||||
|
||||
return (
|
||||
<div className={cx(styles.container)}>
|
||||
<PermissionListContainer
|
||||
popupNode={
|
||||
<PermissionUsersSelectedPopup
|
||||
datasetId={datasetId}
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
/>
|
||||
}>
|
||||
<BusterInfiniteList
|
||||
columns={columns}
|
||||
rows={rows}
|
||||
|
@ -121,26 +130,19 @@ export const PermissionListUsersContainer: React.FC<{
|
|||
showSelectAll={false}
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
useRowClickSelectChange={true}
|
||||
emptyState={
|
||||
<div className="py-12">
|
||||
<Text type="tertiary">No users found</Text>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</PermissionListContainer>
|
||||
);
|
||||
});
|
||||
|
||||
PermissionListUsersContainer.displayName = 'PermissionListUsersContainer';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
container: css`
|
||||
border: 0.5px solid ${token.colorBorder};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
overflow: hidden;
|
||||
`
|
||||
}));
|
||||
|
||||
const PermissionGroupInfoCell = React.memo(({ name, email }: { name: string; email: string }) => {
|
||||
return (
|
||||
<div className="flex w-full items-center space-x-1.5">
|
||||
|
@ -161,39 +163,23 @@ const PermissionGroupInfoCell = React.memo(({ name, email }: { name: string; ema
|
|||
});
|
||||
PermissionGroupInfoCell.displayName = 'PermissionGroupInfoCell';
|
||||
|
||||
const options = [
|
||||
{
|
||||
label: 'Assigned',
|
||||
value: true
|
||||
},
|
||||
{
|
||||
label: 'Not Assigned',
|
||||
value: false
|
||||
}
|
||||
];
|
||||
|
||||
const PermissionGroupAssignedCell = React.memo(
|
||||
({
|
||||
id,
|
||||
assigned,
|
||||
onSelect
|
||||
}: {
|
||||
id: string;
|
||||
assigned: boolean;
|
||||
onSelect: (value: { id: string; assigned: boolean }) => void;
|
||||
}) => {
|
||||
return (
|
||||
<Select
|
||||
options={options}
|
||||
defaultValue={assigned}
|
||||
popupMatchSelectWidth
|
||||
onSelect={(value) => {
|
||||
onSelect({ id, assigned: value });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
() => true
|
||||
);
|
||||
|
||||
PermissionGroupAssignedCell.displayName = 'PermissionGroupAssignedCell';
|
||||
const PermissionGroupAssignedCell: React.FC<{
|
||||
id: string;
|
||||
assigned: boolean;
|
||||
onSelect: (value: { id: string; assigned: boolean }) => void;
|
||||
}> = ({ id, assigned, onSelect }) => {
|
||||
return (
|
||||
<Select
|
||||
options={PERMISSION_USERS_OPTIONS}
|
||||
value={assigned}
|
||||
popupMatchSelectWidth
|
||||
onSelect={(value) => {
|
||||
onSelect({ id, assigned: value });
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -19,7 +19,11 @@ export const PermissionUsers: React.FC<{
|
|||
const { searchText, handleSearchChange, filteredItems } = useDebounceSearch({
|
||||
items: permissionUsers || [],
|
||||
searchPredicate: (item, searchText) => {
|
||||
return item.name.includes(searchText);
|
||||
const lowerCaseSearchText = searchText.toLowerCase();
|
||||
return (
|
||||
item.name.toLocaleLowerCase().includes(lowerCaseSearchText) ||
|
||||
item.email.toLocaleLowerCase().includes(lowerCaseSearchText)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import { useDatasetUpdatePermissionUsers } from '@/api/buster-rest';
|
||||
import { AppMaterialIcons } from '@/components';
|
||||
import { BusterListSelectedOptionPopupContainer } from '@/components/list';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import { MenuProps } from 'antd/lib';
|
||||
import React, { useMemo } from 'react';
|
||||
import { PERMISSION_USERS_OPTIONS } from './config';
|
||||
|
||||
export const PermissionUsersSelectedPopup: React.FC<{
|
||||
selectedRowKeys: string[];
|
||||
onSelectChange: (selectedRowKeys: string[]) => void;
|
||||
datasetId: string;
|
||||
}> = React.memo(({ selectedRowKeys, onSelectChange, datasetId }) => {
|
||||
const show = selectedRowKeys.length > 0;
|
||||
|
||||
return (
|
||||
<BusterListSelectedOptionPopupContainer
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={onSelectChange}
|
||||
buttons={[
|
||||
<PermissionUsersAssignButton
|
||||
key="assign"
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={onSelectChange}
|
||||
datasetId={datasetId}
|
||||
/>
|
||||
]}
|
||||
show={show}
|
||||
/>
|
||||
);
|
||||
});
|
||||
PermissionUsersSelectedPopup.displayName = 'PermissionUsersSelectedPopup';
|
||||
|
||||
const options = PERMISSION_USERS_OPTIONS.map((v) => ({
|
||||
label: v.label,
|
||||
value: v.value,
|
||||
icon: v.value ? <AppMaterialIcons icon="done_all" /> : <AppMaterialIcons icon="remove_done" />
|
||||
}));
|
||||
|
||||
const PermissionUsersAssignButton: React.FC<{
|
||||
selectedRowKeys: string[];
|
||||
onSelectChange: (selectedRowKeys: string[]) => void;
|
||||
datasetId: string;
|
||||
}> = ({ selectedRowKeys, onSelectChange, datasetId }) => {
|
||||
const { mutateAsync: updatePermissionUsers } = useDatasetUpdatePermissionUsers(datasetId);
|
||||
|
||||
const onAssignClick = useMemoizedFn(async (assigned: boolean) => {
|
||||
try {
|
||||
await updatePermissionUsers(selectedRowKeys.map((v) => ({ id: v, assigned })));
|
||||
onSelectChange([]);
|
||||
} catch (error) {
|
||||
// openErrorMessage('Failed to delete collection');
|
||||
}
|
||||
});
|
||||
|
||||
const menuProps: MenuProps = useMemo(() => {
|
||||
return {
|
||||
selectable: true,
|
||||
items: options.map((v) => ({
|
||||
icon: v.icon,
|
||||
label: v.label,
|
||||
key: v.value ? 'included' : 'not_included',
|
||||
onClick: () => onAssignClick(v.value)
|
||||
}))
|
||||
};
|
||||
}, [selectedRowKeys]);
|
||||
|
||||
const onButtonClick = useMemoizedFn((e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
return (
|
||||
<Dropdown menu={menuProps} trigger={['click']}>
|
||||
<Button icon={<AppMaterialIcons icon="done_all" />} type="default" onClick={onButtonClick}>
|
||||
{options[0].label}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
export const PERMISSION_USERS_OPTIONS = [
|
||||
{
|
||||
label: 'Assigned',
|
||||
value: true
|
||||
},
|
||||
{
|
||||
label: 'Not Assigned',
|
||||
value: false
|
||||
}
|
||||
];
|
|
@ -0,0 +1,30 @@
|
|||
import { createStyles } from 'antd-style';
|
||||
import React from 'react';
|
||||
|
||||
export const PermissionListContainer: React.FC<{
|
||||
children: React.ReactNode;
|
||||
popupNode?: React.ReactNode;
|
||||
}> = React.memo(({ children, popupNode }) => {
|
||||
const { styles, cx } = useStyles();
|
||||
|
||||
return (
|
||||
<div className={cx('overflow-hidden', styles.container)}>
|
||||
{children}
|
||||
|
||||
{popupNode && (
|
||||
<div className="fixed bottom-0 left-0 right-0 w-full">
|
||||
<div className="relative ml-[220px] mr-[55px]">{popupNode}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
PermissionListContainer.displayName = 'PermissionListContainer';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
container: css`
|
||||
border: 0.5px solid ${token.colorBorder};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
`
|
||||
}));
|
|
@ -0,0 +1 @@
|
|||
export * from './PermissionListContainer';
|
|
@ -8,9 +8,6 @@ import { useMount } from 'ahooks';
|
|||
const headerHeight = 300;
|
||||
|
||||
const ItemSwag = React.memo(({ index }: { index: number }) => {
|
||||
useMount(() => {
|
||||
console.log('useMount', index);
|
||||
});
|
||||
return <div className="h-[48px] border bg-red-200">Swag {index}</div>;
|
||||
});
|
||||
ItemSwag.displayName = 'ItemSwag';
|
||||
|
|
|
@ -17,7 +17,8 @@ export const BusterListReactWindow: React.FC<BusterListProps> = ({
|
|||
emptyState,
|
||||
showHeader = true,
|
||||
contextMenu,
|
||||
showSelectAll = true
|
||||
showSelectAll = true,
|
||||
useRowClickSelectChange = false
|
||||
}) => {
|
||||
const contextMenuRef = useRef<HTMLDivElement>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
@ -116,9 +117,18 @@ export const BusterListReactWindow: React.FC<BusterListProps> = ({
|
|||
selectedRowKeys,
|
||||
onSelectChange: onSelectChange ? onSelectChangePreflight : undefined,
|
||||
onSelectSectionChange: onSelectChange ? onSelectSectionChange : undefined,
|
||||
onContextMenuClick
|
||||
onContextMenuClick,
|
||||
useRowClickSelectChange
|
||||
};
|
||||
}, [columns, rows, selectedRowKeys, onSelectChange, onSelectSectionChange, onContextMenuClick]);
|
||||
}, [
|
||||
columns,
|
||||
rows,
|
||||
useRowClickSelectChange,
|
||||
selectedRowKeys,
|
||||
onSelectChange,
|
||||
onSelectSectionChange,
|
||||
onContextMenuClick
|
||||
]);
|
||||
|
||||
//context menu click away
|
||||
useEffect(() => {
|
||||
|
|
|
@ -87,10 +87,7 @@ export const BusterListRowComponent = React.memo(
|
|||
</LinkWrapper>
|
||||
);
|
||||
}
|
||||
),
|
||||
(prevProps, nextProps) => {
|
||||
return prevProps.checked === nextProps.checked && prevProps.row.id === nextProps.row.id;
|
||||
}
|
||||
)
|
||||
);
|
||||
BusterListRowComponent.displayName = 'BusterListRowComponent';
|
||||
|
||||
|
|
Loading…
Reference in New Issue