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 { FileType } from '@/api/asset_interfaces';
|
||||
|
||||
|
|
|
@ -40,7 +40,14 @@ const meta = {
|
|||
onVerify: {
|
||||
description: 'Function called when verification status is changed'
|
||||
}
|
||||
}
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="p-5">
|
||||
<Story />
|
||||
</div>
|
||||
)
|
||||
]
|
||||
} satisfies Meta<typeof StatusBadgeButton>;
|
||||
|
||||
export default meta;
|
||||
|
|
|
@ -72,27 +72,27 @@ export const StatusBadgeButton: React.FC<{
|
|||
const buttonText = Array.isArray(id) ? 'Status' : '';
|
||||
|
||||
return (
|
||||
<AppPopoverMenu
|
||||
items={items}
|
||||
trigger={['click']}
|
||||
onOpenChange={onOpenChange}
|
||||
open={isOpen}
|
||||
hideCheckbox
|
||||
doNotSortSelected={true}
|
||||
disabled={disabled}
|
||||
destroyPopupOnHide={true}
|
||||
selectedItems={selectedItem?.key ? [selectedItem.key! as string] : []}
|
||||
placement="bottomRight"
|
||||
headerContent={'Verification status...'}>
|
||||
<AppTooltip title={showButtonTooltip ? '' : 'Request verification from data team'}>
|
||||
<Button
|
||||
disabled={disabled || ((!id || status === 'verified') && !isAdmin)}
|
||||
prefix={<StatusBadgeIndicator showTooltip={false} status={status} size={14} />}
|
||||
variant={buttonVariant}>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</AppTooltip>
|
||||
</AppPopoverMenu>
|
||||
// <AppPopoverMenu
|
||||
// items={items}
|
||||
// trigger={['click']}
|
||||
// onOpenChange={onOpenChange}
|
||||
// open={isOpen}
|
||||
// hideCheckbox
|
||||
// doNotSortSelected={true}
|
||||
// disabled={disabled}
|
||||
// destroyPopupOnHide={true}
|
||||
// selectedItems={selectedItem?.key ? [selectedItem.key! as string] : []}
|
||||
// placement="bottomRight"
|
||||
// headerContent={'Verification status...'}>
|
||||
<AppTooltip title={showButtonTooltip ? '' : 'Request verification from data team'}>
|
||||
<Button
|
||||
disabled={disabled || ((!id || status === 'verified') && !isAdmin)}
|
||||
prefix={<StatusBadgeIndicator showTooltip={false} status={status} size={14} />}
|
||||
variant={buttonVariant}>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</AppTooltip>
|
||||
// </AppPopoverMenu>
|
||||
);
|
||||
});
|
||||
StatusBadgeButton.displayName = 'StatusBadgeButton';
|
||||
|
|
|
@ -3,30 +3,35 @@ import React, { useMemo } from 'react';
|
|||
import { getTooltipText } from './helpers';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { StatusBadgeIndicator } from './StatusBadgeIndicator';
|
||||
import { Dropdown, DropdownItem, DropdownItems } from '@/components/ui/dropdown';
|
||||
|
||||
const statuses = [
|
||||
VerificationStatus.notRequested,
|
||||
VerificationStatus.requested,
|
||||
VerificationStatus.inReview,
|
||||
VerificationStatus.verified,
|
||||
VerificationStatus.backlogged
|
||||
];
|
||||
|
||||
const requiresAdminItems = [
|
||||
VerificationStatus.inReview,
|
||||
VerificationStatus.verified,
|
||||
VerificationStatus.backlogged
|
||||
];
|
||||
|
||||
export const StatusDropdownContent: React.FC<{
|
||||
isAdmin: boolean;
|
||||
status: VerificationStatus;
|
||||
children: React.ReactNode;
|
||||
onChangeStatus: (status: VerificationStatus) => void;
|
||||
}> = React.memo(({ isAdmin, status, onChangeStatus }) => {
|
||||
const items = useMemo(() => {
|
||||
const statuses = [
|
||||
VerificationStatus.notRequested,
|
||||
VerificationStatus.requested,
|
||||
VerificationStatus.inReview,
|
||||
VerificationStatus.verified,
|
||||
VerificationStatus.backlogged
|
||||
];
|
||||
const requiresAdminItems = [
|
||||
VerificationStatus.inReview,
|
||||
VerificationStatus.verified,
|
||||
VerificationStatus.backlogged
|
||||
];
|
||||
return statuses.map((status, index) => {
|
||||
}> = React.memo(({ isAdmin, status, onChangeStatus, children }) => {
|
||||
const items: DropdownItems<VerificationStatus> = useMemo(() => {
|
||||
return statuses.map<DropdownItems<VerificationStatus>[number]>((status, index) => {
|
||||
const requiresAdmin = requiresAdminItems.includes(status);
|
||||
return {
|
||||
index,
|
||||
label: getTooltipText(status),
|
||||
value: status,
|
||||
icon: <StatusBadgeIndicator status={status} />,
|
||||
key: status,
|
||||
disabled: requiresAdmin && !isAdmin,
|
||||
|
@ -39,5 +44,22 @@ export const StatusDropdownContent: React.FC<{
|
|||
});
|
||||
}, [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 { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
export interface DropdownItem {
|
||||
export interface DropdownItem<T = string> {
|
||||
label: React.ReactNode | string;
|
||||
truncate?: boolean;
|
||||
searchLabel?: string; // Used for filtering
|
||||
secondaryLabel?: string;
|
||||
value: string;
|
||||
value: T;
|
||||
showIndex?: boolean;
|
||||
shortcut?: string;
|
||||
onClick?: () => void;
|
||||
|
@ -47,14 +47,14 @@ export interface DropdownDivider {
|
|||
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;
|
||||
selectType?: 'single' | 'multiple' | 'none';
|
||||
menuHeader?: string | React.ReactNode; //if string it will render a search box
|
||||
closeOnSelect?: boolean;
|
||||
onSelect?: (itemId: string) => void;
|
||||
onSelect?: (value: T) => void;
|
||||
align?: 'start' | 'center' | 'end';
|
||||
side?: 'top' | 'right' | 'bottom' | 'left';
|
||||
emptyStateText?: string;
|
||||
|
@ -70,7 +70,7 @@ const dropdownItemKey = (item: DropdownItems[number], index: number) => {
|
|||
|
||||
export const Dropdown: React.FC<DropdownProps> = React.memo(
|
||||
({
|
||||
items = [],
|
||||
items,
|
||||
selectType = 'none',
|
||||
menuHeader,
|
||||
closeOnSelect = true,
|
||||
|
|
|
@ -34,7 +34,9 @@ export const Tooltip = React.memo<TooltipProps>(
|
|||
return (
|
||||
<TooltipProvider delayDuration={delayDuration} skipDelayDuration={skipDelayDuration}>
|
||||
<TooltipBase open={open}>
|
||||
<TooltipTrigger asChild>{children}</TooltipTrigger>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="inline-block">{children}</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContentBase align={align} side={side} sideOffset={sideOffset}>
|
||||
<TooltipContent title={title} shortcut={shortcuts} />
|
||||
</TooltipContentBase>
|
||||
|
|
|
@ -6,7 +6,8 @@ import type {
|
|||
BusterChatMessage_fileMetadata,
|
||||
BusterChatMessageReasoning_pills,
|
||||
BusterChatMessageReasoning_Pill,
|
||||
BusterChatMessageReasoning_file
|
||||
BusterChatMessageReasoning_file,
|
||||
BusterChatMessageReasoning_text
|
||||
} from '@/api/asset_interfaces';
|
||||
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 fourRandomPills: BusterChatMessageReasoning_Pill[] = Array.from(
|
||||
{ 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 = {
|
||||
id: '0',
|
||||
title: 'Mock Chat',
|
||||
|
@ -130,11 +142,10 @@ export const MOCK_CHAT: BusterChat = {
|
|||
request_message: createMockUserMessage(),
|
||||
final_reasoning_message: null,
|
||||
reasoning: [
|
||||
...Array.from({ length: 1 }, () => createMockResponseMessageThought()),
|
||||
createMockReasoningMessageText(),
|
||||
createMockReasoningMessageText(),
|
||||
...Array.from({ length: 1 }, () => createMockResponseMessagePills()),
|
||||
createMockReasoningMessageFile()
|
||||
// createMockReasoningMessageFile(),
|
||||
// createMockResponseMessageThought(),
|
||||
// createMockResponseMessageThought()
|
||||
],
|
||||
response_messages: [
|
||||
createMockResponseMessageText(),
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { MOCK_CHAT } from './MOCK_CHAT';
|
||||
import { useChatIndividual } from './useChatIndividual';
|
||||
import { useMessageIndividual } from './useMessageIndividual';
|
||||
|
||||
export * from './ChatProvider';
|
||||
|
||||
export { useChatIndividual, useMessageIndividual };
|
||||
|
||||
console.log(MOCK_CHAT);
|
||||
|
|
Loading…
Reference in New Issue