myoperator-ui 0.0.210 → 0.0.211-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +459 -130
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -252,7 +252,7 @@ function looksLikeTailwindClasses(str) {
|
|
|
252
252
|
return true;
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
|
-
const singleWordUtilities = /^(flex|grid|block|inline|contents|flow-root|hidden|invisible|visible|static|fixed|absolute|relative|sticky|isolate|isolation-auto|overflow-auto|overflow-hidden|overflow-clip|overflow-visible|overflow-scroll|overflow-x-auto|overflow-y-auto|overscroll-auto|overscroll-contain|overscroll-none|truncate|antialiased|subpixel-antialiased|italic|not-italic|underline|overline|line-through|no-underline|uppercase|lowercase|capitalize|normal-case|ordinal|slashed-zero|lining-nums|oldstyle-nums|proportional-nums|tabular-nums|diagonal-fractions|stacked-fractions|sr-only|not-sr-only|resize|resize-none|resize-x|resize-y|snap-start|snap-end|snap-center|snap-align-none|snap-normal|snap-always|touch-auto|touch-none|touch-pan-x|touch-pan-left|touch-pan-right|touch-pan-y|touch-pan-up|touch-pan-down|touch-pinch-zoom|touch-manipulation|select-none|select-text|select-all|select-auto|will-change-auto|will-change-scroll|will-change-contents|will-change-transform|grow|grow-0|shrink|shrink-0|transform|transform-cpu|transform-gpu|transform-none|transition|transition-none|transition-all|transition-colors|transition-opacity|transition-shadow|transition-transform|animate-none|animate-spin|animate-ping|animate-pulse|animate-bounce)$/;
|
|
255
|
+
const singleWordUtilities = /^(flex|inline-flex|grid|inline-grid|block|inline-block|inline-table|inline|contents|flow-root|hidden|invisible|visible|static|fixed|absolute|relative|sticky|isolate|isolation-auto|overflow-auto|overflow-hidden|overflow-clip|overflow-visible|overflow-scroll|overflow-x-auto|overflow-y-auto|overscroll-auto|overscroll-contain|overscroll-none|truncate|antialiased|subpixel-antialiased|italic|not-italic|underline|overline|line-through|no-underline|uppercase|lowercase|capitalize|normal-case|ordinal|slashed-zero|lining-nums|oldstyle-nums|proportional-nums|tabular-nums|diagonal-fractions|stacked-fractions|sr-only|not-sr-only|resize|resize-none|resize-x|resize-y|snap-start|snap-end|snap-center|snap-align-none|snap-normal|snap-always|touch-auto|touch-none|touch-pan-x|touch-pan-left|touch-pan-right|touch-pan-y|touch-pan-up|touch-pan-down|touch-pinch-zoom|touch-manipulation|select-none|select-text|select-all|select-auto|will-change-auto|will-change-scroll|will-change-contents|will-change-transform|grow|grow-0|shrink|shrink-0|transform|transform-cpu|transform-gpu|transform-none|transition|transition-none|transition-all|transition-colors|transition-opacity|transition-shadow|transition-transform|animate-none|animate-spin|animate-ping|animate-pulse|animate-bounce)$/;
|
|
256
256
|
if (!str.includes(" ") && singleWordUtilities.test(str)) return true;
|
|
257
257
|
if (/^(@[a-z0-9-]+\/)?[a-z][a-z0-9-]*$/.test(str) && !str.includes(" ")) return false;
|
|
258
258
|
const words = str.split(/\s+/);
|
|
@@ -12632,7 +12632,7 @@ export type { BrandIconProps } from "./icon";
|
|
|
12632
12632
|
},
|
|
12633
12633
|
"bots": {
|
|
12634
12634
|
name: "bots",
|
|
12635
|
-
description: "AI Bot management components \u2014 BotList page, BotCard, and CreateBotModal",
|
|
12635
|
+
description: "AI Bot management components \u2014 BotList page, BotListHeader, BotListSearch, BotListCreateCard, BotListGrid, BotCard, and CreateBotModal",
|
|
12636
12636
|
category: "custom",
|
|
12637
12637
|
dependencies: [
|
|
12638
12638
|
"clsx",
|
|
@@ -12640,8 +12640,10 @@ export type { BrandIconProps } from "./icon";
|
|
|
12640
12640
|
"lucide-react"
|
|
12641
12641
|
],
|
|
12642
12642
|
internalDependencies: [
|
|
12643
|
+
"badge",
|
|
12643
12644
|
"button",
|
|
12644
|
-
"dialog"
|
|
12645
|
+
"dialog",
|
|
12646
|
+
"dropdown-menu"
|
|
12645
12647
|
],
|
|
12646
12648
|
isMultiFile: true,
|
|
12647
12649
|
directory: "bots",
|
|
@@ -12650,114 +12652,127 @@ export type { BrandIconProps } from "./icon";
|
|
|
12650
12652
|
{
|
|
12651
12653
|
name: "bot-card.tsx",
|
|
12652
12654
|
content: prefixTailwindClasses(`import * as React from "react";
|
|
12653
|
-
import { MessageSquare, Phone
|
|
12655
|
+
import { MessageSquare, Phone } from "lucide-react";
|
|
12654
12656
|
import { cn } from "../../../lib/utils";
|
|
12655
|
-
import {
|
|
12656
|
-
DropdownMenu,
|
|
12657
|
-
DropdownMenuTrigger,
|
|
12658
|
-
DropdownMenuContent,
|
|
12659
|
-
DropdownMenuItem,
|
|
12660
|
-
DropdownMenuSeparator,
|
|
12661
|
-
} from "../dropdown-menu";
|
|
12662
12657
|
import { Badge } from "../badge";
|
|
12663
|
-
import
|
|
12658
|
+
import { BotListAction } from "./bot-list-action";
|
|
12659
|
+
import type { Bot, BotCardProps, BotType } from "./types";
|
|
12664
12660
|
|
|
12665
|
-
const
|
|
12661
|
+
const DEFAULT_TYPE_LABELS: Record<BotType, string> = {
|
|
12666
12662
|
chatbot: "Chatbot",
|
|
12667
12663
|
voicebot: "Voicebot",
|
|
12668
12664
|
};
|
|
12669
12665
|
|
|
12666
|
+
function getTypeLabel(
|
|
12667
|
+
bot: Bot,
|
|
12668
|
+
typeLabels?: Partial<Record<BotType, string>>
|
|
12669
|
+
): string {
|
|
12670
|
+
if (bot.typeLabel) return bot.typeLabel;
|
|
12671
|
+
const custom = typeLabels?.[bot.type];
|
|
12672
|
+
if (custom) return custom;
|
|
12673
|
+
return DEFAULT_TYPE_LABELS[bot.type];
|
|
12674
|
+
}
|
|
12675
|
+
|
|
12676
|
+
/**
|
|
12677
|
+
* Single card component for both Chatbot and Voicebot.
|
|
12678
|
+
* All displayed data (icon, badge, name, count, last published) comes from the \`bot\` prop.
|
|
12679
|
+
* Set bot.type to "chatbot" or "voicebot"; no separate card components needed.
|
|
12680
|
+
*/
|
|
12670
12681
|
export const BotCard = React.forwardRef<HTMLDivElement, BotCardProps>(
|
|
12671
|
-
({ bot, onEdit, onPublish, onDelete, className }, ref) => {
|
|
12682
|
+
({ bot, typeLabels, onEdit, onPublish, onDelete, className, ...props }, ref) => {
|
|
12683
|
+
const typeLabel = getTypeLabel(bot, typeLabels);
|
|
12672
12684
|
const isChatbot = bot.type === "chatbot";
|
|
12673
12685
|
|
|
12686
|
+
const handleCardClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
12687
|
+
if (onEdit && !(e.target as HTMLElement).closest("[data-bot-card-action]")) {
|
|
12688
|
+
onEdit(bot.id);
|
|
12689
|
+
}
|
|
12690
|
+
};
|
|
12691
|
+
|
|
12692
|
+
const handleCardKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
|
12693
|
+
if (onEdit && !(e.target as HTMLElement).closest("[data-bot-card-action]")) {
|
|
12694
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
12695
|
+
e.preventDefault();
|
|
12696
|
+
onEdit(bot.id);
|
|
12697
|
+
}
|
|
12698
|
+
}
|
|
12699
|
+
};
|
|
12700
|
+
|
|
12674
12701
|
return (
|
|
12675
12702
|
<div
|
|
12676
12703
|
ref={ref}
|
|
12704
|
+
role={onEdit ? "button" : undefined}
|
|
12705
|
+
tabIndex={onEdit ? 0 : undefined}
|
|
12706
|
+
aria-label={onEdit ? \`Edit \${bot.name}\` : undefined}
|
|
12707
|
+
onClick={onEdit ? handleCardClick : undefined}
|
|
12708
|
+
onKeyDown={onEdit ? handleCardKeyDown : undefined}
|
|
12677
12709
|
className={cn(
|
|
12678
|
-
"relative bg-semantic-bg-primary border border-semantic-border-layout rounded-[5px]",
|
|
12679
|
-
"shadow-[0px_4px_15.1px_0px_rgba(0,0,0,0.06)] p-
|
|
12710
|
+
"relative bg-semantic-bg-primary border border-semantic-border-layout rounded-[5px] min-w-0 max-w-full overflow-hidden flex flex-col",
|
|
12711
|
+
"shadow-[0px_4px_15.1px_0px_rgba(0,0,0,0.06)] p-3 sm:p-4 md:p-5",
|
|
12712
|
+
onEdit && "cursor-pointer",
|
|
12680
12713
|
className
|
|
12681
12714
|
)}
|
|
12715
|
+
{...props}
|
|
12682
12716
|
>
|
|
12683
12717
|
{/* Top row: icon + badge + menu */}
|
|
12684
|
-
<div className="flex items-start justify-between mb-4">
|
|
12685
|
-
<div className="flex items-center justify-center size-[38px] rounded-full bg-semantic-info-surface shrink-0">
|
|
12718
|
+
<div className="flex items-start justify-between gap-2 mb-3 sm:mb-4 min-w-0">
|
|
12719
|
+
<div className="flex items-center justify-center size-8 sm:size-[38px] rounded-full bg-semantic-info-surface shrink-0">
|
|
12686
12720
|
{isChatbot ? (
|
|
12687
|
-
<MessageSquare className="size-5 text-semantic-text-secondary" />
|
|
12721
|
+
<MessageSquare className="size-4 sm:size-5 text-semantic-text-secondary" />
|
|
12688
12722
|
) : (
|
|
12689
|
-
<Phone className="size-5 text-semantic-text-secondary" />
|
|
12723
|
+
<Phone className="size-4 sm:size-5 text-semantic-text-secondary" />
|
|
12690
12724
|
)}
|
|
12691
12725
|
</div>
|
|
12692
|
-
<div className="flex items-center gap-2">
|
|
12693
|
-
<Badge variant="outline" className="text-xs font-normal">
|
|
12694
|
-
{
|
|
12726
|
+
<div className="flex items-center gap-1.5 sm:gap-2 min-w-0 shrink-0">
|
|
12727
|
+
<Badge variant="outline" className="text-xs font-normal shrink-0">
|
|
12728
|
+
{typeLabel}
|
|
12695
12729
|
</Badge>
|
|
12696
12730
|
|
|
12697
|
-
|
|
12698
|
-
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
>
|
|
12705
|
-
<MoreVertical className="size-4" />
|
|
12706
|
-
</button>
|
|
12707
|
-
</DropdownMenuTrigger>
|
|
12708
|
-
<DropdownMenuContent align="end" className="min-w-[160px]">
|
|
12709
|
-
<DropdownMenuItem
|
|
12710
|
-
className="flex items-center gap-3 px-4 py-3 text-sm cursor-pointer"
|
|
12711
|
-
onClick={() => onEdit?.(bot.id)}
|
|
12712
|
-
>
|
|
12713
|
-
<Pencil className="size-4 text-semantic-text-muted shrink-0" />
|
|
12714
|
-
<span>Edit</span>
|
|
12715
|
-
</DropdownMenuItem>
|
|
12716
|
-
<DropdownMenuItem
|
|
12717
|
-
className="flex items-center gap-3 px-4 py-3 text-sm cursor-pointer"
|
|
12718
|
-
onClick={() => onPublish?.(bot.id)}
|
|
12719
|
-
>
|
|
12720
|
-
<Play className="size-4 text-semantic-text-muted shrink-0" />
|
|
12721
|
-
<span>Publish</span>
|
|
12722
|
-
</DropdownMenuItem>
|
|
12723
|
-
<DropdownMenuSeparator />
|
|
12724
|
-
<DropdownMenuItem
|
|
12725
|
-
className="flex items-center gap-3 px-4 py-3 text-sm cursor-pointer text-semantic-error-primary focus:text-semantic-error-primary focus:bg-semantic-error-surface"
|
|
12726
|
-
onClick={() => onDelete?.(bot.id)}
|
|
12727
|
-
>
|
|
12728
|
-
<Trash2 className="size-4 shrink-0" />
|
|
12729
|
-
<span>Delete</span>
|
|
12730
|
-
</DropdownMenuItem>
|
|
12731
|
-
</DropdownMenuContent>
|
|
12732
|
-
</DropdownMenu>
|
|
12731
|
+
<span data-bot-card-action className="inline-flex" onClick={(e) => e.stopPropagation()}>
|
|
12732
|
+
<BotListAction
|
|
12733
|
+
align="end"
|
|
12734
|
+
onEdit={() => onEdit?.(bot.id)}
|
|
12735
|
+
onDelete={() => onDelete?.(bot.id)}
|
|
12736
|
+
/>
|
|
12737
|
+
</span>
|
|
12733
12738
|
</div>
|
|
12734
12739
|
</div>
|
|
12735
12740
|
|
|
12736
12741
|
{/* Bot name */}
|
|
12737
|
-
<h3 className="m-0 text-base font-normal text-semantic-text-primary truncate mb-1">
|
|
12742
|
+
<h3 className="m-0 text-sm sm:text-base font-normal text-semantic-text-primary truncate mb-1 min-w-0">
|
|
12738
12743
|
{bot.name}
|
|
12739
12744
|
</h3>
|
|
12740
12745
|
|
|
12741
12746
|
{/* Conversations count */}
|
|
12742
|
-
<p className="m-0 text-sm text-semantic-text-muted mb-4">
|
|
12747
|
+
<p className="m-0 text-xs sm:text-sm text-semantic-text-muted mb-3 sm:mb-4">
|
|
12743
12748
|
{bot.conversationCount.toLocaleString()} Conversations
|
|
12744
12749
|
</p>
|
|
12745
12750
|
|
|
12746
12751
|
{/* Divider */}
|
|
12747
|
-
<div className="border-t border-semantic-border-layout mb-3 mt-auto" />
|
|
12752
|
+
<div className="border-t border-semantic-border-layout mb-2 sm:mb-3 mt-auto" />
|
|
12748
12753
|
|
|
12749
12754
|
{/* Last published */}
|
|
12750
|
-
<div className="flex flex-col gap-1">
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12755
|
+
<div className="flex flex-col gap-0.5 sm:gap-1 min-w-0">
|
|
12756
|
+
{bot.status === "draft" ? (
|
|
12757
|
+
<p className="m-0 text-xs font-normal text-semantic-text-secondary uppercase tracking-[0.048px] flex items-center justify-start gap-5">
|
|
12758
|
+
Last Published
|
|
12759
|
+
<span className="text-xs font-normal text-semantic-error-primary flex items-center gap-1.5 shrink-0">
|
|
12760
|
+
<span className="size-1.5 rounded-full bg-semantic-error-primary shrink-0" aria-hidden />
|
|
12761
|
+
Unpublished changes
|
|
12762
|
+
</span>
|
|
12757
12763
|
</p>
|
|
12758
12764
|
) : (
|
|
12759
|
-
<
|
|
12765
|
+
<span className="text-xs font-normal text-semantic-text-secondary uppercase tracking-[0.048px]">
|
|
12766
|
+
Last Published
|
|
12767
|
+
</span>
|
|
12760
12768
|
)}
|
|
12769
|
+
{bot.lastPublishedBy && bot.lastPublishedDate ? (
|
|
12770
|
+
<p className="m-0 text-xs sm:text-sm text-semantic-text-muted truncate">
|
|
12771
|
+
{bot.lastPublishedBy} | {bot.lastPublishedDate}
|
|
12772
|
+
</p>
|
|
12773
|
+
) : bot.status !== "draft" ? (
|
|
12774
|
+
<p className="m-0 text-xs sm:text-sm text-semantic-text-muted">\u2014</p>
|
|
12775
|
+
) : null}
|
|
12761
12776
|
</div>
|
|
12762
12777
|
</div>
|
|
12763
12778
|
);
|
|
@@ -12779,7 +12794,7 @@ import {
|
|
|
12779
12794
|
DialogTitle,
|
|
12780
12795
|
} from "../dialog";
|
|
12781
12796
|
import { Button } from "../button";
|
|
12782
|
-
import type
|
|
12797
|
+
import { BOT_TYPE, type CreateBotModalProps, type BotType } from "./types";
|
|
12783
12798
|
|
|
12784
12799
|
interface BotTypeOption {
|
|
12785
12800
|
id: BotType;
|
|
@@ -12809,7 +12824,8 @@ export const CreateBotModal = React.forwardRef<
|
|
|
12809
12824
|
|
|
12810
12825
|
const handleSubmit = () => {
|
|
12811
12826
|
if (!name.trim()) return;
|
|
12812
|
-
|
|
12827
|
+
const typeValue = selectedType === "chatbot" ? BOT_TYPE.CHAT : BOT_TYPE.VOICE;
|
|
12828
|
+
onSubmit?.({ name: name.trim(), type: typeValue });
|
|
12813
12829
|
setName("");
|
|
12814
12830
|
setSelectedType("chatbot");
|
|
12815
12831
|
};
|
|
@@ -12822,12 +12838,12 @@ export const CreateBotModal = React.forwardRef<
|
|
|
12822
12838
|
|
|
12823
12839
|
return (
|
|
12824
12840
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
12825
|
-
<DialogContent ref={ref} size="sm" className={cn("mx-
|
|
12841
|
+
<DialogContent ref={ref} size="sm" className={cn("mx-3 max-h-[90vh] overflow-y-auto w-[calc(100%-1.5rem)] sm:mx-auto sm:w-full", className)}>
|
|
12826
12842
|
<DialogHeader>
|
|
12827
12843
|
<DialogTitle>Create AI bot</DialogTitle>
|
|
12828
12844
|
</DialogHeader>
|
|
12829
12845
|
|
|
12830
|
-
<div className="flex flex-col gap-6">
|
|
12846
|
+
<div className="flex flex-col gap-4 sm:gap-6">
|
|
12831
12847
|
{/* Name field */}
|
|
12832
12848
|
<div className="flex flex-col gap-1.5">
|
|
12833
12849
|
<label
|
|
@@ -12858,7 +12874,7 @@ export const CreateBotModal = React.forwardRef<
|
|
|
12858
12874
|
<span className="text-sm font-semibold text-semantic-text-secondary tracking-[0.014px]">
|
|
12859
12875
|
Select Bot Type
|
|
12860
12876
|
</span>
|
|
12861
|
-
<div className="flex gap-3">
|
|
12877
|
+
<div className="flex flex-col gap-3 sm:flex-row sm:gap-3">
|
|
12862
12878
|
{BOT_TYPE_OPTIONS.map(({ id, label, description }) => {
|
|
12863
12879
|
const isSelected = selectedType === id;
|
|
12864
12880
|
return (
|
|
@@ -12867,7 +12883,7 @@ export const CreateBotModal = React.forwardRef<
|
|
|
12867
12883
|
type="button"
|
|
12868
12884
|
onClick={() => setSelectedType(id)}
|
|
12869
12885
|
className={cn(
|
|
12870
|
-
"flex flex-col items-start gap-2.5 p-3 rounded-lg border text-left flex-1 h-[134px] justify-center",
|
|
12886
|
+
"flex flex-col items-start gap-2 sm:gap-2.5 p-3 rounded-lg border text-left flex-1 min-h-[100px] sm:h-[134px] justify-center min-w-0",
|
|
12871
12887
|
"transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-border-focus",
|
|
12872
12888
|
isSelected
|
|
12873
12889
|
? "bg-semantic-brand-surface border-semantic-brand shadow-sm"
|
|
@@ -12913,7 +12929,7 @@ export const CreateBotModal = React.forwardRef<
|
|
|
12913
12929
|
</div>
|
|
12914
12930
|
|
|
12915
12931
|
{/* Footer actions */}
|
|
12916
|
-
<div className="flex gap-4 justify-end mt-2">
|
|
12932
|
+
<div className="flex flex-col-reverse gap-3 sm:flex-row sm:gap-4 justify-end mt-2">
|
|
12917
12933
|
<Button variant="outline" onClick={handleClose}>
|
|
12918
12934
|
Cancel
|
|
12919
12935
|
</Button>
|
|
@@ -12936,9 +12952,12 @@ CreateBotModal.displayName = "CreateBotModal";
|
|
|
12936
12952
|
{
|
|
12937
12953
|
name: "bot-list.tsx",
|
|
12938
12954
|
content: prefixTailwindClasses(`import * as React from "react";
|
|
12939
|
-
import { Plus, Search } from "lucide-react";
|
|
12940
12955
|
import { cn } from "../../../lib/utils";
|
|
12941
12956
|
import { BotCard } from "./bot-card";
|
|
12957
|
+
import { BotListHeader } from "./bot-list-header";
|
|
12958
|
+
import { BotListSearch } from "./bot-list-search";
|
|
12959
|
+
import { BotListCreateCard } from "./bot-list-create-card";
|
|
12960
|
+
import { BotListGrid } from "./bot-list-grid";
|
|
12942
12961
|
import { CreateBotModal } from "./create-bot-modal";
|
|
12943
12962
|
import type { BotListProps } from "./types";
|
|
12944
12963
|
|
|
@@ -12946,6 +12965,7 @@ export const BotList = React.forwardRef<HTMLDivElement, BotListProps>(
|
|
|
12946
12965
|
(
|
|
12947
12966
|
{
|
|
12948
12967
|
bots = [],
|
|
12968
|
+
typeLabels,
|
|
12949
12969
|
onCreateBot,
|
|
12950
12970
|
onCreateBotSubmit,
|
|
12951
12971
|
onBotEdit,
|
|
@@ -12954,7 +12974,10 @@ export const BotList = React.forwardRef<HTMLDivElement, BotListProps>(
|
|
|
12954
12974
|
onSearch,
|
|
12955
12975
|
title = "AI Bot",
|
|
12956
12976
|
subtitle = "Create & manage AI bots",
|
|
12977
|
+
searchPlaceholder = "Search bot...",
|
|
12978
|
+
createCardLabel = "Create new bot",
|
|
12957
12979
|
className,
|
|
12980
|
+
...props
|
|
12958
12981
|
},
|
|
12959
12982
|
ref
|
|
12960
12983
|
) => {
|
|
@@ -12967,64 +12990,41 @@ export const BotList = React.forwardRef<HTMLDivElement, BotListProps>(
|
|
|
12967
12990
|
};
|
|
12968
12991
|
|
|
12969
12992
|
return (
|
|
12970
|
-
<div
|
|
12971
|
-
{
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
12976
|
-
|
|
12977
|
-
|
|
12978
|
-
|
|
12979
|
-
|
|
12980
|
-
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
<div className="flex items-center gap-2 h-10 px-2.5 border border-semantic-border-input rounded bg-semantic-bg-primary hover:border-semantic-border-input-focus focus-within:border-semantic-border-input-focus focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)] w-full sm:w-auto">
|
|
12984
|
-
<Search className="size-[14px] text-semantic-text-muted shrink-0" />
|
|
12985
|
-
<input
|
|
12986
|
-
type="text"
|
|
12987
|
-
value={searchQuery}
|
|
12988
|
-
onChange={(e) => handleSearch(e.target.value)}
|
|
12989
|
-
placeholder="Search bot..."
|
|
12990
|
-
className="text-sm text-semantic-text-primary placeholder:text-semantic-text-muted bg-transparent outline-none w-full sm:w-[180px]"
|
|
12991
|
-
/>
|
|
12992
|
-
</div>
|
|
12993
|
+
<div
|
|
12994
|
+
ref={ref}
|
|
12995
|
+
className={cn("flex flex-col w-full min-w-0 max-w-full overflow-x-hidden box-border", className)}
|
|
12996
|
+
{...props}
|
|
12997
|
+
>
|
|
12998
|
+
{/* Page header: title, subtitle, and search */}
|
|
12999
|
+
<div className="flex flex-col gap-3 pb-4 mb-4 border-b border-semantic-border-layout sm:flex-row sm:items-center sm:justify-between sm:gap-4 sm:pb-5 sm:mb-6 min-w-0">
|
|
13000
|
+
<BotListHeader title={title} subtitle={subtitle} />
|
|
13001
|
+
<BotListSearch
|
|
13002
|
+
value={searchQuery}
|
|
13003
|
+
onSearch={handleSearch}
|
|
13004
|
+
placeholder={searchPlaceholder}
|
|
13005
|
+
/>
|
|
12993
13006
|
</div>
|
|
12994
13007
|
|
|
12995
|
-
{/* Bot grid */}
|
|
12996
|
-
<
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
type="button"
|
|
13008
|
+
{/* Bot grid: create card + bot cards */}
|
|
13009
|
+
<BotListGrid>
|
|
13010
|
+
<BotListCreateCard
|
|
13011
|
+
label={createCardLabel}
|
|
13000
13012
|
onClick={() => {
|
|
13001
13013
|
setCreateModalOpen(true);
|
|
13002
13014
|
onCreateBot?.();
|
|
13003
13015
|
}}
|
|
13004
|
-
|
|
13005
|
-
"flex flex-col items-center justify-center gap-3 p-2.5 rounded-[5px]",
|
|
13006
|
-
"bg-semantic-info-surface-subtle border border-dashed border-[var(--color-primary-100)]",
|
|
13007
|
-
"cursor-pointer hover:bg-semantic-bg-hover transition-colors min-h-[207px]",
|
|
13008
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-border-focus"
|
|
13009
|
-
)}
|
|
13010
|
-
>
|
|
13011
|
-
<Plus className="size-4 text-semantic-text-secondary" />
|
|
13012
|
-
<span className="text-sm font-semibold text-semantic-text-secondary tracking-[0.014px]">
|
|
13013
|
-
Create new bot
|
|
13014
|
-
</span>
|
|
13015
|
-
</button>
|
|
13016
|
-
|
|
13017
|
-
{/* Bot cards */}
|
|
13016
|
+
/>
|
|
13018
13017
|
{bots.map((bot) => (
|
|
13019
13018
|
<BotCard
|
|
13020
13019
|
key={bot.id}
|
|
13021
13020
|
bot={bot}
|
|
13021
|
+
typeLabels={typeLabels}
|
|
13022
13022
|
onEdit={onBotEdit}
|
|
13023
13023
|
onPublish={onBotPublish}
|
|
13024
13024
|
onDelete={onBotDelete}
|
|
13025
13025
|
/>
|
|
13026
13026
|
))}
|
|
13027
|
-
</
|
|
13027
|
+
</BotListGrid>
|
|
13028
13028
|
|
|
13029
13029
|
<CreateBotModal
|
|
13030
13030
|
open={createModalOpen}
|
|
@@ -13040,52 +13040,365 @@ export const BotList = React.forwardRef<HTMLDivElement, BotListProps>(
|
|
|
13040
13040
|
);
|
|
13041
13041
|
|
|
13042
13042
|
BotList.displayName = "BotList";
|
|
13043
|
+
`, prefix)
|
|
13044
|
+
},
|
|
13045
|
+
{
|
|
13046
|
+
name: "bot-list-header.tsx",
|
|
13047
|
+
content: prefixTailwindClasses(`import * as React from "react";
|
|
13048
|
+
import { cn } from "../../../lib/utils";
|
|
13049
|
+
import type { BotListHeaderProps } from "./types";
|
|
13050
|
+
|
|
13051
|
+
export const BotListHeader = React.forwardRef<HTMLDivElement, BotListHeaderProps>(
|
|
13052
|
+
({ title, subtitle, className, ...props }, ref) => (
|
|
13053
|
+
<div
|
|
13054
|
+
ref={ref}
|
|
13055
|
+
className={cn("flex flex-col gap-1.5 min-w-0 shrink", className)}
|
|
13056
|
+
{...props}
|
|
13057
|
+
>
|
|
13058
|
+
{title != null && (
|
|
13059
|
+
<h1 className="m-0 text-base font-semibold text-semantic-text-primary tracking-[0.064px] break-words sm:text-lg">
|
|
13060
|
+
{title}
|
|
13061
|
+
</h1>
|
|
13062
|
+
)}
|
|
13063
|
+
{subtitle != null && (
|
|
13064
|
+
<p className="m-0 text-xs sm:text-sm text-semantic-text-muted tracking-[0.035px] break-words">
|
|
13065
|
+
{subtitle}
|
|
13066
|
+
</p>
|
|
13067
|
+
)}
|
|
13068
|
+
</div>
|
|
13069
|
+
)
|
|
13070
|
+
);
|
|
13071
|
+
|
|
13072
|
+
BotListHeader.displayName = "BotListHeader";
|
|
13073
|
+
`, prefix)
|
|
13074
|
+
},
|
|
13075
|
+
{
|
|
13076
|
+
name: "bot-list-search.tsx",
|
|
13077
|
+
content: prefixTailwindClasses(`import * as React from "react";
|
|
13078
|
+
import { Search } from "lucide-react";
|
|
13079
|
+
import { cn } from "../../../lib/utils";
|
|
13080
|
+
import type { BotListSearchProps } from "./types";
|
|
13081
|
+
|
|
13082
|
+
export const BotListSearch = React.forwardRef<HTMLDivElement, BotListSearchProps>(
|
|
13083
|
+
(
|
|
13084
|
+
{
|
|
13085
|
+
value,
|
|
13086
|
+
placeholder = "Search bot...",
|
|
13087
|
+
onSearch,
|
|
13088
|
+
defaultValue,
|
|
13089
|
+
className,
|
|
13090
|
+
...props
|
|
13091
|
+
},
|
|
13092
|
+
ref
|
|
13093
|
+
) => {
|
|
13094
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue ?? "");
|
|
13095
|
+
const isControlled = value !== undefined;
|
|
13096
|
+
const displayValue = isControlled ? value : internalValue;
|
|
13097
|
+
|
|
13098
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
13099
|
+
const next = e.target.value;
|
|
13100
|
+
if (!isControlled) setInternalValue(next);
|
|
13101
|
+
onSearch?.(next);
|
|
13102
|
+
};
|
|
13103
|
+
|
|
13104
|
+
return (
|
|
13105
|
+
<div
|
|
13106
|
+
ref={ref}
|
|
13107
|
+
className={cn(
|
|
13108
|
+
"flex items-center gap-2 h-9 sm:h-10 px-2.5 sm:px-3 border border-semantic-border-input rounded bg-semantic-bg-primary min-w-0 shrink-0",
|
|
13109
|
+
"hover:border-semantic-border-input-focus focus-within:border-semantic-border-input-focus",
|
|
13110
|
+
"focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)] w-full max-w-full sm:max-w-[180px] md:max-w-[220px] sm:shrink-0",
|
|
13111
|
+
className
|
|
13112
|
+
)}
|
|
13113
|
+
{...props}
|
|
13114
|
+
>
|
|
13115
|
+
<Search className="size-[14px] text-semantic-text-muted shrink-0" />
|
|
13116
|
+
<input
|
|
13117
|
+
type="text"
|
|
13118
|
+
value={displayValue}
|
|
13119
|
+
onChange={handleChange}
|
|
13120
|
+
placeholder={placeholder}
|
|
13121
|
+
className="text-sm text-semantic-text-primary placeholder:text-semantic-text-muted bg-transparent outline-none w-full min-w-0"
|
|
13122
|
+
aria-label={placeholder}
|
|
13123
|
+
/>
|
|
13124
|
+
</div>
|
|
13125
|
+
);
|
|
13126
|
+
}
|
|
13127
|
+
);
|
|
13128
|
+
|
|
13129
|
+
BotListSearch.displayName = "BotListSearch";
|
|
13130
|
+
`, prefix)
|
|
13131
|
+
},
|
|
13132
|
+
{
|
|
13133
|
+
name: "bot-list-create-card.tsx",
|
|
13134
|
+
content: prefixTailwindClasses(`import * as React from "react";
|
|
13135
|
+
import { Plus } from "lucide-react";
|
|
13136
|
+
import { cn } from "../../../lib/utils";
|
|
13137
|
+
import type { BotListCreateCardProps } from "./types";
|
|
13138
|
+
|
|
13139
|
+
export const BotListCreateCard = React.forwardRef<
|
|
13140
|
+
HTMLButtonElement,
|
|
13141
|
+
BotListCreateCardProps
|
|
13142
|
+
>(
|
|
13143
|
+
(
|
|
13144
|
+
{
|
|
13145
|
+
label = "Create new bot",
|
|
13146
|
+
onClick,
|
|
13147
|
+
className,
|
|
13148
|
+
...props
|
|
13149
|
+
},
|
|
13150
|
+
ref
|
|
13151
|
+
) => (
|
|
13152
|
+
<button
|
|
13153
|
+
ref={ref}
|
|
13154
|
+
type="button"
|
|
13155
|
+
onClick={onClick}
|
|
13156
|
+
className={cn(
|
|
13157
|
+
"flex flex-col items-center justify-center gap-2 sm:gap-3 p-3 sm:p-2.5 rounded-[5px] min-h-[180px] sm:min-h-[207px] w-full min-w-0 max-w-full",
|
|
13158
|
+
"bg-semantic-info-surface-subtle border border-dashed border-semantic-border-layout",
|
|
13159
|
+
"cursor-pointer transition-colors hover:bg-semantic-bg-hover hover:border-semantic-border-input",
|
|
13160
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-border-focus",
|
|
13161
|
+
"self-stretch justify-self-stretch",
|
|
13162
|
+
className
|
|
13163
|
+
)}
|
|
13164
|
+
aria-label={label}
|
|
13165
|
+
{...props}
|
|
13166
|
+
>
|
|
13167
|
+
<Plus className="size-4 text-semantic-text-secondary shrink-0" />
|
|
13168
|
+
<span className="text-sm font-semibold leading-5 text-semantic-text-secondary text-center tracking-[0.014px]">
|
|
13169
|
+
{label}
|
|
13170
|
+
</span>
|
|
13171
|
+
</button>
|
|
13172
|
+
)
|
|
13173
|
+
);
|
|
13174
|
+
|
|
13175
|
+
BotListCreateCard.displayName = "BotListCreateCard";
|
|
13176
|
+
`, prefix)
|
|
13177
|
+
},
|
|
13178
|
+
{
|
|
13179
|
+
name: "bot-list-grid.tsx",
|
|
13180
|
+
content: prefixTailwindClasses(`import * as React from "react";
|
|
13181
|
+
import { cn } from "../../../lib/utils";
|
|
13182
|
+
import type { BotListGridProps } from "./types";
|
|
13183
|
+
|
|
13184
|
+
export const BotListGrid = React.forwardRef<HTMLDivElement, BotListGridProps>(
|
|
13185
|
+
({ children, className, ...props }, ref) => (
|
|
13186
|
+
<div
|
|
13187
|
+
ref={ref}
|
|
13188
|
+
className={cn(
|
|
13189
|
+
"grid w-full min-w-0 max-w-full overflow-hidden gap-3 sm:gap-5 md:gap-6",
|
|
13190
|
+
"grid-cols-[repeat(auto-fill,minmax(min(100%,280px),1fr))]",
|
|
13191
|
+
className
|
|
13192
|
+
)}
|
|
13193
|
+
{...props}
|
|
13194
|
+
>
|
|
13195
|
+
{children}
|
|
13196
|
+
</div>
|
|
13197
|
+
)
|
|
13198
|
+
);
|
|
13199
|
+
|
|
13200
|
+
BotListGrid.displayName = "BotListGrid";
|
|
13201
|
+
`, prefix)
|
|
13202
|
+
},
|
|
13203
|
+
{
|
|
13204
|
+
name: "bot-list-action.tsx",
|
|
13205
|
+
content: prefixTailwindClasses(`import * as React from "react";
|
|
13206
|
+
import { MoreVertical, Pencil, Trash2 } from "lucide-react";
|
|
13207
|
+
import { cn } from "../../../lib/utils";
|
|
13208
|
+
import {
|
|
13209
|
+
DropdownMenu,
|
|
13210
|
+
DropdownMenuTrigger,
|
|
13211
|
+
DropdownMenuContent,
|
|
13212
|
+
DropdownMenuItem,
|
|
13213
|
+
DropdownMenuSeparator,
|
|
13214
|
+
} from "../dropdown-menu";
|
|
13215
|
+
import type { BotListActionProps } from "./types";
|
|
13216
|
+
|
|
13217
|
+
const defaultTrigger = (
|
|
13218
|
+
<button
|
|
13219
|
+
type="button"
|
|
13220
|
+
className="p-2 min-h-[44px] min-w-[44px] sm:p-1 sm:min-h-0 sm:min-w-0 rounded hover:bg-semantic-bg-hover text-semantic-text-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-border-focus flex items-center justify-center touch-manipulation"
|
|
13221
|
+
aria-label="More options"
|
|
13222
|
+
>
|
|
13223
|
+
<MoreVertical className="size-4 shrink-0" />
|
|
13224
|
+
</button>
|
|
13225
|
+
);
|
|
13226
|
+
|
|
13227
|
+
export const BotListAction = React.forwardRef<HTMLDivElement, BotListActionProps>(
|
|
13228
|
+
(
|
|
13229
|
+
{
|
|
13230
|
+
onEdit,
|
|
13231
|
+
onDelete,
|
|
13232
|
+
trigger = defaultTrigger,
|
|
13233
|
+
align = "end",
|
|
13234
|
+
className,
|
|
13235
|
+
...props
|
|
13236
|
+
},
|
|
13237
|
+
ref
|
|
13238
|
+
) => {
|
|
13239
|
+
return (
|
|
13240
|
+
<div ref={ref} className={cn("inline-flex", className)} {...props}>
|
|
13241
|
+
<DropdownMenu>
|
|
13242
|
+
<DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
|
|
13243
|
+
<DropdownMenuContent
|
|
13244
|
+
align={align}
|
|
13245
|
+
className="min-w-[160px] max-w-[min(100vw-2rem,320px)] max-h-[min(70vh,400px)] overflow-y-auto rounded-lg border border-semantic-border-layout bg-semantic-bg-ui p-1 shadow-lg"
|
|
13246
|
+
>
|
|
13247
|
+
<DropdownMenuItem
|
|
13248
|
+
className="flex cursor-pointer items-center gap-2 px-3 py-2.5 text-sm text-semantic-text-primary outline-none transition-colors focus:bg-semantic-bg-hover focus:text-semantic-text-primary"
|
|
13249
|
+
onSelect={(e) => {
|
|
13250
|
+
e.preventDefault();
|
|
13251
|
+
onEdit?.();
|
|
13252
|
+
}}
|
|
13253
|
+
>
|
|
13254
|
+
<Pencil className="size-4 shrink-0 text-semantic-text-primary" />
|
|
13255
|
+
<span>Edit</span>
|
|
13256
|
+
</DropdownMenuItem>
|
|
13257
|
+
<DropdownMenuSeparator className="my-1 bg-semantic-border-layout" />
|
|
13258
|
+
<DropdownMenuItem
|
|
13259
|
+
className="flex cursor-pointer items-center gap-2 px-3 py-2.5 text-sm text-semantic-error-primary outline-none transition-colors focus:bg-semantic-error-surface focus:text-semantic-error-primary"
|
|
13260
|
+
onSelect={(e) => {
|
|
13261
|
+
e.preventDefault();
|
|
13262
|
+
onDelete?.();
|
|
13263
|
+
}}
|
|
13264
|
+
>
|
|
13265
|
+
<Trash2 className="size-4 shrink-0 text-semantic-error-primary" />
|
|
13266
|
+
<span>Delete</span>
|
|
13267
|
+
</DropdownMenuItem>
|
|
13268
|
+
</DropdownMenuContent>
|
|
13269
|
+
</DropdownMenu>
|
|
13270
|
+
</div>
|
|
13271
|
+
);
|
|
13272
|
+
}
|
|
13273
|
+
);
|
|
13274
|
+
|
|
13275
|
+
BotListAction.displayName = "BotListAction";
|
|
13043
13276
|
`, prefix)
|
|
13044
13277
|
},
|
|
13045
13278
|
{
|
|
13046
13279
|
name: "types.ts",
|
|
13047
|
-
content: prefixTailwindClasses(`
|
|
13280
|
+
content: prefixTailwindClasses(`import type * as React from "react";
|
|
13281
|
+
|
|
13282
|
+
export const BOT_TYPE = {
|
|
13283
|
+
CHAT: 1,
|
|
13284
|
+
VOICE: 2,
|
|
13285
|
+
} as const;
|
|
13286
|
+
|
|
13287
|
+
export type BOT_TYPE = (typeof BOT_TYPE)[keyof typeof BOT_TYPE];
|
|
13288
|
+
|
|
13289
|
+
export type BotType = "chatbot" | "voicebot";
|
|
13290
|
+
|
|
13291
|
+
export type BotStatus = "draft" | "published";
|
|
13048
13292
|
|
|
13293
|
+
/**
|
|
13294
|
+
* Single bot shape for both Chatbot and Voicebot.
|
|
13295
|
+
* Use the same BotCard for both; set type to "chatbot" or "voicebot" and pass all data via this prop.
|
|
13296
|
+
*/
|
|
13049
13297
|
export interface Bot {
|
|
13050
13298
|
id: string;
|
|
13051
13299
|
name: string;
|
|
13300
|
+
/** "chatbot" | "voicebot" \u2014 determines icon and default badge label; all other data is from this object */
|
|
13052
13301
|
type: BotType;
|
|
13053
13302
|
conversationCount: number;
|
|
13054
13303
|
lastPublishedBy?: string;
|
|
13055
13304
|
lastPublishedDate?: string;
|
|
13305
|
+
/** Optional custom label for the type badge (overrides typeLabels and default "Chatbot"/"Voicebot") */
|
|
13306
|
+
typeLabel?: string;
|
|
13307
|
+
/** When "draft", card shows "Unpublished changes" with red indicator in the Last Published section */
|
|
13308
|
+
status?: BotStatus;
|
|
13056
13309
|
}
|
|
13057
13310
|
|
|
13058
|
-
export interface BotCardProps
|
|
13311
|
+
export interface BotCardProps
|
|
13312
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "title" | "children"> {
|
|
13313
|
+
/** Single bot object: pass chatbot or voicebot data here; card renders based on bot.type and bot fields */
|
|
13059
13314
|
bot: Bot;
|
|
13315
|
+
/** Override labels for bot types (e.g. { chatbot: "Chat", voicebot: "Voice" }). Ignored if bot.typeLabel is set. */
|
|
13316
|
+
typeLabels?: Partial<Record<BotType, string>>;
|
|
13060
13317
|
/** Called when Edit action is selected */
|
|
13061
13318
|
onEdit?: (botId: string) => void;
|
|
13062
13319
|
/** Called when Publish action is selected */
|
|
13063
13320
|
onPublish?: (botId: string) => void;
|
|
13064
13321
|
/** Called when Delete action is selected */
|
|
13065
13322
|
onDelete?: (botId: string) => void;
|
|
13066
|
-
className?: string;
|
|
13067
13323
|
}
|
|
13068
13324
|
|
|
13069
13325
|
export interface CreateBotModalProps {
|
|
13070
13326
|
open: boolean;
|
|
13071
13327
|
onOpenChange: (open: boolean) => void;
|
|
13072
|
-
|
|
13328
|
+
/** Called with name and BOT_TYPE (CHAT = 1, VOICE = 2) when user submits */
|
|
13329
|
+
onSubmit?: (data: { name: string; type: BOT_TYPE }) => void;
|
|
13073
13330
|
className?: string;
|
|
13074
13331
|
}
|
|
13075
13332
|
|
|
13076
|
-
export interface
|
|
13333
|
+
export interface BotListHeaderProps
|
|
13334
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
13335
|
+
/** Page title */
|
|
13336
|
+
title?: string;
|
|
13337
|
+
/** Optional subtitle below the title */
|
|
13338
|
+
subtitle?: string;
|
|
13339
|
+
}
|
|
13340
|
+
|
|
13341
|
+
export interface BotListSearchProps
|
|
13342
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
13343
|
+
/** Controlled value (use with onSearch) */
|
|
13344
|
+
value?: string;
|
|
13345
|
+
/** Placeholder text */
|
|
13346
|
+
placeholder?: string;
|
|
13347
|
+
/** Called when the search value changes */
|
|
13348
|
+
onSearch?: (query: string) => void;
|
|
13349
|
+
/** Uncontrolled: default value */
|
|
13350
|
+
defaultValue?: string;
|
|
13351
|
+
}
|
|
13352
|
+
|
|
13353
|
+
export interface BotListCreateCardProps
|
|
13354
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
13355
|
+
/** Label for the create card (e.g. "Create new bot") */
|
|
13356
|
+
label?: string;
|
|
13357
|
+
}
|
|
13358
|
+
|
|
13359
|
+
export interface BotListGridProps
|
|
13360
|
+
extends React.HTMLAttributes<HTMLDivElement> {
|
|
13361
|
+
children: React.ReactNode;
|
|
13362
|
+
}
|
|
13363
|
+
|
|
13364
|
+
export interface BotListActionProps
|
|
13365
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
13366
|
+
/** Called when Edit is selected */
|
|
13367
|
+
onEdit?: () => void;
|
|
13368
|
+
/** Called when Delete is selected */
|
|
13369
|
+
onDelete?: () => void;
|
|
13370
|
+
/** Custom trigger element; defaults to three-dot icon button */
|
|
13371
|
+
trigger?: React.ReactNode;
|
|
13372
|
+
/** Content alignment relative to trigger */
|
|
13373
|
+
align?: "start" | "center" | "end";
|
|
13374
|
+
}
|
|
13375
|
+
|
|
13376
|
+
export interface BotListProps
|
|
13377
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "title" | "children"> {
|
|
13378
|
+
/** List of bots to display */
|
|
13077
13379
|
bots?: Bot[];
|
|
13380
|
+
/** Override type badge labels for all cards (e.g. { chatbot: "Chat", voicebot: "Voice" }). Per-bot bot.typeLabel still wins. */
|
|
13381
|
+
typeLabels?: Partial<Record<BotType, string>>;
|
|
13078
13382
|
/** Called when the "Create new bot" card is clicked (modal opens) */
|
|
13079
13383
|
onCreateBot?: () => void;
|
|
13080
|
-
/** Called when the Create Bot modal is submitted with the new bot data */
|
|
13081
|
-
onCreateBotSubmit?: (data: { name: string; type:
|
|
13384
|
+
/** Called when the Create Bot modal is submitted with the new bot data (type is BOT_TYPE: CHAT = 1, VOICE = 2) */
|
|
13385
|
+
onCreateBotSubmit?: (data: { name: string; type: BOT_TYPE }) => void;
|
|
13386
|
+
/** Called when user selects Edit on a bot (card click or menu) */
|
|
13082
13387
|
onBotEdit?: (botId: string) => void;
|
|
13388
|
+
/** Called when user selects Publish on a bot (menu; optional) */
|
|
13083
13389
|
onBotPublish?: (botId: string) => void;
|
|
13390
|
+
/** Called when user selects Delete on a bot */
|
|
13084
13391
|
onBotDelete?: (botId: string) => void;
|
|
13392
|
+
/** Called when the search query changes */
|
|
13085
13393
|
onSearch?: (query: string) => void;
|
|
13394
|
+
/** Page title (default: "AI Bot") */
|
|
13086
13395
|
title?: string;
|
|
13396
|
+
/** Page subtitle (default: "Create & manage AI bots") */
|
|
13087
13397
|
subtitle?: string;
|
|
13088
|
-
|
|
13398
|
+
/** Placeholder for the search input (default: "Search bot...") */
|
|
13399
|
+
searchPlaceholder?: string;
|
|
13400
|
+
/** Label for the create-new-bot card (default: "Create new bot") */
|
|
13401
|
+
createCardLabel?: string;
|
|
13089
13402
|
}
|
|
13090
13403
|
`, prefix)
|
|
13091
13404
|
},
|
|
@@ -13098,7 +13411,23 @@ export { CreateBotModal } from "./create-bot-modal";
|
|
|
13098
13411
|
export type { CreateBotModalProps } from "./types";
|
|
13099
13412
|
|
|
13100
13413
|
export { BotList } from "./bot-list";
|
|
13101
|
-
export
|
|
13414
|
+
export { BotListHeader } from "./bot-list-header";
|
|
13415
|
+
export { BotListSearch } from "./bot-list-search";
|
|
13416
|
+
export { BotListCreateCard } from "./bot-list-create-card";
|
|
13417
|
+
export { BotListGrid } from "./bot-list-grid";
|
|
13418
|
+
export { BotListAction } from "./bot-list-action";
|
|
13419
|
+
export { BOT_TYPE } from "./types";
|
|
13420
|
+
export type {
|
|
13421
|
+
BotListProps,
|
|
13422
|
+
BotListHeaderProps,
|
|
13423
|
+
BotListSearchProps,
|
|
13424
|
+
BotListCreateCardProps,
|
|
13425
|
+
BotListGridProps,
|
|
13426
|
+
BotListActionProps,
|
|
13427
|
+
Bot,
|
|
13428
|
+
BotType,
|
|
13429
|
+
BotStatus,
|
|
13430
|
+
} from "./types";
|
|
13102
13431
|
`, prefix)
|
|
13103
13432
|
}
|
|
13104
13433
|
]
|