Skip to content

Commit

Permalink
refactor: move job modal to queue dropdown actions
Browse files Browse the repository at this point in the history
  • Loading branch information
felixmosh committed May 19, 2024
1 parent 2f8fff5 commit 1a1ffd0
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 78 deletions.
56 changes: 11 additions & 45 deletions packages/ui/src/components/HeaderActions/HeaderActions.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import React, { useState, Suspense } from 'react';
import React, { Suspense } from 'react';
import { useModal } from '../../hooks/useModal';
import { useUIConfig } from '../../hooks/useUIConfig';
import { Button } from '../Button/Button';
import { CustomLinksDropdown } from '../CustomLinksDropdown/CustomLinksDropdown';
import { AddIcon } from '../Icons/Add';
import { FullscreenIcon } from '../Icons/Fullscreen';
import { RedisIcon } from '../Icons/Redis';
import { Settings } from '../Icons/Settings';
import { Button } from '../Button/Button';
import s from './HeaderActions.module.css';

type ModalTypes = 'redis' | 'settings' | 'addJobs';
type AllModalTypes = ModalTypes | `${ModalTypes}Closing` | null;

function waitForClosingAnimation(
state: ModalTypes,
setModalOpen: (newState: AllModalTypes) => void
) {
return () => {
setModalOpen(`${state}Closing`);
setTimeout(() => setModalOpen(null), 300); // fadeout animation duration
};
}
type ModalTypes = 'redis' | 'settings';

const RedisStatsModalLazy = React.lazy(() =>
import('../RedisStatsModal/RedisStatsModal').then(({ RedisStatsModal }) => ({
Expand All @@ -39,21 +28,15 @@ const onClickFullScreen = async () => {
return document.exitFullscreen();
};

const AddJobModalLazy = React.lazy(() =>
import('../AddJobModal/AddJobModal').then(({ AddJobModal }) => ({
default: AddJobModal,
}))
);

export const HeaderActions = () => {
const [openedModal, setModalOpen] = useState<AllModalTypes>(null);
const { miscLinks = [] } = useUIConfig();
const modal = useModal<ModalTypes>();

return (
<>
<ul className={s.actions}>
<li>
<Button onClick={() => setModalOpen('redis')} className={s.button}>
<Button onClick={() => modal.open('redis')} className={s.button}>
<RedisIcon />
</Button>
</li>
Expand All @@ -63,12 +46,7 @@ export const HeaderActions = () => {
</Button>
</li>
<li>
<Button onClick={() => setModalOpen('addJobs')} className={s.button}>
<AddIcon />
</Button>
</li>
<li>
<Button onClick={() => setModalOpen('settings')} className={s.button}>
<Button onClick={() => modal.open('settings')} className={s.button}>
<Settings />
</Button>
</li>
Expand All @@ -79,23 +57,11 @@ export const HeaderActions = () => {
)}
</ul>
<Suspense fallback={null}>
{(openedModal === 'redis' || openedModal === 'redisClosing') && (
<RedisStatsModalLazy
open={openedModal === 'redis'}
onClose={waitForClosingAnimation('redis', setModalOpen)}
/>
)}
{(openedModal === 'settings' || openedModal === 'settingsClosing') && (
<SettingsModalLazy
open={openedModal === 'settings'}
onClose={waitForClosingAnimation('settings', setModalOpen)}
/>
{modal.isMounted('redis') && (
<RedisStatsModalLazy open={modal.isOpen('redis')} onClose={modal.close('redis')} />
)}
{(openedModal === 'addJobs' || openedModal === 'addJobsClosing') && (
<AddJobModalLazy
open={openedModal === 'addJobs'}
onClose={waitForClosingAnimation('addJobs', setModalOpen)}
/>
{modal.isMounted('settings') && (
<SettingsModalLazy open={modal.isOpen('settings')} onClose={modal.close('settings')} />
)}
</Suspense>
</>
Expand Down
25 changes: 2 additions & 23 deletions packages/ui/src/components/Icons/Add.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,7 @@
import React from 'react';

export const AddIcon = () => (
<svg
role="img"
width="256px"
height="256px"
viewBox="0 0 24.00 24.00"
fill="none"
xmlns="http://www.w3.org/2000/svg"
stroke="#748094"
>
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g>
<g id="SVGRepo_iconCarrier">
<path
d="M12 6C12.5523 6 13 6.44772 13 7V11H17C17.5523 11 18 11.4477 18 12C18 12.5523 17.5523 13 17 13H13V17C13 17.5523 12.5523 18 12 18C11.4477 18 11 17.5523 11 17V13H7C6.44772 13 6 12.5523 6 12C6 11.4477 6.44772 11 7 11H11V7C11 6.44772 11.4477 6 12 6Z"
fill="#748094"
></path>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2 4.5C2 3.11929 3.11929 2 4.5 2H19.5C20.8807 2 22 3.11929 22 4.5V19.5C22 20.8807 20.8807 22 19.5 22H4.5C3.11929 22 2 20.8807 2 19.5V4.5ZM4.5 4C4.22386 4 4 4.22386 4 4.5V19.5C4 19.7761 4.22386 20 4.5 20H19.5C19.7761 20 20 19.7761 20 19.5V4.5C20 4.22386 19.7761 4 19.5 4H4.5Z"
fill="#748094"
></path>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M64 80c-8.8 0-16 7.2-16 16v320c0 8.8 7.2 16 16 16h320c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96c0-35.3 28.7-64 64-64h320c35.3 0 64 28.7 64 64v320c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm200 248v-64h-64c-13.3 0-24-10.7-24-24s10.7-24 24-24h64v-64c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24h-64v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z" />
</svg>
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next';
import { QueueActions } from '../../../typings/app';
import { Button } from '../Button/Button';
import { DropdownContent } from '../DropdownContent/DropdownContent';
import { AddIcon } from '../Icons/Add';
import { EllipsisVerticalIcon } from '../Icons/EllipsisVertical';
import { PauseIcon } from '../Icons/Pause';
import { PlayIcon } from '../Icons/Play';
Expand All @@ -16,9 +17,10 @@ export const QueueDropdownActions = ({
actions,
}: {
queue: AppQueue;
actions: QueueActions;
actions: Omit<QueueActions, 'addJob'> & { addJob: () => void };
}) => {
const { t } = useTranslation();

return (
<Root>
<Trigger asChild>
Expand All @@ -29,6 +31,10 @@ export const QueueDropdownActions = ({

<Portal>
<DropdownContent align="end">
<Item onSelect={actions.addJob}>
<AddIcon />
{t('QUEUE.ACTIONS.ADD_JOB')}
</Item>
<Item
onSelect={
queue.isPaused ? actions.resumeQueue(queue.name) : actions.pauseQueue(queue.name)
Expand Down
11 changes: 3 additions & 8 deletions packages/ui/src/components/StatusMenu/StatusMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { AppQueue } from '@bull-board/api/typings/app';
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { useTranslation } from 'react-i18next';
import { NavLink } from 'react-router-dom';
import { links } from '../../utils/links';
import { QueueDropdownActions } from '../QueueDropdownActions/QueueDropdownActions';
import s from './StatusMenu.module.css';

export const StatusMenu = ({ queue, actions }: { queue: AppQueue; actions: any }) => {
export const StatusMenu = ({ queue, children }: PropsWithChildren<{ queue: AppQueue }>) => {
const { t } = useTranslation();

return (
Expand All @@ -29,11 +28,7 @@ export const StatusMenu = ({ queue, actions }: { queue: AppQueue; actions: any }
</NavLink>
);
})}
{!queue.readOnlyMode && (
<div>
<QueueDropdownActions queue={queue} actions={actions} />
</div>
)}
{!!children && <div>{children}</div>}
</div>
);
};
24 changes: 24 additions & 0 deletions packages/ui/src/hooks/useModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useState } from 'react';

export function useModal<ModalTypes extends string>() {
type AllModalTypes = ModalTypes | `${ModalTypes}Closing` | null;
const [openedModal, setModalOpen] = useState<AllModalTypes>(null);

return {
isOpen(modal: ModalTypes): boolean {
return openedModal === modal;
},
isMounted(modal: ModalTypes): boolean {
return [modal, `${modal}Closing`].includes(openedModal as any);
},
open(modal: ModalTypes): void {
setModalOpen(modal);
},
close(modal: ModalTypes): () => void {
return () => {
setModalOpen(`${modal}Closing`);
setTimeout(() => setModalOpen(null), 300); // fadeout animation duration
};
},
};
}
21 changes: 20 additions & 1 deletion packages/ui/src/pages/QueuePage/QueuePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@ import { useTranslation } from 'react-i18next';
import { JobCard } from '../../components/JobCard/JobCard';
import { Pagination } from '../../components/Pagination/Pagination';
import { QueueActions } from '../../components/QueueActions/QueueActions';
import { QueueDropdownActions } from '../../components/QueueDropdownActions/QueueDropdownActions';
import { StatusMenu } from '../../components/StatusMenu/StatusMenu';
import { StickyHeader } from '../../components/StickyHeader/StickyHeader';
import { useActiveQueue } from '../../hooks/useActiveQueue';
import { useJob } from '../../hooks/useJob';
import { useModal } from '../../hooks/useModal';
import { useQueues } from '../../hooks/useQueues';
import { useSelectedStatuses } from '../../hooks/useSelectedStatuses';
import { links } from '../../utils/links';

const AddJobModalLazy = React.lazy(() =>
import('../../components/AddJobModal/AddJobModal').then(({ AddJobModal }) => ({
default: AddJobModal,
}))
);

export const QueuePage = () => {
const { t } = useTranslation();
const selectedStatus = useSelectedStatuses();
const { actions } = useQueues();
const { actions: jobActions } = useJob();
const queue = useActiveQueue();
const modal = useModal<'addJob'>();
actions.pollQueues();

if (!queue) {
Expand Down Expand Up @@ -50,7 +59,14 @@ export const QueuePage = () => {
</>
}
>
<StatusMenu queue={queue} actions={actions} />
<StatusMenu queue={queue}>
{!queue.readOnlyMode && (
<QueueDropdownActions
queue={queue}
actions={{ ...actions, addJob: () => modal.open('addJob') }}
/>
)}
</StatusMenu>
</StickyHeader>
{queue.jobs.map((job) => (
<JobCard
Expand All @@ -68,6 +84,9 @@ export const QueuePage = () => {
allowRetries={(job.isFailed || queue.allowCompletedRetries) && queue.allowRetries}
/>
))}
{modal.isMounted('addJob') && (
<AddJobModalLazy open={modal.isOpen('addJob')} onClose={modal.close('addJob')} />
)}
</section>
);
};
1 change: 1 addition & 0 deletions packages/ui/src/static/locales/en-US/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"RESUME": "Resume",
"PAUSE": "Pause",
"EMPTY": "Empty",
"ADD_JOB": "Add job",
"RETRY_ALL_CONFIRM_MSG": "Are you sure that you want to retry all {{status}} jobs?",
"CLEAN_ALL_CONFIRM_MSG": "Are you sure that you want to clean all {{status}} jobs?",
"PROMOTE_ALL_CONFIRM_MSG": "Are you sure that you want to promote all delayed jobs?",
Expand Down

0 comments on commit 1a1ffd0

Please sign in to comment.