Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 2084/activity list items layout - adding subtitles #2213

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import dayjs from 'dayjs';
import { FC } from 'react';
import { EmailOutlined, Person } from '@mui/icons-material';

import { EmailActivity } from 'features/campaigns/types';
import messageIds from 'features/campaigns/l10n/messageIds';
import { Msg } from 'core/i18n';
import useEmailStats from 'features/emails/hooks/useEmailStats';
import ZUIRelativeTime from 'zui/ZUIRelativeTime';
import OverviewListItem, { STATUS_COLORS } from './OverviewListItem';
import { getEmailSubtitle } from '../../../utils/subtitles';

interface EmailOverviewListItemProps {
activity: EmailActivity;
Expand All @@ -24,25 +21,6 @@ const EmailOverviewListItem: FC<EmailOverviewListItemProps> = ({
email.id
);

function getSubtitle(published: string | null) {
if (published === null) {
return undefined;
}
const now = new Date();
const publishedDate = dayjs(published);
const id = publishedDate.isBefore(now)
? messageIds.activitiesOverview.subtitles.sentEarlier
: messageIds.activitiesOverview.subtitles.sentLater;
return (
<Msg
id={id}
values={{
relative: <ZUIRelativeTime datetime={publishedDate.toISOString()} />,
}}
/>
);
}

function getColor() {
const now = new Date();

Expand Down Expand Up @@ -73,7 +51,7 @@ const EmailOverviewListItem: FC<EmailOverviewListItemProps> = ({
PrimaryIcon={EmailOutlined}
SecondaryIcon={Person}
startDate={activity.visibleFrom}
subtitle={getSubtitle(activity.data.published)}
subtitle={getEmailSubtitle(activity.data.published)}
title={email.title || ''}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import { Box, SvgIconTypeMap, Theme, Tooltip, Typography } from '@mui/material';
import { CampaignActivity } from 'features/campaigns/types';
import getStatusDotLabel from 'features/events/utils/getStatusDotLabel';
import { isSameDate } from 'utils/dateUtils';
import messageIds from 'features/campaigns/l10n/messageIds';
import { Msg } from 'core/i18n';
import theme from 'theme';
import ZUIRelativeTime from 'zui/ZUIRelativeTime';
import ZUISuffixedNumber from 'zui/ZUISuffixedNumber';
import ZUIIconLabel, { ZUIIconLabelProps } from 'zui/ZUIIconLabel';
import { getEndsLabel, getStartsLabel } from '../../../utils/subtitles';

interface StyleProps {
color: STATUS_COLORS;
Expand Down Expand Up @@ -102,9 +100,7 @@ const OverviewListItem = ({
//const color = getStatusColor(startDate, endDate);
const classes = useStyles({ color });

const now = new Date();
let label: JSX.Element | null = null;

if (subtitle) {
label = subtitle;
} else if (!focusDate) {
Expand All @@ -119,40 +115,6 @@ const OverviewListItem = ({
label = getEndsLabel(endDate);
}

function getEndsLabel(endDate: Date) {
if (endDate && isSameDate(endDate, now)) {
return <Msg id={messageIds.activitiesOverview.subtitles.endsToday} />;
} else if (endDate && endDate > now) {
return (
<Msg
id={messageIds.activitiesOverview.subtitles.endsLater}
values={{
relative: <ZUIRelativeTime datetime={endDate.toISOString()} />,
}}
/>
);
}

return null;
}

function getStartsLabel(startDate: Date) {
if (startDate && isSameDate(startDate, now)) {
return <Msg id={messageIds.activitiesOverview.subtitles.startsToday} />;
} else if (startDate && startDate > now) {
return (
<Msg
id={messageIds.activitiesOverview.subtitles.startsLater}
values={{
relative: <ZUIRelativeTime datetime={startDate.toISOString()} />,
}}
/>
);
}

return null;
}

return (
<NextLink
href={href}
Expand Down
9 changes: 8 additions & 1 deletion src/features/campaigns/components/ActivityList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const Activities = ({ activities, orgId }: ActivitiesProps) => {
<CanvassAssignmentListItem
caId={activity.data.id}
orgId={orgId}
visibleFrom={activity.visibleFrom}
visibleUntil={activity.visibleUntil}
/>
</Box>
);
Expand All @@ -68,7 +70,12 @@ const Activities = ({ activities, orgId }: ActivitiesProps) => {
return (
<Box key={`task-${activity.data.id}`}>
{index > 0 && <Divider />}
<TaskListItem orgId={orgId} taskId={activity.data.id} />
<TaskListItem
orgId={orgId}
taskId={activity.data.id}
visibleFrom={activity.data.published}
visibleUntil={activity.data.expires || activity.data.deadline}
/>
</Box>
);
} else if (activity.kind === ACTIVITIES.EMAIL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Box, SvgIconTypeMap, Theme, Tooltip, Typography } from '@mui/material';
import getStatusDotLabel from 'features/events/utils/getStatusDotLabel';
import theme from 'theme';
import ZUIIconLabel, { ZUIIconLabelProps } from 'zui/ZUIIconLabel';
import { getSubtitles } from '../../../utils/subtitles';

interface StyleProps {
color: STATUS_COLORS;
Expand All @@ -26,6 +27,7 @@ const useStyles = makeStyles<Theme, StyleProps>((theme) => ({
height: '10px',
marginLeft: '0.5em',
marginRight: '0.5em',
marginTop: '0.2em',
width: '10px',
},
endNumber: {
Expand Down Expand Up @@ -65,19 +67,21 @@ export enum STATUS_COLORS {
RED = 'red',
}

export type AcitivityListItemProps = {
export type ActivityListItemProps = {
PrimaryIcon: OverridableComponent<
SvgIconTypeMap<Record<string, unknown>, 'svg'>
>;
SecondaryIcon: OverridableComponent<
SvgIconTypeMap<Record<string, unknown>, 'svg'>
>;
color: STATUS_COLORS;
endDate?: string | null;
endNumber: string | number;
endNumberColor?: ZUIIconLabelProps['color'];
href: string;
meta?: JSX.Element;
onEventItemClick?: (x: number, y: number) => void;
startDate?: string | null;
subtitle?: JSX.Element;
title: string;
};
Expand All @@ -93,9 +97,10 @@ const ActivityListItem = ({
title,
endNumber,
endNumberColor = 'secondary',
}: AcitivityListItemProps) => {
endDate,
startDate,
}: ActivityListItemProps) => {
const classes = useStyles({ color });

return (
<NextLink href={href} passHref style={{ textDecoration: 'none' }}>
<Box
Expand All @@ -108,17 +113,21 @@ const ActivityListItem = ({
}}
>
<Box className={classes.left}>
<Tooltip title={getStatusDotLabel({ color })}>
<Box className={classes.dot} />
</Tooltip>
<PrimaryIcon className={classes.primaryIcon} />
<Box>
<Typography color={theme.palette.text.primary}>{title}</Typography>
{subtitle && (
<Box>
<Typography variant="body2">{subtitle}</Typography>
</Box>
)}
<Box className={classes.left}>
<PrimaryIcon className={classes.primaryIcon} />
<Typography color={theme.palette.text.primary}>
{title}
</Typography>
</Box>
<Box className={classes.left}>
<Tooltip title={getStatusDotLabel({ color })}>
<Box className={classes.dot} />
</Tooltip>
<Typography color={theme.palette.grey[500]} variant="body2">
{getSubtitles(subtitle, startDate, endDate)}
</Typography>
</Box>
</Box>
</Box>
<Box className={classes.meta}>{meta}</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { CircularProgress } from '@mui/material';
import { FC } from 'react';

import ZUIMultiNumberChip from 'zui/ZUIMultiNumberChip';
import ActivityListItem, { AcitivityListItemProps } from './ActivityListItem';
import ActivityListItem, { ActivityListItemProps } from './ActivityListItem';

type ActivityListItemWithStatsProps = AcitivityListItemProps & {
type ActivityListItemWithStatsProps = ActivityListItemProps & {
blueChipValue?: string | number;
greenChipValue: string | number | undefined;
orangeChipValue: string | number | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const CallAssignmentListItem: FC<CallAssignmentListItemProps> = ({
<ActivityListItemWithStats
blueChipValue={ready}
color={color}
endDate={callAssignment.end_date}
endNumber={callsMade}
greenChipValue={done}
href={`/organize/${orgId}/projects/${
Expand All @@ -55,6 +56,7 @@ const CallAssignmentListItem: FC<CallAssignmentListItemProps> = ({
orangeChipValue={blocked}
PrimaryIcon={HeadsetMic}
SecondaryIcon={PhoneOutlined}
startDate={callAssignment.start_date}
statsLoading={statsFuture.isLoading}
title={callAssignment?.title}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ import useCanvassAssignment from 'features/areas/hooks/useCanvassAssignment';
type Props = {
caId: string;
orgId: number;
visibleFrom: Date | null;
visibleUntil: Date | null;
};

const CanvassAssignmentListItem: FC<Props> = ({ caId, orgId }) => {
const CanvassAssignmentListItem: FC<Props> = ({
caId,
orgId,
visibleFrom,
visibleUntil,
}) => {
const { data: assignment } = useCanvassAssignment(orgId, caId);

if (!assignment) {
Expand All @@ -21,12 +28,14 @@ const CanvassAssignmentListItem: FC<Props> = ({ caId, orgId }) => {
return (
<ActivityListItem
color={color}
endDate={visibleUntil ? visibleUntil.toString() : null}
endNumber={''}
href={`/organize/${orgId}/projects/${
assignment?.campaign?.id ?? 'standalone'
}/canvassassignments/${caId}`}
PrimaryIcon={Map}
SecondaryIcon={Map}
startDate={visibleFrom ? visibleFrom.toString() : null}
title={assignment?.title || ''}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import useEmail from 'features/emails/hooks/useEmail';
import useEmailStats from 'features/emails/hooks/useEmailStats';
import ActivityListItem, { STATUS_COLORS } from './ActivityListItem';
import useEmailState, { EmailState } from 'features/emails/hooks/useEmailState';
import { getEmailSubtitle } from '../../../utils/subtitles';

interface EmailListItemProps {
emailId: number;
Expand Down Expand Up @@ -53,6 +54,7 @@ const EmailListItem: FC<EmailListItemProps> = ({ orgId, emailId }) => {
PrimaryIcon={EmailOutlined}
SecondaryIcon={Person}
statsLoading={statsLoading}
subtitle={getEmailSubtitle(email.published)}
title={email.title || ''}
/>
) : (
Expand All @@ -64,6 +66,7 @@ const EmailListItem: FC<EmailListItemProps> = ({ orgId, emailId }) => {
}/emails/${emailId}`}
PrimaryIcon={EmailOutlined}
SecondaryIcon={Person}
subtitle={getEmailSubtitle(email.published)}
title={email.title || ''}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ const SurveyListItem: FC<SurveyListItemProps> = ({ orgId, surveyId }) => {
return (
<ActivityListItemWithStats
color={color}
endDate={data.expires}
endNumber={submissionCount.toString()}
greenChipValue={linkedSubmissionCount}
href={getSurveyUrl(data, orgId)}
orangeChipValue={unlinkedSubmissionCount}
PrimaryIcon={AssignmentOutlined}
SecondaryIcon={ChatBubbleOutline}
startDate={data.published}
statsLoading={statsFuture.isLoading}
title={data.title}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import getTaskStatus, { TASK_STATUS } from 'features/tasks/utils/getTaskStatus';
interface TaskListItemProps {
orgId: number;
taskId: number;
visibleFrom?: string;
visibleUntil?: string;
}

const TaskListItem = ({ orgId, taskId }: TaskListItemProps) => {
const TaskListItem = ({
orgId,
taskId,
visibleFrom,
visibleUntil,
}: TaskListItemProps) => {
const task = useTask(orgId, taskId);
const { data: stats, isLoading: statsLoading } = useTaskStats(orgId, taskId);

Expand All @@ -34,6 +41,7 @@ const TaskListItem = ({ orgId, taskId }: TaskListItemProps) => {
<ActivityListItemWithStats
blueChipValue={stats?.assigned}
color={color}
endDate={visibleUntil ? visibleUntil.toString() : null}
endNumber={stats?.individuals ?? 0}
greenChipValue={stats?.completed}
href={`/organize/${orgId}/projects/${
Expand All @@ -42,6 +50,7 @@ const TaskListItem = ({ orgId, taskId }: TaskListItemProps) => {
orangeChipValue={stats?.ignored}
PrimaryIcon={CheckBoxOutlined}
SecondaryIcon={People}
startDate={visibleFrom ? visibleFrom.toString() : null}
statsLoading={statsLoading}
title={task.title}
/>
Expand Down
1 change: 1 addition & 0 deletions src/features/campaigns/l10n/messageIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default makeMessages('feat.campaigns', {
endsToday: m('Ends today'),
sentEarlier: m<{ relative: ReactElement }>('Was sent {relative}'),
sentLater: m<{ relative: ReactElement }>('To be sent {relative}'),
startedBefore: m<{ relative: ReactElement }>('Started {relative}'),
startsLater: m<{ relative: ReactElement }>('Starts {relative}'),
startsToday: m('Starts today'),
},
Expand Down
Loading
Loading