-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Rules improvements #1087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Rules improvements #1087
Changes from 71 commits
Commits
Show all changes
74 commits
Select commit
Hold shift + click to select a range
68f7c6a
Add stats cards to setup page
jshwrnr 4f2ed54
Add home to sidebar
jshwrnr c0d4a2c
Clean up rules table UI
jshwrnr 936599f
Remove unused code
jshwrnr 7a1ed21
Align "Add rule" button to the right side
jshwrnr 29fac52
Initial clean up of Rules creator
jshwrnr ac5f1ac
Wrap rule conditions in card
jshwrnr 9f4e1f4
Move rule steps to a separate component
jshwrnr adfba60
Replace match all dropdown
jshwrnr dbe8fe7
Remove step number in rule steps
jshwrnr ecc810f
Remove isActionsEditMode
jshwrnr 35c39e1
Add "Where" next to dropdown in rule select
jshwrnr 011e312
Cleaning up the user experience of creating rules
jshwrnr 2cea0fe
Replace text
jshwrnr 3edf40b
Refactor action rule builder
jshwrnr 69c8fac
Add icons to actions select
jshwrnr ea00e77
Various changes
jshwrnr 6d532d0
Make trash icon lighter gray
jshwrnr f50f723
Text and icon changes
jshwrnr 92a9d14
Clean up label rule form
jshwrnr d813ac1
Wrap certain actions in cards and show their labels
jshwrnr bead928
Show all form content within card
jshwrnr 02b7ede
Show "show all fields" above the fields that are then shown
jshwrnr ebab99c
Styling fixes for rules modal
jshwrnr 474d30a
field gap fix
jshwrnr 5b70a4a
Fix spacing in rules form
jshwrnr 309b2b3
Update placeholder
jshwrnr 360a7b6
Move tooltips to fields
jshwrnr b1d660f
Use new delay fields for "Mark read" option
jshwrnr a9b2b29
Color fix
jshwrnr 3acb5f7
Fix issue when removing an action
jshwrnr ceddc3e
Add card around webhook action
jshwrnr d22cbad
Update text
jshwrnr a3847b6
Merge branch 'main' into feat/rules-improvements
jshwrnr 5c1171c
Fix typo
jshwrnr 4119f65
Fix
jshwrnr 096ea69
Merge branch 'main' into feat/rules-improvements
elie222 e2fe6fb
Merge branch 'feat/rules-improvements' of https://github.com/jshwrnr/…
jshwrnr 258d6c1
Merge branch 'main' into feat/rules-improvements
jshwrnr 3de9d99
Merge branch 'main' into feat/ux-improvements
jshwrnr 336e9ad
Merge branch 'feat/ux-improvements' into feat/rules-improvements
jshwrnr b353538
Remove "rules executed" and "inbox coverage" and replace them with "d…
jshwrnr 4e377f8
Merge branch 'feat/ux-improvements' into feat/rules-improvements
jshwrnr 0236d7f
Align action columns to the left instead of right
jshwrnr dde60f6
Merge branch 'main' into feat/rules-improvements
elie222 3fb0612
Move advanced rule options behind dropdown menu
jshwrnr 8de5b88
Change copy to "When"
jshwrnr 7d5f421
Merge branch 'main' into feat/rules-improvements
jshwrnr 2a70d9f
Remove conditional title in automation rules
jshwrnr 6c45c95
Spacing fix
jshwrnr 607735d
Change name from "Home" to "Dashboard"
jshwrnr 0646081
Merge branch 'main' into feat/rules-improvements
jshwrnr 4df816e
Undo changes with conditions
jshwrnr 347723a
Allow condition values to be set to null
jshwrnr 6067f44
Merge branch 'main' into feat/rules-improvements
elie222 81b98f0
refactor
elie222 20083e8
clean up
elie222 46dfcd2
uniform button size
elie222 5a0ebfc
simplify rule form ui
elie222 b03158c
copy
elie222 500fcac
Merge branch 'main' into feat/rules-improvements
elie222 1673fd8
fix up action buttons
elie222 10208dd
fix up ui when logic
elie222 7436a3c
simplify ui
elie222 62f50a1
fixes for dev
elie222 e30a17f
copy
elie222 5263376
fix
elie222 9543c3d
revert changes that arent ready
elie222 1493fab
styling
elie222 39d3dc9
fixes
elie222 6b10a0d
fix paths
elie222 7357a21
show if a rule has static conditions
elie222 8bfa7cb
show icon on each row with conditions
elie222 c1c2e2c
fix
elie222 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
773 changes: 773 additions & 0 deletions
773
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsx
Large diffs are not rendered by default.
Oops, something went wrong.
547 changes: 547 additions & 0 deletions
547
apps/web/app/(app)/[emailAccountId]/assistant/ConditionSteps.tsx
Large diffs are not rendered by default.
Oops, something went wrong.
1,422 changes: 269 additions & 1,153 deletions
1,422
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
Large diffs are not rendered by default.
Oops, something went wrong.
37 changes: 37 additions & 0 deletions
37
apps/web/app/(app)/[emailAccountId]/assistant/RuleSectionCard.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { Card } from "@/components/ui/card"; | ||
| import { TypographyH3 } from "@/components/Typography"; | ||
| import { cn } from "@/utils"; | ||
|
|
||
| export function RuleSectionCard({ | ||
| icon: Icon, | ||
| color, | ||
| title, | ||
| errors, | ||
| children, | ||
| }: { | ||
| icon: React.ComponentType<{ className?: string }>; | ||
| color: "blue" | "green"; | ||
| title: string; | ||
| errors?: React.ReactNode; | ||
| children: React.ReactNode; | ||
| }) { | ||
| return ( | ||
| <Card className="rounded-lg p-4"> | ||
| <div> | ||
| <div className="flex items-center gap-3"> | ||
| <Icon | ||
| className={cn("size-5", { | ||
| "text-blue-600 dark:text-blue-400": color === "blue", | ||
| "text-green-600 dark:text-green-400": color === "green", | ||
| })} | ||
| /> | ||
| <TypographyH3 className="text-base">{title}</TypographyH3> | ||
| </div> | ||
|
|
||
| {errors && <div className="mt-2">{errors}</div>} | ||
|
|
||
| {children && <div className="mt-4 space-y-2">{children}</div>} | ||
| </div> | ||
| </Card> | ||
| ); | ||
| } | ||
233 changes: 233 additions & 0 deletions
233
apps/web/app/(app)/[emailAccountId]/assistant/RuleStep.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,233 @@ | ||
| import { Button } from "@/components/ui/button"; | ||
| import { | ||
| TrashIcon, | ||
| MoreHorizontalIcon, | ||
| ClockIcon, | ||
| SparklesIcon, | ||
| PenLineIcon, | ||
| } from "lucide-react"; | ||
| import { cn } from "@/utils"; | ||
| import { | ||
| DropdownMenu, | ||
| DropdownMenuContent, | ||
| DropdownMenuItem, | ||
| DropdownMenuTrigger, | ||
| } from "@/components/ui/dropdown-menu"; | ||
|
elie222 marked this conversation as resolved.
|
||
|
|
||
| function DeleteButton({ | ||
| onClick, | ||
| ariaLabel, | ||
| }: { | ||
| onClick: () => void; | ||
| ariaLabel: string; | ||
| }) { | ||
| return ( | ||
| <Button | ||
| size="icon" | ||
| variant="ghost" | ||
| className="size-8 mt-1" | ||
| aria-label={ariaLabel} | ||
| onClick={onClick} | ||
| > | ||
| <TrashIcon className="size-4 text-muted-foreground" /> | ||
| </Button> | ||
| ); | ||
| } | ||
|
|
||
| function OptionsMenu({ | ||
| onAddDelay, | ||
| onRemoveDelay, | ||
| hasDelay, | ||
| onUsePrompt, | ||
| onUseLabel, | ||
| isPromptMode, | ||
| onSetManually, | ||
| onUseAiDraft, | ||
| isManualMode, | ||
| }: { | ||
| onAddDelay?: () => void; | ||
| onRemoveDelay?: () => void; | ||
| hasDelay?: boolean; | ||
| onUsePrompt?: () => void; | ||
| onUseLabel?: () => void; | ||
| isPromptMode?: boolean; | ||
| onSetManually?: () => void; | ||
| onUseAiDraft?: () => void; | ||
| isManualMode?: boolean; | ||
| }) { | ||
| const hasOptions = | ||
| onAddDelay || | ||
| onRemoveDelay || | ||
| onUsePrompt || | ||
| onUseLabel || | ||
| onSetManually || | ||
| onUseAiDraft; | ||
|
|
||
| if (!hasOptions) return null; | ||
|
|
||
| return ( | ||
| <DropdownMenu> | ||
| <DropdownMenuTrigger asChild> | ||
| <Button | ||
| size="icon" | ||
| variant="ghost" | ||
| className="size-8 mt-1" | ||
| aria-label="More options" | ||
| > | ||
| <MoreHorizontalIcon className="size-4 text-muted-foreground" /> | ||
| </Button> | ||
| </DropdownMenuTrigger> | ||
| <DropdownMenuContent align="end"> | ||
| {onUsePrompt && !isPromptMode && ( | ||
| <DropdownMenuItem onClick={onUsePrompt}> | ||
| <SparklesIcon className="mr-2 size-4" /> | ||
| Use prompt | ||
| </DropdownMenuItem> | ||
| )} | ||
| {onUseLabel && isPromptMode && ( | ||
| <DropdownMenuItem onClick={onUseLabel}> | ||
| <SparklesIcon className="mr-2 size-4" /> | ||
| Use label | ||
| </DropdownMenuItem> | ||
| )} | ||
| {onSetManually && !isManualMode && ( | ||
| <DropdownMenuItem onClick={onSetManually}> | ||
| <PenLineIcon className="mr-2 size-4" /> | ||
| Set content manually | ||
| </DropdownMenuItem> | ||
| )} | ||
| {onUseAiDraft && isManualMode && ( | ||
| <DropdownMenuItem onClick={onUseAiDraft}> | ||
| <SparklesIcon className="mr-2 size-4" /> | ||
| Use AI draft | ||
| </DropdownMenuItem> | ||
| )} | ||
| {onAddDelay && !hasDelay && ( | ||
| <DropdownMenuItem onClick={onAddDelay}> | ||
| <ClockIcon className="mr-2 size-4" /> | ||
| Add delay | ||
| </DropdownMenuItem> | ||
| )} | ||
| {onRemoveDelay && hasDelay && ( | ||
| <DropdownMenuItem onClick={onRemoveDelay}> | ||
| <ClockIcon className="mr-2 size-4" /> | ||
| Remove delay | ||
| </DropdownMenuItem> | ||
| )} | ||
| </DropdownMenuContent> | ||
| </DropdownMenu> | ||
| ); | ||
| } | ||
|
|
||
| function ActionButtons({ | ||
| onRemove, | ||
| removeAriaLabel, | ||
| onAddDelay, | ||
| onRemoveDelay, | ||
| hasDelay, | ||
| onUsePrompt, | ||
| onUseLabel, | ||
| isPromptMode, | ||
| onSetManually, | ||
| onUseAiDraft, | ||
| isManualMode, | ||
| }: { | ||
| onRemove: () => void; | ||
| removeAriaLabel: string; | ||
| onAddDelay?: () => void; | ||
| onRemoveDelay?: () => void; | ||
| hasDelay?: boolean; | ||
| onUsePrompt?: () => void; | ||
| onUseLabel?: () => void; | ||
| isPromptMode?: boolean; | ||
| onSetManually?: () => void; | ||
| onUseAiDraft?: () => void; | ||
| isManualMode?: boolean; | ||
| }) { | ||
| return ( | ||
| <div className="flex items-start"> | ||
| <OptionsMenu | ||
| onAddDelay={onAddDelay} | ||
| onRemoveDelay={onRemoveDelay} | ||
| hasDelay={hasDelay} | ||
| onUsePrompt={onUsePrompt} | ||
| onUseLabel={onUseLabel} | ||
| isPromptMode={isPromptMode} | ||
| onSetManually={onSetManually} | ||
| onUseAiDraft={onUseAiDraft} | ||
| isManualMode={isManualMode} | ||
| /> | ||
| <DeleteButton onClick={onRemove} ariaLabel={removeAriaLabel} /> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| function CardLayout({ children }: { children: React.ReactNode }) { | ||
| return <div className="flex flex-col sm:flex-row gap-2">{children}</div>; | ||
| } | ||
|
|
||
| function CardLayoutRight({ | ||
| children, | ||
| className, | ||
| }: { | ||
| children: React.ReactNode; | ||
| className?: string; | ||
| }) { | ||
| return ( | ||
| <div className={cn("space-y-2 mx-auto w-full", className)}>{children}</div> | ||
| ); | ||
| } | ||
|
|
||
| export function RuleStep({ | ||
| onRemove, | ||
| leftContent, | ||
| rightContent, | ||
| removeAriaLabel, | ||
| onAddDelay, | ||
| onRemoveDelay, | ||
| hasDelay, | ||
| onUsePrompt, | ||
| onUseLabel, | ||
| isPromptMode, | ||
| onSetManually, | ||
| onUseAiDraft, | ||
| isManualMode, | ||
| }: { | ||
| onRemove: () => void; | ||
| leftContent: React.ReactNode | null; | ||
| rightContent: React.ReactNode; | ||
| removeAriaLabel: string; | ||
| onAddDelay?: () => void; | ||
| onRemoveDelay?: () => void; | ||
| hasDelay?: boolean; | ||
| onUsePrompt?: () => void; | ||
| onUseLabel?: () => void; | ||
| isPromptMode?: boolean; | ||
| onSetManually?: () => void; | ||
| onUseAiDraft?: () => void; | ||
| isManualMode?: boolean; | ||
| }) { | ||
| return ( | ||
| <div className="flex items-start gap-3"> | ||
| <div className="relative flex-1"> | ||
| <CardLayout> | ||
| {leftContent && <div className="shrink-0">{leftContent}</div>} | ||
| <CardLayoutRight>{rightContent}</CardLayoutRight> | ||
| <ActionButtons | ||
| onRemove={onRemove} | ||
| removeAriaLabel={removeAriaLabel} | ||
| onAddDelay={onAddDelay} | ||
| onRemoveDelay={onRemoveDelay} | ||
| hasDelay={hasDelay} | ||
| onUsePrompt={onUsePrompt} | ||
| onUseLabel={onUseLabel} | ||
| isPromptMode={isPromptMode} | ||
| onSetManually={onSetManually} | ||
| onUseAiDraft={onUseAiDraft} | ||
| isManualMode={isManualMode} | ||
| /> | ||
| </CardLayout> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
40 changes: 40 additions & 0 deletions
40
apps/web/app/(app)/[emailAccountId]/assistant/RuleSteps.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import { Card } from "@/components/ui/card"; | ||
| import { Button } from "@/components/ui/button"; | ||
| import { PlusIcon } from "lucide-react"; | ||
| import { Tooltip } from "@/components/Tooltip"; | ||
| import type { ReactNode } from "react"; | ||
|
|
||
| export function RuleSteps({ | ||
| children, | ||
| onAdd, | ||
| addButtonLabel, | ||
| addButtonDisabled = false, | ||
| addButtonTooltip, | ||
| }: { | ||
| children: ReactNode; | ||
| onAdd: () => void; | ||
| addButtonLabel: string; | ||
| addButtonDisabled?: boolean; | ||
| addButtonTooltip?: string; | ||
| }) { | ||
| return ( | ||
| <Card className="p-4 space-y-2 border-none shadow-none bg-gray-50 dark:bg-gray-900"> | ||
| {children} | ||
| <div> | ||
| <Tooltip hide={!addButtonTooltip} content={addButtonTooltip || ""}> | ||
| <span> | ||
| <Button | ||
| variant="ghost" | ||
| size="sm" | ||
| onClick={onAdd} | ||
| disabled={addButtonDisabled} | ||
| Icon={PlusIcon} | ||
| > | ||
| {addButtonLabel} | ||
| </Button> | ||
| </span> | ||
| </Tooltip> | ||
| </div> | ||
| </Card> | ||
| ); | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.