Skip to content

Commit

Permalink
chore(ui): Consolidate components (#3738)
Browse files Browse the repository at this point in the history
* chore(refactor): consolidate some of the components and use existing styles

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix conflicts

Signed-off-by: Mark Phelps <[email protected]>

* chore: spacing

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix sizing and dropdown disabled

Signed-off-by: Mark Phelps <[email protected]>

* chore: dropdown should be false by default

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix search on segment table

Signed-off-by: Mark Phelps <[email protected]>

* chore: try to fix tests

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix lint issues

Signed-off-by: Mark Phelps <[email protected]>

* update table skeleton

Signed-off-by: Roman Dmytrenko <[email protected]>

---------

Signed-off-by: Mark Phelps <[email protected]>
Signed-off-by: Roman Dmytrenko <[email protected]>
Co-authored-by: Roman Dmytrenko <[email protected]>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 17, 2024
1 parent 1489fe1 commit 397341c
Show file tree
Hide file tree
Showing 47 changed files with 196 additions and 342 deletions.
2 changes: 1 addition & 1 deletion ui/src/app/Onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
UsersIcon
} from '@heroicons/react/24/outline';
import { useDispatch } from 'react-redux';
import Button from '~/components/forms/buttons/Button';
import { Button } from '~/components/Button';
import { Icon } from '~/types/Icon';
import { cls } from '~/utils/helpers';
import { useNavigate } from 'react-router-dom';
Expand Down
11 changes: 5 additions & 6 deletions ui/src/app/console/Console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import { selectCurrentRef } from '~/app/refs/refsSlice';
import { ContextEditor } from '~/components/console/ContextEditor';
import EmptyState from '~/components/EmptyState';
import { Button } from '~/components/ui/button';
import Combobox from '~/components/forms/Combobox';
import Dropdown from '~/components/forms/Dropdown';
import { Button } from '~/components/Button';
import Combobox from '~/components/Combobox';
import Dropdown from '~/components/Dropdown';
import Input from '~/components/forms/Input';
import { evaluateURL, evaluateV2 } from '~/data/api';
import { useError } from '~/data/hooks/error';
Expand Down Expand Up @@ -268,13 +268,12 @@ export default function Console() {
aria-label="New Entity ID"
title="New Entity ID"
variant="ghost"
size="icon"
onClick={(e) => {
e.preventDefault();
formik.setFieldValue('entityId', uuidv4());
}}
>
<RefreshCwIcon className="text-gray-400" />
<RefreshCwIcon className="h-4 w-4 text-gray-400" />
</Button>
</div>
</div>
Expand Down Expand Up @@ -318,7 +317,7 @@ export default function Console() {
]}
/>
<Button
variant="default"
variant="primary"
type="submit"
disabled={!(formik.dirty && formik.isValid)}
>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/flags/Flag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
selectNamespaces
} from '~/app/namespaces/namespacesSlice';
import FlagForm from '~/components/flags/forms/FlagForm';
import Dropdown from '~/components/forms/Dropdown';
import Dropdown from '~/components/Dropdown';
import Loading from '~/components/Loading';
import Modal from '~/components/Modal';
import MoreInfo from '~/components/MoreInfo';
Expand Down
12 changes: 7 additions & 5 deletions ui/src/app/flags/Flags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { selectReadonly } from '~/app/meta/metaSlice';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import { Plus } from 'lucide-react';
import { Button } from '~/components/ui/button';
import { ButtonWithPlus } from '~/components/Button';
import FlagTable from '~/components/flags/FlagTable';
import { PageHeader } from '~/components/ui/page';

Expand All @@ -18,10 +17,13 @@ export default function Flags() {
return (
<>
<PageHeader title="Flags">
<Button onClick={() => navigate(`${path}/new`)} disabled={readOnly}>
<Plus />
<ButtonWithPlus
variant="primary"
onClick={() => navigate(`${path}/new`)}
disabled={readOnly}
>
New Flag
</Button>
</ButtonWithPlus>
</PageHeader>
<div className="flex flex-col gap-1 space-y-2 py-2">
<FlagTable namespace={namespace} />
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/flags/rules/Rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { selectReadonly } from '~/app/meta/metaSlice';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import { useListSegmentsQuery } from '~/app/segments/segmentsApi';
import EmptyState from '~/components/EmptyState';
import { ButtonWithPlus, TextButton } from '~/components/forms/buttons/Button';
import { ButtonWithPlus, TextButton } from '~/components/Button';

import Loading from '~/components/Loading';
import Modal from '~/components/Modal';
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/namespaces/Namespaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { selectReadonly } from '~/app/meta/metaSlice';
import EmptyState from '~/components/EmptyState';
import { ButtonWithPlus } from '~/components/forms/buttons/Button';
import { ButtonWithPlus } from '~/components/Button';
import Modal from '~/components/Modal';
import NamespaceForm from '~/components/namespaces/NamespaceForm';
import NamespaceTable from '~/components/namespaces/NamespaceTable';
Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/segments/Segment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
} from '~/app/segments/segmentsApi';
import Chips from '~/components/Chips';
import EmptyState from '~/components/EmptyState';
import Button from '~/components/forms/buttons/Button';
import Dropdown from '~/components/forms/Dropdown';
import { Button } from '~/components/Button';
import Dropdown from '~/components/Dropdown';
import Loading from '~/components/Loading';
import Modal from '~/components/Modal';
import MoreInfo from '~/components/MoreInfo';
Expand Down
12 changes: 7 additions & 5 deletions ui/src/app/segments/Segments.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Plus } from 'lucide-react';
import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { selectReadonly } from '~/app/meta/metaSlice';
import { ButtonWithPlus } from '~/components/Button';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import SegmentTable from '~/components/segments/SegmentTable';
import { Button } from '~/components/ui/button';
import { PageHeader } from '~/components/ui/page';

export default function Segments() {
Expand All @@ -19,10 +18,13 @@ export default function Segments() {
return (
<>
<PageHeader title="Segments">
<Button onClick={() => navigate(`${path}/new`)} disabled={readOnly}>
<Plus />
<ButtonWithPlus
variant="primary"
onClick={() => navigate(`${path}/new`)}
disabled={readOnly}
>
New Segment
</Button>
</ButtonWithPlus>
</PageHeader>
<div className="flex flex-col gap-1 space-y-2 py-2">
<SegmentTable namespace={namespace} />
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/tokens/Tokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
useListTokensQuery
} from '~/app/tokens/tokensApi';
import EmptyState from '~/components/EmptyState';
import { ButtonWithPlus } from '~/components/forms/buttons/Button';
import { ButtonWithPlus } from '~/components/Button';
import Loading from '~/components/Loading';
import Modal from '~/components/Modal';
import DeletePanel from '~/components/panels/DeletePanel';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';

import { cn } from '~/lib/utils';
import { cls } from '~/utils/helpers';

const badgeVariants = cva(
'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
Expand Down Expand Up @@ -33,7 +33,7 @@ export interface BadgeProps

function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
<div className={cls(badgeVariants({ variant }), className)} {...props} />
);
}

Expand Down
99 changes: 99 additions & 0 deletions ui/src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { faPlus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Slot } from '@radix-ui/react-slot';
import React from 'react';
import { cls } from '~/utils/helpers';

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
variant?: 'primary' | 'secondary' | 'soft' | 'link' | 'ghost';
className?: string;
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
children,
type = 'button',
variant = 'secondary',
asChild = false,
...props
},
ref
) => {
const Comp = asChild ? Slot : 'button';
return (
<Comp
type={type}
className={cls(
'cursor-hand inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium focus:outline-none focus:ring-1 focus:ring-offset-1',
className,
{
'cursor-not-allowed': props.disabled,
'border border-transparent bg-violet-400 text-background shadow-sm enabled:bg-violet-600 enabled:hover:bg-violet-500 enabled:focus:ring-violet-600':
variant === 'primary',
'border border-violet-300 bg-background text-gray-500 shadow-sm enabled:hover:bg-gray-50 enabled:focus:ring-gray-500':
variant === 'secondary',
'border-violet-300 text-violet-600 enabled:hover:bg-violet-100 enabled:focus:ring-violet-500':
variant === 'soft',
'enabled:cursor-hand enabled:cursor mb-1 inline-flex items-center justify-center border-0 px-0 py-0 text-sm font-medium text-gray-300 focus:outline-none focus:ring-0 enabled:text-gray-500 enabled:hover:text-gray-600 disabled:cursor-not-allowed':
variant === 'link',
'bg-transparent text-gray-500 hover:bg-gray-50 enabled:focus:ring-gray-500':
variant === 'ghost'
}
)}
ref={ref}
{...props}
>
{children}
</Comp>
);
}
);

Button.displayName = 'Button';

export { Button };

export const ButtonWithPlus = (props: ButtonProps) => {
return (
<Button {...props}>
<FontAwesomeIcon
icon={faPlus}
className="-ml-1.5 mr-1.5 h-4 w-4 text-background"
aria-hidden="true"
/>
{props.children}
</Button>
);
};

export const TextButton = (props: ButtonProps) => {
return <Button {...props} variant="link" />;
};

export const ButtonIcon = ({
icon,
onClick,
disabled = false
}: {
icon: IconProp;
onClick: () => void;
disabled: boolean;
}) => (
<button
type="button"
className={cls('p-1 text-gray-300 hover:text-gray-500', {
'hover:text-gray-400': disabled
})}
onClick={onClick}
title={disabled ? 'Not allowed in Read-Only mode' : undefined}
disabled={disabled}
>
<FontAwesomeIcon icon={icon} className="h-4 w-4" aria-hidden="true" />
</button>
);
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
import { Fragment } from 'react';

import { ChevronDown, EllipsisVerticalIcon } from 'lucide-react';
import { Button, ButtonSize, ButtonVariant } from '~/components/ui/button';
import { Button } from '~/components/Button';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '~/lib/utils';
import { cls } from '~/utils/helpers';

const dropdownVariants = cva('', {
variants: {
Expand Down Expand Up @@ -43,33 +43,30 @@ type DropdownProps = {
};

export default function Dropdown(props: DropdownProps) {
const { label, actions, disabled, side, kind } = props;
const { label, actions, disabled = false, side, kind } = props;
let BtnIcon = ChevronDown;
let variant: ButtonVariant = 'outline';
let size: ButtonSize = 'default';
let variant: 'primary' | 'secondary' | 'soft' | 'link' | 'ghost' =
'secondary';

if (kind === 'dots') {
variant = 'ghost';
size = 'icon';
BtnIcon = EllipsisVerticalIcon;
}

return (
<DropdownMenu modal={false}>
<DropdownMenuTrigger asChild>
<DropdownMenuTrigger asChild disabled={disabled}>
<Button
role="button"
disabled={disabled}
variant={variant}
size={size}
type="button"
data-testid={props['data-testid']}
>
{label}
<BtnIcon aria-hidden="true" />
<BtnIcon className="ml-1 h-4 w-4" aria-hidden="true" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side={side || 'bottom'} key="actions">
<DropdownMenuContent align="end" side={side || 'bottom'}>
{actions.map((action, i) => (
<Fragment key={i}>
{action.variant === 'destructive' && i != 0 && (
Expand All @@ -83,7 +80,7 @@ export default function Dropdown(props: DropdownProps) {
}
}}
disabled={action.disabled}
className={cn(dropdownVariants({ variant: action.variant }))}
className={cls(dropdownVariants({ variant: action.variant }))}
>
{action.icon && <action.icon aria-hidden="true" />}
{action.label}
Expand Down
6 changes: 2 additions & 4 deletions ui/src/components/Searchbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ export default function Searchbox(props: SearchboxProps) {
}, [debounce, onChange, value]);

return (
<div
className={`${className} flex flex-1 items-center justify-center lg:justify-start`}
>
<div className="lg:max-w-s w-full max-w-lg">
<div className={`${className} flex flex-1 items-center justify-start`}>
<div className="w-full max-w-60 lg:max-w-md">
<label htmlFor="search" className="sr-only">
Search
</label>
Expand Down
18 changes: 7 additions & 11 deletions ui/src/components/flags/FlagTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ import {
setSorting,
useListFlagsQuery
} from '~/app/flags/flagsApi';
import { cn } from '~/lib/utils';
import { Badge } from '~/components/ui/badge';
import { cls } from '~/utils/helpers';
import { Badge } from '~/components/Badge';
import { formatDistanceToNowStrict, parseISO } from 'date-fns';
import { Search } from '~/components/ui/search';
import Searchbox from '~/components/Searchbox';
import { DataTableViewOptions } from '~/components/ui/table-view-options';
import { VariableIcon, ToggleLeftIcon } from 'lucide-react';
import { useError } from '~/data/hooks/error';
import { INamespaceBase } from '~/types/Namespace';
import { TableSkeleton } from '~/components/ui/table-skeleton';
import Well from '../Well';
import Well from '~/components/Well';

type FlagTableProps = {
namespace: INamespaceBase;
Expand Down Expand Up @@ -176,12 +176,8 @@ export default function FlagTable(props: FlagTableProps) {
return (
<>
<div className="flex items-center justify-between">
<div className="flex flex-1 items-center justify-between space-x-2">
<Search
value={filter ?? ''}
onChange={setFilter}
className="h-8 w-[150px] flex-grow text-xs lg:w-[250px]"
/>
<div className="flex flex-1 items-center justify-between">
<Searchbox value={filter ?? ''} onChange={setFilter} />
<DataTableViewOptions table={table} />
</div>
</div>
Expand All @@ -208,7 +204,7 @@ export default function FlagTable(props: FlagTableProps) {
<button
role="link"
key={row.id}
className={cn(
className={cls(
'flex flex-col items-start gap-2 rounded-lg border p-3 text-left text-sm transition-all hover:bg-accent'
)}
onClick={() => navigate(`${path}/${item.key}`)}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/flags/forms/FlagForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '~/app/flags/flagsApi';
import { selectReadonly } from '~/app/meta/metaSlice';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import Button from '~/components/forms/buttons/Button';
import { Button } from '~/components/Button';
import Input from '~/components/forms/Input';
import Toggle from '~/components/forms/Toggle';
import Loading from '~/components/Loading';
Expand Down
Loading

0 comments on commit 397341c

Please sign in to comment.