diff --git a/apps/dashboard/src/components/activity/activity-job-item.tsx b/apps/dashboard/src/components/activity/activity-job-item.tsx index 3be677d1834..ff6996ea2af 100644 --- a/apps/dashboard/src/components/activity/activity-job-item.tsx +++ b/apps/dashboard/src/components/activity/activity-job-item.tsx @@ -69,7 +69,7 @@ export function ActivityJobItem({ job, isFirst, isLast }: ActivityJobItemProps)
{getStatusMessage(job)} - + {format(new Date(job.updatedAt), 'MMM d yyyy, HH:mm:ss')} diff --git a/apps/dashboard/src/components/activity/activity-table.tsx b/apps/dashboard/src/components/activity/activity-table.tsx index d70121b8d05..baf56dd9c54 100644 --- a/apps/dashboard/src/components/activity/activity-table.tsx +++ b/apps/dashboard/src/components/activity/activity-table.tsx @@ -1,19 +1,19 @@ +import { ActivityFilters } from '@/api/activity'; +import { Skeleton } from '@/components/primitives/skeleton'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/primitives/table'; -import { format } from 'date-fns'; +import { TimeDisplayHoverCard } from '@/components/time-display-hover-card'; import { cn } from '@/utils/ui'; import { ISubscriber } from '@novu/shared'; -import { TimeDisplayHoverCard } from '@/components/time-display-hover-card'; -import { createSearchParams, useLocation, useSearchParams, useNavigate } from 'react-router-dom'; -import { StatusBadge } from './components/status-badge'; -import { StepIndicators } from './components/step-indicators'; -import { ActivityEmptyState } from './activity-empty-state'; +import { format } from 'date-fns'; import { AnimatePresence, motion } from 'motion/react'; -import { ArrowPagination } from './components/arrow-pagination'; import { useEffect } from 'react'; -import { ActivityFilters } from '@/api/activity'; -import { useFetchActivities } from '../../hooks/use-fetch-activities'; +import { createSearchParams, useLocation, useNavigate, useSearchParams } from 'react-router-dom'; import { toast } from 'sonner'; -import { Skeleton } from '@/components/primitives/skeleton'; +import { useFetchActivities } from '../../hooks/use-fetch-activities'; +import { ActivityEmptyState } from './activity-empty-state'; +import { ArrowPagination } from './components/arrow-pagination'; +import { ActivityStatusBadge } from './components/status-badge'; +import { StepIndicators } from './components/step-indicators'; export interface ActivityTableProps { selectedActivityId: string | null; @@ -120,7 +120,7 @@ export function ActivityTable({
- + diff --git a/apps/dashboard/src/components/activity/components/status-badge.tsx b/apps/dashboard/src/components/activity/components/status-badge.tsx index 5a51cbbddf5..df25efad726 100644 --- a/apps/dashboard/src/components/activity/components/status-badge.tsx +++ b/apps/dashboard/src/components/activity/components/status-badge.tsx @@ -1,15 +1,14 @@ -import { useState, useRef, useEffect } from 'react'; -import { Badge, BadgeVariant } from '@/components/primitives/badge'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/primitives/popover'; import { IActivityJob, JobStatusEnum } from '@novu/shared'; -import { StatusPreviewCard } from './status-preview-card'; +import { useEffect, useRef, useState } from 'react'; +import { StatusBadge as StatusBadgeComponent, StatusBadgeIcon } from '../../primitives/status-badge'; import { JOB_STATUS_CONFIG } from '../constants'; - +import { StatusPreviewCard } from './status-preview-card'; export interface StatusBadgeProps { jobs: IActivityJob[]; } -export function StatusBadge({ jobs }: StatusBadgeProps) { +export function ActivityStatusBadge({ jobs }: StatusBadgeProps) { const [isOpen, setIsOpen] = useState(false); const errorCount = jobs.filter((job) => job.status === JobStatusEnum.FAILED).length; const timeoutRef = useRef>(); @@ -49,10 +48,9 @@ export function StatusBadge({ jobs }: StatusBadgeProps) { return ( - - - {displayLabel} - + + {displayLabel} + = { [JobStatusEnum.COMPLETED]: { - variant: 'success' as const, + variant: 'completed' as const, color: 'success', icon: RiCheckboxCircleFill, label: 'SUCCESS', }, [JobStatusEnum.FAILED]: { - variant: 'destructive' as const, + variant: 'failed' as const, color: 'destructive', icon: RiErrorWarningFill, label: `ERROR`, }, [JobStatusEnum.MERGED]: { - variant: 'success' as const, + variant: 'disabled' as const, color: 'success', icon: RiForbidFill, label: 'MERGED', }, [JobStatusEnum.PENDING]: { - variant: 'warning' as const, + variant: 'pending' as const, icon: RiLoader3Line, color: 'neutral-300', label: 'PENDING', }, [JobStatusEnum.CANCELED]: { - variant: 'warning' as const, + variant: 'disabled' as const, icon: RiLoader3Line, color: 'neutral-300', label: 'CANCELED', }, [JobStatusEnum.SKIPPED]: { - variant: 'warning' as const, + variant: 'disabled' as const, icon: RiLoader3Line, color: 'neutral-300', label: 'SKIPPED', }, [JobStatusEnum.RUNNING]: { - variant: 'warning' as const, + variant: 'pending' as const, icon: RiLoader3Line, color: 'warning', label: 'RUNNING', }, [JobStatusEnum.DELAYED]: { - variant: 'warning' as const, + variant: 'pending' as const, icon: RiLoader4Fill, label: 'DELAYED', color: 'warning', animationClass: 'animate-spin-slow', }, [JobStatusEnum.QUEUED]: { - variant: 'warning' as const, + variant: 'pending' as const, icon: RiLoader3Line, color: 'warning', label: 'QUEUED', diff --git a/apps/dashboard/src/components/billing/active-plan-banner.tsx b/apps/dashboard/src/components/billing/active-plan-banner.tsx index 091b99856d8..079e4aad03b 100644 --- a/apps/dashboard/src/components/billing/active-plan-banner.tsx +++ b/apps/dashboard/src/components/billing/active-plan-banner.tsx @@ -51,7 +51,7 @@ export function ActivePlanBanner({ selectedBillingInterval }: ActivePlanBannerPr

{subscription.apiServiceLevel?.toLowerCase()}

)} {subscription?.trial.isActive && ( - + Trial )} diff --git a/apps/dashboard/src/components/billing/highlights-row.tsx b/apps/dashboard/src/components/billing/highlights-row.tsx index a2678384e3f..603c823811a 100644 --- a/apps/dashboard/src/components/billing/highlights-row.tsx +++ b/apps/dashboard/src/components/billing/highlights-row.tsx @@ -36,7 +36,12 @@ function PlanHighlights({ planHighlights }: { planHighlights: Highlight[] }) { {planHighlights.map((item, index) => (
  • - {item.text} {item.badgeLabel && {item.badgeLabel}} + {item.text}{' '} + {item.badgeLabel && ( + + {item.badgeLabel} + + )}
  • ))} diff --git a/apps/dashboard/src/components/billing/plans-row.tsx b/apps/dashboard/src/components/billing/plans-row.tsx index f6190348964..8d591b5baa5 100644 --- a/apps/dashboard/src/components/billing/plans-row.tsx +++ b/apps/dashboard/src/components/billing/plans-row.tsx @@ -44,7 +44,11 @@ export function PlansRow({ selectedBillingInterval, currentPlan, trial }: PlansR

    Free

    - {effectiveCurrentPlan === 'free' && Current Plan} + {effectiveCurrentPlan === 'free' && ( + + Current Plan + + )}
      @@ -73,7 +77,11 @@ export function PlansRow({ selectedBillingInterval, currentPlan, trial }: PlansR

      Business

      - {effectiveCurrentPlan === 'business' && Current Plan} + {effectiveCurrentPlan === 'business' && ( + + Current Plan + + )}

      Enterprise

      - {effectiveCurrentPlan === 'enterprise' && Current Plan} + {effectiveCurrentPlan === 'enterprise' && ( + + Current Plan + + )}
      diff --git a/apps/dashboard/src/components/integrations/components/integration-card.tsx b/apps/dashboard/src/components/integrations/components/integration-card.tsx index ca11cce2c53..e451b4618d3 100644 --- a/apps/dashboard/src/components/integrations/components/integration-card.tsx +++ b/apps/dashboard/src/components/integrations/components/integration-card.tsx @@ -3,9 +3,16 @@ import { Button } from '@/components/primitives/button'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/primitives/tooltip'; import { ROUTES } from '@/utils/routes'; import { ChannelTypeEnum, type IEnvironment, type IIntegration, type IProviderConfig } from '@novu/shared'; -import { RiCheckboxCircleFill, RiGitBranchFill, RiSettings4Line, RiStarSmileLine } from 'react-icons/ri'; +import { + RiCheckboxCircleFill, + RiCloseCircleFill, + RiGitBranchFill, + RiSettings4Line, + RiStarSmileLine, +} from 'react-icons/ri'; import { useNavigate } from 'react-router-dom'; import { cn } from '../../../utils/ui'; +import { StatusBadge, StatusBadgeIcon } from '../../primitives/status-badge'; import { TableIntegration } from '../types'; import { ProviderIcon } from './provider-icon'; import { isDemoIntegration } from './utils/helpers'; @@ -74,7 +81,7 @@ export function IntegrationCard({ integration, provider, environment, onClick }: - + DEMO @@ -102,17 +109,17 @@ export function IntegrationCard({ integration, provider, environment, onClick }: Connect ) : ( - - + + {integration.active ? 'Active' : 'Inactive'} - + )} - + {environment.name} - +
      ); diff --git a/apps/dashboard/src/components/primitives/badge.tsx b/apps/dashboard/src/components/primitives/badge.tsx index eec878cd6c3..450d507a88c 100644 --- a/apps/dashboard/src/components/primitives/badge.tsx +++ b/apps/dashboard/src/components/primitives/badge.tsx @@ -1,44 +1,458 @@ -import { cn } from '@/utils/ui'; -import { cva, type VariantProps } from 'class-variance-authority'; +// AlignUI Badge v0.0.0 + +import { Slot } from '@radix-ui/react-slot'; import * as React from 'react'; -const badgeVariants = cva( - 'inline-flex items-center [&>svg]:shrink-0 gap-1 h-fit border transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', - { - variants: { - variant: { - neutral: 'border-neutral-100 bg-neutral-100 text-neutral-500', - destructive: 'border-transparent bg-destructive/10 text-destructive', - success: 'border-transparent bg-success/10 text-success', - warning: 'border-transparent bg-warning/10 text-warning', - soft: 'bg-neutral-alpha-200 text-foreground-500 border-transparent', - outline: 'border-neutral-alpha-200 bg-transparent font-normal text-foreground-600 shadow-sm', - }, - kind: { - default: 'rounded-md px-2 py-1', - pill: 'rounded-full px-2', - 'pill-stroke': 'rounded-full px-2', - tag: 'rounded-md py-0.5 px-2', - }, - size: { - default: 'text-xs', - '2xs': 'text-[10px] leading-[14px] font-medium', - }, - }, - defaultVariants: { - variant: 'neutral', - kind: 'default', - size: 'default', +import type { PolymorphicComponentProps } from '@/utils/polymorphic'; +import { recursiveCloneChildren } from '@/utils/recursive-clone-children'; +import { tv, type VariantProps } from '@/utils/tv'; + +const BADGE_ROOT_NAME = 'BadgeRoot'; +const BADGE_ICON_NAME = 'BadgeIcon'; +const BADGE_DOT_NAME = 'BadgeDot'; + +export const badgeVariants = tv({ + slots: { + root: 'inline-flex items-center justify-center rounded-full leading-none transition duration-200 ease-out', + icon: 'shrink-0', + dot: [ + // base + 'dot', + 'flex items-center justify-center', + // before + 'before:size-1 before:rounded-full before:bg-current', + ], + }, + variants: { + size: { + sm: { + root: 'h-4 gap-1.5 px-2 text-subheading-2xs uppercase has-[>.dot]:gap-2', + icon: '-mx-1 size-3', + dot: '-mx-2 size-4', + }, + md: { + root: 'h-5 gap-1.5 px-2 text-label-xs', + icon: '-mx-1 size-4', + dot: '-mx-1.5 size-4', + }, + }, + variant: { + filled: { + root: 'text-static-white', + }, + light: {}, + lighter: {}, + stroke: { + root: 'ring-1 ring-inset ring-current', + }, + }, + color: { + gray: {}, + blue: {}, + orange: {}, + red: {}, + green: {}, + yellow: {}, + purple: {}, + sky: {}, + pink: {}, + teal: {}, + }, + disabled: { + true: { + root: 'pointer-events-none', + }, + }, + square: { + true: {}, + }, + }, + compoundVariants: [ + //#region variant=filled + { + variant: 'filled', + color: 'gray', + class: { + root: 'bg-faded-base', + }, + }, + { + variant: 'filled', + color: 'blue', + class: { + root: 'bg-information-base', + }, + }, + { + variant: 'filled', + color: 'orange', + class: { + root: 'bg-warning-base', + }, + }, + { + variant: 'filled', + color: 'red', + class: { + root: 'bg-error-base', + }, + }, + { + variant: 'filled', + color: 'green', + class: { + root: 'bg-success-base', + }, + }, + { + variant: 'filled', + color: 'yellow', + class: { + root: 'bg-away-base', + }, + }, + { + variant: 'filled', + color: 'purple', + class: { + root: 'bg-feature-base', + }, + }, + { + variant: 'filled', + color: 'sky', + class: { + root: 'bg-verified-base', + }, + }, + { + variant: 'filled', + color: 'pink', + class: { + root: 'bg-highlighted-base', + }, + }, + { + variant: 'filled', + color: 'teal', + class: { + root: 'bg-stable-base', + }, + }, + // #endregion + + //#region variant=light + { + variant: 'light', + color: 'gray', + class: { + root: 'bg-faded-light text-faded-dark', + }, + }, + { + variant: 'light', + color: 'blue', + class: { + root: 'bg-information-light text-information-dark', + }, + }, + { + variant: 'light', + color: 'orange', + class: { + root: 'bg-warning-light text-warning-dark', + }, + }, + { + variant: 'light', + color: 'red', + class: { + root: 'bg-error-light text-error-dark', + }, + }, + { + variant: 'light', + color: 'green', + class: { + root: 'bg-success-light text-success-dark', + }, + }, + { + variant: 'light', + color: 'yellow', + class: { + root: 'bg-away-light text-away-dark', + }, + }, + { + variant: 'light', + color: 'purple', + class: { + root: 'bg-feature-light text-feature-dark', + }, + }, + { + variant: 'light', + color: 'sky', + class: { + root: 'bg-verified-light text-verified-dark', + }, + }, + { + variant: 'light', + color: 'pink', + class: { + root: 'bg-highlighted-light text-highlighted-dark', + }, + }, + { + variant: 'light', + color: 'teal', + class: { + root: 'bg-stable-light text-stable-dark', + }, + }, + //#endregion + + //#region variant=lighter + { + variant: 'lighter', + color: 'gray', + class: { + root: 'bg-faded-lighter text-faded-base', + }, + }, + { + variant: 'lighter', + color: 'blue', + class: { + root: 'bg-information-lighter text-information-base', + }, + }, + { + variant: 'lighter', + color: 'orange', + class: { + root: 'bg-warning-lighter text-warning-base', + }, + }, + { + variant: 'lighter', + color: 'red', + class: { + root: 'bg-error-lighter text-error-base', + }, + }, + { + variant: 'lighter', + color: 'green', + class: { + root: 'bg-success-lighter text-success-base', + }, + }, + { + variant: 'lighter', + color: 'yellow', + class: { + root: 'bg-away-lighter text-away-base', + }, + }, + { + variant: 'lighter', + color: 'purple', + class: { + root: 'bg-feature-lighter text-feature-base', + }, + }, + { + variant: 'lighter', + color: 'sky', + class: { + root: 'bg-verified-lighter text-verified-base', + }, + }, + { + variant: 'lighter', + color: 'pink', + class: { + root: 'bg-highlighted-lighter text-highlighted-base', + }, + }, + { + variant: 'lighter', + color: 'teal', + class: { + root: 'bg-stable-lighter text-stable-base', + }, + }, + //#endregion + + //#region variant=stroke + { + variant: 'stroke', + color: 'gray', + class: { + root: 'text-faded-base', + }, + }, + { + variant: 'stroke', + color: 'blue', + class: { + root: 'text-information-base', + }, + }, + { + variant: 'stroke', + color: 'orange', + class: { + root: 'text-warning-base', + }, + }, + { + variant: 'stroke', + color: 'red', + class: { + root: 'text-error-base', + }, + }, + { + variant: 'stroke', + color: 'green', + class: { + root: 'text-success-base', + }, + }, + { + variant: 'stroke', + color: 'yellow', + class: { + root: 'text-away-base', + }, + }, + { + variant: 'stroke', + color: 'purple', + class: { + root: 'text-feature-base', + }, + }, + { + variant: 'stroke', + color: 'sky', + class: { + root: 'text-verified-base', + }, + }, + { + variant: 'stroke', + color: 'pink', + class: { + root: 'text-highlighted-base', + }, + }, + { + variant: 'stroke', + color: 'teal', + class: { + root: 'text-stable-base', + }, + }, + //#endregion + + //#region square + { + size: 'sm', + square: true, + class: { + root: 'min-w-4 px-1', + }, + }, + { + size: 'md', + square: true, + class: { + root: 'min-w-5 px-1', + }, + }, + //#endregion + + //#region disabled + { + disabled: true, + variant: ['stroke', 'filled', 'light', 'lighter'], + color: ['red', 'gray', 'blue', 'orange', 'green', 'yellow', 'purple', 'sky', 'pink', 'teal'], + class: { + root: ['ring-1 ring-inset ring-stroke-soft', 'bg-transparent text-text-disabled'], + }, }, + //#endregion + ], + defaultVariants: { + variant: 'filled', + size: 'sm', + color: 'gray', + }, +}); + +type BadgeSharedProps = VariantProps; + +type BadgeRootProps = VariantProps & + React.HTMLAttributes & { + asChild?: boolean; + }; + +const BadgeRoot = React.forwardRef( + ({ asChild, size, variant, color, disabled, square, children, className, ...rest }, forwardedRef) => { + const uniqueId = React.useId(); + const Component = asChild ? Slot : 'div'; + const { root } = badgeVariants({ size, variant, color, disabled, square }); + + const sharedProps: BadgeSharedProps = { + size, + variant, + color, + }; + + const extendedChildren = recursiveCloneChildren( + children as React.ReactElement[], + sharedProps, + [BADGE_ICON_NAME, BADGE_DOT_NAME], + uniqueId, + asChild + ); + + return ( + + {extendedChildren} + + ); } ); +BadgeRoot.displayName = BADGE_ROOT_NAME; + +function BadgeIcon({ + className, + size, + variant, + color, + as, + ...rest +}: PolymorphicComponentProps) { + const Component = as || 'div'; + const { icon } = badgeVariants({ size, variant, color }); + + return ; +} +BadgeIcon.displayName = BADGE_ICON_NAME; -export interface BadgeProps extends React.HTMLAttributes, VariantProps {} +type BadgeDotProps = BadgeSharedProps & Omit, 'color'>; -export type BadgeVariant = VariantProps['variant']; +function BadgeDot({ size, variant, color, className, ...rest }: BadgeDotProps) { + const { dot } = badgeVariants({ size, variant, color }); -function Badge({ className, variant, kind, size, ...props }: BadgeProps) { - return
      ; + return
      ; } +BadgeDot.displayName = BADGE_DOT_NAME; -export { Badge }; +export { BadgeRoot as Badge, BadgeIcon, BadgeDot as Dot, BadgeRoot as Root }; diff --git a/apps/dashboard/src/components/primitives/form/faceted-filter/components/filter-badge.tsx b/apps/dashboard/src/components/primitives/form/faceted-filter/components/filter-badge.tsx index 34a9a0828d3..9a32f1b3af8 100644 --- a/apps/dashboard/src/components/primitives/form/faceted-filter/components/filter-badge.tsx +++ b/apps/dashboard/src/components/primitives/form/faceted-filter/components/filter-badge.tsx @@ -1,7 +1,7 @@ -import { Badge } from '../../../badge'; import { cn } from '../../../../../utils/ui'; -import { SizeType } from '../types'; +import { Badge } from '../../../badge'; import { STYLES } from '../styles'; +import { SizeType } from '../types'; interface FilterBadgeProps { content: React.ReactNode; @@ -12,7 +12,8 @@ interface FilterBadgeProps { export function FilterBadge({ content, size, className }: FilterBadgeProps) { return ( .dot]:gap-1.5', + ], + icon: '-mx-1 size-4', + dot: [ + // base + 'dot -mx-1 flex size-4 items-center justify-center', + // before + 'before:size-1.5 before:rounded-full before:bg-current', + ], + }, + variants: { + variant: { + stroke: { + root: 'bg-bg-white text-text-sub ring-1 ring-inset ring-stroke-soft', + }, + light: {}, + }, + status: { + completed: { + icon: 'text-success-base', + dot: 'text-success-base', + }, + pending: { + icon: 'text-warning-base', + dot: 'text-warning-base', + }, + failed: { + icon: 'text-error-base', + dot: 'text-error-base', + }, + disabled: { + icon: 'text-faded-base', + dot: 'text-faded-base', + }, + }, + }, + compoundVariants: [ + { + variant: 'light', + status: 'completed', + class: { + root: 'bg-success-lighter text-success-base', + }, + }, + { + variant: 'light', + status: 'pending', + class: { + root: 'bg-warning-lighter text-warning-base', + }, + }, + { + variant: 'light', + status: 'failed', + class: { + root: 'bg-error-lighter text-error-base', + }, + }, + { + variant: 'light', + status: 'disabled', + class: { + root: 'bg-faded-lighter text-text-sub', + }, + }, + ], + defaultVariants: { + status: 'disabled', + variant: 'stroke', + }, +}); + +type StatusBadgeSharedProps = VariantProps; + +type StatusBadgeRootProps = React.HTMLAttributes & + VariantProps & { + asChild?: boolean; + }; + +const StatusBadgeRoot = React.forwardRef( + ({ asChild, children, variant, status, className, ...rest }, forwardedRef) => { + const uniqueId = React.useId(); + const Component = asChild ? Slot : 'div'; + const { root } = statusBadgeVariants({ variant, status }); + + const sharedProps: StatusBadgeSharedProps = { + variant, + status, + }; + + const extendedChildren = recursiveCloneChildren( + children as React.ReactElement[], + sharedProps, + [STATUS_BADGE_ICON_NAME, STATUS_BADGE_DOT_NAME], + uniqueId, + asChild + ); + + return ( + + {extendedChildren} + + ); + } +); +StatusBadgeRoot.displayName = STATUS_BADGE_ROOT_NAME; + +function StatusBadgeIcon({ + variant, + status, + className, + as, +}: PolymorphicComponentProps) { + const Component = as || 'div'; + const { icon } = statusBadgeVariants({ variant, status }); + + return ; +} +StatusBadgeIcon.displayName = STATUS_BADGE_ICON_NAME; + +function StatusBadgeDot({ + variant, + status, + className, + ...rest +}: StatusBadgeSharedProps & React.HTMLAttributes) { + const { dot } = statusBadgeVariants({ variant, status }); + + return
      ; +} +StatusBadgeDot.displayName = STATUS_BADGE_DOT_NAME; + +export { + StatusBadgeDot as Dot, + StatusBadgeRoot as Root, + StatusBadgeRoot as StatusBadge, + StatusBadgeIcon, + type StatusBadgeRootProps as StatusBadgeProps, +}; diff --git a/apps/dashboard/src/components/primitives/tag-input.tsx b/apps/dashboard/src/components/primitives/tag-input.tsx index e4f23639b93..0af12f659ef 100644 --- a/apps/dashboard/src/components/primitives/tag-input.tsx +++ b/apps/dashboard/src/components/primitives/tag-input.tsx @@ -1,12 +1,11 @@ 'use client'; -import { Badge } from '@/components/primitives/badge'; import { CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/primitives/command'; import { Popover, PopoverAnchor, PopoverContent } from '@/components/primitives/popover'; import { cn } from '@/utils/ui'; import { Command } from 'cmdk'; import { forwardRef, useEffect, useMemo, useState } from 'react'; -import { RiCloseFill } from 'react-icons/ri'; +import { Tag } from './tag'; type TagInputProps = Omit, 'onChange'> & { value: string[]; @@ -83,13 +82,9 @@ const TagInput = forwardRef((props, ref) => {
      {tags.map((tag, index) => ( - + removeTag(tag)}> {tag} - - + ))}
      diff --git a/apps/dashboard/src/components/primitives/tag.tsx b/apps/dashboard/src/components/primitives/tag.tsx index c27d039465c..9d31810e31b 100644 --- a/apps/dashboard/src/components/primitives/tag.tsx +++ b/apps/dashboard/src/components/primitives/tag.tsx @@ -16,15 +16,15 @@ const TAG_DISMISS_ICON_NAME = 'TagDismissIcon'; export const tagVariants = tv({ slots: { root: [ - 'group/tag inline-flex h-6 items-center gap-2 rounded-md px-2 text-label-xs text-text-sub-600', + 'group/tag inline-flex h-6 items-center gap-2 rounded-md px-2 text-label-xs text-text-sub', 'transition duration-200 ease-out', 'ring-1 ring-inset', ], icon: [ // base - '-mx-1 size-4 shrink-0 text-text-soft-400 transition duration-200 ease-out', + '-mx-1 size-4 shrink-0 text-text-soft transition duration-200 ease-out', // hover - 'group-hover/tag:text-text-sub-600', + 'group-hover/tag:text-text-sub', ], dismissButton: [ // base @@ -32,24 +32,24 @@ export const tagVariants = tv({ // focus 'focus:outline-none', ], - dismissIcon: 'size-4 text-text-soft-400 transition duration-200 ease-out', + dismissIcon: 'size-4 text-text-soft transition duration-200 ease-out', }, variants: { variant: { stroke: { root: [ // base - 'bg-bg-white-0 ring-stroke-soft-200', + 'bg-bg-white-0 ring-stroke-soft', // hover - 'hover:bg-bg-weak-50 hover:ring-transparent', + 'hover:bg-bg-weak', // focus-within - 'focus-within:bg-bg-weak-50 focus-within:ring-transparent', + 'focus-within:bg-bg-weak focus-within:ring-transparent', ], dismissIcon: [ // hover - 'group-hover/dismiss-button:text-text-sub-600', + 'group-hover/dismiss-button:text-text-sub', // focus - 'group-focus/dismiss-button:text-text-sub-600', + 'group-focus/dismiss-button:text-text-sub', ], }, gray: { @@ -57,15 +57,15 @@ export const tagVariants = tv({ // base 'bg-bg-weak-50 ring-transparent', // hover - 'hover:bg-bg-white-0 hover:ring-stroke-soft-200', + 'hover:bg-bg-white-0 hover:ring-stroke-soft', ], }, }, disabled: { true: { - root: 'pointer-events-none bg-bg-weak-50 text-text-disabled-300 ring-transparent', - icon: 'text-text-disabled-300 [&:not(.remixicon)]:opacity-[.48]', - dismissIcon: 'text-text-disabled-300', + root: 'pointer-events-none bg-bg-weak text-text-disabled ring-transparent', + icon: 'text-text-disabled [&:not(.remixicon)]:opacity-[.48]', + dismissIcon: 'text-text-disabled', }, }, }, diff --git a/apps/dashboard/src/components/side-navigation/getting-started-menu-item.tsx b/apps/dashboard/src/components/side-navigation/getting-started-menu-item.tsx index d60024985e5..a272372f639 100644 --- a/apps/dashboard/src/components/side-navigation/getting-started-menu-item.tsx +++ b/apps/dashboard/src/components/side-navigation/getting-started-menu-item.tsx @@ -6,7 +6,7 @@ import { useUser } from '@clerk/clerk-react'; import { motion } from 'motion/react'; import { RiCloseFill, RiQuestionLine, RiSparkling2Fill } from 'react-icons/ri'; import { useOnboardingSteps } from '../../hooks/use-onboarding-steps'; -import { Badge } from '../primitives/badge'; +import { Badge, BadgeIcon } from '../primitives/badge'; import { CompactButton } from '../primitives/button-compact'; import { Tooltip, TooltipContent, TooltipTrigger } from '../primitives/tooltip'; import { NavigationLink } from './navigation-link'; @@ -48,11 +48,7 @@ export function GettingStartedMenuItem() { Getting started - + - + {completedSteps}/{totalSteps} diff --git a/apps/dashboard/src/components/workflow-editor/add-step-menu.tsx b/apps/dashboard/src/components/workflow-editor/add-step-menu.tsx index f4dfcc2ab0d..784a31985db 100644 --- a/apps/dashboard/src/components/workflow-editor/add-step-menu.tsx +++ b/apps/dashboard/src/components/workflow-editor/add-step-menu.tsx @@ -59,7 +59,7 @@ const MenuItem = ({ /> {children} {disabled && ( - + coming soon )} diff --git a/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx b/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx index 83f194cd27b..9ab23f77392 100644 --- a/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx +++ b/apps/dashboard/src/components/workflow-editor/editor-breadcrumbs.tsx @@ -64,7 +64,7 @@ export const EditorBreadcrumbs = () => { {workflow && ( {workflow.origin === WorkflowOriginEnum.EXTERNAL ? ( - + ) : ( diff --git a/apps/dashboard/src/components/workflow-row.tsx b/apps/dashboard/src/components/workflow-row.tsx index 1ffba9c6604..6d09f6f786d 100644 --- a/apps/dashboard/src/components/workflow-row.tsx +++ b/apps/dashboard/src/components/workflow-row.tsx @@ -185,7 +185,7 @@ export const WorkflowRow = ({ workflow }: WorkflowRowProps) => {
      {workflow.origin === WorkflowOriginEnum.EXTERNAL && ( - + )} diff --git a/apps/dashboard/src/components/workflow-status.tsx b/apps/dashboard/src/components/workflow-status.tsx index 60c757dd896..03b6ffb466f 100644 --- a/apps/dashboard/src/components/workflow-status.tsx +++ b/apps/dashboard/src/components/workflow-status.tsx @@ -1,8 +1,8 @@ -import { Badge } from '@/components/primitives/badge'; import { WorkflowStatusEnum } from '@/utils/enums'; import { ComponentProps } from 'react'; import { type IconType } from 'react-icons/lib'; import { RiCheckboxCircleFill, RiErrorWarningFill, RiForbidFill } from 'react-icons/ri'; +import { StatusBadge, StatusBadgeIcon } from './primitives/status-badge'; type WorkflowStatusProps = { status: WorkflowStatusEnum; @@ -11,23 +11,23 @@ type WorkflowStatusProps = { const statusRenderData: Record< WorkflowStatusEnum, { - badgeVariant: ComponentProps['variant']; + badgeVariant: ComponentProps['status']; text: string; icon: IconType; } > = { [WorkflowStatusEnum.ACTIVE]: { - badgeVariant: 'success', + badgeVariant: 'completed', text: 'Active', icon: RiCheckboxCircleFill, }, [WorkflowStatusEnum.INACTIVE]: { - badgeVariant: 'soft', + badgeVariant: 'disabled', text: 'Inactive', icon: RiForbidFill, }, [WorkflowStatusEnum.ERROR]: { - badgeVariant: 'destructive', + badgeVariant: 'failed', text: 'Action required', icon: RiErrorWarningFill, }, @@ -40,8 +40,8 @@ export const WorkflowStatus = (props: WorkflowStatusProps) => { const text = statusRenderData[status].text; return ( - - {text} - + + {text} + ); }; diff --git a/apps/dashboard/src/components/workflow-tags.tsx b/apps/dashboard/src/components/workflow-tags.tsx index f3dcef55800..96a1d7731e3 100644 --- a/apps/dashboard/src/components/workflow-tags.tsx +++ b/apps/dashboard/src/components/workflow-tags.tsx @@ -22,17 +22,12 @@ export const WorkflowTags = (props: WorkflowTagsProps) => {
      <> {firstTags.map((tag) => ( - + {tag} ))} {restTags.length > 0 && ( - + +{restTags.length} )} diff --git a/apps/dashboard/src/pages/integrations-list-page.tsx b/apps/dashboard/src/pages/integrations-list-page.tsx index 0ddf3afbb73..caaea64210f 100644 --- a/apps/dashboard/src/pages/integrations-list-page.tsx +++ b/apps/dashboard/src/pages/integrations-list-page.tsx @@ -39,7 +39,7 @@ export function IntegrationsListPage() { Data{' '} - + SOON