Skip to content

Commit

Permalink
feat(schedules): mobile support, updated UI
Browse files Browse the repository at this point in the history
  • Loading branch information
he3als committed Aug 17, 2024
1 parent 780dc75 commit ecae788
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 51 deletions.
17 changes: 10 additions & 7 deletions resources/scripts/components/elements/ItemContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@ import { useMemo } from 'react';
import { v4 } from 'uuid';

export interface ContainerProps {
label: string;
title: string;
description: string;
children: React.ReactNode;
labelClasses?: string;
titleClasses?: string;
descriptionClasses?: string;
divClasses?: string;
}

const ItemContainer = ({ label, description, children, labelClasses }: ContainerProps) => {
const ItemContainer = ({ title, description, children, labelClasses, titleClasses, descriptionClasses, divClasses }: ContainerProps) => {
const uuid = useMemo(() => v4(), []);

return (
<div className='flex items-center justify-between gap-2 bg-[#3333332a] border-[1px] border-[#ffffff0e] p-4 rounded-lg'>
<div className='flex flex-col'>
<label htmlFor={uuid} className={`text-neutral-300 text-md font-bold ${labelClasses}`}>
{label}
<div className={`flex items-center justify-between gap-2 bg-[#3333332a] border-[1px] border-[#ffffff0e] p-4 rounded-lg ${divClasses}`}>
<div className={`flex flex-col ${labelClasses}`}>
<label htmlFor={uuid} className={`text-neutral-300 text-md font-bold ${titleClasses}`}>
{title}
</label>
<label htmlFor={uuid} className={`text-neutral-500 text-sm font-semibold ${labelClasses}`}>
<label htmlFor={uuid} className={`text-neutral-500 text-sm font-semibold ${descriptionClasses}`}>
{description}
</label>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface SwitchProps {

const SwitchV2Container = ({ name, label, description, defaultChecked, readOnly, onChange }: SwitchProps) => {
return (
<ItemContainer label={label} description={description}>
<ItemContainer title={label} description={description}>
<Switch
name={name}
onCheckedChange={(checked) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default ({ scheduleId, onDeleted }: Props) => {
</Dialog.Confirm>
<Button.Danger
variant={Button.Variants.Secondary}
className={'flex-1 sm:flex-none mr-4 border-transparent'}
className={'flex-1 sm:flex-none border-transparent'}
onClick={() => setVisible(true)}
>
Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const EditScheduleModal = ({ schedule }: Props) => {
<a href='https://crontab.guru/' target='_blank' rel='noreferrer'>
<ItemContainer
description={'Online editor for cron schedule experessions.'}
label={'Crontab Guru'}
title={'Crontab Guru'}
// defaultChecked={showCheatsheet}
// onChange={() => setShowCheetsheet((s) => !s)}
labelClasses='cursor-pointer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ import getServerSchedule from '@/api/server/schedules/getServerSchedule';
import { ServerContext } from '@/state/server';

import useFlash from '@/plugins/useFlash';
import ItemContainer from '@/components/elements/ItemContainer';

const CronBox = ({ title, value }: { title: string; value: string }) => (
<div className={`bg-neutral-700 rounded p-3`}>
<p className={`text-neutral-300 text-sm`}>{title}</p>
<p className={`text-xl font-medium text-neutral-100`}>{value}</p>
</div>
<ItemContainer title={title} description={value} children={undefined} />
);

const ActivePill = ({ active }: { active: boolean }) => (
Expand Down Expand Up @@ -79,9 +77,9 @@ export default () => {
<>
<div className={`rounded shadow`}>
<div
className={`bg-[#ffffff09] border-[1px] border-[#ffffff11] flex items-center p-6 rounded-2xl`}
className={`bg-[#ffffff09] border-[1px] border-[#ffffff11] flex items-center place-content-between flex-col md:flex-row gap-6 p-6 rounded-2xl mb-6`}
>
<div className={`flex-1`}>
<div className={`flex-none self-start`}>
<h3 className={`flex items-center text-neutral-100 text-2xl`}>
{schedule.name}
{schedule.isProcessing ? (
Expand All @@ -94,57 +92,58 @@ export default () => {
<ActivePill active={schedule.isActive} />
)}
</h3>
<p className={`mt-1 text-sm text-neutral-200`}>
Last run at:&nbsp;
<p className={`mt-1 text-sm`}>
<strong>Last run at:&nbsp;</strong>
{schedule.lastRunAt ? (
format(schedule.lastRunAt, "MMM do 'at' h:mma")
) : (
<span className={`text-neutral-300`}>n/a</span>
<span>N/A</span>
)}

<br className={`sm:invisible`} />

<strong>Next run at:&nbsp;</strong>
{schedule.nextRunAt ? (
format(schedule.nextRunAt, "MMM do 'at' h:mma")
) : (
<span>N/A</span>
)}
<span className={`ml-4 pl-4 border-l-4 border-neutral-600 py-px`}>
Next run at:&nbsp;
{schedule.nextRunAt ? (
format(schedule.nextRunAt, "MMM do 'at' h:mma")
) : (
<span className={`text-neutral-300`}>n/a</span>
)}
</span>
</p>
</div>
<div className={`flex sm:block mt-3 sm:mt-0`}>
<div className={`flex flex-col gap-2 md:min-w-60 min-w-full`}>
<Can action={'schedule.update'}>
<Button.Text className={'flex-1 mr-4'} onClick={toggleEditModal}>
<Button.Text onClick={toggleEditModal} className={'flex-1'}>
Edit
</Button.Text>
<NewTaskButton schedule={schedule} />
</Can>
</div>
</div>
<div className={`hidden sm:grid grid-cols-5 md:grid-cols-5 gap-4 mb-4 mt-4`}>
<div className={`hidden sm:grid grid-cols-5 md:grid-cols-5 gap-4 mb-6`}>
<CronBox title={'Minute'} value={schedule.cron.minute} />
<CronBox title={'Hour'} value={schedule.cron.hour} />
<CronBox title={'Day (Month)'} value={schedule.cron.dayOfMonth} />
<CronBox title={'Month'} value={schedule.cron.month} />
<CronBox title={'Day (Week)'} value={schedule.cron.dayOfWeek} />
</div>
<div className={`bg-neutral-700 rounded-b`}>
<div>
{schedule.tasks.length > 0
? schedule.tasks
.sort((a, b) =>
a.sequenceId === b.sequenceId ? 0 : a.sequenceId > b.sequenceId ? 1 : -1,
)
.map((task) => (
<ScheduleTaskRow
key={`${schedule.id}_${task.id}`}
task={task}
schedule={schedule}
/>
))
.sort((a, b) =>
a.sequenceId === b.sequenceId ? 0 : a.sequenceId > b.sequenceId ? 1 : -1,
)
.map((task) => (
<ScheduleTaskRow
key={`${schedule.id}_${task.id}`}
task={task}
schedule={schedule}
/>
))
: null}
</div>
</div>
<EditScheduleModal visible={showEditModal} schedule={schedule} onModalDismissed={toggleEditModal} />
<div className={`mt-6 flex sm:justify-end`}>
<div className={`mt-6 gap-3 flex sm:justify-end`}>
<Can action={'schedule.delete'}>
<DeleteScheduleButton
scheduleId={schedule.id}
Expand Down
19 changes: 10 additions & 9 deletions resources/scripts/components/server/schedules/ScheduleTaskRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Schedule, Task } from '@/api/server/schedules/getServerSchedules';
import { ServerContext } from '@/state/server';

import useFlash from '@/plugins/useFlash';
import ItemContainer from '@/components/elements/ItemContainer';

interface Props {
schedule: Schedule;
Expand Down Expand Up @@ -61,7 +62,7 @@ export default ({ schedule, task }: Props) => {
const [title] = getActionDetails(task.action);

return (
<div className={`sm:flex items-center p-3 sm:p-6 border-b border-zinc-800`}>
<ItemContainer title={title} description={task.payload} divClasses={`mb-2`}>
<SpinnerOverlay visible={isLoading} fixed size={'large'} />
<TaskDetailsModal
schedule={schedule}
Expand All @@ -79,7 +80,7 @@ export default ({ schedule, task }: Props) => {
Are you sure you want to delete this task? This action cannot be undone.
</ConfirmationModal>
{/* <FontAwesomeIcon icon={icon} className={`text-lg text-white hidden md:block`} /> */}
<div className={`flex-none sm:flex-1 w-full sm:w-auto overflow-x-auto`}>
{/* <div className={`flex-none sm:flex-1 w-full sm:w-auto overflow-x-auto`}>
<p className={`md:ml-6 text-zinc-200 uppercase text-sm`}>{title}</p>
{task.payload && (
<div className={`md:ml-6 mt-2`}>
Expand All @@ -93,20 +94,20 @@ export default ({ schedule, task }: Props) => {
</div>
</div>
)}
</div>
<div className={`mt-3 sm:mt-0 flex items-center w-full sm:w-auto`}>
</div> */}
<div className={`flex flex-none items-end flex-col sm:flex-row`}>
{task.continueOnFailure && (
<div className={`mr-6`}>
<div className={`sm:mr-6`}>
<div
className={`flex items-center px-2 py-1 bg-yellow-500 text-yellow-800 text-sm rounded-full`}
className={`px-2 py-1 bg-yellow-500 text-yellow-800 text-sm rounded-full`}
>
Continues on Failure
</div>
</div>
)}
{task.sequenceId > 1 && task.timeOffset > 0 && (
<div className={`mr-6`}>
<div className={`flex items-center px-2 py-1 bg-zinc-500 text-sm rounded-full`}>
<div className={`sm:mr-6`}>
<div className={`px-2 py-1 bg-zinc-500 text-sm rounded-full`}>
{task.timeOffset}s later
</div>
</div>
Expand Down Expand Up @@ -134,6 +135,6 @@ export default ({ schedule, task }: Props) => {
</button>
</Can>
</div>
</div>
</ItemContainer>
);
};

0 comments on commit ecae788

Please sign in to comment.