Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const BAIProjectBulkEditModal = ({
showIcon
ghostInfoBg={false}
title={t(
'comp:BAIProjectBulkEditModal.FollowingFoldersWillBeUpdated',
'comp:BAIProjectBulkEditModal.FollowingProjectsWillBeUpdated',
)}
description={
<ul
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import { BAIConfigProvider } from '../provider/BAIConfigProvider';
import { BAIMetaDataProvider } from '../provider/BAIMetaDataProvider';
import BAIProjectTable, {
availableProjectSorterValues,
type ProjectInList,
} from './BAIProjectTable';
import { DeleteFilled, SettingOutlined } from '@ant-design/icons';
import type { Meta, StoryObj } from '@storybook/react-vite';
import { App } from 'antd';
import { BanIcon, UndoIcon } from 'lucide-react';
import { useState } from 'react';
import { graphql, useLazyLoadQuery } from 'react-relay';

Expand Down Expand Up @@ -45,12 +48,10 @@ const meta: Meta<typeof BAIProjectTable> = {
|------|------|---------|-------------|
| \`projectFragment\` | \`BAIProjectTableFragment$key\` | - | GraphQL fragment reference (required) |
| \`onChangeOrder\` | \`(order: ProjectSorterValue \\| null) => void\` | - | Callback when sort order changes |
| \`onClickProjectEditButton\` | \`(project: Project) => void\` | - | Callback when edit button is clicked (required) |
| \`updateFetchKey\` | \`() => void\` | - | Callback to trigger data refetch |
| \`nameColumnActionProps\` | \`BAINameActionCellProps \\| ((value, record, index) => BAINameActionCellProps)\` | - | Props forwarded to the name column's \`BAINameActionCell\`. The page composes the per-row action list (edit / deactivate / activate / purge) here so action logic stays in the app layer |

## Pre-configured Columns
- **Name**: Project name (sortable)
- **Controls**: Edit, Deactivate, and Purge buttons
- **Name**: Project name (sortable) with caller-composed row actions via \`nameColumnActionProps\`
- **Domain**: Domain name (sortable)
- **Description**: Project description
- **Created At**: Creation timestamp (sortable)
Expand Down Expand Up @@ -86,18 +87,15 @@ For other props (loading, pagination, etc.), refer to [BAITable](?path=/docs/tab
},
},
},
onClickProjectEditButton: {
action: 'edit-clicked',
description: 'Callback when edit button is clicked',
table: {
type: { summary: '(project: Project) => void' },
},
},
updateFetchKey: {
action: 'fetch-triggered',
description: 'Callback to trigger data refetch',
nameColumnActionProps: {
control: false,
description:
"Props forwarded to the name column's BAINameActionCell. The page composes the per-row action list (edit / deactivate / activate / purge) here.",
table: {
type: { summary: '() => void' },
type: {
summary:
'BAINameActionCellProps | ((value, record, index) => BAINameActionCellProps)',
},
},
},
},
Expand Down Expand Up @@ -126,19 +124,27 @@ For other props (loading, pagination, etc.), refer to [BAITable](?path=/docs/tab
export default meta;
type Story = StoryObj<typeof BAIProjectTable>;

interface QueryResolverProps extends Pick<
React.ComponentProps<typeof BAIProjectTable>,
| 'onClickProjectEditButton'
| 'onChangeOrder'
| 'updateFetchKey'
| 'loading'
| 'order'
> {}
interface QueryResolverProps extends Partial<
Pick<
React.ComponentProps<typeof BAIProjectTable>,
'onChangeOrder' | 'loading' | 'order'
>
> {
onClickProjectEditButton?: (project: ProjectInList) => void;
onClickDeactivateProject?: (project: ProjectInList) => Promise<void>;
onClickRestoreProject?: (project: ProjectInList) => Promise<void>;
onClickPurgeProject?: (project: ProjectInList) => void;
}

const noop = () => {};
const asyncNoop = async () => {};

const QueryResolver: React.FC<QueryResolverProps> = ({
onClickProjectEditButton,
onChangeOrder,
updateFetchKey,
onClickProjectEditButton = noop,
onClickDeactivateProject = asyncNoop,
onClickRestoreProject = asyncNoop,
onClickPurgeProject = noop,
onChangeOrder = noop,
loading,
order,
}) => {
Expand Down Expand Up @@ -169,9 +175,60 @@ const QueryResolver: React.FC<QueryResolverProps> = ({
return (
<BAIProjectTable
projectFragment={projectNodes}
onClickProjectEditButton={onClickProjectEditButton}
nameColumnActionProps={(_value, record) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use customizeColumns like other components.

const isModelStore = record.type === 'MODEL_STORE';
return {
actions: [
{
key: 'edit',
title: 'Edit',
icon: <SettingOutlined />,
disabled: isModelStore,
onClick: () => onClickProjectEditButton(record),
},
...(record.is_active
? [
{
key: 'deactivate',
title: 'Deactivate',
icon: <BanIcon />,
type: 'danger' as const,
disabled: isModelStore,
popConfirm: {
title: 'Deactivate project',
description: record.name,
okButtonProps: { danger: true },
okText: 'Deactivate',
onConfirm: () => onClickDeactivateProject(record),
},
},
]
: [
{
key: 'activate',
title: 'Activate',
icon: <UndoIcon />,
disabled: isModelStore,
popConfirm: {
title: 'Activate project',
description: record.name,
okText: 'Activate',
onConfirm: () => onClickRestoreProject(record),
},
},
{
key: 'purge',
title: 'Purge',
icon: <DeleteFilled />,
type: 'danger' as const,
disabled: isModelStore,
onClick: () => onClickPurgeProject(record),
},
]),
],
};
}}
onChangeOrder={onChangeOrder}
updateFetchKey={updateFetchKey}
loading={loading}
order={order}
pagination={{
Expand Down Expand Up @@ -315,7 +372,6 @@ export const DifferentTypes: Story = {
<QueryResolver
onClickProjectEditButton={() => {}}
onChangeOrder={() => {}}
updateFetchKey={() => {}}
/>
</RelayResolver>
),
Expand Down Expand Up @@ -374,7 +430,6 @@ export const ActiveInactiveStates: Story = {
<QueryResolver
onClickProjectEditButton={() => {}}
onChangeOrder={() => {}}
updateFetchKey={() => {}}
/>
</RelayResolver>
),
Expand Down Expand Up @@ -437,7 +492,6 @@ export const WithSorting: Story = {
order={order}
onChangeOrder={(newOrder) => setOrder(newOrder)}
onClickProjectEditButton={() => {}}
updateFetchKey={() => {}}
/>
</RelayResolver>
</div>
Expand Down Expand Up @@ -477,7 +531,6 @@ export const Loading: Story = {
loading={true}
onClickProjectEditButton={() => {}}
onChangeOrder={() => {}}
updateFetchKey={() => {}}
/>
</RelayResolver>
),
Expand Down Expand Up @@ -510,7 +563,6 @@ export const Empty: Story = {
<QueryResolver
onClickProjectEditButton={() => {}}
onChangeOrder={() => {}}
updateFetchKey={() => {}}
/>
</RelayResolver>
),
Expand Down Expand Up @@ -580,7 +632,6 @@ export const VariousResourceAllocations: Story = {
<QueryResolver
onClickProjectEditButton={() => {}}
onChangeOrder={() => {}}
updateFetchKey={() => {}}
/>
</RelayResolver>
),
Expand Down Expand Up @@ -693,11 +744,19 @@ export const RealWorldExample: Story = {
onClickProjectEditButton={(project) =>
addAction(`Edit: ${project.name}`)
}
onClickDeactivateProject={async (project) => {
addAction(`Deactivate: ${project.name}`);
}}
onClickRestoreProject={async (project) => {
addAction(`Restore: ${project.name}`);
}}
onClickPurgeProject={(project) =>
addAction(`Purge: ${project.name}`)
}
onChangeOrder={(newOrder) => {
setOrder(newOrder);
addAction(`Sort: ${newOrder || 'default'}`);
}}
updateFetchKey={() => addAction('Refetch data')}
/>
</RelayResolver>
</div>
Expand Down
Loading
Loading