@tightknitai/block-kitchen 0.8.10 → 0.8.11
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/README.md +65 -1
- package/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +705 -320
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +706 -321
- package/dist/index.js.map +1 -1
- package/dist/{palette-DBTHRygt.d.cts → palette-Bup05opK.d.cts} +152 -4
- package/dist/{palette-DBTHRygt.d.ts → palette-Bup05opK.d.ts} +152 -4
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2724,6 +2724,91 @@ function JsonDrawer({
|
|
|
2724
2724
|
] })
|
|
2725
2725
|
] }) });
|
|
2726
2726
|
}
|
|
2727
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
2728
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2729
|
+
{
|
|
2730
|
+
variants: {
|
|
2731
|
+
variant: {
|
|
2732
|
+
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
2733
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
2734
|
+
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
2735
|
+
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
2736
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
2737
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
2738
|
+
},
|
|
2739
|
+
size: {
|
|
2740
|
+
default: "h-9 px-4 py-2",
|
|
2741
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
2742
|
+
lg: "h-10 rounded-md px-8",
|
|
2743
|
+
icon: "h-9 w-9"
|
|
2744
|
+
}
|
|
2745
|
+
},
|
|
2746
|
+
defaultVariants: {
|
|
2747
|
+
variant: "default",
|
|
2748
|
+
size: "default"
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
);
|
|
2752
|
+
var Button = React__namespace.forwardRef(
|
|
2753
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
2754
|
+
const Comp = asChild ? reactSlot.Slot : "button";
|
|
2755
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
2756
|
+
}
|
|
2757
|
+
);
|
|
2758
|
+
Button.displayName = "Button";
|
|
2759
|
+
var Dialog = DialogPrimitive__namespace.Root;
|
|
2760
|
+
var DialogPortal = DialogPrimitive__namespace.Portal;
|
|
2761
|
+
var DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2762
|
+
DialogPrimitive__namespace.Overlay,
|
|
2763
|
+
{
|
|
2764
|
+
ref,
|
|
2765
|
+
className: cn(
|
|
2766
|
+
"bk-portal-content fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
2767
|
+
className
|
|
2768
|
+
),
|
|
2769
|
+
...props
|
|
2770
|
+
}
|
|
2771
|
+
));
|
|
2772
|
+
DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
|
|
2773
|
+
var DialogContent = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
2774
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
2775
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2776
|
+
DialogPrimitive__namespace.Content,
|
|
2777
|
+
{
|
|
2778
|
+
ref,
|
|
2779
|
+
className: cn(
|
|
2780
|
+
"bk-portal-content fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg",
|
|
2781
|
+
className
|
|
2782
|
+
),
|
|
2783
|
+
...props,
|
|
2784
|
+
children: [
|
|
2785
|
+
children,
|
|
2786
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-1 focus:ring-ring", children: [
|
|
2787
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
|
|
2788
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
2789
|
+
] })
|
|
2790
|
+
]
|
|
2791
|
+
}
|
|
2792
|
+
)
|
|
2793
|
+
] }));
|
|
2794
|
+
DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
|
|
2795
|
+
function DialogHeader({ className, ...props }) {
|
|
2796
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
2797
|
+
}
|
|
2798
|
+
function DialogFooter({ className, ...props }) {
|
|
2799
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
|
|
2800
|
+
}
|
|
2801
|
+
var DialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2802
|
+
DialogPrimitive__namespace.Title,
|
|
2803
|
+
{
|
|
2804
|
+
ref,
|
|
2805
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
2806
|
+
...props
|
|
2807
|
+
}
|
|
2808
|
+
));
|
|
2809
|
+
DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
|
|
2810
|
+
var DialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
2811
|
+
DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
|
|
2727
2812
|
var Input = React__namespace.forwardRef(
|
|
2728
2813
|
({ className, type, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2729
2814
|
"input",
|
|
@@ -2739,6 +2824,213 @@ var Input = React__namespace.forwardRef(
|
|
|
2739
2824
|
)
|
|
2740
2825
|
);
|
|
2741
2826
|
Input.displayName = "Input";
|
|
2827
|
+
var Label = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2828
|
+
LabelPrimitive__namespace.Root,
|
|
2829
|
+
{
|
|
2830
|
+
ref,
|
|
2831
|
+
className: cn("text-sm font-medium leading-none text-foreground", className),
|
|
2832
|
+
...props
|
|
2833
|
+
}
|
|
2834
|
+
));
|
|
2835
|
+
Label.displayName = LabelPrimitive__namespace.Root.displayName;
|
|
2836
|
+
function recentToResult(msg) {
|
|
2837
|
+
return {
|
|
2838
|
+
ok: true,
|
|
2839
|
+
channelId: msg.channelId,
|
|
2840
|
+
channelName: msg.channelName,
|
|
2841
|
+
ts: msg.ts,
|
|
2842
|
+
blocks: msg.blocks,
|
|
2843
|
+
editableVia: msg.editableVia ?? "bot",
|
|
2844
|
+
workspaceName: msg.workspaceName,
|
|
2845
|
+
username: msg.username,
|
|
2846
|
+
iconUrl: msg.iconUrl
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
function LoadMessageDialog({
|
|
2850
|
+
open,
|
|
2851
|
+
onOpenChange,
|
|
2852
|
+
onLoadMessage,
|
|
2853
|
+
loadRecentMessages,
|
|
2854
|
+
onLoaded,
|
|
2855
|
+
onOpenAsNew
|
|
2856
|
+
}) {
|
|
2857
|
+
const [link, setLink] = React.useState("");
|
|
2858
|
+
const [status, setStatus] = React.useState({ kind: "idle" });
|
|
2859
|
+
const [recent, setRecent] = React.useState(null);
|
|
2860
|
+
const [recentError, setRecentError] = React.useState(null);
|
|
2861
|
+
const inputRef = React.useRef(null);
|
|
2862
|
+
const onLoadMessageRef = React.useRef(onLoadMessage);
|
|
2863
|
+
const loadRecentMessagesRef = React.useRef(loadRecentMessages);
|
|
2864
|
+
React.useEffect(() => {
|
|
2865
|
+
onLoadMessageRef.current = onLoadMessage;
|
|
2866
|
+
loadRecentMessagesRef.current = loadRecentMessages;
|
|
2867
|
+
});
|
|
2868
|
+
const hasRecent = !!loadRecentMessages;
|
|
2869
|
+
React.useEffect(() => {
|
|
2870
|
+
if (!open) {
|
|
2871
|
+
return;
|
|
2872
|
+
}
|
|
2873
|
+
setLink("");
|
|
2874
|
+
setStatus({ kind: "idle" });
|
|
2875
|
+
if (!loadRecentMessagesRef.current) {
|
|
2876
|
+
setRecent([]);
|
|
2877
|
+
setRecentError(null);
|
|
2878
|
+
return;
|
|
2879
|
+
}
|
|
2880
|
+
setRecent(null);
|
|
2881
|
+
setRecentError(null);
|
|
2882
|
+
let cancelled = false;
|
|
2883
|
+
loadRecentMessagesRef.current().then((list) => {
|
|
2884
|
+
if (!cancelled) {
|
|
2885
|
+
setRecent(list);
|
|
2886
|
+
}
|
|
2887
|
+
}).catch((e) => {
|
|
2888
|
+
if (!cancelled) {
|
|
2889
|
+
setRecentError(e instanceof Error ? e.message : "Failed to load recent messages.");
|
|
2890
|
+
}
|
|
2891
|
+
});
|
|
2892
|
+
return () => {
|
|
2893
|
+
cancelled = true;
|
|
2894
|
+
};
|
|
2895
|
+
}, [open]);
|
|
2896
|
+
const handleLoad = async () => {
|
|
2897
|
+
const trimmed = link.trim();
|
|
2898
|
+
if (!trimmed) {
|
|
2899
|
+
setStatus({ kind: "error", error: "Paste a Slack message link first." });
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
setStatus({ kind: "loading" });
|
|
2903
|
+
try {
|
|
2904
|
+
const result = await onLoadMessageRef.current({ link: trimmed });
|
|
2905
|
+
if (result.ok) {
|
|
2906
|
+
onLoaded(result);
|
|
2907
|
+
return;
|
|
2908
|
+
}
|
|
2909
|
+
setStatus({ kind: "not-editable", reason: result.reason, blocks: result.blocks });
|
|
2910
|
+
} catch (e) {
|
|
2911
|
+
setStatus({ kind: "error", error: e instanceof Error ? e.message : "Failed to load message." });
|
|
2912
|
+
}
|
|
2913
|
+
};
|
|
2914
|
+
const notEditable = status.kind === "not-editable" ? status : null;
|
|
2915
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2916
|
+
DialogContent,
|
|
2917
|
+
{
|
|
2918
|
+
className: "w-[calc(100vw-1.5rem)] max-w-lg rounded-lg",
|
|
2919
|
+
onOpenAutoFocus: (e) => {
|
|
2920
|
+
e.preventDefault();
|
|
2921
|
+
inputRef.current?.focus();
|
|
2922
|
+
},
|
|
2923
|
+
children: [
|
|
2924
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
2925
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Edit an existing message" }),
|
|
2926
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5", children: [
|
|
2927
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: hasRecent ? "Paste a Slack message link, or pick a recent message your app posted." : `Paste a Slack message link (Slack's "Copy link") to load its blocks for editing.` }),
|
|
2928
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
2929
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2930
|
+
"button",
|
|
2931
|
+
{
|
|
2932
|
+
type: "button",
|
|
2933
|
+
"aria-label": "How to copy a message link",
|
|
2934
|
+
className: "mt-0.5 shrink-0 rounded text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2935
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { className: "h-3.5 w-3.5" })
|
|
2936
|
+
}
|
|
2937
|
+
) }),
|
|
2938
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TooltipContent, { className: "max-w-xs leading-relaxed", children: [
|
|
2939
|
+
"In Slack, hover over the message and click the ",
|
|
2940
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "\u22EE More actions" }),
|
|
2941
|
+
" button (or right-click the message), then choose ",
|
|
2942
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Copy link" }),
|
|
2943
|
+
"."
|
|
2944
|
+
] })
|
|
2945
|
+
] })
|
|
2946
|
+
] })
|
|
2947
|
+
] }),
|
|
2948
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
2949
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
2950
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "message-link", children: "Message link" }),
|
|
2951
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2952
|
+
Input,
|
|
2953
|
+
{
|
|
2954
|
+
ref: inputRef,
|
|
2955
|
+
id: "message-link",
|
|
2956
|
+
value: link,
|
|
2957
|
+
onChange: (e) => {
|
|
2958
|
+
setLink(e.target.value);
|
|
2959
|
+
if (status.kind !== "idle" && status.kind !== "loading") {
|
|
2960
|
+
setStatus({ kind: "idle" });
|
|
2961
|
+
}
|
|
2962
|
+
},
|
|
2963
|
+
onKeyDown: (e) => {
|
|
2964
|
+
if (e.key === "Enter" && status.kind !== "loading") {
|
|
2965
|
+
e.preventDefault();
|
|
2966
|
+
handleLoad();
|
|
2967
|
+
}
|
|
2968
|
+
},
|
|
2969
|
+
placeholder: "https://your-workspace.slack.com/archives/C\u2026/p\u2026",
|
|
2970
|
+
autoComplete: "off",
|
|
2971
|
+
spellCheck: false
|
|
2972
|
+
}
|
|
2973
|
+
)
|
|
2974
|
+
] }),
|
|
2975
|
+
status.kind === "error" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-2 text-xs text-destructive", children: status.error }),
|
|
2976
|
+
notEditable && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 rounded-md border border-amber-200! bg-amber-50 p-3 text-xs text-amber-800", children: [
|
|
2977
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
2978
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
|
|
2979
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: notEditable.reason })
|
|
2980
|
+
] }),
|
|
2981
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2982
|
+
Button,
|
|
2983
|
+
{
|
|
2984
|
+
type: "button",
|
|
2985
|
+
variant: "outline",
|
|
2986
|
+
size: "sm",
|
|
2987
|
+
className: "self-start",
|
|
2988
|
+
onClick: () => onOpenAsNew(notEditable.blocks),
|
|
2989
|
+
children: "Open as a new message instead"
|
|
2990
|
+
}
|
|
2991
|
+
)
|
|
2992
|
+
] }),
|
|
2993
|
+
hasRecent && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
2994
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2995
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-px flex-1 bg-border" }),
|
|
2996
|
+
"or pick a recent message",
|
|
2997
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-px flex-1 bg-border" })
|
|
2998
|
+
] }),
|
|
2999
|
+
recent === null && !recentError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Loading recent messages\u2026" }),
|
|
3000
|
+
recentError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: recentError }),
|
|
3001
|
+
recent && recent.length === 0 && !recentError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "No recent messages from this app." }),
|
|
3002
|
+
recent && recent.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex max-h-48 flex-col gap-1 overflow-y-auto", children: recent.map((m) => {
|
|
3003
|
+
const asUser = (m.editableVia ?? "bot") === "user";
|
|
3004
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3005
|
+
"button",
|
|
3006
|
+
{
|
|
3007
|
+
type: "button",
|
|
3008
|
+
onClick: () => onLoaded(recentToResult(m)),
|
|
3009
|
+
className: "flex flex-col gap-0.5 rounded-md border border-input bg-background px-3 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
3010
|
+
children: [
|
|
3011
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-baseline justify-between gap-2", children: [
|
|
3012
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-baseline gap-1.5", children: [
|
|
3013
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: m.channelName ? `#${m.channelName}` : m.channelId }),
|
|
3014
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 rounded border px-1 py-px text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: asUser ? "You" : "Bot" })
|
|
3015
|
+
] }),
|
|
3016
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: m.ts })
|
|
3017
|
+
] }),
|
|
3018
|
+
m.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-muted-foreground", children: m.label })
|
|
3019
|
+
]
|
|
3020
|
+
},
|
|
3021
|
+
`${m.channelId}:${m.ts}`
|
|
3022
|
+
);
|
|
3023
|
+
}) })
|
|
3024
|
+
] })
|
|
3025
|
+
] }),
|
|
3026
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
|
|
3027
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
3028
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", onClick: handleLoad, disabled: status.kind === "loading" || !link.trim(), children: status.kind === "loading" ? "Loading\u2026" : "Load message" })
|
|
3029
|
+
] })
|
|
3030
|
+
]
|
|
3031
|
+
}
|
|
3032
|
+
) });
|
|
3033
|
+
}
|
|
2742
3034
|
var PALETTE_DRAG_PREFIX = "palette:";
|
|
2743
3035
|
function parsePaletteDragId(id) {
|
|
2744
3036
|
if (typeof id !== "string" || !id.startsWith(PALETTE_DRAG_PREFIX)) {
|
|
@@ -2938,100 +3230,6 @@ function PaletteItem({
|
|
|
2938
3230
|
}
|
|
2939
3231
|
);
|
|
2940
3232
|
}
|
|
2941
|
-
var buttonVariants = classVarianceAuthority.cva(
|
|
2942
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2943
|
-
{
|
|
2944
|
-
variants: {
|
|
2945
|
-
variant: {
|
|
2946
|
-
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
2947
|
-
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
2948
|
-
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
2949
|
-
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
2950
|
-
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
2951
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
2952
|
-
},
|
|
2953
|
-
size: {
|
|
2954
|
-
default: "h-9 px-4 py-2",
|
|
2955
|
-
sm: "h-8 rounded-md px-3 text-xs",
|
|
2956
|
-
lg: "h-10 rounded-md px-8",
|
|
2957
|
-
icon: "h-9 w-9"
|
|
2958
|
-
}
|
|
2959
|
-
},
|
|
2960
|
-
defaultVariants: {
|
|
2961
|
-
variant: "default",
|
|
2962
|
-
size: "default"
|
|
2963
|
-
}
|
|
2964
|
-
}
|
|
2965
|
-
);
|
|
2966
|
-
var Button = React__namespace.forwardRef(
|
|
2967
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
2968
|
-
const Comp = asChild ? reactSlot.Slot : "button";
|
|
2969
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
2970
|
-
}
|
|
2971
|
-
);
|
|
2972
|
-
Button.displayName = "Button";
|
|
2973
|
-
var Dialog = DialogPrimitive__namespace.Root;
|
|
2974
|
-
var DialogPortal = DialogPrimitive__namespace.Portal;
|
|
2975
|
-
var DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2976
|
-
DialogPrimitive__namespace.Overlay,
|
|
2977
|
-
{
|
|
2978
|
-
ref,
|
|
2979
|
-
className: cn(
|
|
2980
|
-
"bk-portal-content fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
2981
|
-
className
|
|
2982
|
-
),
|
|
2983
|
-
...props
|
|
2984
|
-
}
|
|
2985
|
-
));
|
|
2986
|
-
DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
|
|
2987
|
-
var DialogContent = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
2988
|
-
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
2989
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2990
|
-
DialogPrimitive__namespace.Content,
|
|
2991
|
-
{
|
|
2992
|
-
ref,
|
|
2993
|
-
className: cn(
|
|
2994
|
-
"bk-portal-content fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg",
|
|
2995
|
-
className
|
|
2996
|
-
),
|
|
2997
|
-
...props,
|
|
2998
|
-
children: [
|
|
2999
|
-
children,
|
|
3000
|
-
/* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-1 focus:ring-ring", children: [
|
|
3001
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
|
|
3002
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
3003
|
-
] })
|
|
3004
|
-
]
|
|
3005
|
-
}
|
|
3006
|
-
)
|
|
3007
|
-
] }));
|
|
3008
|
-
DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
|
|
3009
|
-
function DialogHeader({ className, ...props }) {
|
|
3010
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
3011
|
-
}
|
|
3012
|
-
function DialogFooter({ className, ...props }) {
|
|
3013
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
|
|
3014
|
-
}
|
|
3015
|
-
var DialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3016
|
-
DialogPrimitive__namespace.Title,
|
|
3017
|
-
{
|
|
3018
|
-
ref,
|
|
3019
|
-
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
3020
|
-
...props
|
|
3021
|
-
}
|
|
3022
|
-
));
|
|
3023
|
-
DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
|
|
3024
|
-
var DialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
3025
|
-
DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
|
|
3026
|
-
var Label = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3027
|
-
LabelPrimitive__namespace.Root,
|
|
3028
|
-
{
|
|
3029
|
-
ref,
|
|
3030
|
-
className: cn("text-sm font-medium leading-none text-foreground", className),
|
|
3031
|
-
...props
|
|
3032
|
-
}
|
|
3033
|
-
));
|
|
3034
|
-
Label.displayName = LabelPrimitive__namespace.Root.displayName;
|
|
3035
3233
|
function SendDialog({
|
|
3036
3234
|
open,
|
|
3037
3235
|
onOpenChange,
|
|
@@ -4172,7 +4370,7 @@ function TextItemCard({
|
|
|
4172
4370
|
id: `ctx-text-${index}`,
|
|
4173
4371
|
value: element.text,
|
|
4174
4372
|
rows: 2,
|
|
4175
|
-
placeholder: "e.g. Posted by @
|
|
4373
|
+
placeholder: "e.g. Posted by @riley",
|
|
4176
4374
|
onChange: (e) => onChange({ ...element, text: e.target.value })
|
|
4177
4375
|
}
|
|
4178
4376
|
) }),
|
|
@@ -4257,7 +4455,7 @@ function ImageItemCard({
|
|
|
4257
4455
|
{
|
|
4258
4456
|
id: `ctx-img-alt-${index}`,
|
|
4259
4457
|
value: element.alt_text,
|
|
4260
|
-
placeholder: "e.g.
|
|
4458
|
+
placeholder: "e.g. Riley's avatar",
|
|
4261
4459
|
onChange: (e) => onChange({ ...element, alt_text: e.target.value })
|
|
4262
4460
|
}
|
|
4263
4461
|
) })
|
|
@@ -8590,6 +8788,8 @@ var SURFACE_DROPPABLE_ID = "builder-surface";
|
|
|
8590
8788
|
function Surface({
|
|
8591
8789
|
blocks,
|
|
8592
8790
|
workspaceName,
|
|
8791
|
+
authorName,
|
|
8792
|
+
authorIcon,
|
|
8593
8793
|
previewHooks,
|
|
8594
8794
|
previewTheme,
|
|
8595
8795
|
previewSurface = "message",
|
|
@@ -8665,16 +8865,20 @@ function Surface({
|
|
|
8665
8865
|
{
|
|
8666
8866
|
"aria-label": "Block preview",
|
|
8667
8867
|
className: cn("flex min-w-0 flex-1 flex-col overflow-y-auto bg-muted p-3 sm:p-6"),
|
|
8668
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-2xl", children: previewSurface === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(ModalFrame, { isDark, children: blocksList }) : previewSurface === "app_home" ? /* @__PURE__ */ jsxRuntime.jsx(AppHomeFrame, { workspaceName, isDark, children: blocksList }) : /* @__PURE__ */ jsxRuntime.jsx(MessageFrame, { workspaceName, isDark, children: blocksList }) })
|
|
8868
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-2xl", children: previewSurface === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(ModalFrame, { isDark, children: blocksList }) : previewSurface === "app_home" ? /* @__PURE__ */ jsxRuntime.jsx(AppHomeFrame, { workspaceName, isDark, children: blocksList }) : /* @__PURE__ */ jsxRuntime.jsx(MessageFrame, { workspaceName, authorName, authorIcon, isDark, children: blocksList }) })
|
|
8669
8869
|
}
|
|
8670
8870
|
);
|
|
8671
8871
|
}
|
|
8672
8872
|
function MessageFrame({
|
|
8673
8873
|
workspaceName,
|
|
8874
|
+
authorName,
|
|
8875
|
+
authorIcon,
|
|
8674
8876
|
isDark,
|
|
8675
8877
|
children
|
|
8676
8878
|
}) {
|
|
8677
|
-
const
|
|
8879
|
+
const displayName = authorName ?? workspaceName ?? "Your app";
|
|
8880
|
+
const initial = displayName.slice(0, 1).toUpperCase();
|
|
8881
|
+
const safeIcon = authorIcon && isSafeImageSrc(authorIcon) ? authorIcon : null;
|
|
8678
8882
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8679
8883
|
"div",
|
|
8680
8884
|
{
|
|
@@ -8688,7 +8892,7 @@ function MessageFrame({
|
|
|
8688
8892
|
{
|
|
8689
8893
|
className: cn("flex items-center gap-2 px-5 pt-3 pb-1 text-xs", isDark ? "text-white/60" : "text-[#616061]"),
|
|
8690
8894
|
children: [
|
|
8691
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8895
|
+
safeIcon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: safeIcon, alt: "", className: "h-7 w-7 shrink-0 rounded object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
8692
8896
|
"span",
|
|
8693
8897
|
{
|
|
8694
8898
|
className: cn(
|
|
@@ -8698,17 +8902,7 @@ function MessageFrame({
|
|
|
8698
8902
|
children: initial
|
|
8699
8903
|
}
|
|
8700
8904
|
),
|
|
8701
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-bold text-sm", isDark ? "text-white" : "text-[#1d1c1d]"), children:
|
|
8702
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8703
|
-
"span",
|
|
8704
|
-
{
|
|
8705
|
-
className: cn(
|
|
8706
|
-
"rounded px-1 text-[10px] font-semibold",
|
|
8707
|
-
isDark ? "bg-white/10 text-white/70" : "bg-[#f3f3f3] text-[#616061]"
|
|
8708
|
-
),
|
|
8709
|
-
children: "APP"
|
|
8710
|
-
}
|
|
8711
|
-
),
|
|
8905
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-bold text-sm", isDark ? "text-white" : "text-[#1d1c1d]"), children: displayName }),
|
|
8712
8906
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "10:37 AM" })
|
|
8713
8907
|
]
|
|
8714
8908
|
}
|
|
@@ -8910,6 +9104,14 @@ var SURFACE_OPTIONS = [
|
|
|
8910
9104
|
];
|
|
8911
9105
|
var DEFAULT_DOCS_HREF = "https://docs.slack.dev/reference/block-kit/blocks";
|
|
8912
9106
|
var DEFAULT_DOCS_LABEL = "Docs";
|
|
9107
|
+
function formatMessageTs(ts) {
|
|
9108
|
+
const seconds = Number.parseFloat(ts);
|
|
9109
|
+
if (!Number.isFinite(seconds)) return ts;
|
|
9110
|
+
const date = new Date(seconds * 1e3);
|
|
9111
|
+
if (Number.isNaN(date.getTime())) return ts;
|
|
9112
|
+
return date.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
|
|
9113
|
+
}
|
|
9114
|
+
var SEND_MENU_ITEM = "flex w-full cursor-pointer items-center gap-2 rounded px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50";
|
|
8913
9115
|
function Toolbar2({
|
|
8914
9116
|
onClear,
|
|
8915
9117
|
onOpenJson,
|
|
@@ -8926,7 +9128,14 @@ function Toolbar2({
|
|
|
8926
9128
|
showThemeControl = true,
|
|
8927
9129
|
docsLink,
|
|
8928
9130
|
errorCount,
|
|
8929
|
-
sendButtonLabel = "
|
|
9131
|
+
sendButtonLabel = "Review & send",
|
|
9132
|
+
editingEnabled = false,
|
|
9133
|
+
editBadge,
|
|
9134
|
+
onOpenLoad,
|
|
9135
|
+
onOpenUpdate,
|
|
9136
|
+
onExitEdit,
|
|
9137
|
+
loadButtonLabel = "Load message",
|
|
9138
|
+
updateButtonLabel = "Review & update"
|
|
8930
9139
|
}) {
|
|
8931
9140
|
const activeTheme = THEME_OPTIONS.find((t) => t.value === previewTheme) ?? THEME_OPTIONS[0];
|
|
8932
9141
|
const activeSurface = SURFACE_OPTIONS.find((s) => s.value === previewSurface) ?? SURFACE_OPTIONS[0];
|
|
@@ -8936,184 +9145,210 @@ function Toolbar2({
|
|
|
8936
9145
|
const docsLabel = docsLink === false ? null : docsLink?.label ?? DEFAULT_DOCS_LABEL;
|
|
8937
9146
|
const [surfaceMenuOpen, setSurfaceMenuOpen] = React.useState(false);
|
|
8938
9147
|
const [themeMenuOpen, setThemeMenuOpen] = React.useState(false);
|
|
8939
|
-
const [
|
|
8940
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8941
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
8942
|
-
|
|
8943
|
-
Button,
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
className: "md:hidden",
|
|
8950
|
-
"aria-label": "Add a block",
|
|
8951
|
-
children: [
|
|
8952
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }),
|
|
8953
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Blocks" })
|
|
8954
|
-
]
|
|
8955
|
-
}
|
|
8956
|
-
) : null,
|
|
8957
|
-
showSurfaceControl ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: surfaceMenuOpen, onOpenChange: setSurfaceMenuOpen, children: [
|
|
8958
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `Preview surface: ${activeSurface.label}`, children: [
|
|
8959
|
-
/* @__PURE__ */ jsxRuntime.jsx(activeSurface.Icon, { className: "h-3.5 w-3.5" }),
|
|
8960
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: activeSurface.label }),
|
|
8961
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 opacity-60" })
|
|
8962
|
-
] }) }),
|
|
8963
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-36 p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8964
|
-
Menu,
|
|
9148
|
+
const [sendMenuOpen, setSendMenuOpen] = React.useState(false);
|
|
9149
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9150
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-2 gap-y-1 border-b bg-background px-2 py-1.5 sm:px-3 sm:py-2", children: [
|
|
9151
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-1 sm:gap-2", children: [
|
|
9152
|
+
editingEnabled && !editBadge ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: onOpenLoad, "aria-label": loadButtonLabel, children: [
|
|
9153
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" }),
|
|
9154
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: loadButtonLabel })
|
|
9155
|
+
] }) : null,
|
|
9156
|
+
onOpenPalette ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9157
|
+
Button,
|
|
8965
9158
|
{
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
9159
|
+
type: "button",
|
|
9160
|
+
variant: "ghost",
|
|
9161
|
+
size: "sm",
|
|
9162
|
+
onClick: onOpenPalette,
|
|
9163
|
+
className: "md:hidden",
|
|
9164
|
+
"aria-label": "Add a block",
|
|
9165
|
+
children: [
|
|
9166
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }),
|
|
9167
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Blocks" })
|
|
9168
|
+
]
|
|
9169
|
+
}
|
|
9170
|
+
) : null,
|
|
9171
|
+
showSurfaceControl ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: surfaceMenuOpen, onOpenChange: setSurfaceMenuOpen, children: [
|
|
9172
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `Preview surface: ${activeSurface.label}`, children: [
|
|
9173
|
+
/* @__PURE__ */ jsxRuntime.jsx(activeSurface.Icon, { className: "h-3.5 w-3.5" }),
|
|
9174
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: activeSurface.label }),
|
|
9175
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "hidden h-3.5 w-3.5 opacity-60 md:inline" })
|
|
9176
|
+
] }) }),
|
|
9177
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-36 p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9178
|
+
Menu,
|
|
9179
|
+
{
|
|
9180
|
+
ariaLabel: "Preview surface",
|
|
9181
|
+
options: surfaceOptions,
|
|
9182
|
+
value: previewSurface,
|
|
9183
|
+
onChange: (next) => {
|
|
9184
|
+
onPreviewSurfaceChange(next);
|
|
9185
|
+
setSurfaceMenuOpen(false);
|
|
9186
|
+
}
|
|
9187
|
+
}
|
|
9188
|
+
) })
|
|
9189
|
+
] }) : null,
|
|
9190
|
+
showThemeControl ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: themeMenuOpen, onOpenChange: setThemeMenuOpen, children: [
|
|
9191
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `Preview theme: ${activeTheme.label}`, children: [
|
|
9192
|
+
/* @__PURE__ */ jsxRuntime.jsx(activeTheme.Icon, { className: "h-3.5 w-3.5" }),
|
|
9193
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: activeTheme.label }),
|
|
9194
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 opacity-60" })
|
|
9195
|
+
] }) }),
|
|
9196
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-32 p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9197
|
+
Menu,
|
|
9198
|
+
{
|
|
9199
|
+
ariaLabel: "Preview theme",
|
|
9200
|
+
options: THEME_OPTIONS,
|
|
9201
|
+
value: previewTheme,
|
|
9202
|
+
onChange: (next) => {
|
|
9203
|
+
onPreviewThemeChange(next);
|
|
9204
|
+
setThemeMenuOpen(false);
|
|
9205
|
+
}
|
|
8972
9206
|
}
|
|
9207
|
+
) })
|
|
9208
|
+
] }) : null,
|
|
9209
|
+
docsHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9210
|
+
"a",
|
|
9211
|
+
{
|
|
9212
|
+
href: docsHref,
|
|
9213
|
+
target: "_blank",
|
|
9214
|
+
rel: "noreferrer noopener",
|
|
9215
|
+
className: "inline-flex h-8 items-center gap-1.5 rounded-md px-2 text-xs font-medium text-muted-foreground no-underline transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
9216
|
+
"aria-label": `${docsLabel} (opens in a new tab)`,
|
|
9217
|
+
children: [
|
|
9218
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookOpen, { className: "h-3.5 w-3.5" }),
|
|
9219
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: docsLabel }),
|
|
9220
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "hidden h-3 w-3 opacity-50 md:inline" })
|
|
9221
|
+
]
|
|
8973
9222
|
}
|
|
8974
|
-
)
|
|
8975
|
-
] })
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: activeTheme.label }),
|
|
8980
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 opacity-60" })
|
|
8981
|
-
] }) }),
|
|
8982
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-32 p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8983
|
-
Menu,
|
|
9223
|
+
) : null
|
|
9224
|
+
] }),
|
|
9225
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 sm:gap-2", children: [
|
|
9226
|
+
errorCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9227
|
+
Button,
|
|
8984
9228
|
{
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
9229
|
+
type: "button",
|
|
9230
|
+
variant: "ghost",
|
|
9231
|
+
size: "sm",
|
|
9232
|
+
onClick: onOpenIssues,
|
|
9233
|
+
className: "border border-red-200! bg-red-50 text-red-700 hover:bg-red-100 hover:text-red-700",
|
|
9234
|
+
"aria-label": `${errorCount} ${errorCount === 1 ? "issue" : "issues"}`,
|
|
9235
|
+
children: [
|
|
9236
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" }),
|
|
9237
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
9238
|
+
errorCount,
|
|
9239
|
+
" ",
|
|
9240
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: errorCount === 1 ? "issue" : "issues" })
|
|
9241
|
+
] })
|
|
9242
|
+
]
|
|
8992
9243
|
}
|
|
8993
|
-
)
|
|
8994
|
-
|
|
8995
|
-
docsHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8996
|
-
"a",
|
|
8997
|
-
{
|
|
8998
|
-
href: docsHref,
|
|
8999
|
-
target: "_blank",
|
|
9000
|
-
rel: "noreferrer noopener",
|
|
9001
|
-
className: "hidden h-8 items-center gap-1.5 rounded-md px-2 py-1 text-sm text-muted-foreground no-underline transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:inline-flex",
|
|
9002
|
-
"aria-label": `${docsLabel} (opens in a new tab)`,
|
|
9003
|
-
children: [
|
|
9004
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookOpen, { className: "h-3.5 w-3.5" }),
|
|
9005
|
-
docsLabel,
|
|
9006
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3 opacity-50" })
|
|
9007
|
-
]
|
|
9008
|
-
}
|
|
9009
|
-
) : null
|
|
9010
|
-
] }),
|
|
9011
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 sm:gap-2", children: [
|
|
9012
|
-
errorCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9013
|
-
Button,
|
|
9014
|
-
{
|
|
9015
|
-
type: "button",
|
|
9016
|
-
variant: "ghost",
|
|
9017
|
-
size: "sm",
|
|
9018
|
-
onClick: onOpenIssues,
|
|
9019
|
-
className: "border border-red-200! bg-red-50 text-red-700 hover:bg-red-100 hover:text-red-700",
|
|
9020
|
-
"aria-label": `${errorCount} ${errorCount === 1 ? "issue" : "issues"}`,
|
|
9021
|
-
children: [
|
|
9022
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" }),
|
|
9023
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
9024
|
-
errorCount,
|
|
9025
|
-
" ",
|
|
9026
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: errorCount === 1 ? "issue" : "issues" })
|
|
9027
|
-
] })
|
|
9028
|
-
]
|
|
9029
|
-
}
|
|
9030
|
-
) : null,
|
|
9031
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9032
|
-
Button,
|
|
9033
|
-
{
|
|
9034
|
-
type: "button",
|
|
9035
|
-
variant: "ghost",
|
|
9036
|
-
size: "sm",
|
|
9037
|
-
onClick: onClear,
|
|
9038
|
-
disabled: !canClear,
|
|
9039
|
-
className: "hidden hover:bg-destructive/10 hover:text-destructive sm:inline-flex",
|
|
9040
|
-
"aria-label": "Clear all blocks",
|
|
9041
|
-
children: [
|
|
9042
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }),
|
|
9043
|
-
"Clear"
|
|
9044
|
-
]
|
|
9045
|
-
}
|
|
9046
|
-
),
|
|
9047
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9048
|
-
Button,
|
|
9049
|
-
{
|
|
9050
|
-
type: "button",
|
|
9051
|
-
variant: "ghost",
|
|
9052
|
-
size: "sm",
|
|
9053
|
-
onClick: onOpenJson,
|
|
9054
|
-
"aria-label": "View JSON",
|
|
9055
|
-
className: "hidden sm:inline-flex",
|
|
9056
|
-
children: [
|
|
9057
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { className: "h-3.5 w-3.5" }),
|
|
9058
|
-
"View JSON"
|
|
9059
|
-
]
|
|
9060
|
-
}
|
|
9061
|
-
),
|
|
9062
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: moreMenuOpen, onOpenChange: setMoreMenuOpen, children: [
|
|
9063
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9244
|
+
) : null,
|
|
9245
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9064
9246
|
Button,
|
|
9065
9247
|
{
|
|
9066
9248
|
type: "button",
|
|
9067
9249
|
variant: "ghost",
|
|
9068
9250
|
size: "sm",
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
className: "
|
|
9072
|
-
|
|
9251
|
+
onClick: onClear,
|
|
9252
|
+
disabled: !canClear,
|
|
9253
|
+
className: "hover:bg-destructive/10 hover:text-destructive",
|
|
9254
|
+
"aria-label": "Clear all blocks",
|
|
9255
|
+
children: [
|
|
9256
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }),
|
|
9257
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: "Clear" })
|
|
9258
|
+
]
|
|
9073
9259
|
}
|
|
9074
|
-
)
|
|
9075
|
-
/* @__PURE__ */ jsxRuntime.
|
|
9076
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
}
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9260
|
+
),
|
|
9261
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: onOpenJson, "aria-label": "View JSON", children: [
|
|
9262
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { className: "h-3.5 w-3.5" }),
|
|
9263
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: "View JSON" })
|
|
9264
|
+
] }),
|
|
9265
|
+
editBadge ? (
|
|
9266
|
+
// A message is loaded: split button. Main action updates it in
|
|
9267
|
+
// place; the menu also offers posting the blocks as a new message.
|
|
9268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-stretch", children: [
|
|
9269
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9270
|
+
Button,
|
|
9271
|
+
{
|
|
9272
|
+
type: "button",
|
|
9273
|
+
size: "sm",
|
|
9274
|
+
onClick: onOpenUpdate,
|
|
9275
|
+
disabled: !canSend,
|
|
9276
|
+
"aria-label": updateButtonLabel,
|
|
9277
|
+
className: "rounded-r-none",
|
|
9278
|
+
children: [
|
|
9279
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" }),
|
|
9280
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: updateButtonLabel })
|
|
9281
|
+
]
|
|
9282
|
+
}
|
|
9283
|
+
),
|
|
9284
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: sendMenuOpen, onOpenChange: setSendMenuOpen, children: [
|
|
9285
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9286
|
+
Button,
|
|
9287
|
+
{
|
|
9288
|
+
type: "button",
|
|
9289
|
+
size: "sm",
|
|
9290
|
+
"aria-label": "More message options",
|
|
9291
|
+
"aria-haspopup": "menu",
|
|
9292
|
+
className: "rounded-l-none border-l border-l-primary-foreground/30! px-1.5",
|
|
9293
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5" })
|
|
9294
|
+
}
|
|
9295
|
+
) }),
|
|
9296
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "end", className: "w-56 p-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "menu", "aria-label": "Message options", className: "flex flex-col", children: [
|
|
9297
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9298
|
+
"button",
|
|
9299
|
+
{
|
|
9300
|
+
type: "button",
|
|
9301
|
+
role: "menuitem",
|
|
9302
|
+
disabled: !canSend,
|
|
9303
|
+
onClick: () => {
|
|
9304
|
+
setSendMenuOpen(false);
|
|
9305
|
+
onOpenUpdate?.();
|
|
9306
|
+
},
|
|
9307
|
+
className: SEND_MENU_ITEM,
|
|
9308
|
+
children: [
|
|
9309
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" }),
|
|
9310
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: "Update message" })
|
|
9311
|
+
]
|
|
9312
|
+
}
|
|
9313
|
+
),
|
|
9314
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9315
|
+
"button",
|
|
9316
|
+
{
|
|
9317
|
+
type: "button",
|
|
9318
|
+
role: "menuitem",
|
|
9319
|
+
disabled: !canSend,
|
|
9320
|
+
onClick: () => {
|
|
9321
|
+
setSendMenuOpen(false);
|
|
9322
|
+
onOpenSend();
|
|
9323
|
+
},
|
|
9324
|
+
className: SEND_MENU_ITEM,
|
|
9325
|
+
children: [
|
|
9326
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3.5 w-3.5" }),
|
|
9327
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: "Send as a new message" })
|
|
9328
|
+
]
|
|
9329
|
+
}
|
|
9330
|
+
)
|
|
9331
|
+
] }) })
|
|
9332
|
+
] })
|
|
9333
|
+
] })
|
|
9334
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: onOpenSend, disabled: !canSend, "aria-label": sendButtonLabel, children: [
|
|
9335
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3.5 w-3.5" }),
|
|
9336
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: sendButtonLabel })
|
|
9337
|
+
] })
|
|
9338
|
+
] })
|
|
9339
|
+
] }),
|
|
9340
|
+
editingEnabled && editBadge ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 border-b bg-muted px-2 py-2 text-foreground sm:px-3", children: [
|
|
9341
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-4 w-4 shrink-0 text-primary" }),
|
|
9342
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1 text-sm", children: [
|
|
9343
|
+
"References an existing message in ",
|
|
9344
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: editBadge.channelLabel }),
|
|
9345
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-xs opacity-70", title: editBadge.ts, children: formatMessageTs(editBadge.ts) })
|
|
9111
9346
|
] }),
|
|
9112
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick:
|
|
9113
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
9114
|
-
|
|
9347
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: onExitEdit, className: "shrink-0", children: [
|
|
9348
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" }),
|
|
9349
|
+
"Switch to a new message"
|
|
9115
9350
|
] })
|
|
9116
|
-
] })
|
|
9351
|
+
] }) : null
|
|
9117
9352
|
] });
|
|
9118
9353
|
}
|
|
9119
9354
|
function Menu({
|
|
@@ -9171,52 +9406,132 @@ function Menu({
|
|
|
9171
9406
|
);
|
|
9172
9407
|
}) });
|
|
9173
9408
|
}
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9409
|
+
function UpdateDialog({
|
|
9410
|
+
open,
|
|
9411
|
+
onOpenChange,
|
|
9412
|
+
target,
|
|
9413
|
+
blocks,
|
|
9414
|
+
loadSendAsUserStatus,
|
|
9415
|
+
onUpdate,
|
|
9416
|
+
confirmUpdateLabel = "Update message",
|
|
9417
|
+
errorCount,
|
|
9418
|
+
onShowIssues
|
|
9181
9419
|
}) {
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9420
|
+
const asUser = target.editableVia === "user";
|
|
9421
|
+
const [userStatus, setUserStatus] = React.useState(null);
|
|
9422
|
+
const [status, setStatus] = React.useState({ kind: "idle" });
|
|
9423
|
+
const loadSendAsUserStatusRef = React.useRef(loadSendAsUserStatus);
|
|
9424
|
+
React.useEffect(() => {
|
|
9425
|
+
loadSendAsUserStatusRef.current = loadSendAsUserStatus;
|
|
9426
|
+
});
|
|
9427
|
+
const refreshSendAsUser = React.useCallback(() => {
|
|
9428
|
+
loadSendAsUserStatusRef.current().then(setUserStatus).catch(() => setUserStatus({ canSendAsUser: false }));
|
|
9429
|
+
}, []);
|
|
9430
|
+
React.useEffect(() => {
|
|
9431
|
+
if (!open) {
|
|
9432
|
+
return;
|
|
9194
9433
|
}
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
icon,
|
|
9200
|
-
trailingIcon,
|
|
9201
|
-
children,
|
|
9202
|
-
onSelect
|
|
9203
|
-
}) {
|
|
9204
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9205
|
-
"a",
|
|
9206
|
-
{
|
|
9207
|
-
role: "menuitem",
|
|
9208
|
-
href,
|
|
9209
|
-
target: "_blank",
|
|
9210
|
-
rel: "noreferrer noopener",
|
|
9211
|
-
onClick: onSelect,
|
|
9212
|
-
className: ACTION_ITEM_BASE,
|
|
9213
|
-
children: [
|
|
9214
|
-
icon,
|
|
9215
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children }),
|
|
9216
|
-
trailingIcon
|
|
9217
|
-
]
|
|
9434
|
+
setStatus({ kind: "idle" });
|
|
9435
|
+
if (asUser) {
|
|
9436
|
+
setUserStatus(null);
|
|
9437
|
+
refreshSendAsUser();
|
|
9218
9438
|
}
|
|
9219
|
-
);
|
|
9439
|
+
}, [open, asUser, refreshSendAsUser]);
|
|
9440
|
+
React.useEffect(() => {
|
|
9441
|
+
if (!open || !asUser) {
|
|
9442
|
+
return;
|
|
9443
|
+
}
|
|
9444
|
+
const handler = () => refreshSendAsUser();
|
|
9445
|
+
window.addEventListener("focus", handler);
|
|
9446
|
+
return () => window.removeEventListener("focus", handler);
|
|
9447
|
+
}, [open, asUser, refreshSendAsUser]);
|
|
9448
|
+
const needsSignIn = asUser && userStatus !== null && !userStatus.canSendAsUser;
|
|
9449
|
+
const handleSubmit = async () => {
|
|
9450
|
+
setStatus({ kind: "updating" });
|
|
9451
|
+
try {
|
|
9452
|
+
const result = await onUpdate({
|
|
9453
|
+
channelId: target.channelId,
|
|
9454
|
+
ts: target.ts,
|
|
9455
|
+
blocks: toSlackBlocks(blocks),
|
|
9456
|
+
asUser
|
|
9457
|
+
});
|
|
9458
|
+
if (result.ok) {
|
|
9459
|
+
setStatus({ kind: "idle" });
|
|
9460
|
+
onOpenChange(false);
|
|
9461
|
+
return;
|
|
9462
|
+
}
|
|
9463
|
+
setStatus({ kind: "error", error: result.error ?? "Update failed." });
|
|
9464
|
+
} catch (e) {
|
|
9465
|
+
setStatus({ kind: "error", error: e instanceof Error ? e.message : "Update failed." });
|
|
9466
|
+
}
|
|
9467
|
+
};
|
|
9468
|
+
const channelLabel = target.channelName ? `#${target.channelName}` : target.channelId;
|
|
9469
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "w-[calc(100vw-1.5rem)] max-w-lg rounded-lg", children: [
|
|
9470
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
9471
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Update message" }),
|
|
9472
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "This replaces the message that's already posted. It stays in the same channel and can't be moved." })
|
|
9473
|
+
] }),
|
|
9474
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
9475
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
9476
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Channel" }),
|
|
9477
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex h-9 items-center rounded-md border border-input bg-muted px-3 text-sm text-muted-foreground", children: channelLabel })
|
|
9478
|
+
] }),
|
|
9479
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
9480
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Posting as" }),
|
|
9481
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex h-9 items-center rounded-md border border-input bg-muted px-3 text-sm text-muted-foreground", children: asUser ? "Your account" : "App bot" }),
|
|
9482
|
+
needsSignIn && userStatus?.oauthUrl && isSafeHref(userStatus.oauthUrl) && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
9483
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9484
|
+
"a",
|
|
9485
|
+
{
|
|
9486
|
+
href: userStatus.oauthUrl,
|
|
9487
|
+
target: "_blank",
|
|
9488
|
+
rel: "noopener noreferrer",
|
|
9489
|
+
className: "inline-flex items-center gap-1 text-primary hover:underline",
|
|
9490
|
+
children: [
|
|
9491
|
+
"Sign in with Slack ",
|
|
9492
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
|
|
9493
|
+
]
|
|
9494
|
+
}
|
|
9495
|
+
),
|
|
9496
|
+
" ",
|
|
9497
|
+
"to update your own message."
|
|
9498
|
+
] }),
|
|
9499
|
+
needsSignIn && !userStatus?.oauthUrl && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Sign in with Slack to update your own message." })
|
|
9500
|
+
] }),
|
|
9501
|
+
errorCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9502
|
+
"button",
|
|
9503
|
+
{
|
|
9504
|
+
type: "button",
|
|
9505
|
+
onClick: onShowIssues,
|
|
9506
|
+
className: "flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/5 p-2 text-left text-xs text-destructive hover:bg-destructive/10",
|
|
9507
|
+
children: [
|
|
9508
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
9509
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex-1", children: [
|
|
9510
|
+
"Fix ",
|
|
9511
|
+
errorCount,
|
|
9512
|
+
" ",
|
|
9513
|
+
errorCount === 1 ? "issue" : "issues",
|
|
9514
|
+
" before updating."
|
|
9515
|
+
] }),
|
|
9516
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 underline", children: "Show issues" })
|
|
9517
|
+
]
|
|
9518
|
+
}
|
|
9519
|
+
) : null,
|
|
9520
|
+
status.kind === "error" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-2 text-xs text-destructive", children: status.error })
|
|
9521
|
+
] }),
|
|
9522
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
|
|
9523
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
9524
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9525
|
+
Button,
|
|
9526
|
+
{
|
|
9527
|
+
type: "button",
|
|
9528
|
+
onClick: handleSubmit,
|
|
9529
|
+
disabled: status.kind === "updating" || blocks.length === 0 || errorCount > 0 || needsSignIn,
|
|
9530
|
+
children: status.kind === "updating" ? "Updating\u2026" : confirmUpdateLabel
|
|
9531
|
+
}
|
|
9532
|
+
)
|
|
9533
|
+
] })
|
|
9534
|
+
] }) });
|
|
9220
9535
|
}
|
|
9221
9536
|
function BlockKitchen(props) {
|
|
9222
9537
|
const {
|
|
@@ -9228,6 +9543,10 @@ function BlockKitchen(props) {
|
|
|
9228
9543
|
loadChannels,
|
|
9229
9544
|
loadSendAsUserStatus,
|
|
9230
9545
|
onSend,
|
|
9546
|
+
editing,
|
|
9547
|
+
loadButtonLabel,
|
|
9548
|
+
updateButtonLabel,
|
|
9549
|
+
confirmUpdateLabel,
|
|
9231
9550
|
palette,
|
|
9232
9551
|
disabledBlockTypes,
|
|
9233
9552
|
showPaletteSearch,
|
|
@@ -9273,6 +9592,10 @@ function BlockKitchen(props) {
|
|
|
9273
9592
|
}, [blocks]);
|
|
9274
9593
|
const [jsonOpen, setJsonOpen] = React.useState(false);
|
|
9275
9594
|
const [sendOpen, setSendOpen] = React.useState(false);
|
|
9595
|
+
const [updateOpen, setUpdateOpen] = React.useState(false);
|
|
9596
|
+
const [loadOpen, setLoadOpen] = React.useState(false);
|
|
9597
|
+
const [editTarget, setEditTarget] = React.useState(null);
|
|
9598
|
+
const activeEditTarget = editing ? editTarget : null;
|
|
9276
9599
|
const [issuesOpen, setIssuesOpen] = React.useState(false);
|
|
9277
9600
|
const [paletteOpen, setPaletteOpen] = React.useState(false);
|
|
9278
9601
|
const [openBlockId, setOpenBlockId] = React.useState(null);
|
|
@@ -9393,7 +9716,21 @@ function BlockKitchen(props) {
|
|
|
9393
9716
|
allowedSurfaces,
|
|
9394
9717
|
showThemeControl: isPreviewThemeControlled ? false : showThemeControl,
|
|
9395
9718
|
docsLink,
|
|
9396
|
-
sendButtonLabel
|
|
9719
|
+
sendButtonLabel,
|
|
9720
|
+
editingEnabled: !!editing,
|
|
9721
|
+
editBadge: activeEditTarget ? {
|
|
9722
|
+
channelLabel: activeEditTarget.channelName ? `#${activeEditTarget.channelName}` : activeEditTarget.channelId,
|
|
9723
|
+
ts: activeEditTarget.ts
|
|
9724
|
+
} : null,
|
|
9725
|
+
onOpenLoad: () => setLoadOpen(true),
|
|
9726
|
+
onOpenUpdate: () => setUpdateOpen(true),
|
|
9727
|
+
onExitEdit: () => {
|
|
9728
|
+
setEditTarget(null);
|
|
9729
|
+
replaceAll([]);
|
|
9730
|
+
setLoadOpen(true);
|
|
9731
|
+
},
|
|
9732
|
+
loadButtonLabel,
|
|
9733
|
+
updateButtonLabel
|
|
9397
9734
|
}
|
|
9398
9735
|
),
|
|
9399
9736
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 items-stretch", children: [
|
|
@@ -9412,6 +9749,8 @@ function BlockKitchen(props) {
|
|
|
9412
9749
|
{
|
|
9413
9750
|
blocks,
|
|
9414
9751
|
workspaceName,
|
|
9752
|
+
authorName: activeEditTarget?.username,
|
|
9753
|
+
authorIcon: activeEditTarget?.iconUrl,
|
|
9415
9754
|
previewHooks: mergedPreviewHooks,
|
|
9416
9755
|
previewTheme,
|
|
9417
9756
|
previewSurface,
|
|
@@ -9477,6 +9816,52 @@ function BlockKitchen(props) {
|
|
|
9477
9816
|
}
|
|
9478
9817
|
}
|
|
9479
9818
|
),
|
|
9819
|
+
activeEditTarget && editing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9820
|
+
UpdateDialog,
|
|
9821
|
+
{
|
|
9822
|
+
open: updateOpen,
|
|
9823
|
+
onOpenChange: setUpdateOpen,
|
|
9824
|
+
target: activeEditTarget,
|
|
9825
|
+
blocks: blockPayloads,
|
|
9826
|
+
loadSendAsUserStatus,
|
|
9827
|
+
onUpdate: editing.onUpdate,
|
|
9828
|
+
confirmUpdateLabel,
|
|
9829
|
+
errorCount: validation.total,
|
|
9830
|
+
onShowIssues: () => {
|
|
9831
|
+
setUpdateOpen(false);
|
|
9832
|
+
setIssuesOpen(true);
|
|
9833
|
+
}
|
|
9834
|
+
}
|
|
9835
|
+
) : null,
|
|
9836
|
+
editing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9837
|
+
LoadMessageDialog,
|
|
9838
|
+
{
|
|
9839
|
+
open: loadOpen,
|
|
9840
|
+
onOpenChange: setLoadOpen,
|
|
9841
|
+
onLoadMessage: editing.onLoadMessage,
|
|
9842
|
+
loadRecentMessages: editing.loadRecentMessages,
|
|
9843
|
+
onLoaded: (result) => {
|
|
9844
|
+
replaceAll(result.blocks);
|
|
9845
|
+
setEditTarget({
|
|
9846
|
+
channelId: result.channelId,
|
|
9847
|
+
channelName: result.channelName,
|
|
9848
|
+
ts: result.ts,
|
|
9849
|
+
editableVia: result.editableVia,
|
|
9850
|
+
workspaceName: result.workspaceName,
|
|
9851
|
+
username: result.username,
|
|
9852
|
+
iconUrl: result.iconUrl
|
|
9853
|
+
});
|
|
9854
|
+
setLoadOpen(false);
|
|
9855
|
+
},
|
|
9856
|
+
onOpenAsNew: (loadedBlocks) => {
|
|
9857
|
+
if (loadedBlocks) {
|
|
9858
|
+
replaceAll(loadedBlocks);
|
|
9859
|
+
}
|
|
9860
|
+
setEditTarget(null);
|
|
9861
|
+
setLoadOpen(false);
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
) : null,
|
|
9480
9865
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9481
9866
|
IssuesSheet,
|
|
9482
9867
|
{
|