status badge updates

This commit is contained in:
Nate Kelley 2025-03-03 16:30:38 -07:00
parent a5000067d6
commit 284e708862
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
8 changed files with 97 additions and 52 deletions

View File

@ -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';

View File

@ -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;

View File

@ -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';

View File

@ -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';

View File

@ -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,

View File

@ -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>

View File

@ -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(),

View File

@ -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);