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

Add icon support on group titles #9

Merged
merged 1 commit into from
Oct 17, 2024
Merged
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
52 changes: 52 additions & 0 deletions src/components/Clock/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
useEffect,
useState,
} from 'react';

const dateTimeFormatter = new Intl.DateTimeFormat(
[],
{
year: 'numeric',
month: 'short',
day: 'numeric',
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
// second: 'numeric',
hour12: true,
},
);

function formatTime(date: Date) {
return dateTimeFormatter.format(date);
}

function Clock() {
const [dateStr, setDateStr] = useState(() => {
const date = new Date();
return formatTime(date);
});
useEffect(
() => {
const timeout = window.setInterval(
() => {
const date = new Date();
const dateAsString = formatTime(date);
setDateStr(dateAsString);
},
500,
);
return () => {
window.clearInterval(timeout);
};
},
[],
);
return (
<div>
{dateStr}
</div>
);
}

export default Clock;
15 changes: 12 additions & 3 deletions src/components/MonthlyCalendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ import DateContext from '#contexts/date';

import styles from './styles.module.css';

const dateFormatter = new Intl.DateTimeFormat(
[],
{
year: 'numeric',
month: 'short',
},
);

const weekDaysName = [
'Su',
'Mo',
Expand Down Expand Up @@ -129,6 +137,8 @@ function MonthlyCalendar(props: Props) {
return days;
}, [year, month]);

const formattedDate = dateFormatter.format(new Date(year, month, 1));

return (
<div className={_cs(styles.calendarContainer, className)}>
<div className={styles.header}>
Expand All @@ -150,10 +160,9 @@ function MonthlyCalendar(props: Props) {
>
<RiArrowRightSLine />
</Button>
<div className={styles.spacer} />
<div>
{year}
/
{String(month + 1).padStart(2, '0')}
{formattedDate}
</div>
</div>
<div className={styles.monthlyCalendar}>
Expand Down
4 changes: 4 additions & 0 deletions src/components/MonthlyCalendar/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
gap: var(--spacing-sm);
align-items: baseline;
font-size: var(--font-size-sm);

.spacer {
flex-grow: 1;
}
}

.monthly-calendar {
Expand Down
54 changes: 26 additions & 28 deletions src/views/DailyJournal/AvailabilityDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ function AvailabilityDialog(props: Props) {
return key === 'FIRST_HALF';
}
if (dialogState.wfhType === 'FULL') {
return false;
// NOTE: So that we can see all options
return true;
}
return true;
},
Expand All @@ -204,7 +205,8 @@ function AvailabilityDialog(props: Props) {
return key === 'FIRST_HALF';
}
if (dialogState.leaveType === 'FULL') {
return false;
// NOTE: So that we can see all options
return true;
}
return true;
},
Expand All @@ -221,32 +223,28 @@ function AvailabilityDialog(props: Props) {
contentClassName={styles.modalContent}
className={styles.availabilityDialog}
>
{dialogState.wfhType !== 'FULL' && (
<RadioInput
name="leaveType"
label="Leave"
options={availableLeaveTypeOptions}
keySelector={leaveTypeKeySelector}
labelSelector={leaveTypeLabelSelector}
onChange={setFieldValue}
value={dialogState.leaveType}
disabled={disabled}
clearable
/>
)}
{dialogState.leaveType !== 'FULL' && (
<RadioInput
name="wfhType"
label="Work from home"
options={availableWfhTypeOptions}
keySelector={wfhTypeKeySelector}
labelSelector={wfhTypeLabelSelector}
onChange={setFieldValue}
value={dialogState.wfhType}
disabled={disabled}
clearable
/>
)}
<RadioInput
name="leaveType"
label="Leave"
options={availableLeaveTypeOptions}
keySelector={leaveTypeKeySelector}
labelSelector={leaveTypeLabelSelector}
onChange={setFieldValue}
value={dialogState.leaveType}
disabled={disabled || dialogState.wfhType === 'FULL'}
clearable
/>
<RadioInput
name="wfhType"
label="Work from home"
options={availableWfhTypeOptions}
keySelector={wfhTypeKeySelector}
labelSelector={wfhTypeLabelSelector}
onChange={setFieldValue}
value={dialogState.wfhType}
disabled={disabled || dialogState.leaveType === 'FULL'}
clearable
/>
<div className={styles.actions}>
<Button
title="Cancel update availability"
Expand Down
39 changes: 39 additions & 0 deletions src/views/DailyJournal/DayView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,23 @@ function DayView(props: Props) {
return undefined;
}, [taskById]);

const getWorkItemIconFromAttr = useCallback((
item: WorkItem,
attr: DailyJournalAttribute,
) => {
if (isNotDefined(taskById)) {
return undefined;
}

const taskDetails = taskById[item.task];

if (attr.key === 'project') {
return taskDetails.contract.project.logo;
}

return undefined;
}, [taskById]);

const formattedDate = dateFormatter.format(new Date(selectedDate));
const formattedRelativeDate = useFormattedRelativeDate(selectedDate);

Expand Down Expand Up @@ -199,6 +216,10 @@ function DayView(props: Props) {
groupedItem.value,
groupedItem.attribute,
);
const currentIcon = getWorkItemIconFromAttr(
groupedItem.value,
groupedItem.attribute,
);

const Heading = `h${bound(groupedItem.level + 2, 2, 4)}` as unknown as ElementType;

Expand All @@ -208,6 +229,13 @@ function DayView(props: Props) {
className={styles.nestedHeading}
>
{indent && <Indent level={groupedItem.level} />}
{currentIcon && (
<img
className={styles.icon}
src={currentIcon.url}
alt={headingText}
/>
)}
{headingText}
</Heading>
);
Expand Down Expand Up @@ -236,6 +264,10 @@ function DayView(props: Props) {
groupedItem.value,
attribute,
);
const currentIcon = getWorkItemIconFromAttr(
groupedItem.value,
attribute,
);

if (i < (groupLevel - joinLevel)) {
return null;
Expand All @@ -246,6 +278,13 @@ function DayView(props: Props) {
{i > (groupLevel - joinLevel) && (
<div className={styles.separator} />
)}
{currentIcon && (
<img
className={styles.icon}
src={currentIcon.url}
alt={currentLabel}
/>
)}
<div>{currentLabel}</div>
</Fragment>
);
Expand Down
8 changes: 8 additions & 0 deletions src/views/DailyJournal/DayView/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@

&h2 {
margin-top: var(--spacing-md);

.icon {
height: 1em;
}
}
}

Expand All @@ -76,6 +80,10 @@
width: 0.5rem;
height: 0.5rem;
}

.icon {
height: 1em;
}
}

.work-item-container {
Expand Down
3 changes: 1 addition & 2 deletions src/views/DailyJournal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
encodeDate,
isDefined,
isNotDefined,
isTruthyString,
} from '@togglecorp/fujs';
import {
gql,
Expand Down Expand Up @@ -751,7 +750,7 @@ export function Component() {
>
Add entry
</Button>
{!isTruthyString(dateFromParams) && (
{selectedDate !== fullDate && (
<Link
to="dailyJournal"
variant="quaternary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}

.days {
width: 5rem;
width: 6rem;
color: var(--color-text-light);
}
}
25 changes: 3 additions & 22 deletions src/views/DailyStandup/DeadlineSection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
useQuery,
} from 'urql';

import Clock from '#components/Clock';
import {
type DeadlinesAndEventsQuery,
type DeadlinesAndEventsQueryVariables,
Expand All @@ -26,16 +27,6 @@ import GeneralEventOutput from './GeneralEvent';

import styles from './styles.module.css';

const dateFormatter = new Intl.DateTimeFormat(
[],
{
year: 'numeric',
month: 'short',
day: 'numeric',
weekday: 'short',
},
);

const DEADLINES_AND_EVENTS = gql`
query DeadlinesAndEvents {
private {
Expand All @@ -60,15 +51,7 @@ const DEADLINES_AND_EVENTS = gql`
}
`;

interface Props {
date: string;
}

function DeadlineSection(props: Props) {
const {
date,
} = props;

function DeadlineSection() {
const [deadlinesAndEvents] = useQuery<
DeadlinesAndEventsQuery,
DeadlinesAndEventsQueryVariables
Expand All @@ -79,8 +62,6 @@ function DeadlineSection(props: Props) {
const projects = deadlinesAndEvents.data?.private.allProjects;
const events = deadlinesAndEvents.data?.private.relativeEvents;

const formattedDate = dateFormatter.format(new Date(date));

const upcomingEvents = useMemo<GeneralEvent[]>(() => {
const deadlines = projects?.flatMap(
(project) => project.deadlines.map((deadline) => ({
Expand Down Expand Up @@ -121,7 +102,7 @@ function DeadlineSection(props: Props) {
variant="split"
primaryPreText="Welcome to"
primaryHeading="Daily Standup"
primaryDescription={formattedDate}
primaryDescription={<Clock />}
secondaryHeading="Upcoming Events"
secondaryContent={upcomingEvents.map(
(generalEvent, index) => (
Expand Down
Loading