diff --git a/ui/src/common/DateTimeSelector.tsx b/ui/src/common/DateTimeSelector.tsx index de12406..30fab98 100644 --- a/ui/src/common/DateTimeSelector.tsx +++ b/ui/src/common/DateTimeSelector.tsx @@ -21,10 +21,11 @@ export const DateTimeSelector: React.FC = React.memo( return ( { popoverOpen(true); diff --git a/ui/src/common/TagChip.tsx b/ui/src/common/TagChip.tsx index 006c365..4dc9259 100644 --- a/ui/src/common/TagChip.tsx +++ b/ui/src/common/TagChip.tsx @@ -9,7 +9,15 @@ export const TagChip = ({color, label}: {label: string; color: string}) => { ); diff --git a/ui/src/dashboard/DashboardsPage.tsx b/ui/src/dashboard/DashboardsPage.tsx index b329a3c..0911bd1 100644 --- a/ui/src/dashboard/DashboardsPage.tsx +++ b/ui/src/dashboard/DashboardsPage.tsx @@ -30,7 +30,6 @@ const useStyles = makeStyles((theme) => ({ paddingBottom: theme.spacing(3), textAlign: 'center', maxWidth: 800, - minWidth: 500, margin: '0 auto', }, })); diff --git a/ui/src/devices/DevicesPage.tsx b/ui/src/devices/DevicesPage.tsx index dcc119d..981b8cc 100644 --- a/ui/src/devices/DevicesPage.tsx +++ b/ui/src/devices/DevicesPage.tsx @@ -34,7 +34,6 @@ const useStyles = makeStyles((theme) => ({ paddingBottom: theme.spacing(3), textAlign: 'center', maxWidth: 1200, - minWidth: 800, margin: '0 auto', }, })); diff --git a/ui/src/global.css b/ui/src/global.css index 302cbfe..fd43541 100644 --- a/ui/src/global.css +++ b/ui/src/global.css @@ -3,3 +3,35 @@ body, html { height: 100%; } + +/* Allows the tag Chips to wrap lines */ +.MuiChip-label { + white-space: normal !important; +} + +/* The wrapping box around the input and icon for the datetime picker */ +.time-picker .MuiInputBase-root.MuiInput-root.MuiInputBase-formControl.MuiInput-formControl.MuiInputBase-adornedEnd { + margin-top: 0; +} + +/* The calendar icon for the datetime picker */ +.time-picker + .MuiInputBase-root.MuiInputBase-formControl.MuiInputBase-adornedEnd + .MuiInputAdornment-root.MuiInputAdornment-positionEnd + .MuiButtonBase-root.MuiIconButton-root { + position: absolute; + left: 0; +} + +/* The label for the datetime picker */ +.time-picker.MuiFormControl-root.MuiTextField-root .MuiFormLabel-root.MuiInputLabel-root.MuiInputLabel-formControl { + margin-left: 48px; +} + +/* The input box for the datetime picker */ +.time-picker.MuiFormControl-root.MuiTextField-root .MuiInputBase-input.MuiInput-input.MuiInputBase-inputAdornedEnd { + margin-left: 48px; + /* margin-top: 8px; */ + margin-top: 12px; + min-width: calc(100% - 48px); +} diff --git a/ui/src/setting/SettingsPage.tsx b/ui/src/setting/SettingsPage.tsx index cde31bd..fb9ba10 100644 --- a/ui/src/setting/SettingsPage.tsx +++ b/ui/src/setting/SettingsPage.tsx @@ -17,7 +17,6 @@ const useStyles = makeStyles((theme) => ({ paddingTop: theme.spacing(1), paddingBottom: theme.spacing(3), maxWidth: 500, - minWidth: 500, margin: '0 auto', }, })); diff --git a/ui/src/tag/TagPage.tsx b/ui/src/tag/TagPage.tsx index f822341..866cc15 100644 --- a/ui/src/tag/TagPage.tsx +++ b/ui/src/tag/TagPage.tsx @@ -34,7 +34,6 @@ const useStyles = makeStyles((theme) => ({ paddingBottom: theme.spacing(3), textAlign: 'center', maxWidth: 1200, - minWidth: 800, margin: '0 auto', }, })); diff --git a/ui/src/tag/TagSelector.tsx b/ui/src/tag/TagSelector.tsx index 1b29559..019e16f 100644 --- a/ui/src/tag/TagSelector.tsx +++ b/ui/src/tag/TagSelector.tsx @@ -138,7 +138,7 @@ export const TagSelector: React.FC = ({ return ( setOpen(false)}> -
+
= ({ }>
(container.current = ref)} - style={{display: 'flex', flexWrap: 'wrap', cursor: 'text'}} + style={{display: 'flex', flexWrap: 'wrap', cursor: 'text', width: '100%'}} onClick={focusInput}> {toChips(selectedEntries)} ({ + innerTimespan: { + position: 'relative', + width: '100%', + display: 'flex', + alignItems: 'center', + textAlign: 'center', + '@media (max-width: 750px)': { + flexDirection: 'column', + }, + }, + tagInput: { + width: '100%', + flex: '1', + marginRight: 10, + '@media (max-width: 750px)': { + display: 'flex', + width: 'calc(100% - 48px)', + marginRight: '48px', + }, + }, + timeSelection: { + display: 'inline-flex', + '@media (max-width: 750px)': { + justifyContent: 'space-evenly', + width: '100%', + flexWrap: 'wrap', + }, + }, + showMoreButton: { + display: 'flex', + alignItems: 'center', + '@media (max-width: 750px)': { + position: 'absolute', + top: '0', + right: '0', + }, + }, +})); + export const TimeSpan: React.FC = React.memo( ({ range: {from, to, oldFrom}, @@ -58,6 +96,7 @@ export const TimeSpan: React.FC = React.memo( elevation = 1, addTagsToTracker, }) => { + const styles = useStyles(); const [showNotes, toggleShowingNotes] = React.useState(initialNote !== ''); const note = React.useRef<{value: string; handle?: number}>({value: initialNote}); @@ -147,18 +186,10 @@ export const TimeSpan: React.FC = React.memo( padding: '10px', margin: '10px 0', opacity: wasMoved ? 0.5 : 1, + width: '100%', }}> -
- - toggleShowingNotes(!showNotes)}> - {showNotes ? : } - - -
+
+
= React.memo( }} />
- { - if (!newFrom.isValid()) { - return; - } - newFrom.set({second: 0}); - if (to && moment(newFrom).isAfter(to)) { - const newTo = moment(newFrom).add(15, 'minute'); - noteAwareUpdateTimeSpan({ - variables: { - oldStart: oldFrom, - id, - start: inUserTz(newFrom).format(), - end: inUserTz(newTo).format(), - tags: toInputTags(selectedEntries), - }, - }).then(() => rangeChange({from: newFrom, to: newTo})); - } else { - noteAwareUpdateTimeSpan({ - variables: { - id, - oldStart: oldFrom, - start: inUserTz(newFrom).format(), - end: to && inUserTz(to).format(), - tags: toInputTags(selectedEntries), - }, - }).then(() => rangeChange({from: newFrom, to})); - } - }} - showDate={showDate} - label="start" - /> - {to !== undefined ? ( - { - if (!newTo.isValid()) { - return; - } - newTo.set({second: 0}); - if (moment(newTo).isBefore(from)) { - const newFrom = moment(newTo).subtract(15, 'minute'); - noteAwareUpdateTimeSpan({ - variables: { - id, - oldStart: oldFrom, - start: inUserTz(newFrom).format(), - end: inUserTz(newTo).format(), - tags: toInputTags(selectedEntries), - }, - }).then(() => rangeChange({from: newFrom, to: newTo})); - } else { - noteAwareUpdateTimeSpan({ - variables: { - id, - oldStart: oldFrom, - start: inUserTz(from).format(), - end: inUserTz(newTo).format(), - tags: toInputTags(selectedEntries), - }, - }).then(() => rangeChange({from, to: newTo})); - } - }} - showDate={showDate} - label="end" - /> - ) : ( - - )} - <> - { - - {to ? : } - - } - ) => setOpenMenu(e.currentTarget)}> - - - setOpenMenu(null)}> - {to ? ( - { - setOpenMenu(null); - startTimer({ + +
+
+ { + if (!newFrom.isValid()) { + return; + } + newFrom.set({second: 0}); + if (to && moment(newFrom).isAfter(to)) { + const newTo = moment(newFrom).add(15, 'minute'); + noteAwareUpdateTimeSpan({ variables: { - start: inUserTz(moment()).format(), + oldStart: oldFrom, + id, + start: inUserTz(newFrom).format(), + end: inUserTz(newTo).format(), tags: toInputTags(selectedEntries), - note: note.current.value, }, - }).then(() => continued()); - }}> - Continue - - ) : null} - {addTagsToTracker ? ( - rangeChange({from: newFrom, to: newTo})); + } else { + noteAwareUpdateTimeSpan({ + variables: { + id, + oldStart: oldFrom, + start: inUserTz(newFrom).format(), + end: to && inUserTz(to).format(), + tags: toInputTags(selectedEntries), + }, + }).then(() => rangeChange({from: newFrom, to})); + } + }} + showDate={showDate} + label="start" + /> + {to !== undefined ? ( + { + if (!newTo.isValid()) { + return; + } + newTo.set({second: 0}); + if (moment(newTo).isBefore(from)) { + const newFrom = moment(newTo).subtract(15, 'minute'); + noteAwareUpdateTimeSpan({ + variables: { + id, + oldStart: oldFrom, + start: inUserTz(newFrom).format(), + end: inUserTz(newTo).format(), + tags: toInputTags(selectedEntries), + }, + }).then(() => rangeChange({from: newFrom, to: newTo})); + } else { + noteAwareUpdateTimeSpan({ + variables: { + id, + oldStart: oldFrom, + start: inUserTz(from).format(), + end: inUserTz(newTo).format(), + tags: toInputTags(selectedEntries), + }, + }).then(() => rangeChange({from, to: newTo})); + } + }} + showDate={showDate} + label="end" + /> + ) : ( + + )} +
+ +
+ + {to ? : } + +
+
+ + ) => setOpenMenu(e.currentTarget)}> + + + + setOpenMenu(null)}> + {to ? ( { setOpenMenu(null); - removeTimeSpan({variables: {id}}).then(() => deleted()); + startTimer({ + variables: { + start: inUserTz(moment()).format(), + tags: toInputTags(selectedEntries), + note: note.current.value, + }, + }).then(() => continued()); }}> - Delete + Continue - - + ) : null} + {addTagsToTracker ? ( + { + setOpenMenu(null); + addTagsToTracker(selectedEntries); + }}> + Copy tags + + ) : null} + { + setOpenMenu(null); + toggleShowingNotes(!showNotes); + }}> + Show Notes + + { + setOpenMenu(null); + removeTimeSpan({variables: {id}}).then(() => deleted()); + }}> + Delete + +
{showNotes ? (
diff --git a/ui/src/timespan/calendar/CalendarPage.tsx b/ui/src/timespan/calendar/CalendarPage.tsx index 0bc0198..0ebd143 100644 --- a/ui/src/timespan/calendar/CalendarPage.tsx +++ b/ui/src/timespan/calendar/CalendarPage.tsx @@ -265,7 +265,7 @@ export const CalendarPage: React.FC = () => { eventClick={onClick} eventDrop={onDrop} slotLabelFormat={(s) => toMoment(s.start.marker).format('LT')} - columnHeaderFormat={(s) => toMoment(s.start.marker).format('D, dddd')} + columnHeaderFormat={(s) => toMoment(s.start.marker).format('DD ddd')} nowIndicator={true} plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin, momentPlugin]} header={{ diff --git a/ui/src/timespan/calendar/FullCalendarStyling.tsx b/ui/src/timespan/calendar/FullCalendarStyling.tsx index bc9d671..f07fba2 100644 --- a/ui/src/timespan/calendar/FullCalendarStyling.tsx +++ b/ui/src/timespan/calendar/FullCalendarStyling.tsx @@ -10,6 +10,40 @@ const useStyle = makeStyles((theme) => { // opacity: 0, // border: 'none', // }, + '& .fc-head': { + fontFamily: 'monospace', + }, + '& .fc-toolbar': { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + }, + '& .fc-left, .fc-center, .fc-right': { + display: 'inline-block', + verticalAlign: 'middle', + textAlign: 'center', + // width: '33.33%', + boxSizing: 'border-box', + // padding: '0 10px', + }, + '& .fc-center h2': { + margin: 0, + fontSize: '1.5rem', + }, + '@media (max-width: 600px)': { + '& .fc-toolbar': { + display: 'inherit', + justifyContent: 'space-between', + alignItems: 'center', + }, + '& .fc-left, .fc-center, .fc-right': { + display: 'block', + width: '100%', + }, + '& .fc-left, .fc-right': { + textAlign: 'center', + }, + }, '& .fc-time-grid-event.fc-v-event.fc-event': { borderRadius: 1, border: 'none', diff --git a/ui/src/user/UsersPage.tsx b/ui/src/user/UsersPage.tsx index e9019f6..7d4d9b8 100644 --- a/ui/src/user/UsersPage.tsx +++ b/ui/src/user/UsersPage.tsx @@ -31,7 +31,6 @@ const useStyles = makeStyles((theme) => ({ paddingBottom: theme.spacing(3), textAlign: 'center', maxWidth: 800, - minWidth: 500, margin: '0 auto', }, }));