From f222249f4f08c23f77f8c663b2985e25de316c9a Mon Sep 17 00:00:00 2001 From: George Desipris <73396808+desiprisg@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:12:55 +0200 Subject: [PATCH] feat(dashboard): Read only code first workflows & sidebar cleanups (#6823) --- apps/dashboard/eslint.config.js | 2 +- .../src/components/dashboard-layout.tsx | 2 +- .../header-navigation/header-navigation.tsx | 17 ++-- .../src/components/primitives/button.tsx | 38 ++++++- .../src/components/primitives/pagination.tsx | 3 +- .../src/components/primitives/variants.ts | 33 ------- .../components/side-navigation/Sidebar.tsx | 33 +++++++ .../side-navigation/side-navigation.tsx | 99 ++++++++++--------- .../workflow-editor/action-picker.tsx | 3 +- .../workflow-editor/configure-workflow.tsx | 71 +++++++------ .../src/components/workflow-editor/edges.tsx | 14 +-- .../src/components/workflow-editor/nodes.tsx | 6 +- .../components/workflow-editor/steps/chat.tsx | 7 +- .../workflow-editor/steps/common-fields.tsx | 6 +- .../workflow-editor/steps/configure-step.tsx | 37 +++++-- .../steps/delete-step-button.tsx | 17 ---- .../steps/edit-step-sidebar.tsx | 14 +-- .../workflow-editor/steps/in-app.tsx | 17 ++-- .../test-workflow-logs-sidebar.tsx | 2 +- .../workflow-editor-context.tsx | 1 + .../workflow-editor-provider.tsx | 6 +- .../src/components/workflow-list.tsx | 3 +- apps/dashboard/src/hooks/use-form-autosave.ts | 6 +- apps/dashboard/src/pages/edit-workflow.tsx | 5 +- 24 files changed, 251 insertions(+), 191 deletions(-) create mode 100644 apps/dashboard/src/components/side-navigation/Sidebar.tsx delete mode 100644 apps/dashboard/src/components/workflow-editor/steps/delete-step-button.tsx diff --git a/apps/dashboard/eslint.config.js b/apps/dashboard/eslint.config.js index 16d07b7f581..95bb45ab773 100644 --- a/apps/dashboard/eslint.config.js +++ b/apps/dashboard/eslint.config.js @@ -20,7 +20,7 @@ export default tseslint.config( rules: { ...reactHooks.configs.recommended.rules, '@typescript-eslint/no-explicit-any': 'warn', - 'react-refresh/only-export-components': ['error', { allowConstantExport: true }], + 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], '@typescript-eslint/no-unused-vars': ['off'], '@typescript-eslint/naming-convention': [ 'error', diff --git a/apps/dashboard/src/components/dashboard-layout.tsx b/apps/dashboard/src/components/dashboard-layout.tsx index 8977c31bca5..366bb332969 100644 --- a/apps/dashboard/src/components/dashboard-layout.tsx +++ b/apps/dashboard/src/components/dashboard-layout.tsx @@ -18,7 +18,7 @@ export const DashboardLayout = ({
- +
{children}
diff --git a/apps/dashboard/src/components/header-navigation/header-navigation.tsx b/apps/dashboard/src/components/header-navigation/header-navigation.tsx index 869902079fc..a613622f950 100644 --- a/apps/dashboard/src/components/header-navigation/header-navigation.tsx +++ b/apps/dashboard/src/components/header-navigation/header-navigation.tsx @@ -1,18 +1,21 @@ -import { ReactNode } from 'react'; +import { HTMLAttributes, ReactNode } from 'react'; import { UserProfile } from '@/components/user-profile'; import { InboxButton } from '@/components/inbox-button'; import { CustomerSupportButton } from './customer-support-button'; import { EditBridgeUrlButton } from './edit-bridge-url-button'; +import { cn } from '@/utils/ui'; -export const HeaderNavigation = ({ - startItems, - hideBridgeUrl = false, -}: { +type HeaderNavigationProps = HTMLAttributes & { startItems?: ReactNode; hideBridgeUrl?: boolean; -}) => { +}; +export const HeaderNavigation = (props: HeaderNavigationProps) => { + const { startItems, hideBridgeUrl = false, className, ...rest } = props; return ( -
+
{startItems}
{!hideBridgeUrl ? : null} diff --git a/apps/dashboard/src/components/primitives/button.tsx b/apps/dashboard/src/components/primitives/button.tsx index 14ddf1bcf7f..001dbaaf3c0 100644 --- a/apps/dashboard/src/components/primitives/button.tsx +++ b/apps/dashboard/src/components/primitives/button.tsx @@ -1,8 +1,42 @@ import * as React from 'react'; import { Slot } from '@radix-ui/react-slot'; -import { type VariantProps } from 'class-variance-authority'; +import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '@/utils/ui'; -import { buttonVariants } from './variants'; + +export const buttonVariants = cva( + `relative isolate inline-flex items-center justify-center whitespace-nowrap rounded-lg gap-1 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50`, + { + variants: { + variant: { + default: + 'bg-gradient-to-b from-neutral-alpha-900 to-neutral-900 text-neutral-foreground [clip-path:border-box] shadow-[inset_0_-4px_2px_-2px_hsl(var(--neutral-900)),inset_0_0_0_1px_rgba(255,255,255,0.16),0_0_0_1px_hsl(var(--neutral-900)),0px_1px_2px_0px_#0E121B3D] after:content-[""] after:absolute after:w-full after:h-full after:bg-gradient-to-b after:from-background/10 after:opacity-0 hover:after:opacity-100 after:rounded-lg after:transition-opacity after:duration-300', + primary: + 'bg-gradient-to-b from-primary/90 to-primary text-primary-foreground [clip-path:border-box] shadow-[inset_0_-4px_2px_-2px_hsl(var(--primary)),inset_0_0_0_1px_rgba(255,255,255,0.16),0_0_0_1px_hsl(var(--primary)),0px_1px_2px_0px_#0E121B3D] after:content-[""] after:absolute after:w-full after:h-full after:bg-gradient-to-b after:from-background/10 after:opacity-0 hover:after:opacity-100 after:rounded-lg after:transition-opacity after:duration-300', + destructive: + 'bg-gradient-to-b from-destructive/90 to-destructive text-destructive-foreground [clip-path:border-box] shadow-[inset_0_-4px_2px_-2px_hsl(var(--destructive)),inset_0_0_0_1px_rgba(255,255,255,0.16),0_0_0_1px_hsl(var(--destructive)),0px_1px_2px_0px_#0E121B3D] after:content-[""] after:absolute after:w-full after:h-full after:bg-gradient-to-b after:from-background/10 after:opacity-0 hover:after:opacity-100 after:rounded-lg after:transition-opacity after:duration-300', + outline: + 'border border-input text-foreground-600 bg-background shadow-xs hover:bg-accent hover:text-accent-foreground', + dashed: 'border border-dashed border-input bg-background hover:bg-accent text-foreground-600', + ghost: 'hover:bg-accent', + ghostDestructive: 'hover:bg-destructive/10 text-destructive', + link: 'underline-offset-4 hover:underline', + light: + 'bg-destructive/10 hover:bg-background hover:border hover:border-destructive text-destructive focus-visible:ring-destructive/10 focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:bg-background focus-visible:border focus-visible:border-destructive', + }, + size: { + default: 'h-9 p-2.5', + xs: 'h-6 px-1.5 rounded-md text-xs', + sm: 'h-8 px-1.5 rounded-md text-xs', + lg: 'h-10 rounded-md px-8', + icon: 'size-8', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + } +); export interface ButtonProps extends React.ButtonHTMLAttributes, diff --git a/apps/dashboard/src/components/primitives/pagination.tsx b/apps/dashboard/src/components/primitives/pagination.tsx index 762a74ff278..8a348c592b6 100644 --- a/apps/dashboard/src/components/primitives/pagination.tsx +++ b/apps/dashboard/src/components/primitives/pagination.tsx @@ -8,8 +8,7 @@ import { } from '@radix-ui/react-icons'; import { cn } from '@/utils/ui'; -import { ButtonProps } from '@/components/primitives/button'; -import { buttonVariants } from '@/components/primitives/variants'; +import { ButtonProps, buttonVariants } from '@/components/primitives/button'; import { Link, LinkProps } from 'react-router-dom'; const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => ( diff --git a/apps/dashboard/src/components/primitives/variants.ts b/apps/dashboard/src/components/primitives/variants.ts index ecfdeab6b90..e85a8236b26 100644 --- a/apps/dashboard/src/components/primitives/variants.ts +++ b/apps/dashboard/src/components/primitives/variants.ts @@ -57,39 +57,6 @@ export const badgeContentVariants = cva('text-xs font-medium', { }, }); -export const buttonVariants = cva( - `relative isolate inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50`, - { - variants: { - variant: { - default: - 'bg-gradient-to-b from-neutral-alpha-900 to-neutral-900 text-neutral-foreground [clip-path:border-box] shadow-[inset_0_-4px_2px_-2px_hsl(var(--neutral-900)),inset_0_0_0_1px_rgba(255,255,255,0.16),0_0_0_1px_hsl(var(--neutral-900)),0px_1px_2px_0px_#0E121B3D] after:content-[""] after:absolute after:w-full after:h-full after:bg-gradient-to-b after:from-background/10 after:opacity-0 hover:after:opacity-100 after:rounded-lg after:transition-opacity after:duration-300', - primary: - 'bg-gradient-to-b from-primary/90 to-primary text-primary-foreground [clip-path:border-box] shadow-[inset_0_-4px_2px_-2px_hsl(var(--primary)),inset_0_0_0_1px_rgba(255,255,255,0.16),0_0_0_1px_hsl(var(--primary)),0px_1px_2px_0px_#0E121B3D] after:content-[""] after:absolute after:w-full after:h-full after:bg-gradient-to-b after:from-background/10 after:opacity-0 hover:after:opacity-100 after:rounded-lg after:transition-opacity after:duration-300', - destructive: - 'bg-gradient-to-b from-destructive/90 to-destructive text-destructive-foreground [clip-path:border-box] shadow-[inset_0_-4px_2px_-2px_hsl(var(--destructive)),inset_0_0_0_1px_rgba(255,255,255,0.16),0_0_0_1px_hsl(var(--destructive)),0px_1px_2px_0px_#0E121B3D] after:content-[""] after:absolute after:w-full after:h-full after:bg-gradient-to-b after:from-background/10 after:opacity-0 hover:after:opacity-100 after:rounded-lg after:transition-opacity after:duration-300', - outline: 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground', - dashed: 'border border-dashed border-input bg-background hover:bg-accent text-foreground-600', - ghost: 'hover:bg-accent', - link: 'underline-offset-4 hover:underline', - light: - 'bg-destructive/10 hover:bg-background hover:border hover:border-destructive text-destructive focus-visible:ring-destructive/10 focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:bg-background focus-visible:border focus-visible:border-destructive', - }, - size: { - default: 'h-9 p-2.5', - xs: 'h-6 px-1.5 rounded-md text-xs', - sm: 'h-8 px-1.5 rounded-md text-sm', - lg: 'h-10 rounded-md px-8', - icon: 'size-8', - }, - }, - defaultVariants: { - variant: 'default', - size: 'default', - }, - } -); - export const stepVariants = cva( 'inline-flex items-center shadow-xs rounded-full border text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 bg-neutral-50', { diff --git a/apps/dashboard/src/components/side-navigation/Sidebar.tsx b/apps/dashboard/src/components/side-navigation/Sidebar.tsx new file mode 100644 index 00000000000..48a7d970aca --- /dev/null +++ b/apps/dashboard/src/components/side-navigation/Sidebar.tsx @@ -0,0 +1,33 @@ +import { cn } from '@/utils/ui'; +import { cva, VariantProps } from 'class-variance-authority'; +import { HTMLAttributes } from 'react'; + +type SidebarHeaderProps = HTMLAttributes; +export const SidebarHeader = (props: SidebarHeaderProps) => { + const { className, ...rest } = props; + return
; +}; + +export const sidebarContentVariants = cva(`flex flex-col`, { + variants: { + size: { + sm: 'gap-2 px-3 py-2', + md: 'gap-2.5 px-3 py-3', + lg: 'gap-2.5 px-3 py-4', + }, + }, + defaultVariants: { + size: 'md', + }, +}); +type SidebarContentProps = HTMLAttributes & VariantProps; +export const SidebarContent = (props: SidebarContentProps) => { + const { className, size, ...rest } = props; + return
; +}; + +type SidebarFooterProps = HTMLAttributes; +export const SidebarFooter = (props: SidebarFooterProps) => { + const { className, ...rest } = props; + return
; +}; diff --git a/apps/dashboard/src/components/side-navigation/side-navigation.tsx b/apps/dashboard/src/components/side-navigation/side-navigation.tsx index 249e1d7b8fa..66b338462bd 100644 --- a/apps/dashboard/src/components/side-navigation/side-navigation.tsx +++ b/apps/dashboard/src/components/side-navigation/side-navigation.tsx @@ -19,6 +19,7 @@ import { buildRoute, LEGACY_ROUTES, ROUTES } from '@/utils/routes'; import { SubscribersStayTunedModal } from './subscribers-stay-tuned-modal'; import { TelemetryEvent } from '@/utils/telemetry'; import { useTelemetry } from '@/hooks/use-telemetry'; +import { SidebarContent } from '@/components/side-navigation/Sidebar'; const linkVariants = cva( `flex items-center gap-2 text-sm py-1.5 px-2 rounded-lg focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring cursor-pointer`, @@ -91,54 +92,56 @@ export const SideNavigation = () => { }; return ( -