Skip to content

Commit

Permalink
Add checkbox to enable experiment: collapsible group
Browse files Browse the repository at this point in the history
- Add collapsed groups to local storage
- Clear collapsed groups when grouping or ordering is changed
  • Loading branch information
tnagorra committed Oct 22, 2024
1 parent d17fcfe commit 3f0f481
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 46 deletions.
34 changes: 32 additions & 2 deletions src/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,40 @@ function App() {
},
});

const handleStorageStateUpdate: typeof setStorageState = useCallback(
(val) => {
setStorageState((prevValue) => {
const newValue = typeof val === 'function'
? val(prevValue)
: val;

if (
prevValue['timur-config'].value?.dailyJournalGrouping !== newValue['timur-config'].value?.dailyJournalGrouping
|| prevValue['timur-config'].value?.dailyJournalAttributeOrder !== newValue['timur-config'].value?.dailyJournalAttributeOrder
) {
const overriddenValue: typeof newValue = {
...newValue,
'timur-config': {
...newValue['timur-config'],
value: {
...(newValue['timur-config'].value ?? defaultConfigValue),
collapsedGroups: [],
},
},
};
return overriddenValue;
}

return newValue;
});
},
[],
);

const storageContextValue = useMemo<LocalStorageContextProps>(() => ({
storageState,
setStorageState,
}), [storageState]);
setStorageState: handleStorageStateUpdate,
}), [storageState, handleStorageStateUpdate]);

// Device Size

Expand Down
2 changes: 2 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const defaultConfigValue: ConfigStorage = {
indent: true,
compactTextArea: false,
checkboxForStatus: false,
enableCollapsibleGroups: false,
startSidebarShown: window.innerWidth >= 900,
endSidebarShown: false,
dailyJournalGrouping: {
Expand All @@ -22,6 +23,7 @@ export const defaultConfigValue: ConfigStorage = {
{ key: 'task', sortDirection: 1 },
{ key: 'status', sortDirection: 1 },
],
collapsedGroups: [],
};

export const colorscheme: [string, string][] = [
Expand Down
2 changes: 2 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ export type ConfigStorage = {
checkboxForStatus: boolean,
compactTextArea: boolean,
indent: boolean,
enableCollapsibleGroups: boolean,

dailyJournalAttributeOrder: DailyJournalAttribute[];
dailyJournalGrouping: DailyJournalGrouping;

collapsedGroups: string[],
startSidebarShown: boolean,
endSidebarShown: boolean,
}
Expand Down
105 changes: 61 additions & 44 deletions src/views/DailyJournal/DayView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
useCallback,
useContext,
useMemo,
useState,
} from 'react';
import {
RiArrowDownSLine,
Expand Down Expand Up @@ -75,21 +74,42 @@ function DayView(props: Props) {

const { taskById } = useContext(EnumsContext);

const [groupVisibility, setGroupVisibility] = useState<string[]>([]);
const [
storedConfig,
setStoredConfig,
] = useLocalStorage('timur-config');

const toggleGroupVisibility = useCallback(
const handleToggleCollapseGroup = useCallback(
(value: string) => {
setGroupVisibility((prevValues) => {
setStoredConfig((prevConfig) => {
// FIXME: We should not need to add fallback
const prevValues = prevConfig.collapsedGroups ?? [];

if (!prevValues.includes(value)) {
return [...prevValues, value];
return {
...prevConfig,
collapsedGroups: [...prevValues, value],
};
}
return prevValues.filter((prevValue) => prevValue !== value);
return {
...prevConfig,
collapsedGroups: prevValues.filter((prevValue) => prevValue !== value),
};
});
},
[],
[setStoredConfig],
);

const [storedConfig] = useLocalStorage('timur-config');
const {
dailyJournalAttributeOrder,
dailyJournalGrouping: {
groupLevel,
joinLevel,
},
indent,
enableCollapsibleGroups,
collapsedGroups,
} = storedConfig;

const getWorkItemLabelFromAttr = useCallback((
item: WorkItem,
Expand Down Expand Up @@ -151,15 +171,6 @@ function DayView(props: Props) {
[workItems],
);

const {
dailyJournalAttributeOrder,
dailyJournalGrouping: {
groupLevel,
joinLevel,
},
indent,
} = storedConfig;

const groupedItems = useMemo(() => {
if (isNotDefined(taskById) || isNotDefined(workItems)) {
return [];
Expand Down Expand Up @@ -230,10 +241,11 @@ function DayView(props: Props) {
<div className={styles.newGroup}>
{groupedItems.map((groupedItem) => {
if (groupedItem.type === 'heading') {
const hidden = groupVisibility.some((groupKey) => (
groupedItem.groupKey !== groupKey
&& groupedItem.groupKey.startsWith(groupKey)
));
const hidden = enableCollapsibleGroups
&& collapsedGroups.some((groupKey) => (
groupedItem.groupKey !== groupKey
&& groupedItem.groupKey.startsWith(groupKey)
));
if (hidden) {
return null;
}
Expand Down Expand Up @@ -268,16 +280,18 @@ function DayView(props: Props) {
/>
)}
{headingText}
<Button
name={groupedItem.groupKey}
onClick={toggleGroupVisibility}
title="Toggle group visibility"
variant="transparent"
>
{groupVisibility.includes(groupedItem.groupKey)
? <RiArrowUpSLine />
: <RiArrowDownSLine />}
</Button>
{enableCollapsibleGroups && (
<Button
name={groupedItem.groupKey}
onClick={handleToggleCollapseGroup}
title="Toggle group visibility"
variant="transparent"
>
{collapsedGroups.includes(groupedItem.groupKey)
? <RiArrowUpSLine />
: <RiArrowDownSLine />}
</Button>
)}
</Heading>
);
}
Expand Down Expand Up @@ -331,16 +345,18 @@ function DayView(props: Props) {
</Fragment>
);
})}
<Button
name={groupedItem.groupKey}
onClick={toggleGroupVisibility}
title="Toggle group visibility"
variant="transparent"
>
{groupVisibility.includes(groupedItem.groupKey)
? <RiArrowUpSLine />
: <RiArrowDownSLine />}
</Button>
{enableCollapsibleGroups && (
<Button
name={groupedItem.groupKey}
onClick={handleToggleCollapseGroup}
title="Toggle group visibility"
variant="transparent"
>
{collapsedGroups.includes(groupedItem.groupKey)
? <RiArrowUpSLine />
: <RiArrowDownSLine />}
</Button>
)}
</h4>
);
}
Expand All @@ -352,9 +368,10 @@ function DayView(props: Props) {
if (!taskDetails) {
return null;
}
const hidden = groupVisibility.some(
(groupKey) => groupedItem.itemKey.startsWith(groupKey),
);
const hidden = enableCollapsibleGroups
&& collapsedGroups.some(
(groupKey) => groupedItem.itemKey.startsWith(groupKey),
);
if (hidden) {
return null;
}
Expand Down
6 changes: 6 additions & 0 deletions src/views/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ export function Component() {
value={storedConfig.indent}
onChange={setConfigFieldValue}
/>
<Checkbox
name="enableCollapsibleGroups"
label="Enable collapsible groups 🧪"
value={storedConfig.enableCollapsibleGroups}
onChange={setConfigFieldValue}
/>
<WorkItemRow
className={styles.workItem}
workItem={{
Expand Down

0 comments on commit 3f0f481

Please sign in to comment.