[ENG-970] Job dropdown with actions (#1329)

* Job dropdown with actions

* Update JobGroup.tsx

* fix hover colors for theme support

* Update Dropdown.tsx

* Update JobGroup.tsx

---------

Co-authored-by: Utku <74243531+utkubakir@users.noreply.github.com>
This commit is contained in:
ameer2468
2023-09-11 18:41:51 +03:00
committed by GitHub
parent 0730cae58d
commit f153c08e70
2 changed files with 111 additions and 23 deletions

View File

@@ -1,7 +1,8 @@
import { Folder } from '@sd/assets/icons';
import { useQueryClient } from '@tanstack/react-query';
import clsx from 'clsx';
import dayjs from 'dayjs';
import { DotsThreeVertical, Pause, Play, Stop } from '@phosphor-icons/react';
import { DotsThreeVertical, Eye, Pause, Play, Stop, Trash } from '@phosphor-icons/react';
import { useMemo, useState } from 'react';
import {
getJobNiceActionName,
@@ -12,8 +13,7 @@ import {
useLibraryMutation,
useTotalElapsedTimeText
} from '@sd/client';
import { Button, ProgressBar, Tooltip } from '@sd/ui';
import { Button, Dropdown, ProgressBar, Tooltip, toast } from '@sd/ui';
import Job from './Job';
import JobContainer from './JobContainer';
@@ -40,9 +40,14 @@ export default function ({ group, progress }: JobGroupProps) {
if (jobs.length === 0) return <></>;
return (
<ul className="relative overflow-hidden">
<ul className="relative overflow-visible">
<div className="row absolute right-3 top-3 z-50 flex space-x-1">
<Options activeJob={runningJob} group={group} />
<Options
showChildJobs={showChildJobs}
setShowChildJobs={() => setShowChildJobs((v) => !v)}
activeJob={runningJob}
group={group}
/>
</div>
{jobs?.length > 1 ? (
<>
@@ -112,10 +117,70 @@ export default function ({ group, progress }: JobGroupProps) {
);
}
function Options({ activeJob, group }: { activeJob?: JobReport; group: JobGroup }) {
const resumeJob = useLibraryMutation(['jobs.resume'], { onError: alert });
const pauseJob = useLibraryMutation(['jobs.pause'], { onError: alert });
const cancelJob = useLibraryMutation(['jobs.cancel'], { onError: alert });
function Options({
activeJob,
group,
setShowChildJobs,
showChildJobs
}: {
activeJob?: JobReport;
group: JobGroup;
setShowChildJobs: () => void;
showChildJobs: boolean;
}) {
const queryClient = useQueryClient();
const toastErrorSuccess = (
errorMessage?: string,
successMessage?: string,
successCallBack?: () => void
) => {
return {
onError: () => {
errorMessage &&
toast.error({
title: 'Error',
body: errorMessage
});
},
onSuccess: () => {
successMessage &&
toast.success({
title: 'Success',
body: successMessage
}),
successCallBack?.();
}
};
};
const resumeJob = useLibraryMutation(
['jobs.resume'],
toastErrorSuccess('Failed to resume job.', 'Job has been resumed.')
);
const pauseJob = useLibraryMutation(
['jobs.pause'],
toastErrorSuccess('Failed to pause job.', 'Job has been paused.')
);
const cancelJob = useLibraryMutation(
['jobs.cancel'],
toastErrorSuccess('Failed to cancel job.', 'Job has been canceled.')
);
const clearJob = useLibraryMutation(
['jobs.clear'],
toastErrorSuccess('Failed to remove job.', undefined, () => {
queryClient.invalidateQueries(['jobs.reports']);
})
);
const clearJobHandler = () => {
group.jobs.forEach((job) => {
clearJob.mutate(job.id);
//only one toast for all jobs
if (job.id === group.id)
toast.success({ title: 'Success', body: 'Job has been removed.' });
});
};
const isJobPaused = useMemo(
() => group.jobs.some((job) => job.status === 'Paused'),
@@ -137,18 +202,38 @@ function Options({ activeJob, group }: { activeJob?: JobReport; group: JobGroup
</Tooltip>
</Button>
)}
{/* TODO: Fix this */}
{activeJob === undefined ? (
<Button
className="cursor-pointer"
// onClick={() => clearJob?.(data.id as string)}
size="icon"
variant="outline"
<Dropdown.Root
align="right"
itemsClassName="!bg-app-darkBox mt-1 border-app-line/90 !divide-none top-[-10px]"
button={
<Tooltip label="Actions">
<Button className="!px-1" variant="outline">
<DotsThreeVertical className="h-4 w-4 cursor-pointer" />
</Button>
</Tooltip>
}
>
<Tooltip label="Remove">
<DotsThreeVertical className="h-4 w-4 cursor-pointer" />
</Tooltip>
</Button>
<Dropdown.Section>
<Dropdown.Item
active={showChildJobs}
onClick={setShowChildJobs}
icon={Eye}
iconClassName="!w-3"
className="!text-[11px] text-ink-dull"
>
Expand
</Dropdown.Item>
<Dropdown.Item
onClick={() => clearJobHandler()}
icon={Trash}
iconClassName="!w-3"
className="!text-[11px] text-ink-dull"
>
Remove
</Dropdown.Item>
</Dropdown.Section>
</Dropdown.Root>
) : (
<>
{/* Pause / Stop */}

View File

@@ -16,11 +16,11 @@ const itemStyles = cva(
variants: {
selected: {
true: 'bg-accent text-white hover:!bg-accent',
undefined: 'hover:bg-menu-hover',
false: 'hover:bg-menu-hover'
undefined: 'hover:bg-sidebar-selected/40',
false: 'hover:bg-sidebar-selected/40'
},
active: {
true: ''
true: 'bg-sidebar-selected/40 text-sidebar-ink'
}
}
}
@@ -34,6 +34,7 @@ type DropdownItemProps = PropsWithChildren<{
to?: string;
className?: string;
icon?: any;
iconClassName?: string;
onClick?: () => void;
}> &
VariantProps<typeof itemStyles>;
@@ -41,7 +42,9 @@ type DropdownItemProps = PropsWithChildren<{
export const Item = ({ to, className, icon: Icon, children, ...props }: DropdownItemProps) => {
const content = (
<>
{Icon && <Icon weight="bold" className={itemIconStyles(props)} />}
{Icon && (
<Icon weight="bold" className={clsx(itemIconStyles(props), props.iconClassName)} />
)}
<span className="text-left">{children}</span>
</>
);