mirror of https://github.com/buster-so/buster.git
status badge updates
This commit is contained in:
parent
a5000067d6
commit
284e708862
|
@ -1,4 +1,4 @@
|
||||||
import { BASE_URL } from '@/api/buster_rest/instances';
|
import { BASE_URL } from '@/api/buster_rest/config';
|
||||||
import { PublicAssetResponse } from './interface';
|
import { PublicAssetResponse } from './interface';
|
||||||
import { FileType } from '@/api/asset_interfaces';
|
import { FileType } from '@/api/asset_interfaces';
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,14 @@ const meta = {
|
||||||
onVerify: {
|
onVerify: {
|
||||||
description: 'Function called when verification status is changed'
|
description: 'Function called when verification status is changed'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
decorators: [
|
||||||
|
(Story) => (
|
||||||
|
<div className="p-5">
|
||||||
|
<Story />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
]
|
||||||
} satisfies Meta<typeof StatusBadgeButton>;
|
} satisfies Meta<typeof StatusBadgeButton>;
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
|
@ -72,18 +72,18 @@ export const StatusBadgeButton: React.FC<{
|
||||||
const buttonText = Array.isArray(id) ? 'Status' : '';
|
const buttonText = Array.isArray(id) ? 'Status' : '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppPopoverMenu
|
// <AppPopoverMenu
|
||||||
items={items}
|
// items={items}
|
||||||
trigger={['click']}
|
// trigger={['click']}
|
||||||
onOpenChange={onOpenChange}
|
// onOpenChange={onOpenChange}
|
||||||
open={isOpen}
|
// open={isOpen}
|
||||||
hideCheckbox
|
// hideCheckbox
|
||||||
doNotSortSelected={true}
|
// doNotSortSelected={true}
|
||||||
disabled={disabled}
|
// disabled={disabled}
|
||||||
destroyPopupOnHide={true}
|
// destroyPopupOnHide={true}
|
||||||
selectedItems={selectedItem?.key ? [selectedItem.key! as string] : []}
|
// selectedItems={selectedItem?.key ? [selectedItem.key! as string] : []}
|
||||||
placement="bottomRight"
|
// placement="bottomRight"
|
||||||
headerContent={'Verification status...'}>
|
// headerContent={'Verification status...'}>
|
||||||
<AppTooltip title={showButtonTooltip ? '' : 'Request verification from data team'}>
|
<AppTooltip title={showButtonTooltip ? '' : 'Request verification from data team'}>
|
||||||
<Button
|
<Button
|
||||||
disabled={disabled || ((!id || status === 'verified') && !isAdmin)}
|
disabled={disabled || ((!id || status === 'verified') && !isAdmin)}
|
||||||
|
@ -92,7 +92,7 @@ export const StatusBadgeButton: React.FC<{
|
||||||
{buttonText}
|
{buttonText}
|
||||||
</Button>
|
</Button>
|
||||||
</AppTooltip>
|
</AppTooltip>
|
||||||
</AppPopoverMenu>
|
// </AppPopoverMenu>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
StatusBadgeButton.displayName = 'StatusBadgeButton';
|
StatusBadgeButton.displayName = 'StatusBadgeButton';
|
||||||
|
|
|
@ -3,13 +3,8 @@ import React, { useMemo } from 'react';
|
||||||
import { getTooltipText } from './helpers';
|
import { getTooltipText } from './helpers';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { StatusBadgeIndicator } from './StatusBadgeIndicator';
|
import { StatusBadgeIndicator } from './StatusBadgeIndicator';
|
||||||
|
import { Dropdown, DropdownItem, DropdownItems } from '@/components/ui/dropdown';
|
||||||
|
|
||||||
export const StatusDropdownContent: React.FC<{
|
|
||||||
isAdmin: boolean;
|
|
||||||
status: VerificationStatus;
|
|
||||||
onChangeStatus: (status: VerificationStatus) => void;
|
|
||||||
}> = React.memo(({ isAdmin, status, onChangeStatus }) => {
|
|
||||||
const items = useMemo(() => {
|
|
||||||
const statuses = [
|
const statuses = [
|
||||||
VerificationStatus.notRequested,
|
VerificationStatus.notRequested,
|
||||||
VerificationStatus.requested,
|
VerificationStatus.requested,
|
||||||
|
@ -17,16 +12,26 @@ export const StatusDropdownContent: React.FC<{
|
||||||
VerificationStatus.verified,
|
VerificationStatus.verified,
|
||||||
VerificationStatus.backlogged
|
VerificationStatus.backlogged
|
||||||
];
|
];
|
||||||
|
|
||||||
const requiresAdminItems = [
|
const requiresAdminItems = [
|
||||||
VerificationStatus.inReview,
|
VerificationStatus.inReview,
|
||||||
VerificationStatus.verified,
|
VerificationStatus.verified,
|
||||||
VerificationStatus.backlogged
|
VerificationStatus.backlogged
|
||||||
];
|
];
|
||||||
return statuses.map((status, index) => {
|
|
||||||
|
export const StatusDropdownContent: React.FC<{
|
||||||
|
isAdmin: boolean;
|
||||||
|
status: VerificationStatus;
|
||||||
|
children: React.ReactNode;
|
||||||
|
onChangeStatus: (status: VerificationStatus) => void;
|
||||||
|
}> = React.memo(({ isAdmin, status, onChangeStatus, children }) => {
|
||||||
|
const items: DropdownItems<VerificationStatus> = useMemo(() => {
|
||||||
|
return statuses.map<DropdownItems<VerificationStatus>[number]>((status, index) => {
|
||||||
const requiresAdmin = requiresAdminItems.includes(status);
|
const requiresAdmin = requiresAdminItems.includes(status);
|
||||||
return {
|
return {
|
||||||
index,
|
index,
|
||||||
label: getTooltipText(status),
|
label: getTooltipText(status),
|
||||||
|
value: status,
|
||||||
icon: <StatusBadgeIndicator status={status} />,
|
icon: <StatusBadgeIndicator status={status} />,
|
||||||
key: status,
|
key: status,
|
||||||
disabled: requiresAdmin && !isAdmin,
|
disabled: requiresAdmin && !isAdmin,
|
||||||
|
@ -39,5 +44,22 @@ export const StatusDropdownContent: React.FC<{
|
||||||
});
|
});
|
||||||
}, [isAdmin, status, onChangeStatus]);
|
}, [isAdmin, status, onChangeStatus]);
|
||||||
|
|
||||||
return <div>StatusDropdownContent</div>;
|
const onSelect = useMemoizedFn((item: DropdownItems[number]) => {
|
||||||
|
const _item = item as DropdownItem<VerificationStatus>;
|
||||||
|
onChangeStatus(_item.value as VerificationStatus);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
emptyStateText="Nothing to see here..."
|
||||||
|
items={items}
|
||||||
|
onSelect={(v) => {
|
||||||
|
console.log(v);
|
||||||
|
}}
|
||||||
|
selectType="single"
|
||||||
|
menuHeader="Status">
|
||||||
|
{children}
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
StatusDropdownContent.displayName = 'StatusDropdownContent';
|
||||||
|
|
|
@ -25,12 +25,12 @@ import { useDebounceSearch } from '@/hooks';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
export interface DropdownItem {
|
export interface DropdownItem<T = string> {
|
||||||
label: React.ReactNode | string;
|
label: React.ReactNode | string;
|
||||||
truncate?: boolean;
|
truncate?: boolean;
|
||||||
searchLabel?: string; // Used for filtering
|
searchLabel?: string; // Used for filtering
|
||||||
secondaryLabel?: string;
|
secondaryLabel?: string;
|
||||||
value: string;
|
value: T;
|
||||||
showIndex?: boolean;
|
showIndex?: boolean;
|
||||||
shortcut?: string;
|
shortcut?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
@ -47,14 +47,14 @@ export interface DropdownDivider {
|
||||||
type: 'divider';
|
type: 'divider';
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DropdownItems = (DropdownItem | DropdownDivider | React.ReactNode)[];
|
export type DropdownItems<T = string> = (DropdownItem<T> | DropdownDivider | React.ReactNode)[];
|
||||||
|
|
||||||
export interface DropdownProps extends DropdownMenuProps {
|
export interface DropdownProps<T = string> extends DropdownMenuProps {
|
||||||
items: DropdownItems;
|
items: DropdownItems;
|
||||||
selectType?: 'single' | 'multiple' | 'none';
|
selectType?: 'single' | 'multiple' | 'none';
|
||||||
menuHeader?: string | React.ReactNode; //if string it will render a search box
|
menuHeader?: string | React.ReactNode; //if string it will render a search box
|
||||||
closeOnSelect?: boolean;
|
closeOnSelect?: boolean;
|
||||||
onSelect?: (itemId: string) => void;
|
onSelect?: (value: T) => void;
|
||||||
align?: 'start' | 'center' | 'end';
|
align?: 'start' | 'center' | 'end';
|
||||||
side?: 'top' | 'right' | 'bottom' | 'left';
|
side?: 'top' | 'right' | 'bottom' | 'left';
|
||||||
emptyStateText?: string;
|
emptyStateText?: string;
|
||||||
|
@ -70,7 +70,7 @@ const dropdownItemKey = (item: DropdownItems[number], index: number) => {
|
||||||
|
|
||||||
export const Dropdown: React.FC<DropdownProps> = React.memo(
|
export const Dropdown: React.FC<DropdownProps> = React.memo(
|
||||||
({
|
({
|
||||||
items = [],
|
items,
|
||||||
selectType = 'none',
|
selectType = 'none',
|
||||||
menuHeader,
|
menuHeader,
|
||||||
closeOnSelect = true,
|
closeOnSelect = true,
|
||||||
|
|
|
@ -34,7 +34,9 @@ export const Tooltip = React.memo<TooltipProps>(
|
||||||
return (
|
return (
|
||||||
<TooltipProvider delayDuration={delayDuration} skipDelayDuration={skipDelayDuration}>
|
<TooltipProvider delayDuration={delayDuration} skipDelayDuration={skipDelayDuration}>
|
||||||
<TooltipBase open={open}>
|
<TooltipBase open={open}>
|
||||||
<TooltipTrigger asChild>{children}</TooltipTrigger>
|
<TooltipTrigger asChild>
|
||||||
|
<span className="inline-block">{children}</span>
|
||||||
|
</TooltipTrigger>
|
||||||
<TooltipContentBase align={align} side={side} sideOffset={sideOffset}>
|
<TooltipContentBase align={align} side={side} sideOffset={sideOffset}>
|
||||||
<TooltipContent title={title} shortcut={shortcuts} />
|
<TooltipContent title={title} shortcut={shortcuts} />
|
||||||
</TooltipContentBase>
|
</TooltipContentBase>
|
||||||
|
|
|
@ -6,7 +6,8 @@ import type {
|
||||||
BusterChatMessage_fileMetadata,
|
BusterChatMessage_fileMetadata,
|
||||||
BusterChatMessageReasoning_pills,
|
BusterChatMessageReasoning_pills,
|
||||||
BusterChatMessageReasoning_Pill,
|
BusterChatMessageReasoning_Pill,
|
||||||
BusterChatMessageReasoning_file
|
BusterChatMessageReasoning_file,
|
||||||
|
BusterChatMessageReasoning_text
|
||||||
} from '@/api/asset_interfaces';
|
} from '@/api/asset_interfaces';
|
||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ const createMockResponseMessageText = (): BusterChatMessage_text => ({
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const createMockResponseMessageThought = (): BusterChatMessageReasoning_pills => {
|
const createMockResponseMessagePills = (): BusterChatMessageReasoning_pills => {
|
||||||
const randomPillCount = faker.number.int({ min: 0, max: 10 });
|
const randomPillCount = faker.number.int({ min: 0, max: 10 });
|
||||||
const fourRandomPills: BusterChatMessageReasoning_Pill[] = Array.from(
|
const fourRandomPills: BusterChatMessageReasoning_Pill[] = Array.from(
|
||||||
{ length: randomPillCount },
|
{ length: randomPillCount },
|
||||||
|
@ -119,6 +120,17 @@ const createMockReasoningMessageFile = (): BusterChatMessageReasoning_file => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createMockReasoningMessageText = (): BusterChatMessageReasoning_text => {
|
||||||
|
return {
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
type: 'text',
|
||||||
|
message: faker.lorem.sentence(),
|
||||||
|
title: faker.lorem.words(4),
|
||||||
|
secondary_title: faker.lorem.sentence(),
|
||||||
|
status: 'loading'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const MOCK_CHAT: BusterChat = {
|
export const MOCK_CHAT: BusterChat = {
|
||||||
id: '0',
|
id: '0',
|
||||||
title: 'Mock Chat',
|
title: 'Mock Chat',
|
||||||
|
@ -130,11 +142,10 @@ export const MOCK_CHAT: BusterChat = {
|
||||||
request_message: createMockUserMessage(),
|
request_message: createMockUserMessage(),
|
||||||
final_reasoning_message: null,
|
final_reasoning_message: null,
|
||||||
reasoning: [
|
reasoning: [
|
||||||
...Array.from({ length: 1 }, () => createMockResponseMessageThought()),
|
createMockReasoningMessageText(),
|
||||||
|
createMockReasoningMessageText(),
|
||||||
|
...Array.from({ length: 1 }, () => createMockResponseMessagePills()),
|
||||||
createMockReasoningMessageFile()
|
createMockReasoningMessageFile()
|
||||||
// createMockReasoningMessageFile(),
|
|
||||||
// createMockResponseMessageThought(),
|
|
||||||
// createMockResponseMessageThought()
|
|
||||||
],
|
],
|
||||||
response_messages: [
|
response_messages: [
|
||||||
createMockResponseMessageText(),
|
createMockResponseMessageText(),
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
import { MOCK_CHAT } from './MOCK_CHAT';
|
||||||
import { useChatIndividual } from './useChatIndividual';
|
import { useChatIndividual } from './useChatIndividual';
|
||||||
import { useMessageIndividual } from './useMessageIndividual';
|
import { useMessageIndividual } from './useMessageIndividual';
|
||||||
|
|
||||||
export * from './ChatProvider';
|
export * from './ChatProvider';
|
||||||
|
|
||||||
export { useChatIndividual, useMessageIndividual };
|
export { useChatIndividual, useMessageIndividual };
|
||||||
|
|
||||||
|
console.log(MOCK_CHAT);
|
||||||
|
|
Loading…
Reference in New Issue