Skip to content

Commit

Permalink
Merge branch 'next' into feat/secretManager
Browse files Browse the repository at this point in the history
  • Loading branch information
merrcury authored Jan 8, 2025
2 parents aa61d61 + 1aef77e commit dce4f51
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Copy } from 'lucide-react';
import { ReactNode } from 'react';
import { cn } from '@/utils/ui';
import { CopyButton } from '@/components/primitives/copy-button';
import { cn } from '@/utils/ui';
import { ReactNode } from 'react';

interface OverviewItemProps {
label: string;
Expand All @@ -28,11 +27,9 @@ export function OverviewItem({
<CopyButton
valueToCopy={value}
mode="ghost"
size="xs"
size="2xs"
className="text-foreground-600 mr-0 size-3 gap-0 p-0 opacity-0 transition-opacity group-hover:opacity-100"
>
<Copy className="h-3 w-3" />
</CopyButton>
></CopyButton>
)}
{children || <span className={cn('text-foreground-600 text-xs', isMonospace && 'font-mono')}>{value}</span>}
</div>
Expand Down
30 changes: 17 additions & 13 deletions apps/dashboard/src/components/primitives/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export const buttonVariants = tv({
],
icon: [
// base
'flex size-5 shrink-0 items-center justify-center',
'flex size-5 shrink-0 items-center justify-center transition-transform duration-200',
'[&.arrow-right-hover-animation]:group-hover:translate-x-0.5',
],
},
variants: {
Expand Down Expand Up @@ -353,17 +354,20 @@ export type ButtonProps = React.ComponentPropsWithoutRef<typeof ButtonRoot> & {
trailingIcon?: IconType;
};

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ children, leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, ...rest }, forwardedRef) => {
return (
<ButtonRoot ref={forwardedRef} {...rest}>
{LeadingIcon && <ButtonIcon as={LeadingIcon} />}
<Slottable>{children}</Slottable>
{TrailingIcon && <ButtonIcon as={TrailingIcon} />}
</ButtonRoot>
);
}
);
const Button = ({ leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, children, ...rest }: ButtonProps) => {
const isArrowRight = TrailingIcon?.name === 'RiArrowRightSLine';

return (
<ButtonRoot {...rest}>
{LeadingIcon && <ButtonIcon as={LeadingIcon} />}
<Slottable>{children}</Slottable>
{TrailingIcon && (
<ButtonIcon className={isArrowRight ? 'arrow-right-hover-animation' : undefined} as={TrailingIcon} />
)}
</ButtonRoot>
);
};

Button.displayName = 'Button';

function ButtonIcon<T extends React.ElementType>({
Expand All @@ -381,4 +385,4 @@ function ButtonIcon<T extends React.ElementType>({
}
ButtonIcon.displayName = BUTTON_ICON_NAME;

export { Button, ButtonIcon as ButtonIcon, ButtonRoot as Root };
export { Button, ButtonIcon, ButtonRoot };
75 changes: 66 additions & 9 deletions apps/dashboard/src/components/primitives/copy-button.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,77 @@
import { HoverToCopy } from '@/components/primitives/hover-to-copy';
import { cn } from '@/utils/ui';
import { RiFileCopyLine } from 'react-icons/ri';
import { AnimatePresence, motion } from 'motion/react';
import { useState } from 'react';
import { RiCheckLine, RiFileCopyLine } from 'react-icons/ri';
import { cn } from '../../utils/ui';
import { Button, ButtonProps } from './button';
import { Tooltip, TooltipContent, TooltipTrigger } from './tooltip';

type CopyButtonProps = ButtonProps & {
valueToCopy: string;
inputGroup?: boolean;
};

export const CopyButton = (props: CopyButtonProps) => {
const { className, valueToCopy, children, ...rest } = props;
const { className, valueToCopy, inputGroup, children, ...rest } = props;

const [copied, setCopied] = useState<boolean>(false);

const handleCopy = async () => {
try {
await navigator.clipboard.writeText(valueToCopy);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
} catch (err) {
console.error('Failed to copy text: ', err);
}
};

const sizeClass = props.size === '2xs' ? 'size-3' : 'size-4';

return (
<HoverToCopy asChild valueToCopy={valueToCopy}>
<Button mode="outline" variant="secondary" className={cn('flex items-center gap-1', className)} {...rest}>
{children || <RiFileCopyLine className="size-4" />}
</Button>
</HoverToCopy>
<Tooltip>
<TooltipTrigger asChild>
<Button
mode="outline"
variant="secondary"
className={cn(className, inputGroup && 'h-[34px] rounded-none border-l ring-0')}
onClick={handleCopy}
aria-label={copied ? 'Copied' : 'Copy to clipboard'}
disabled={copied}
{...rest}
>
{children}
<div className={`relative ${sizeClass}`}>
<AnimatePresence mode="wait" initial={false}>
{copied ? (
<motion.div
key="check"
initial={{ scale: 0.5, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0.5, opacity: 0 }}
transition={{ type: 'spring', duration: 0.1, bounce: 0.5 }}
className="absolute inset-0"
>
<RiCheckLine className={`${sizeClass} text-success`} aria-hidden="true" />
</motion.div>
) : (
<motion.div
key="copy"
initial={{ scale: 0.5, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0.5, opacity: 0 }}
transition={{ type: 'spring', duration: 0.15, bounce: 0.5 }}
className="absolute inset-0"
>
<RiFileCopyLine className={`${sizeClass}`} />
</motion.div>
)}
</AnimatePresence>
</div>
</Button>
</TooltipTrigger>
<TooltipContent className="px-2 py-1 text-xs" sideOffset={4}>
{copied ? 'Copied!' : 'Click to copy'}
</TooltipContent>
</Tooltip>
);
};
37 changes: 0 additions & 37 deletions apps/dashboard/src/components/primitives/hover-to-copy.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,7 @@ export const ConfigureWorkflowForm = (props: ConfigureWorkflowFormProps) => {
<FormControl>
<InputField className="flex overflow-hidden pr-0">
<Input placeholder="Untitled" className="cursor-default" {...field} readOnly />
<CopyButton
valueToCopy={field.value}
className="h-[34px] rounded-none border-l border-neutral-200"
/>
<CopyButton valueToCopy={field.value} inputGroup />
</InputField>
</FormControl>
<FormMessage />
Expand Down Expand Up @@ -364,8 +361,10 @@ export const ConfigureWorkflowForm = (props: ConfigureWorkflowFormProps) => {
leadingIcon={RiSettingsLine}
className="flex w-full justify-start gap-1.5 p-1.5 text-xs font-medium"
type="button"
trailingIcon={RiArrowRightSLine}
>
Configure channel preferences <RiArrowRightSLine className="ml-auto h-4 w-4 text-neutral-600" />
Configure channel preferences
<span className="ml-auto" />
</Button>
</Link>
</SidebarContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,7 @@ export const ConfigureStepForm = (props: ConfigureStepFormProps) => {
<FormControl>
<Input placeholder="Untitled" className="cursor-default" {...field} readOnly />
</FormControl>
<CopyButton
valueToCopy={field.value}
size="xs"
className="h-[34px] rounded-none border-l border-neutral-200"
/>
<CopyButton valueToCopy={field.value} size="xs" inputGroup />
</InputField>
<FormMessage />
</FormItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { WorkflowResponseDto } from '@novu/shared';
import { loadLanguage } from '@uiw/codemirror-extensions-langs';
import { useMemo, useState } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { RiFileCopyLine, RiSendPlaneFill } from 'react-icons/ri';
import { RiSendPlaneFill } from 'react-icons/ri';
import { Code2 } from '../../icons/code-2';
import { CopyButton } from '../../primitives/copy-button';
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '../../primitives/form/form';
Expand Down Expand Up @@ -133,13 +133,7 @@ export const TestWorkflowForm = ({ workflow }: { workflow?: WorkflowResponseDto
<TabsTrigger className={tabsTriggerClassName} value="python" variant="regular">
Python
</TabsTrigger>
<CopyButton
mode="ghost"
leadingIcon={RiFileCopyLine}
className="text-foreground-400 ml-auto"
size="xs"
valueToCopy={snippetValue}
>
<CopyButton mode="ghost" className="text-foreground-400 ml-auto" size="xs" valueToCopy={snippetValue}>
Copy code
</CopyButton>
</TabsList>
Expand Down
15 changes: 10 additions & 5 deletions apps/dashboard/src/components/workflow-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/primitives/dropdown-menu';
import { HoverToCopy } from '@/components/primitives/hover-to-copy';
import { TableCell, TableRow } from '@/components/primitives/table';
import { Tooltip, TooltipContent, TooltipPortal, TooltipTrigger } from '@/components/primitives/tooltip';
import TruncatedText from '@/components/truncated-text';
Expand All @@ -27,7 +26,6 @@ import { ComponentProps, useState } from 'react';
import { FaCode } from 'react-icons/fa6';
import {
RiDeleteBin2Line,
RiFileCopyLine,
RiFlashlightLine,
RiGitPullRequestFill,
RiMore2Fill,
Expand All @@ -40,6 +38,7 @@ import { type ExternalToast } from 'sonner';
import { ConfirmationModal } from './confirmation-modal';
import { DeleteWorkflowDialog } from './delete-workflow-dialog';
import { CompactButton } from './primitives/button-compact';
import { CopyButton } from './primitives/copy-button';
import { ToastIcon } from './primitives/sonner';
import { showToast } from './primitives/sonner-helpers';
import { TimeDisplayHoverCard } from './time-display-hover-card';
Expand Down Expand Up @@ -191,10 +190,16 @@ export const WorkflowRow = ({ workflow }: WorkflowRowProps) => {
)}
<TruncatedText className="max-w-[32ch]">{workflow.name}</TruncatedText>
</div>
<HoverToCopy className="group relative z-10 flex items-center gap-1" valueToCopy={workflow.workflowId}>
<div className="flex items-center gap-1 transition-opacity duration-200">
<TruncatedText className="text-foreground-400 font-code block text-xs">{workflow.workflowId}</TruncatedText>
<RiFileCopyLine className="text-foreground-400 invisible size-3 group-hover:visible" />
</HoverToCopy>

<CopyButton
className="z-10 flex size-2 p-0 px-1 opacity-0 group-hover:opacity-100"
valueToCopy={workflow.workflowId}
size="2xs"
mode="ghost"
></CopyButton>
</div>
</WorkflowLinkTableCell>
<WorkflowLinkTableCell workflow={workflow} className="min-w-[200px]">
<WorkflowStatus status={workflow.status} />
Expand Down

0 comments on commit dce4f51

Please sign in to comment.