Skip to content

Commit

Permalink
feat: align pages links to use a single point of truth
Browse files Browse the repository at this point in the history
  • Loading branch information
felixmosh committed Aug 9, 2023
1 parent d33ea04 commit e866635
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 71 deletions.
82 changes: 43 additions & 39 deletions packages/ui/src/components/JobCard/JobCard.module.css
Original file line number Diff line number Diff line change
@@ -1,70 +1,74 @@
.card {
background-color: #fff;
box-shadow: 0 1px 1px 0 rgba(60, 75, 100, 0.14), 0 2px 1px -1px rgba(60, 75, 100, 0.12),
background-color: #fff;
box-shadow: 0 1px 1px 0 rgba(60, 75, 100, 0.14), 0 2px 1px -1px rgba(60, 75, 100, 0.12),
0 1px 3px 0 rgba(60, 75, 100, 0.2);
border-radius: 0.25rem;
padding: 1em;
display: flex;
min-height: 320px;
max-height: 500px;
border-radius: 0.25rem;
padding: 1em;
display: flex;
min-height: 320px;
max-height: 500px;
}

.card + .card {
margin-top: 2rem;
margin-top: 2rem;
}

.contentWrapper {
flex: 1;
display: flex;
flex-direction: column;
flex: 1;
display: flex;
flex-direction: column;
}

.title {
display: flex;
justify-content: space-between;
display: flex;
justify-content: space-between;
}

.title h4,
.sideInfo span {
font-size: 1.44rem;
font-weight: 300;
color: #4a5568;
line-height: 1;
font-size: 1.44rem;
font-weight: 300;
color: #4a5568;
line-height: 1;
}

.title h4 span {
margin-left: 1.5rem;
color: #a0aec0;
font-size: 0.694em;
margin-left: 1.5rem;
color: #a0aec0;
font-size: 0.694em;
}

.sideInfo {
width: 200px;
padding-right: 2rem;
display: flex;
flex-direction: column;
text-align: right;
color: #cbd5e0;
flex-shrink: 0;
width: 200px;
padding-right: 2rem;
display: flex;
flex-direction: column;
text-align: right;
color: #cbd5e0;
flex-shrink: 0;
}

.sideInfo span {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: #cbd5e0;
padding-right: 1rem;
display: block;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: #cbd5e0;
padding-right: 1rem;
}

.content {
position: relative;
flex: 1;
overflow: hidden;
position: relative;
flex: 1;
overflow: hidden;
}

.content .progress {
position: absolute;
bottom: 0;
right: 0;
position: absolute;
bottom: 0;
right: 0;
}

.jobLink {
text-decoration: none;
}
16 changes: 8 additions & 8 deletions packages/ui/src/components/JobCard/JobCard.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { STATUSES } from '@bull-board/api/dist/src/constants/statuses';
import { AppJob, Status } from '@bull-board/api/typings/app';
import React from 'react';
import { NavLink } from 'react-router-dom';
import { Link } from 'react-router-dom';
import { Card } from '../Card/Card';
import { Details } from './Details/Details';
import { JobActions } from './JobActions/JobActions';
import s from './JobCard.module.css';
import { Progress } from './Progress/Progress';
import { Timeline } from './Timeline/Timeline';
import { AppJob, Status } from '@bull-board/api/typings/app';
import { STATUSES } from '@bull-board/api/dist/src/constants/statuses';

interface JobCardProps {
job: AppJob;
jobUrlPath?: string;
jobUrl?: string;
status: Status;
readOnlyMode: boolean;
allowRetries: boolean;
Expand All @@ -31,14 +31,14 @@ export const JobCard = ({
actions,
readOnlyMode,
allowRetries,
jobUrlPath,
jobUrl,
}: JobCardProps) => (
<Card className={s.card}>
<div className={s.sideInfo}>
{jobUrlPath ? (
<NavLink to={jobUrlPath}>
{jobUrl ? (
<Link className={s.jobLink} to={jobUrl}>
<span title={`#${job.id}`}>#{job.id}</span>
</NavLink>
</Link>
) : (
<span title={`#${job.id}`}>#{job.id}</span>
)}
Expand Down
8 changes: 2 additions & 6 deletions packages/ui/src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { AppQueue } from '@bull-board/api/typings/app';
import cn from 'clsx';
import React, { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { STATUS_LIST } from '../../constants/status-list';
import { useSelectedStatuses } from '../../hooks/useSelectedStatuses';
import { links } from '../../utils/links';
import { SearchIcon } from '../Icons/Search';
import s from './Menu.module.css';

Expand Down Expand Up @@ -38,11 +38,7 @@ export const Menu = ({ queues }: { queues: AppQueue[] | null }) => {
.map(({ name: queueName, isPaused }) => (
<li key={queueName}>
<NavLink
to={`/queue/${encodeURIComponent(queueName)}${
!selectedStatuses[queueName] || selectedStatuses[queueName] === STATUS_LIST[0]
? ''
: `?status=${selectedStatuses[queueName]}`
}`}
to={links.queuePage(queueName, selectedStatuses)}
activeClassName={s.active}
title={queueName}
>
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/components/QueueCard/QueueCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AppQueue } from '@bull-board/api/dist/typings/app';
import React from 'react';
import { NavLink } from 'react-router-dom';
import { links } from '../../utils/links';
import { Card } from '../Card/Card';
import { QueueStats } from './QueueStats/QueueStats';
import s from './QueueCard.module.css';
Expand All @@ -12,7 +13,7 @@ interface IQueueCardProps {
export const QueueCard = ({ queue }: IQueueCardProps) => (
<Card className={s.queueCard}>
<div>
<NavLink to={`/queue/${encodeURIComponent(queue.name)}`} className={s.link}>
<NavLink to={links.queuePage(queue.name)} className={s.link}>
{queue.name}
</NavLink>
</div>
Expand Down
27 changes: 17 additions & 10 deletions packages/ui/src/pages/JobPage/JobPage.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { AppQueue, JobRetryStatus } from '@bull-board/api/typings/app';
import cn from 'clsx';
import React from 'react';
import { Link, useHistory, useLocation } from 'react-router-dom';
import { Link, useHistory } from 'react-router-dom';
import { ArrowLeftIcon } from '../../components/Icons/ArrowLeft';
import { JobCard } from '../../components/JobCard/JobCard';
import { useJob } from '../../hooks/useJob';
import { useSelectedStatuses } from '../../hooks/useSelectedStatuses';
import { links } from '../../utils/links';
import s from '../QueuePage/QueuePage.module.css';
import buttonS from '../../components/Button/Button.module.css';

export const JobPage = ({ queue }: { queue: AppQueue | null }) => {
const { search } = useLocation();
const history = useHistory();
const { job, status, actions } = useJob();
const selectedStatuses = useSelectedStatuses();

actions.pollJob();

Expand All @@ -22,15 +26,18 @@ export const JobPage = ({ queue }: { queue: AppQueue | null }) => {
}

const cleanJob = async () => {
await actions.cleanJob(queue?.name)(job)();
history.replace(`/queue/${queue.name}`);
await actions.cleanJob(queue.name)(job)();
history.replace(links.queuePage(queue.name, selectedStatuses));
};

return (
<section>
<div className={s.stickyHeader}>
<div className={s.actionContainer}>
<Link to={`/queue/${queue.name}${search}`}>
<Link
className={cn(buttonS.button, buttonS.default)}
to={links.queuePage(queue.name, selectedStatuses)}
>
<ArrowLeftIcon />
</Link>
<div>Status: {status.toLocaleUpperCase()}</div>
Expand All @@ -42,12 +49,12 @@ export const JobPage = ({ queue }: { queue: AppQueue | null }) => {
status={status}
actions={{
cleanJob,
promoteJob: actions.promoteJob(queue?.name)(job),
retryJob: actions.retryJob(queue?.name, status as JobRetryStatus)(job),
getJobLogs: actions.getJobLogs(queue?.name)(job),
promoteJob: actions.promoteJob(queue.name)(job),
retryJob: actions.retryJob(queue.name, status as JobRetryStatus)(job),
getJobLogs: actions.getJobLogs(queue.name)(job),
}}
readOnlyMode={queue?.readOnlyMode}
allowRetries={(job.isFailed || queue.allowCompletedRetries) && queue?.allowRetries}
readOnlyMode={queue.readOnlyMode}
allowRetries={(job.isFailed || queue.allowCompletedRetries) && queue.allowRetries}
/>
</section>
);
Expand Down
11 changes: 5 additions & 6 deletions packages/ui/src/pages/QueuePage/QueuePage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { STATUSES } from '@bull-board/api/dist/src/constants/statuses';
import { JobRetryStatus } from '@bull-board/api/typings/app';
import React from 'react';
import { useLocation } from 'react-router-dom';
import { JobCard } from '../../components/JobCard/JobCard';
import { Pagination } from '../../components/Pagination/Pagination';
import { QueueActions } from '../../components/QueueActions/QueueActions';
Expand All @@ -9,21 +9,22 @@ import { useActiveQueue } from '../../hooks/useActiveQueue';
import { useJob } from '../../hooks/useJob';
import { useQueues } from '../../hooks/useQueues';
import { useSelectedStatuses } from '../../hooks/useSelectedStatuses';
import { links } from '../../utils/links';
import s from './QueuePage.module.css';

export const QueuePage = () => {
const selectedStatus = useSelectedStatuses();
const { actions, queues } = useQueues();
const { actions: jobActions } = useJob();
const queue = useActiveQueue({ queues });
const { search } = useLocation();
actions.pollQueues();

if (!queue) {
return <section>Queue Not found</section>;
}

const status = selectedStatus[queue.name];
const isLatest = status === STATUSES.latest;

return (
<section>
Expand All @@ -50,10 +51,8 @@ export const QueuePage = () => {
<JobCard
key={job.id}
job={job}
jobUrlPath={`/queue/${encodeURIComponent(queue.name)}/${encodeURIComponent(
job.id ?? ''
)}${search}`}
status={status}
jobUrl={links.jobPage(queue.name, `${job.id}`, selectedStatus)}
status={isLatest && job.isFailed ? STATUSES.failed : status}
actions={{
cleanJob: jobActions.cleanJob(queue.name)(job),
promoteJob: jobActions.promoteJob(queue.name)(job),
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/src/utils/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { SelectedStatuses } from '../../typings/app';
import { STATUS_LIST } from '../constants/status-list';

export const links = {
queuePage(queueName: string, selectedStatuses: SelectedStatuses): string {
queuePage(queueName: string, selectedStatuses: SelectedStatuses = {}): string {
const withoutStatus =
!selectedStatuses[queueName] || selectedStatuses[queueName] === STATUS_LIST[0];
return `/queue/${encodeURIComponent(queueName)}${
withoutStatus ? '' : `?status=${selectedStatuses[queueName]}`
}`;
},
jobPage(queueName: string, jobId: string, selectedStatuses: SelectedStatuses = {}): string {
const [queuePage, search] = links.queuePage(queueName, selectedStatuses).split('?');
return [`${queuePage}/${encodeURIComponent(jobId)}`, search].filter(Boolean).join('?');
},
};

0 comments on commit e866635

Please sign in to comment.