mirror of
https://github.com/snowball-tools/snowballtools-base.git
synced 2024-12-22 16:37:44 +00:00
Merge pull request #193 from snowball-tools/main
storybook and project settings styling
This commit is contained in:
commit
8533c41c58
@ -19,7 +19,7 @@ const AddEnvironmentVariableRow = ({
|
||||
isDeleteDisabled,
|
||||
}: AddEnvironmentVariableRowProps) => {
|
||||
return (
|
||||
<div className="flex py-4 self-stretch">
|
||||
<div className="flex gap-2 py-1 self-stretch items-end">
|
||||
<Input
|
||||
size="md"
|
||||
{...register(`variables.${index}.key`, {
|
||||
@ -34,16 +34,9 @@ const AddEnvironmentVariableRow = ({
|
||||
required: 'Value field cannot be empty',
|
||||
})}
|
||||
/>
|
||||
<div className="self-end">
|
||||
<Button
|
||||
size="md"
|
||||
iconOnly
|
||||
onClick={onDelete}
|
||||
disabled={isDeleteDisabled}
|
||||
>
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<Button size="md" iconOnly onClick={onDelete} disabled={isDeleteDisabled}>
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,20 +1,13 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Project } from 'gql-client';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogHeader,
|
||||
DialogBody,
|
||||
DialogFooter,
|
||||
Input,
|
||||
Typography,
|
||||
} from '@snowballtools/material-tailwind-react-fork';
|
||||
|
||||
import { useGQLClient } from '../../../../context/GQLClientContext';
|
||||
import { useGQLClient } from 'context/GQLClientContext';
|
||||
import { useToast } from 'components/shared/Toast';
|
||||
import { Modal } from 'components/shared/Modal';
|
||||
import { Button } from 'components/shared/Button';
|
||||
import { Input } from 'components/shared/Input';
|
||||
import { Project } from 'gql-client';
|
||||
|
||||
interface DeleteProjectDialogProp {
|
||||
open: boolean;
|
||||
@ -60,51 +53,36 @@ const DeleteProjectDialog = ({
|
||||
}, [client, project, handleOpen]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} handler={handleOpen}>
|
||||
<DialogHeader className="flex justify-between">
|
||||
<div>Delete project?</div>
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={handleOpen}
|
||||
className="mr-1 rounded-3xl"
|
||||
>
|
||||
X
|
||||
</Button>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit(deleteProjectHandler)}>
|
||||
<DialogBody className="flex flex-col gap-2">
|
||||
<Typography variant="paragraph">
|
||||
Deleting your project is irreversible. Enter your project’s
|
||||
name
|
||||
<span className="bg-blue-100 text-blue-700">({project.name})</span>
|
||||
below to confirm you want to permanently delete it:
|
||||
</Typography>
|
||||
<Input
|
||||
id="input"
|
||||
{...register('projectName', {
|
||||
required: 'Project name is required',
|
||||
validate: (value) => value === project.name,
|
||||
})}
|
||||
/>
|
||||
<Typography variant="small" color="red">
|
||||
^ Deleting your project is irreversible.
|
||||
</Typography>
|
||||
</DialogBody>
|
||||
<DialogFooter className="flex justify-start">
|
||||
<Button variant="outlined" onClick={handleOpen} className="mr-1">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="gradient"
|
||||
color="red"
|
||||
type="submit"
|
||||
disabled={!isValid}
|
||||
>
|
||||
Yes, Delete project
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Dialog>
|
||||
<Modal open={open} onOpenChange={handleOpen}>
|
||||
<Modal.Content>
|
||||
<Modal.Header>Delete project?</Modal.Header>
|
||||
<form onSubmit={handleSubmit(deleteProjectHandler)}>
|
||||
<Modal.Body>
|
||||
<Input
|
||||
label={
|
||||
"Deleting your project is irreversible. Enter your project's name " +
|
||||
project.name +
|
||||
' below to confirm you want to permanently delete it:'
|
||||
}
|
||||
id="input"
|
||||
{...register('projectName', {
|
||||
required: 'Project name is required',
|
||||
validate: (value) => value === project.name,
|
||||
})}
|
||||
helperText="Deleting your project is irreversible."
|
||||
/>
|
||||
</Modal.Body>
|
||||
<Modal.Footer className="flex justify-start">
|
||||
<Button onClick={handleOpen} variant="tertiary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="danger" type="submit" disabled={!isValid}>
|
||||
Yes, delete project
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,16 +1,20 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import toast from 'react-hot-toast';
|
||||
import { EnvironmentVariable } from 'gql-client';
|
||||
|
||||
import {
|
||||
IconButton,
|
||||
Typography,
|
||||
} from '@snowballtools/material-tailwind-react-fork';
|
||||
|
||||
import { useGQLClient } from 'context/GQLClientContext';
|
||||
import { DeleteVariableDialog } from 'components/projects/Dialog/DeleteVariableDialog';
|
||||
import { Input } from 'components/shared/Input';
|
||||
import { Button } from 'components/shared/Button';
|
||||
import {
|
||||
CheckRoundFilledIcon,
|
||||
CrossIcon,
|
||||
EditBigIcon,
|
||||
HideEyeOffIcon,
|
||||
ShowEyeIcon,
|
||||
TrashIcon,
|
||||
} from 'components/shared/CustomIcon';
|
||||
import { EnvironmentVariable } from 'gql-client';
|
||||
import { useToast } from 'components/shared/Toast';
|
||||
|
||||
const ShowPasswordIcon = ({
|
||||
handler,
|
||||
@ -26,19 +30,24 @@ const ShowPasswordIcon = ({
|
||||
}}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{isVisible ? '-' : '+'}
|
||||
{isVisible ? <ShowEyeIcon size={16} /> : <HideEyeOffIcon size={16} />}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export interface EditEnvironmentVariableRowProps {
|
||||
variable: EnvironmentVariable;
|
||||
onUpdate: () => Promise<void>;
|
||||
isFirstVariable?: boolean;
|
||||
}
|
||||
|
||||
const EditEnvironmentVariableRow = ({
|
||||
variable,
|
||||
onUpdate,
|
||||
}: {
|
||||
variable: EnvironmentVariable;
|
||||
onUpdate: () => Promise<void>;
|
||||
}) => {
|
||||
isFirstVariable = false,
|
||||
}: EditEnvironmentVariableRowProps) => {
|
||||
const client = useGQLClient();
|
||||
const { toast, dismiss } = useToast();
|
||||
|
||||
const { handleSubmit, register, reset } = useForm({
|
||||
defaultValues: {
|
||||
@ -58,9 +67,19 @@ const EditEnvironmentVariableRow = ({
|
||||
if (isEnvironmentVariableRemoved) {
|
||||
await onUpdate();
|
||||
setDeleteDialogOpen((preVal) => !preVal);
|
||||
toast.success('Variable deleted');
|
||||
toast({
|
||||
id: 'variable_deleted',
|
||||
title: 'Variable deleted',
|
||||
variant: 'success',
|
||||
onDismiss: dismiss,
|
||||
});
|
||||
} else {
|
||||
toast.error('Variable not deleted');
|
||||
toast({
|
||||
id: 'variable_not_deleted',
|
||||
title: 'Variable not deleted',
|
||||
variant: 'error',
|
||||
onDismiss: dismiss,
|
||||
});
|
||||
}
|
||||
}, [variable, onUpdate]);
|
||||
|
||||
@ -71,10 +90,21 @@ const EditEnvironmentVariableRow = ({
|
||||
|
||||
if (isEnvironmentVariableUpdated) {
|
||||
await onUpdate();
|
||||
toast.success('Variable edited');
|
||||
toast({
|
||||
id: 'variable_updated',
|
||||
title: 'Variable edited',
|
||||
variant: 'success',
|
||||
onDismiss: dismiss,
|
||||
});
|
||||
|
||||
setEdit((preVal) => !preVal);
|
||||
} else {
|
||||
toast.error('Variable not edited');
|
||||
toast({
|
||||
id: 'variable_not_updated',
|
||||
title: 'Variable not edited',
|
||||
variant: 'error',
|
||||
onDismiss: dismiss,
|
||||
});
|
||||
}
|
||||
},
|
||||
[variable, onUpdate],
|
||||
@ -86,71 +116,55 @@ const EditEnvironmentVariableRow = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex gap-1 p-2">
|
||||
<div>
|
||||
<Typography variant="small">Key</Typography>
|
||||
<Input disabled={!edit} {...register(`key`)} />
|
||||
</div>
|
||||
<div>
|
||||
<Typography variant="small">Value</Typography>
|
||||
<Input
|
||||
disabled={!edit}
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
leftIcon={
|
||||
<ShowPasswordIcon
|
||||
handler={() => {
|
||||
setShowPassword((prevShowPassword) => !prevShowPassword);
|
||||
}}
|
||||
isVisible={showPassword}
|
||||
/>
|
||||
<div className="flex gap-1 items-end">
|
||||
<Input
|
||||
disabled={!edit}
|
||||
{...register(`key`)}
|
||||
label={isFirstVariable ? 'Key' : undefined}
|
||||
/>
|
||||
<Input
|
||||
disabled={!edit}
|
||||
type={showPassword || edit ? 'text' : 'password'}
|
||||
label={isFirstVariable ? 'Value' : undefined}
|
||||
rightIcon={
|
||||
<ShowPasswordIcon
|
||||
handler={() => {
|
||||
setShowPassword((prevShowPassword) => !prevShowPassword);
|
||||
}}
|
||||
isVisible={showPassword || edit}
|
||||
/>
|
||||
}
|
||||
{...register(`value`)}
|
||||
/>
|
||||
<Button
|
||||
iconOnly
|
||||
size="md"
|
||||
onClick={() => {
|
||||
edit
|
||||
? handleSubmit(updateEnvironmentVariableHandler)()
|
||||
: setEdit((preVal) => !preVal);
|
||||
}}
|
||||
>
|
||||
{edit ? (
|
||||
<CheckRoundFilledIcon size={16} />
|
||||
) : (
|
||||
<EditBigIcon size={16} />
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
iconOnly
|
||||
size="md"
|
||||
onClick={() => {
|
||||
if (edit) {
|
||||
reset();
|
||||
setEdit((preVal) => !preVal);
|
||||
} else {
|
||||
setDeleteDialogOpen((preVal) => !preVal);
|
||||
}
|
||||
{...register(`value`)}
|
||||
/>
|
||||
</div>
|
||||
{edit ? (
|
||||
<>
|
||||
<div className="self-end">
|
||||
<IconButton
|
||||
onClick={handleSubmit(updateEnvironmentVariableHandler)}
|
||||
size="sm"
|
||||
>
|
||||
{'S'}
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="self-end">
|
||||
<IconButton
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
reset();
|
||||
setEdit((preVal) => !preVal);
|
||||
}}
|
||||
>
|
||||
{'C'}
|
||||
</IconButton>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="self-end">
|
||||
<IconButton
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setEdit((preVal) => !preVal);
|
||||
}}
|
||||
>
|
||||
{'E'}
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="self-end">
|
||||
<IconButton
|
||||
size="sm"
|
||||
onClick={() => setDeleteDialogOpen((preVal) => !preVal)}
|
||||
>
|
||||
{'D'}
|
||||
</IconButton>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
}}
|
||||
>
|
||||
{edit ? <CrossIcon size={16} /> : <TrashIcon size={16} />}
|
||||
</Button>
|
||||
</div>
|
||||
<DeleteVariableDialog
|
||||
handleCancel={() => setDeleteDialogOpen((preVal) => !preVal)}
|
||||
|
@ -80,7 +80,7 @@ const MemberCard = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex p-1 items-center ${!isFirstCard && 'mt-1 border-t border-gray-300'}`}
|
||||
className={`flex py-1 items-center ${!isFirstCard && 'mt-1 border-t border-gray-300'}`}
|
||||
>
|
||||
<div className="basis-1/2">
|
||||
{member.name && (
|
||||
|
@ -30,7 +30,7 @@ abbr[title] {
|
||||
@apply !text-elements-disabled !bg-transparent;
|
||||
}
|
||||
|
||||
.react-calendar__month-view__days__day--neighboringMonth {
|
||||
.react-calendar__month-view__days__day--neighboringMonth:focus-visible {
|
||||
@apply !text-elements-disabled !bg-transparent;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
import { CustomIcon, CustomIconProps } from './CustomIcon';
|
||||
|
||||
export const EditBigIcon: React.FC<CustomIconProps> = (props) => {
|
||||
return (
|
||||
<CustomIcon
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M4.61304 1.99935L7.5 1.99935C7.77614 1.99935 8 2.22321 8 2.49935C8 2.77549 7.77614 2.99935 7.5 2.99935H4.63333C4.25171 2.99935 3.99557 2.99974 3.79832 3.01585C3.6069 3.03149 3.51538 3.05941 3.45501 3.09018C3.29821 3.17007 3.17072 3.29755 3.09083 3.45436C3.06007 3.51473 3.03214 3.60625 3.01651 3.79767C3.00039 3.99492 3 4.25106 3 4.63268V11.366C3 11.7476 3.00039 12.0038 3.01651 12.201C3.03214 12.3924 3.06007 12.484 3.09083 12.5443C3.17072 12.7011 3.29821 12.8286 3.45501 12.9085C3.51538 12.9393 3.6069 12.9672 3.79832 12.9828C3.99557 12.999 4.25171 12.9993 4.63333 12.9993H11.3667C11.7483 12.9993 12.0044 12.999 12.2017 12.9828C12.3931 12.9672 12.4846 12.9393 12.545 12.9085C12.7018 12.8286 12.8293 12.7011 12.9092 12.5443C12.9399 12.484 12.9679 12.3924 12.9835 12.201C12.9996 12.0038 13 11.7476 13 11.366V8.49935C13 8.22321 13.2239 7.99935 13.5 7.99935C13.7761 7.99935 14 8.22321 14 8.49935V11.3863C14 11.7424 14 12.0396 13.9802 12.2825C13.9595 12.5357 13.9147 12.7735 13.8002 12.9983C13.6244 13.3433 13.3439 13.6238 12.999 13.7995C12.7741 13.9141 12.5364 13.9588 12.2831 13.9795C12.0403 13.9994 11.7431 13.9994 11.387 13.9993H4.61303C4.25693 13.9994 3.95971 13.9994 3.71689 13.9795C3.46363 13.9588 3.22586 13.9141 3.00102 13.7995C2.65605 13.6238 2.37559 13.3433 2.19982 12.9983C2.08526 12.7735 2.04052 12.5357 2.01983 12.2825C1.99999 12.0396 1.99999 11.7424 2 11.3863V4.61239C1.99999 4.25629 1.99999 3.95906 2.01983 3.71624C2.04052 3.46298 2.08526 3.22521 2.19982 3.00037C2.37559 2.6554 2.65605 2.37494 3.00102 2.19917C3.22586 2.08461 3.46363 2.03987 3.71689 2.01918C3.95971 1.99934 4.25694 1.99934 4.61304 1.99935Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M13.963 1.92174C13.2471 1.20578 12.0863 1.20578 11.3703 1.92174L5.67504 7.617C5.45625 7.83579 5.33333 8.13254 5.33333 8.44196V10.1658C5.33333 10.442 5.55719 10.6658 5.83333 10.6658H7.55719C7.86661 10.6658 8.16336 10.5429 8.38215 10.3241L14.0774 4.62884C14.7934 3.91288 14.7934 2.75208 14.0774 2.03612L13.963 1.92174Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
</CustomIcon>
|
||||
);
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
import { CustomIcon, CustomIconProps } from './CustomIcon';
|
||||
|
||||
export const HideEyeOffIcon: React.FC<CustomIconProps> = (props) => {
|
||||
return (
|
||||
<CustomIcon
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M2.02012 1.31246C1.82486 1.1172 1.50828 1.1172 1.31301 1.31246C1.11775 1.50772 1.11775 1.82431 1.31301 2.01957L2.02012 1.31246ZM1.62744 7.42685L1.1887 7.18704L1.62744 7.42685ZM11.7196 11.719L12.0731 11.3655L11.7196 11.719ZM13.9797 14.6862C14.1749 14.8815 14.4915 14.8815 14.6868 14.6862C14.8821 14.491 14.8821 14.1744 14.6868 13.9791L13.9797 14.6862ZM1.62804 8.57302L1.18932 8.81287H1.18932L1.62804 8.57302ZM5.2498 3.12216C4.99958 3.23898 4.89145 3.53652 5.00828 3.78674C5.1251 4.03695 5.42264 4.14508 5.67286 4.02826L5.2498 3.12216ZM14.3718 7.42567L14.8105 7.18582L14.3718 7.42567ZM12.3668 10.4904C12.1743 10.6884 12.1786 11.0049 12.3766 11.1975C12.5745 11.39 12.891 11.3857 13.0836 11.1877L12.3668 10.4904ZM14.3724 8.57183L13.9336 8.33203V8.33203L14.3724 8.57183ZM6.58569 6.58512L6.93924 6.23157C6.74398 6.03631 6.4274 6.03631 6.23213 6.23157L6.58569 6.58512ZM9.41411 9.41355L9.76767 9.7671C9.86144 9.67334 9.91411 9.54616 9.91411 9.41355C9.91411 9.28094 9.86144 9.15377 9.76767 9.06L9.41411 9.41355ZM1.31301 2.01957L3.92667 4.63323L4.63378 3.92612L2.02012 1.31246L1.31301 2.01957ZM2.06618 7.66665C2.78183 6.35732 3.64551 5.3672 4.57648 4.68246L3.98397 3.87689C2.91986 4.65956 1.96456 5.76756 1.1887 7.18704L2.06618 7.66665ZM3.92667 4.63323L11.366 12.0726L12.0731 11.3655L4.63378 3.92612L3.92667 4.63323ZM11.366 12.0726L13.9797 14.6862L14.6868 13.9791L12.0731 11.3655L11.366 12.0726ZM1.18932 8.81287C2.47954 11.1728 4.26886 12.674 6.21987 13.243C8.17733 13.8138 10.2399 13.428 12.0158 12.1218L11.4233 11.3162C9.88108 12.4506 8.13835 12.7608 6.49983 12.283C4.85485 11.8033 3.25748 10.5112 2.06675 8.33317L1.18932 8.81287ZM1.1887 7.18704C0.911724 7.69378 0.912792 8.30707 1.18932 8.81287L2.06675 8.33317C1.95313 8.12535 1.95308 7.87358 2.06618 7.66665L1.1887 7.18704ZM5.67286 4.02826C7.09829 3.36272 8.63166 3.32591 10.0669 3.91426C11.5069 4.50457 12.8795 5.7385 13.933 7.66553L14.8105 7.18582C13.6688 5.09759 12.1371 3.68216 10.4462 2.98899C8.75047 2.29385 6.92622 2.33943 5.2498 3.12216L5.67286 4.02826ZM13.0836 11.1877C13.7227 10.5308 14.305 9.7376 14.8111 8.81164L13.9336 8.33203C13.4669 9.18586 12.9371 9.90419 12.3668 10.4904L13.0836 11.1877ZM13.933 7.66553C14.0467 7.87336 14.0467 8.12511 13.9336 8.33203L14.8111 8.81164C15.0881 8.30489 15.087 7.69161 14.8105 7.18582L13.933 7.66553ZM7.9999 9.49934C7.17147 9.49934 6.4999 8.82776 6.4999 7.99934H5.4999C5.4999 9.38005 6.61919 10.4993 7.9999 10.4993V9.49934ZM6.4999 7.99934C6.4999 7.58499 6.66725 7.21067 6.93924 6.93868L6.23213 6.23157C5.78027 6.68343 5.4999 7.30912 5.4999 7.99934H6.4999ZM6.23213 6.93868L9.06056 9.7671L9.76767 9.06L6.93924 6.23157L6.23213 6.93868ZM9.06056 9.06C8.78857 9.33199 8.41425 9.49934 7.9999 9.49934V10.4993C8.69012 10.4993 9.3158 10.219 9.76767 9.7671L9.06056 9.06Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</CustomIcon>
|
||||
);
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
import { CustomIcon, CustomIconProps } from './CustomIcon';
|
||||
|
||||
export const ShowEyeIcon: React.FC<CustomIconProps> = (props) => {
|
||||
return (
|
||||
<CustomIcon
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M1.62774 7.42694L2.06646 7.66677L1.62774 7.42694ZM14.3721 7.42686L13.9333 7.66669V7.66669L14.3721 7.42686ZM1.62774 8.5731L2.06646 8.33327H2.06646L1.62774 8.5731ZM14.3721 8.57302L14.8108 8.81285L14.8108 8.81285L14.3721 8.57302ZM2.06646 7.66677C3.61474 4.83447 5.84609 3.50002 7.99991 3.5C10.1537 3.49998 12.3851 4.8344 13.9333 7.66669L14.8108 7.18703C13.1325 4.11679 10.6049 2.49998 7.9999 2.5C5.39486 2.50002 2.86735 4.11687 1.18901 7.18711L2.06646 7.66677ZM1.18901 8.81293C2.86735 11.8832 5.39486 13.5 7.99991 13.5C10.6049 13.4999 13.1325 11.8831 14.8108 8.81285L13.9333 8.33319C12.3851 11.1655 10.1537 12.4999 7.9999 12.5C5.84609 12.5 3.61473 11.1656 2.06646 8.33327L1.18901 8.81293ZM1.18901 7.18711C0.912257 7.69338 0.912257 8.30665 1.18901 8.81293L2.06646 8.33327C1.95311 8.1259 1.95311 7.87414 2.06646 7.66677L1.18901 7.18711ZM13.9333 7.66669C14.0467 7.87406 14.0467 8.12582 13.9333 8.33319L14.8108 8.81285C15.0875 8.30658 15.0875 7.69331 14.8108 7.18703L13.9333 7.66669ZM9.4999 8C9.4999 8.82843 8.82833 9.5 7.9999 9.5V10.5C9.38062 10.5 10.4999 9.38071 10.4999 8H9.4999ZM7.9999 9.5C7.17148 9.5 6.4999 8.82843 6.4999 8H5.4999C5.4999 9.38071 6.61919 10.5 7.9999 10.5V9.5ZM6.4999 8C6.4999 7.17157 7.17148 6.5 7.9999 6.5V5.5C6.61919 5.5 5.4999 6.61929 5.4999 8H6.4999ZM7.9999 6.5C8.82833 6.5 9.4999 7.17157 9.4999 8H10.4999C10.4999 6.61929 9.38062 5.5 7.9999 5.5V6.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</CustomIcon>
|
||||
);
|
||||
};
|
@ -73,6 +73,9 @@ export * from './SwitchIcon';
|
||||
export * from './CollaboratorsIcon';
|
||||
export * from './ChevronUpSmallIcon';
|
||||
export * from './ChevronDownSmallIcon';
|
||||
export * from './EditBigIcon';
|
||||
export * from './ShowEyeIcon';
|
||||
export * from './HideEyeOffIcon';
|
||||
|
||||
// Templates
|
||||
export * from './templates';
|
||||
|
@ -166,7 +166,7 @@ const GeneralTabPanel = () => {
|
||||
setSelectedTransferOrganization(org.org);
|
||||
setOpenTransferDialog(!openTransferDialog);
|
||||
})}
|
||||
className="self-stretch space-y-3 px-2"
|
||||
className="self-stretch space-y-3"
|
||||
>
|
||||
<Heading className="text-sky-950 text-lg font-medium leading-normal">
|
||||
Transfer project
|
||||
@ -197,7 +197,7 @@ const GeneralTabPanel = () => {
|
||||
from={project.organization.name}
|
||||
to={selectedUserOrgName}
|
||||
/>
|
||||
<div className="self-stretch space-y-3 px-2">
|
||||
<div className="self-stretch space-y-3">
|
||||
<Heading className="text-sky-950 text-lg font-medium leading-normal">
|
||||
Delete project
|
||||
</Heading>
|
||||
|
@ -0,0 +1,29 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { EditBigIcon } from 'components/shared/CustomIcon';
|
||||
|
||||
const meta: Meta<typeof EditBigIcon> = {
|
||||
title: 'Icons/EditBigIcon',
|
||||
component: EditBigIcon,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
size: {
|
||||
control: 'text',
|
||||
},
|
||||
name: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof EditBigIcon>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: ({ size, name }) => <EditBigIcon size={size} name={name} />,
|
||||
args: {
|
||||
size: '24px',
|
||||
name: 'plus',
|
||||
},
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { HideEyeOffIcon } from 'components/shared/CustomIcon';
|
||||
|
||||
const meta: Meta<typeof HideEyeOffIcon> = {
|
||||
title: 'Icons/HideEyeOffIcon',
|
||||
component: HideEyeOffIcon,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
size: {
|
||||
control: 'text',
|
||||
},
|
||||
name: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof HideEyeOffIcon>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: ({ size, name }) => <HideEyeOffIcon size={size} name={name} />,
|
||||
args: {
|
||||
size: '24px',
|
||||
name: 'plus',
|
||||
},
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ShowEyeIcon } from 'components/shared/CustomIcon';
|
||||
|
||||
const meta: Meta<typeof ShowEyeIcon> = {
|
||||
title: 'Icons/ShowEyeIcon',
|
||||
component: ShowEyeIcon,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
size: {
|
||||
control: 'text',
|
||||
},
|
||||
name: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof ShowEyeIcon>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: ({ size, name }) => <ShowEyeIcon size={size} name={name} />,
|
||||
args: {
|
||||
size: '24px',
|
||||
name: 'plus',
|
||||
},
|
||||
};
|
114
packages/frontend/src/stories/MockStoriesData.ts
Normal file
114
packages/frontend/src/stories/MockStoriesData.ts
Normal file
@ -0,0 +1,114 @@
|
||||
import {
|
||||
User,
|
||||
Project,
|
||||
Organization,
|
||||
Role,
|
||||
OrganizationMember,
|
||||
ProjectMember,
|
||||
EnvironmentVariable,
|
||||
Deployment,
|
||||
DeploymentStatus,
|
||||
DomainStatus,
|
||||
Domain,
|
||||
Environment,
|
||||
} from 'gql-client';
|
||||
|
||||
export const user: User = {
|
||||
id: '1',
|
||||
email: 'helloworld@helloworld.com',
|
||||
isVerified: true,
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
name: 'Hello World',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
gitHubToken: 'GitHub Token',
|
||||
};
|
||||
|
||||
export const organizationMember: OrganizationMember = {
|
||||
id: '1',
|
||||
member: user,
|
||||
role: Role.Owner,
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
};
|
||||
|
||||
export const organization: Organization = {
|
||||
id: '1',
|
||||
name: 'Organization',
|
||||
slug: 'organization',
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
members: [organizationMember],
|
||||
projects: [],
|
||||
};
|
||||
|
||||
export const member: ProjectMember = {
|
||||
id: '1',
|
||||
member: user,
|
||||
permissions: [],
|
||||
isPending: false,
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
};
|
||||
|
||||
export const environmentVariable0: EnvironmentVariable = {
|
||||
id: '1',
|
||||
key: 'API_KEY',
|
||||
value: '123456',
|
||||
environment: Environment.Development,
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
};
|
||||
|
||||
export const environmentVariable1: EnvironmentVariable = {
|
||||
id: '2',
|
||||
key: 'API_KEY_2',
|
||||
value: '123456',
|
||||
environment: Environment.Development,
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
};
|
||||
|
||||
export const domain0: Domain = {
|
||||
id: '1',
|
||||
name: 'Domain',
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
branch: 'Branch',
|
||||
status: DomainStatus.Live,
|
||||
redirectTo: null,
|
||||
};
|
||||
|
||||
export const deployment0: Deployment = {
|
||||
id: '1',
|
||||
url: 'https://deployment.com',
|
||||
status: DeploymentStatus.Ready,
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
branch: 'Branch',
|
||||
environment: Environment.Development,
|
||||
isCurrent: true,
|
||||
commitHash: 'Commit Hash',
|
||||
domain: domain0,
|
||||
commitMessage: 'Commit Message',
|
||||
createdBy: user,
|
||||
};
|
||||
|
||||
export const project: Project = {
|
||||
id: '1',
|
||||
name: 'GithubUsername-ProjectName',
|
||||
owner: user,
|
||||
deployments: [deployment0],
|
||||
repository: 'Repository',
|
||||
prodBranch: 'Prod Branch',
|
||||
description: 'Description',
|
||||
createdAt: '2021-08-01T00:00:00.000Z',
|
||||
updatedAt: '2021-08-01T00:00:00.000Z',
|
||||
framework: 'NextJS',
|
||||
environmentVariables: [environmentVariable0, environmentVariable1],
|
||||
organization: organization,
|
||||
template: 'Template',
|
||||
members: [member],
|
||||
webhooks: ['beepboop'],
|
||||
icon: 'Icon',
|
||||
subDomain: 'SubDomain',
|
||||
};
|
@ -21,10 +21,45 @@ const meta: Meta<typeof AddEnvironmentVariableRow> = {
|
||||
},
|
||||
}),
|
||||
},
|
||||
} as Meta<typeof AddEnvironmentVariableRow>;
|
||||
argTypes: {
|
||||
onDelete: {
|
||||
action: 'delete',
|
||||
},
|
||||
register: {
|
||||
action: 'register',
|
||||
},
|
||||
index: {
|
||||
type: 'number',
|
||||
},
|
||||
isDeleteDisabled: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
isDeleteDisabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof AddEnvironmentVariableRow>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const DisabledDelete: Story = {
|
||||
args: {
|
||||
isDeleteDisabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const First: Story = {
|
||||
args: {
|
||||
index: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export const Second: Story = {
|
||||
args: {
|
||||
index: 1,
|
||||
},
|
||||
};
|
@ -0,0 +1,31 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import AddMemberDialog from 'components/projects/project/settings/AddMemberDialog';
|
||||
|
||||
const meta: Meta<typeof AddMemberDialog> = {
|
||||
title: 'Project/Settings/AddMemberDialog',
|
||||
component: AddMemberDialog,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
open: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
handleOpen: {
|
||||
action: 'open',
|
||||
},
|
||||
handleAddMember: {
|
||||
action: 'addMember',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
open: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof AddMemberDialog>;
|
||||
|
||||
export const Default: Story = {};
|
@ -0,0 +1,50 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import {
|
||||
reactRouterParameters,
|
||||
withRouter,
|
||||
} from 'storybook-addon-remix-react-router';
|
||||
|
||||
import DeleteProjectDialog from 'components/projects/project/settings/DeleteProjectDialog';
|
||||
import { project } from '../../MockStoriesData';
|
||||
|
||||
const meta: Meta<typeof DeleteProjectDialog> = {
|
||||
title: 'Project/Settings/DeleteProjectDialog',
|
||||
component: DeleteProjectDialog,
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
parameters: {
|
||||
reactRouter: reactRouterParameters({
|
||||
location: {
|
||||
pathParams: { userId: 'me' },
|
||||
},
|
||||
routing: {
|
||||
path: '/snowball-tools-1/projects/6bb3bec2-d71b-4fc0-9e32-4767f68668f4/settings',
|
||||
},
|
||||
}),
|
||||
},
|
||||
argTypes: {
|
||||
open: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
handleOpen: {
|
||||
action: 'open',
|
||||
},
|
||||
project: {
|
||||
control: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
},
|
||||
args: {
|
||||
open: true,
|
||||
project: project,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof DeleteProjectDialog>;
|
||||
|
||||
export const Default: Story = {};
|
@ -0,0 +1,38 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import DisplayEnvironmentVariables from 'components/projects/project/settings/DisplayEnvironmentVariables';
|
||||
import {
|
||||
environmentVariable0,
|
||||
environmentVariable1,
|
||||
} from '../../MockStoriesData';
|
||||
import { Environment } from 'gql-client';
|
||||
|
||||
const meta: Meta<typeof DisplayEnvironmentVariables> = {
|
||||
title: 'Project/Settings/DisplayEnvironmentVariables',
|
||||
component: DisplayEnvironmentVariables,
|
||||
argTypes: {
|
||||
environment: {
|
||||
control: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
variables: {
|
||||
control: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
onUpdate: {
|
||||
action: 'update',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
environment: Environment.Development,
|
||||
variables: [environmentVariable0, environmentVariable1],
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof DisplayEnvironmentVariables>;
|
||||
|
||||
export const Default: Story = {};
|
@ -0,0 +1,28 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import EditEnvironmentVariableRow from 'components/projects/project/settings/EditEnvironmentVariableRow';
|
||||
import { environmentVariable0 } from '../../MockStoriesData';
|
||||
|
||||
const meta: Meta<typeof EditEnvironmentVariableRow> = {
|
||||
title: 'Project/Settings/EditEnvironmentVariableRow',
|
||||
component: EditEnvironmentVariableRow,
|
||||
argTypes: {
|
||||
variable: {
|
||||
control: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
onUpdate: {
|
||||
action: 'update',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
variable: environmentVariable0,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof EditEnvironmentVariableRow>;
|
||||
|
||||
export const Default: Story = {};
|
@ -17,7 +17,7 @@ const meta: Meta<typeof SetupDomain> = {
|
||||
pathParams: { userId: 'me' },
|
||||
},
|
||||
routing: {
|
||||
path: '/snowball-tools-1/projects/6bb3bec2-d71b-4fc0-9e32-4767f68668f4/settings/domains/add',
|
||||
path: '/snowball-tools-1/projects/6bb3bec2-d71b-4fc0-9e32-4767f68668f4/settings/domains',
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
@ -14,9 +14,6 @@ export default withMT({
|
||||
xxs: '400px',
|
||||
xs: '480px',
|
||||
},
|
||||
zIndex: {
|
||||
tooltip: '52',
|
||||
},
|
||||
letterSpacing: {
|
||||
tight: '-0.084px',
|
||||
},
|
||||
@ -178,6 +175,7 @@ export default withMT({
|
||||
4.5: '1.125rem',
|
||||
},
|
||||
zIndex: {
|
||||
tooltip: '52',
|
||||
toast: '9999',
|
||||
},
|
||||
animation: {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import { defineConfig, PluginOption } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [react()] as PluginOption[],
|
||||
resolve: {
|
||||
alias: {
|
||||
utils: '/src/utils',
|
||||
|
Loading…
Reference in New Issue
Block a user