Skip to content

Redesign automations UI with card-based flow and improved UX#1655

Open
karinakharchenko wants to merge 8 commits intorocket-admin:mainfrom
karinakharchenko:automation-empty-state
Open

Redesign automations UI with card-based flow and improved UX#1655
karinakharchenko wants to merge 8 commits intorocket-admin:mainfrom
karinakharchenko:automation-empty-state

Conversation

@karinakharchenko
Copy link
Contributor

Summary

  • Redesign automations page with card-based creation/edit flow featuring WHEN/THEN step badges, trigger pills, and action method pills
  • Replace dropdown-based form with visual tile-based trigger selection (Add row, Update row, Delete row, Custom) with colored active states
  • Improve Save button UX: always active with inline validation that focuses empty fields top-to-bottom
  • Replace sidebar add icon with dashed "Add automation" button showing "New automation" placeholder in real-time
  • Unify styling between creation and edit modes with full dark/light theme support
  • Fix action card visibility bug when all triggers deselected
  • Update icon-picker to show "Add icon"/"Change icon" with dashed border

Test plan

  • Navigate to automations with 0 rules — empty state visible with "Create automation" button
  • Click "Add automation" in sidebar — "New automation" appears in list, form opens
  • Type name — sidebar title updates in real-time
  • Toggle trigger pills — colored active states, "or" separators visible
  • Select Custom trigger — inline settings (label, icon picker, confirmation, affects) appear
  • Action card disabled until triggers selected; pulse animation on Save without triggers
  • Select action method (URL/Email/Slack) — corresponding fields appear
  • Click Save with empty fields — focuses first empty field without red errors
  • Successful save — button shows "Saved" and becomes disabled
  • Click saved rule in sidebar — edit view with same card layout
  • Back button navigates to table view
  • Dark and light themes render correctly

🤖 Generated with Claude Code

karinakharchenko and others added 4 commits March 9, 2026 15:27
Replace dropdown-based rule creation with visual WHEN/THEN card layout.
Add colored trigger pills with glow states, action method pills, and
unified styling for both creation and edit views. Save button shows
"Saved" state after successful save.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gger/action bugs

- Match footer pattern with widgets (routerLink Back, proper shadow/padding per theme)
- Improve dark theme: lighter action pill borders/text, lighter hover states, muted trigger colors
- Improve light theme: muted trigger colors when inactive, darker affects-tab text
- Fix Single/Multiple row buttons not clickable (use setCustomEventType method)
- Fix action card staying visible when all triggers deselected
- Unify icon-picker: show "Add icon"/"Change icon" with dashed border
- Align icon-picker and checkbox vertically with input fields
- Style WHEN/THEN badges: larger text, thinner/lighter background

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Save button always active (disabled only when submitting or already saved)
- On click, validates top-to-bottom: name → triggers → action fields
- Focuses empty input or opens empty select on validation failure
- Highlights trigger card with pulse animation when no triggers selected
- Remove required attributes to avoid red error styling on focus

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rule in list

- Remove icon-button from sidebar header
- Add dashed "Add automation" button below saved rules list
- Show "New automation" placeholder in sidebar when creating
- Sync name input with sidebar title in real-time
- Clean up unsaved rule from list on Back/undo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 9, 2026 16:13
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR redesigns the database table “Automations” page to a card-based WHEN/THEN flow with trigger/action pills, improved empty/creation states, and a refreshed icon picker button UX.

Changes:

  • Reworked automations editor UI into a two-step (Triggers → Action) card layout with pill/tile interactions and a fixed bottom action bar.
  • Updated save UX/state tracking (e.g., isSaved, creation mode) and added inline focus/scroll guidance for missing required inputs.
  • Updated the icon picker trigger button to display “Add icon” / “Change icon” with a unified button style.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
frontend/src/app/components/ui-components/icon-picker/icon-picker.component.html Simplifies icon-picker trigger into a single button that changes label based on whether an icon is selected.
frontend/src/app/components/dashboard/db-table-view/db-table-actions/db-table-actions.component.ts Adds creation/edit state, trigger/action selection helpers, and inline validation/focus logic for the new UI flow.
frontend/src/app/components/dashboard/db-table-view/db-table-actions/db-table-actions.component.html Replaces the old dropdown-based form with a card-based WHEN/THEN flow and sidebar “Add automation” behavior.
frontend/src/app/components/dashboard/db-table-view/db-table-actions/db-table-actions.component.css Introduces new styling for the card flow, pills, and fixed action bar (dark/light scheme support).
Comments suppressed due to low confidence (1)

frontend/src/app/components/dashboard/db-table-view/db-table-actions/db-table-actions.component.ts:548

  • After switching to the new trigger-pill UI, several legacy methods/properties appear unused by the template (handleAddNewRule(), onEventChange(), removeEvent(), and related “trailing null” handling). Leaving both the new flow and the old form logic in place increases complexity and the risk of state bugs. Consider removing the unused legacy paths or explicitly isolating them behind a feature flag to keep the component’s state model single-purpose.
	onEventChange(event: any) {
		console.log(this.selectedRule.events);
		this.selectedEvents.push(event.value);

		let customEvent = this.selectedRule.events.find((event) => event.event === EventType.Custom);

		if (event.value === EventType.Custom) {
			customEvent = {
				...customEvent,
				title: '',
				type: CustomActionType.Single,
				icon: '',
				require_confirmation: false,
			};
			// this.selectedRule.events.push(customEvent);
			this.selectedRuleCustomEvent = customEvent;
		}

		if (this.selectedRule.events.length < 4) {
			this.selectedRule.events.push({ event: null });
		}
	}

	toggleTriggerTile(eventType: EventType) {
		this.isSaved = false;
		const idx = this.selectedEvents.indexOf(eventType);
		if (idx > -1) {
			// Remove trigger
			this.selectedRule.events = this.selectedRule.events.filter((e) => e.event !== eventType);
			this.selectedEvents = this.selectedEvents.filter((e) => e !== eventType);
			if (eventType === EventType.Custom) {
				this.selectedRuleCustomEvent = null;
			}
		} else {
			// Add trigger
			this.selectedRule.events = this.selectedRule.events.filter((e) => e.event !== null);
			this.selectedRule.events.push({ event: eventType });
			this.selectedEvents.push(eventType);
			if (eventType === EventType.Custom) {
				this.selectedRuleCustomEvent = {
					event: EventType.Custom,
					title: '',
					type: CustomActionType.Single,
					icon: '',
					require_confirmation: false,
				};
			}
		}
		// Keep trailing null for the old form
		if (this.selectedRule.events[this.selectedRule.events.length - 1]?.event !== null) {
			this.selectedRule.events.push({ event: null });
		}
	}

	selectActionMethod(method: string) {
		this.isSaved = false;
		if (this.selectedRule.table_actions.length) {
			this.selectedRule.table_actions[0].method = method as CustomActionMethod;
		}
	}

	removeEvent(event: any) {
		this.selectedRule.events = this.selectedRule.events.filter((e) => e.event !== event);
		this.selectedEvents = this.selectedRule.events.map((event) => event.event);

		if (event === EventType.Custom) {
			this.selectedRuleCustomEvent = null;
		}

		if (this.selectedRule.events.length === 3) {
			this.selectedRule.events.push({ event: null });
		}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +4 to 16
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatRadioModule } from '@angular/material/radio';
import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav';
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several newly introduced members/imports that appear unused in this component after the UI refactor (e.g. @ViewChild('newActionInput'), MatButtonToggleModule, MatMenuModule, and MatRadioModule). Keeping unused ViewChild queries and module imports makes the component harder to maintain and can confuse future refactors. Remove unused imports/fields or wire them up if they’re intended for upcoming work.

Copilot uses AI. Check for mistakes.
Comment on lines +129 to +152
<div class="action-methods">
<button type="button" class="action-method-pill"
[class.action-method-pill--active]="$any(selectedRule.table_actions[0]).method === 'URL'"
(click)="selectActionMethod('URL')">
<mat-icon class="action-method-pill__icon">link</mat-icon> URL webhook
</button>
<button type="button" class="action-method-pill"
[class.action-method-pill--active]="$any(selectedRule.table_actions[0]).method === 'EMAIL'"
(click)="selectActionMethod('EMAIL')">
<mat-icon class="action-method-pill__icon">email</mat-icon> Email
</button>
<button type="button" class="action-method-pill"
[class.action-method-pill--active]="$any(selectedRule.table_actions[0]).method === 'SLACK'"
(click)="selectActionMethod('SLACK')">
<mat-icon class="action-method-pill__icon">tag</mat-icon> Slack
</button>
</div>

<div class="custom-event__row">
<mat-radio-group
name="action-type"
[(ngModel)]="selectedRuleCustomEvent.type">
<mat-label>Affects</mat-label>
<mat-radio-button value='single' class="radio-button_first" checked>
Single row
</mat-radio-button>
<mat-radio-button value='multiple' class="radio-button_second">
Multiple rows
</mat-radio-button>
</mat-radio-group>
<div class="action-fields">
@if ($any(selectedRule.table_actions[0]).method === 'URL') {
<mat-form-field appearance="outline" class="action-fields__input">
<mat-label>Webhook URL</mat-label>
<input matInput [(ngModel)]="selectedRule.table_actions[0].url" name="action-url">
</mat-form-field>
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This template assumes selectedRule.table_actions[0] always exists (e.g. $any(selectedRule.table_actions[0]).method and bindings to [0].url/emails/slack_url). If a rule is loaded with an empty table_actions array, change detection will throw when reading .method from undefined and the page will break. Consider guarding this block with an *ngIf/@if on selectedRule.table_actions?.length, or initializing a default action when selecting/creating a rule so [0] is always defined.

Copilot uses AI. Check for mistakes.
Comment on lines 244 to 250
setSelectedRule(rule: Rule) {
this.selectedRule = rule;
this.selectedRuleTitle = rule.title;
this.isCreationMode = !rule.id;
if (this.selectedRule.events[this.selectedRule.events.length - 1].event !== null)
this.selectedRule.events.push({ event: null });
this.selectedEvents = this.selectedRule.events.map((event) => event.event);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isSaved isn't reset when switching rules via setSelectedRule(). After saving one rule (isSaved = true), selecting a different rule will still show a disabled “Saved” button until the user edits something, which is misleading and can block an immediate save. Reset isSaved (and potentially other creation-state flags) inside setSelectedRule() and/or addNewRule() so each rule starts in a consistent state.

Copilot uses AI. Check for mistakes.
Comment on lines 391 to 396
addRule() {
this.submitting = true;
if (this.selectedRuleTitle) this.selectedRule.title = this.selectedRuleTitle;
this.newRule = null;
this.selectedRule.events = this.selectedRule.events.filter((event) => event.event !== null);
this.selectedRule.events = this.selectedRule.events.map((event) => {
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addRule(), this.newRule is cleared before the save request completes. If the request fails, the unsaved placeholder rule remains in rules but can no longer be undone via undoRule() (which relies on newRule), leaving the UI in a stuck creation state. Consider only clearing newRule (and toggling isCreationMode) after a successful save, or keeping a separate reference so cancel/undo still works on failure.

Copilot uses AI. Check for mistakes.
karinakharchenko and others added 4 commits March 10, 2026 14:25
…WHEN/THEN badges inside cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants