mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Polish workflow trigger presentation
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
@@ -19,13 +19,16 @@ import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
||||
import * as React from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
import { useCustomEmoji } from "@/features/custom-emoji/hooks";
|
||||
import { useUsersBatchQuery } from "@/features/profile/hooks";
|
||||
import { resolveUserLabel } from "@/features/profile/lib/identity";
|
||||
import { reactionEmojiUrl } from "@/shared/api/customEmoji";
|
||||
import { useIdentityQuery } from "@/shared/api/hooks";
|
||||
import { getEventById } from "@/shared/api/tauri";
|
||||
import type { Channel } from "@/shared/api/types";
|
||||
import { Button } from "@/shared/ui/button";
|
||||
import { cn } from "@/shared/lib/cn";
|
||||
import { rewriteRelayUrl } from "@/shared/lib/mediaUrl";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -496,6 +499,7 @@ export function WorkflowFormBuilder({
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
const previousModeRef = React.useRef(mode);
|
||||
const identityQuery = useIdentityQuery();
|
||||
const customEmoji = useCustomEmoji();
|
||||
const parsedTriggerConditions = React.useMemo(
|
||||
() =>
|
||||
formState.trigger.filter
|
||||
@@ -506,6 +510,17 @@ export function WorkflowFormBuilder({
|
||||
: [],
|
||||
[formState.trigger.filter, formState.trigger.on],
|
||||
);
|
||||
const triggerReactionCondition = parsedTriggerConditions?.find(
|
||||
(condition) =>
|
||||
condition.field === "trigger_emoji" && condition.operator === "equals",
|
||||
);
|
||||
const triggerReaction =
|
||||
formState.trigger.on === "reaction_added"
|
||||
? triggerReactionCondition?.value || formState.trigger.emoji
|
||||
: undefined;
|
||||
const triggerReactionUrl = triggerReaction
|
||||
? reactionEmojiUrl(triggerReaction, customEmoji)
|
||||
: undefined;
|
||||
const triggerAuthorCondition = parsedTriggerConditions?.find(
|
||||
(condition) => condition.field === "trigger_author",
|
||||
);
|
||||
@@ -735,11 +750,35 @@ export function WorkflowFormBuilder({
|
||||
}
|
||||
disabled={disabled}
|
||||
icon={
|
||||
<TriggerIcon
|
||||
aria-hidden="true"
|
||||
className="h-4 w-4"
|
||||
data-testid={`workflow-trigger-icon-${formState.trigger.on}`}
|
||||
/>
|
||||
triggerReaction ? (
|
||||
triggerReactionUrl ? (
|
||||
<img
|
||||
alt={triggerReaction}
|
||||
className="h-7 w-7 object-contain"
|
||||
data-testid="workflow-trigger-selected-reaction"
|
||||
draggable={false}
|
||||
src={rewriteRelayUrl(triggerReactionUrl)}
|
||||
/>
|
||||
) : (
|
||||
<span
|
||||
className={cn(
|
||||
"max-w-8 overflow-hidden leading-none",
|
||||
triggerReaction.startsWith(":")
|
||||
? "text-xs"
|
||||
: "text-2xl",
|
||||
)}
|
||||
data-testid="workflow-trigger-selected-reaction"
|
||||
>
|
||||
{triggerReaction}
|
||||
</span>
|
||||
)
|
||||
) : (
|
||||
<TriggerIcon
|
||||
aria-hidden="true"
|
||||
className="h-4 w-4"
|
||||
data-testid={`workflow-trigger-icon-${formState.trigger.on}`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
label={`Trigger: ${triggerDescription}`}
|
||||
onAddAfter={(action) => insertStep(0, action)}
|
||||
|
||||
@@ -79,9 +79,9 @@ export const DEFAULT_FORM_STATE: WorkflowFormState = {
|
||||
};
|
||||
|
||||
export const TRIGGER_LABELS: Record<TriggerType, string> = {
|
||||
message_posted: "Message Posted",
|
||||
reaction_added: "Reaction Added",
|
||||
diff_posted: "Diff Posted",
|
||||
message_posted: "Message posted",
|
||||
reaction_added: "Reaction added",
|
||||
diff_posted: "Diff posted",
|
||||
webhook: "Webhook",
|
||||
schedule: "Schedule",
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ test("describes selected trigger conditions on the workflow canvas", () => {
|
||||
on: "reaction_added",
|
||||
filter: 'trigger_emoji == "🔥"',
|
||||
}),
|
||||
"🔥 reaction added",
|
||||
"Reaction added",
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
@@ -50,20 +50,20 @@ test("describes selected trigger conditions on the workflow canvas", () => {
|
||||
},
|
||||
{ authorLabel: "Carl", messageLabel: "hey yourself" },
|
||||
),
|
||||
"👾 reaction added by Carl to “hey yourself”",
|
||||
"Reaction added by Carl to “hey yourself”",
|
||||
);
|
||||
});
|
||||
|
||||
test("keeps the base label for unfiltered and custom triggers", () => {
|
||||
assert.equal(
|
||||
workflowTriggerDescription({ on: "message_posted" }),
|
||||
"Message Posted",
|
||||
"Message posted",
|
||||
);
|
||||
assert.equal(
|
||||
workflowTriggerDescription({
|
||||
on: "message_posted",
|
||||
filter: "custom_variable == 1",
|
||||
}),
|
||||
"Message Posted",
|
||||
"Message posted",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@ export function workflowTriggerDescription(
|
||||
: [];
|
||||
if (!conditions || conditions.length === 0) {
|
||||
return trigger.on === "reaction_added" && trigger.emoji
|
||||
? `${trigger.emoji} reaction added`
|
||||
? eventPhrase
|
||||
: baseLabel;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export function workflowTriggerDescription(
|
||||
description =
|
||||
emojiCondition.operator === "not_equals"
|
||||
? `Any reaction except ${emojiCondition.value} added`
|
||||
: `${emojiCondition.value} reaction added`;
|
||||
: eventPhrase;
|
||||
}
|
||||
if (authorCondition) {
|
||||
const author =
|
||||
@@ -138,7 +138,7 @@ export function workflowTriggerDescription(
|
||||
if (condition.field === "trigger_emoji") {
|
||||
return condition.operator === "not_equals"
|
||||
? `Any reaction except ${condition.value} added`
|
||||
: `${condition.value} reaction added`;
|
||||
: eventPhrase;
|
||||
}
|
||||
|
||||
if (condition.field === "trigger_message_id") {
|
||||
|
||||
@@ -3,9 +3,9 @@ import { expect, test } from "@playwright/test";
|
||||
import { installMockBridge, TEST_IDENTITIES } from "../helpers/bridge";
|
||||
|
||||
const TRIGGER_OPTION_LABELS: Record<string, string> = {
|
||||
diff_posted: "Diff Posted",
|
||||
message_posted: "Message Posted",
|
||||
reaction_added: "Reaction Added",
|
||||
diff_posted: "Diff posted",
|
||||
message_posted: "Message posted",
|
||||
reaction_added: "Reaction added",
|
||||
schedule: "Schedule",
|
||||
webhook: "Webhook",
|
||||
};
|
||||
@@ -465,7 +465,7 @@ test("chooses and clears a reaction trigger with the app emoji picker", async ({
|
||||
await dialog.getByRole("button", { name: /^Trigger:/ }).click();
|
||||
const inspector = dialog.getByTestId("workflow-node-inspector");
|
||||
await inspector.getByLabel("Trigger event").click();
|
||||
await page.getByRole("menuitem", { name: "Reaction Added" }).click();
|
||||
await page.getByRole("menuitem", { name: "Reaction added" }).click();
|
||||
await inspector.getByRole("button", { name: "Reaction emoji" }).click();
|
||||
|
||||
const trigger = inspector.getByRole("button", {
|
||||
@@ -479,11 +479,13 @@ test("chooses and clears a reaction trigger with the app emoji picker", async ({
|
||||
await picker.getByRole("button", { name: ":buzz:" }).first().click();
|
||||
|
||||
await expect(trigger).toContainText(":buzz:");
|
||||
const triggerNode = dialog.getByRole("button", {
|
||||
name: "Trigger: Reaction added",
|
||||
});
|
||||
await expect(triggerNode).toBeVisible();
|
||||
await expect(
|
||||
dialog.getByRole("button", {
|
||||
name: "Trigger: :buzz: reaction added",
|
||||
}),
|
||||
).toBeVisible();
|
||||
triggerNode.getByTestId("workflow-trigger-selected-reaction"),
|
||||
).toHaveAttribute("alt", ":buzz:");
|
||||
await dialog.getByRole("tab", { name: "YAML" }).click();
|
||||
await expect(dialog.getByLabel("Workflow YAML")).toHaveValue(/:buzz:/);
|
||||
|
||||
@@ -494,7 +496,9 @@ test("chooses and clears a reaction trigger with the app emoji picker", async ({
|
||||
dialog.getByRole("button", { name: "Choose condition emoji" }),
|
||||
).toContainText("Choose a reaction");
|
||||
await expect(
|
||||
dialog.getByRole("button", { name: "Trigger: Reaction Added" }),
|
||||
dialog
|
||||
.getByRole("button", { name: "Trigger: Reaction added" })
|
||||
.getByTestId("workflow-trigger-icon-reaction_added"),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -543,7 +547,7 @@ test("chooses a reaction emoji condition with the app emoji picker", async ({
|
||||
await dialog.getByRole("button", { name: /^Trigger:/ }).click();
|
||||
let inspector = dialog.getByTestId("workflow-node-inspector");
|
||||
await inspector.getByLabel("Trigger event").click();
|
||||
await page.getByRole("menuitem", { name: "Reaction Added" }).click();
|
||||
await page.getByRole("menuitem", { name: "Reaction added" }).click();
|
||||
|
||||
inspector = dialog.getByTestId("workflow-node-inspector");
|
||||
await expect(
|
||||
@@ -583,7 +587,7 @@ test("chooses a reacted-to message from the workflow channel", async ({
|
||||
.click();
|
||||
const inspector = dialog.getByTestId("workflow-node-inspector");
|
||||
await inspector.getByLabel("Trigger event").click();
|
||||
await page.getByRole("menuitem", { name: "Reaction Added" }).click();
|
||||
await page.getByRole("menuitem", { name: "Reaction added" }).click();
|
||||
const emojiField = inspector.getByRole("button", {
|
||||
name: "Reaction emoji",
|
||||
});
|
||||
@@ -625,7 +629,7 @@ test("chooses a reacted-to message from the workflow channel", async ({
|
||||
}
|
||||
await expect(
|
||||
dialog.getByRole("button", {
|
||||
name: "Trigger: :buzz: reaction added by alice to “React to me with a custom emoji”",
|
||||
name: "Trigger: Reaction added by alice to “React to me with a custom emoji”",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
@@ -867,7 +871,7 @@ test("captures disabled diff workflows in the list UI", async ({ page }) => {
|
||||
"When a matching diff is posted, wait for a moment",
|
||||
);
|
||||
await expect(card).toContainText(description);
|
||||
await expect(card).toContainText("Diff Posted");
|
||||
await expect(card).toContainText("Diff posted");
|
||||
await expect(card).toContainText("disabled");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user