mirror of https://github.com/buster-so/buster.git
finalize permission popup
Co-Authored-By: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
This commit is contained in:
parent
43c96cbb09
commit
221a4a6280
|
@ -8,7 +8,6 @@ import {
|
|||
useIndividualCollection
|
||||
} from '@/context/Collections';
|
||||
import { Breadcrumb, Button, Dropdown, MenuProps } from 'antd';
|
||||
import { BreadcrumbSeperator } from '@/components';
|
||||
import Link from 'next/link';
|
||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||
import { BusterRoutes } from '@/routes';
|
||||
|
@ -19,10 +18,10 @@ import { ShareMenu } from '../../_components/ShareMenu';
|
|||
import { BusterCollection } from '@/api/buster-rest/collection';
|
||||
import { BusterShareAssetType } from '@/api/buster-rest';
|
||||
import { Text } from '@/components';
|
||||
|
||||
import { useAntToken } from '@/styles/useAntToken';
|
||||
import { measureTextWidth } from '@/utils';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { BreadcrumbSeperator } from '@/components/breadcrumb';
|
||||
import { measureTextWidth } from '@/utils/canvas';
|
||||
|
||||
export const CollectionsIndividualHeader: React.FC<{}> = () => {
|
||||
const selectedThreadId = useBusterThreadsContextSelector((x) => x.selectedThreadId);
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import { BusterListSelectedOptionPopupContainer } from '@/components/list';
|
||||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
import { Button, Dropdown, MenuProps } from 'antd';
|
||||
import React, { useMemo } from 'react';
|
||||
import { PERMISSION_GROUP_ASSIGNED_OPTIONS } from './config';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { useDatasetUpdatePermissionGroups } from '@/api/buster-rest';
|
||||
import { AppMaterialIcons } from '@/components/icons';
|
||||
|
||||
export const PermissionGroupSelectedPopup: React.FC<{
|
||||
selectedRowKeys: string[];
|
||||
datasetId: string;
|
||||
onSelectChange: (selectedRowKeys: string[]) => void;
|
||||
}> = React.memo(({ selectedRowKeys, onSelectChange }) => {
|
||||
}> = React.memo(({ selectedRowKeys, onSelectChange, datasetId }) => {
|
||||
return (
|
||||
<BusterListSelectedOptionPopupContainer
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
|
@ -14,6 +19,7 @@ export const PermissionGroupSelectedPopup: React.FC<{
|
|||
<PermissionGroupAssignButton
|
||||
key="assign"
|
||||
selectedRowKeys={selectedRowKeys}
|
||||
datasetId={datasetId}
|
||||
onSelectChange={onSelectChange}
|
||||
/>
|
||||
]}
|
||||
|
@ -26,6 +32,45 @@ PermissionGroupSelectedPopup.displayName = 'PermissionGroupSelectedPopup';
|
|||
const PermissionGroupAssignButton: React.FC<{
|
||||
selectedRowKeys: string[];
|
||||
onSelectChange: (selectedRowKeys: string[]) => void;
|
||||
}> = ({ selectedRowKeys, onSelectChange }) => {
|
||||
return <Button>Assign</Button>;
|
||||
datasetId: string;
|
||||
}> = ({ selectedRowKeys, onSelectChange, datasetId }) => {
|
||||
const { mutateAsync: updatePermissionGroups, isPending } =
|
||||
useDatasetUpdatePermissionGroups(datasetId);
|
||||
|
||||
const onClickItem = useMemoizedFn(async (assigned: boolean) => {
|
||||
try {
|
||||
await updatePermissionGroups(
|
||||
selectedRowKeys.map((id) => ({
|
||||
id,
|
||||
assigned
|
||||
}))
|
||||
);
|
||||
onSelectChange([]);
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
});
|
||||
|
||||
const menu: MenuProps = useMemo(() => {
|
||||
return {
|
||||
items: PERMISSION_GROUP_ASSIGNED_OPTIONS.map((option) => ({
|
||||
label: option.label,
|
||||
key: option.value ? 'true' : 'false',
|
||||
icon: option.value ? (
|
||||
<AppMaterialIcons icon="done_all" />
|
||||
) : (
|
||||
<AppMaterialIcons icon="remove_done" />
|
||||
),
|
||||
onClick: () => {
|
||||
onClickItem(option.value);
|
||||
}
|
||||
}))
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dropdown menu={menu} trigger={['click']}>
|
||||
<Button loading={isPending}>Assign</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ 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';
|
||||
|
||||
export const PermissionListPermissionGroupContainer: React.FC<{
|
||||
filteredPermissionGroups: ListPermissionGroupsResponse[];
|
||||
|
@ -121,11 +122,13 @@ export const PermissionListPermissionGroupContainer: React.FC<{
|
|||
selectedRowKeys={selectedRowKeys}
|
||||
onSelectChange={setSelectedRowKeys}
|
||||
emptyState={<EmptyState />}
|
||||
useRowClickSelectChange={true}
|
||||
/>
|
||||
|
||||
<div className="fixed bottom-1 left-0 right-0 w-full">
|
||||
<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}
|
||||
/>
|
||||
|
@ -149,18 +152,7 @@ const PermissionGroupInfoCell = React.memo(({ name }: { name: string }) => {
|
|||
});
|
||||
PermissionGroupInfoCell.displayName = 'PermissionGroupInfoCell';
|
||||
|
||||
const options = [
|
||||
{
|
||||
label: 'Assigned',
|
||||
value: true
|
||||
},
|
||||
{
|
||||
label: 'Not Assigned',
|
||||
value: false
|
||||
}
|
||||
];
|
||||
|
||||
const PermissionGroupAssignedCell = React.memo(
|
||||
export const PermissionGroupAssignedCell = React.memo(
|
||||
({
|
||||
id,
|
||||
assigned,
|
||||
|
@ -172,9 +164,13 @@ const PermissionGroupAssignedCell = React.memo(
|
|||
}) => {
|
||||
return (
|
||||
<Select
|
||||
options={options}
|
||||
options={PERMISSION_GROUP_ASSIGNED_OPTIONS}
|
||||
defaultValue={assigned}
|
||||
popupMatchSelectWidth
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onSelect={(value) => {
|
||||
onSelect({ id, assigned: value });
|
||||
}}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
export const PERMISSION_GROUP_ASSIGNED_OPTIONS = [
|
||||
{
|
||||
label: 'Assigned',
|
||||
value: true
|
||||
},
|
||||
{
|
||||
label: 'Not Assigned',
|
||||
value: false
|
||||
}
|
||||
];
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||
import { useMemoizedFn } from 'ahooks';
|
||||
import { BusterListProps } from '../BusterList';
|
||||
import { getAllIdsInSection } from '../BusterList/helpers';
|
||||
import { WindowVirtualizer } from 'virtua';
|
||||
import { useEffect, useMemo, useRef, useCallback } from 'react';
|
||||
import { BusterListHeader } from '../BusterList/BusterListHeader';
|
||||
import { BusterListRowComponentSelector } from '../BusterList/BusterListRowComponentSelector';
|
||||
|
@ -19,6 +20,7 @@ export const BusterInfiniteList: React.FC<BusterInfiniteListProps> = ({
|
|||
onSelectChange,
|
||||
emptyState,
|
||||
showHeader = true,
|
||||
useRowClickSelectChange = false,
|
||||
contextMenu,
|
||||
columnRowVariant = 'containerized',
|
||||
showSelectAll = true,
|
||||
|
@ -26,8 +28,6 @@ export const BusterInfiniteList: React.FC<BusterInfiniteListProps> = ({
|
|||
loadingNewContent,
|
||||
scrollEndThreshold = 200 // Default threshold of 200px
|
||||
}) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const showEmptyState = useMemo(
|
||||
() => (!rows || rows.length === 0 || !rows.some((row) => !row.rowSection)) && !!emptyState,
|
||||
[rows, emptyState]
|
||||
|
@ -72,12 +72,14 @@ export const BusterInfiniteList: React.FC<BusterInfiniteListProps> = ({
|
|||
onSelectChange: onSelectChange ? onSelectChangePreflight : undefined,
|
||||
onSelectSectionChange: onSelectChange ? onSelectSectionChange : undefined,
|
||||
onContextMenuClick: undefined,
|
||||
columnRowVariant
|
||||
columnRowVariant,
|
||||
useRowClickSelectChange
|
||||
};
|
||||
}, [
|
||||
columns,
|
||||
rows,
|
||||
onSelectChange,
|
||||
useRowClickSelectChange,
|
||||
columnRowVariant,
|
||||
onSelectSectionChange,
|
||||
contextMenu,
|
||||
|
@ -86,29 +88,25 @@ export const BusterInfiniteList: React.FC<BusterInfiniteListProps> = ({
|
|||
|
||||
// Add scroll handler
|
||||
const handleScroll = useCallback(() => {
|
||||
if (!containerRef.current || !onScrollEnd) return;
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
||||
const distanceToBottom = scrollHeight - scrollTop - clientHeight;
|
||||
|
||||
if (distanceToBottom <= scrollEndThreshold) {
|
||||
onScrollEnd();
|
||||
}
|
||||
// const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
||||
// const distanceToBottom = scrollHeight - scrollTop - clientHeight;
|
||||
// console.log('distanceToBottom', distanceToBottom);
|
||||
// if (distanceToBottom <= scrollEndThreshold) {
|
||||
// onScrollEnd();
|
||||
// console.log('onScrollEnd');
|
||||
// }
|
||||
}, [onScrollEnd, scrollEndThreshold]);
|
||||
|
||||
// Add scroll event listener
|
||||
useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
if (!container || !onScrollEnd) return;
|
||||
|
||||
container.addEventListener('scroll', handleScroll);
|
||||
return () => container.removeEventListener('scroll', handleScroll);
|
||||
// const container = containerRef.current;
|
||||
// if (!container || !onScrollEnd) return;
|
||||
// container.addEventListener('scroll', handleScroll);
|
||||
// return () => container.removeEventListener('scroll', handleScroll);
|
||||
}, [handleScroll, onScrollEnd]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="infinite-list-container relative flex h-full w-full flex-col"
|
||||
ref={containerRef}>
|
||||
<div className="infinite-list-container relative flex h-full w-full flex-col">
|
||||
{showHeader && !showEmptyState && (
|
||||
<BusterListHeader
|
||||
columns={columns}
|
||||
|
|
|
@ -18,10 +18,20 @@ export const BusterListRowComponent = React.memo(
|
|||
onContextMenuClick?: (e: React.MouseEvent<HTMLDivElement>, id: string) => void;
|
||||
style?: React.CSSProperties;
|
||||
columnRowVariant: BusterListProps['columnRowVariant'];
|
||||
useRowClickSelectChange: boolean;
|
||||
}
|
||||
>(
|
||||
(
|
||||
{ style, columnRowVariant, row, columns, onSelectChange, checked, onContextMenuClick },
|
||||
{
|
||||
style,
|
||||
columnRowVariant,
|
||||
row,
|
||||
columns,
|
||||
onSelectChange,
|
||||
checked,
|
||||
onContextMenuClick,
|
||||
useRowClickSelectChange
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const { styles, cx } = useStyles();
|
||||
|
@ -31,14 +41,21 @@ export const BusterListRowComponent = React.memo(
|
|||
onContextMenuClick?.(e, row.id);
|
||||
});
|
||||
|
||||
const onChange = useMemoizedFn((checked: boolean) => {
|
||||
onSelectChange?.(checked, row.id);
|
||||
const onChange = useMemoizedFn((newChecked: boolean) => {
|
||||
onSelectChange?.(newChecked, row.id);
|
||||
});
|
||||
|
||||
const onContainerClick = useMemoizedFn(() => {
|
||||
if (useRowClickSelectChange) {
|
||||
onChange(!checked);
|
||||
}
|
||||
row.onClick?.();
|
||||
});
|
||||
|
||||
return (
|
||||
<LinkWrapper href={link}>
|
||||
<div
|
||||
onClick={row.onClick}
|
||||
onClick={onContainerClick}
|
||||
style={style}
|
||||
onContextMenu={onContextMenu}
|
||||
className={cx(
|
||||
|
@ -46,7 +63,7 @@ export const BusterListRowComponent = React.memo(
|
|||
'group flex items-center',
|
||||
checked ? 'checked' : '',
|
||||
columnRowVariant,
|
||||
{ clickable: !!(link || row.onClick) }
|
||||
{ clickable: !!(link || row.onClick || (onSelectChange && useRowClickSelectChange)) }
|
||||
)}
|
||||
ref={ref}>
|
||||
{!!onSelectChange ? (
|
||||
|
@ -124,15 +141,14 @@ export const useStyles = createStyles(({ css, token }) => ({
|
|||
row: css`
|
||||
height: ${HEIGHT_OF_ROW}px;
|
||||
min-height: ${HEIGHT_OF_ROW}px;
|
||||
|
||||
border-bottom: 0.5px solid ${token.colorBorder};
|
||||
|
||||
&:hover {
|
||||
background-color: ${token.controlItemBgHover};
|
||||
}
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: ${token.controlItemBgHover};
|
||||
}
|
||||
}
|
||||
|
||||
.row-cell {
|
||||
|
@ -149,9 +165,15 @@ export const useStyles = createStyles(({ css, token }) => ({
|
|||
}
|
||||
}
|
||||
|
||||
&.containerized {
|
||||
&.containerized:not(.checked) {
|
||||
background-color: ${token.colorBgContainer};
|
||||
|
||||
&.clickable {
|
||||
&:hover {
|
||||
background-color: ${token.controlItemBgHover};
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ export const BusterListRowComponentSelector = React.forwardRef<
|
|||
rows: BusterListRow[];
|
||||
style?: React.CSSProperties;
|
||||
columnRowVariant?: BusterListProps['columnRowVariant'];
|
||||
useRowClickSelectChange: boolean;
|
||||
}
|
||||
>(
|
||||
(
|
||||
|
@ -28,7 +29,8 @@ export const BusterListRowComponentSelector = React.forwardRef<
|
|||
onSelectSectionChange,
|
||||
selectedRowKeys,
|
||||
onContextMenuClick,
|
||||
columnRowVariant
|
||||
columnRowVariant,
|
||||
useRowClickSelectChange = false
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
|
@ -58,6 +60,7 @@ export const BusterListRowComponentSelector = React.forwardRef<
|
|||
ref={ref}
|
||||
onContextMenuClick={onContextMenuClick}
|
||||
columnRowVariant={columnRowVariant}
|
||||
useRowClickSelectChange={useRowClickSelectChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ export const BusterListVirtua = React.memo(
|
|||
emptyState,
|
||||
showHeader = true,
|
||||
contextMenu,
|
||||
showSelectAll = true
|
||||
showSelectAll = true,
|
||||
useRowClickSelectChange = false
|
||||
}: BusterListProps) => {
|
||||
const contextMenuRef = useRef<HTMLDivElement>(null);
|
||||
const showEmptyState = (!rows || rows.length === 0) && !!emptyState;
|
||||
|
@ -70,9 +71,18 @@ export const BusterListVirtua = React.memo(
|
|||
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
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (contextMenu && contextMenuPosition?.show) {
|
||||
|
|
|
@ -16,6 +16,7 @@ export interface BusterListProps {
|
|||
selectedRowKeys?: string[];
|
||||
contextMenu?: BusterListContextMenu;
|
||||
showSelectAll?: boolean;
|
||||
useRowClickSelectChange?: boolean;
|
||||
}
|
||||
|
||||
export interface BusterListColumn {
|
||||
|
|
Loading…
Reference in New Issue