Skip to content

Commit

Permalink
feat(hideTracker): add hide / make visible tracker feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Clm-Roig committed Apr 11, 2022
1 parent 3ea388c commit c4d7ca1
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 77 deletions.
37 changes: 21 additions & 16 deletions src/components/TrackerCard/TrackerCardActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import { FC, useState } from 'react';
import { useAppDispatch } from '../../app/hooks';
import Completion from '../../models/Completion';
import Tracker from '../../models/Tracker';
import { completelyValidate, customValidate } from '../../store/trackers/trackersSlice';
import {
completelyValidate,
customValidate,
hideTracker,
makeTrackerVisible
} from '../../store/trackers/trackersSlice';
import CompleteValidationDialog from '../TrackerValidationDialog/CompleteValidationDialog';
import CustomValidationDialog from '../TrackerValidationDialog/CustomValidationDialog';
import MakeHiddenDialog from '../TrackerValidationDialog/MakeHiddenDialog';
Expand All @@ -30,11 +35,11 @@ const TrackerCardActions: FC<Props> = ({
tracker
}) => {
const dispatch = useAppDispatch();
const [isCompleteValidationOpen, setIsCompleteValidationOpen] = useState(false);
const { enqueueSnackbar } = useSnackbar();
const [isCompleteValidationOpen, setIsCompleteValidationOpen] = useState(false);
const [isCustomValidationOpen, setIsCustomValidationOpen] = useState(false);
const [isMakeVisible, setIsMakeVisible] = useState(false);
const [isMakeHidden, setIsMakeHidden] = useState(false);
const [isMakeVisibleOpen, setIsMakeVisibleOpen] = useState(false);
const [isMakeHiddenOpen, setIsMakeHiddenOpen] = useState(false);

const handleCompleteValidation = () => {
dispatch(completelyValidate(tracker.id));
Expand All @@ -51,15 +56,15 @@ const TrackerCardActions: FC<Props> = ({
// TODO: remove next line when feature is implemented
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const handleMakeVisible = () => {
// eslint-disable-next-line no-console
console.log('make visible to be implementend');
dispatch(makeTrackerVisible(tracker.id));
setIsMakeVisibleOpen(false);
enqueueSnackbar('Tracker affiché !', { variant: 'success' });
};

// TODO: remove next line when feature is implemented
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const handleMakeHidden = () => {
// eslint-disable-next-line no-console
console.log('make hidden to be implementend');
dispatch(hideTracker(tracker.id));
setIsMakeHiddenOpen(false);
enqueueSnackbar('Tracker masqué !', { variant: 'success' });
};

const isHidden = tracker.dateHidden && isToday(new Date(tracker.dateHidden));
Expand Down Expand Up @@ -89,11 +94,11 @@ const TrackerCardActions: FC<Props> = ({
</>
)}
{isHidden ? (
<IconButton color="primary" size="large" onClick={() => setIsMakeVisible(true)}>
<IconButton color="primary" size="large" onClick={() => setIsMakeVisibleOpen(true)}>
<VisibilityIcon fontSize="large" />
</IconButton>
) : (
<IconButton color="primary" size="large" onClick={() => setIsMakeHidden(true)}>
<IconButton color="primary" size="large" onClick={() => setIsMakeHiddenOpen(true)}>
<VisibilityOffIcon fontSize="large" />
</IconButton>
)}
Expand Down Expand Up @@ -125,8 +130,8 @@ const TrackerCardActions: FC<Props> = ({
/>
<MakeVisibleValidationDialog
dialogProps={{
open: isMakeVisible,
onClose: () => setIsMakeVisible(false),
open: isMakeVisibleOpen,
onClose: () => setIsMakeVisibleOpen(false),
sx: {
'.MuiDialog-paper': { bgcolor: 'secondary' }
}
Expand All @@ -136,8 +141,8 @@ const TrackerCardActions: FC<Props> = ({
/>
<MakeHiddenDialog
dialogProps={{
open: isMakeHidden,
onClose: () => setIsMakeHidden(false),
open: isMakeHiddenOpen,
onClose: () => setIsMakeHiddenOpen(false),
sx: {
'.MuiDialog-paper': { bgcolor: 'secondary' }
}
Expand Down
8 changes: 5 additions & 3 deletions src/components/TrackerValidationDialog/MakeHiddenDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ interface Props {
}

const MakeHiddenDialog: FC<Props> = ({ dialogProps, onValidation, tracker }) => {
const { name, requiredCompletions } = tracker;
const { name } = tracker;
return (
<Dialog {...dialogProps}>
<DialogTitle id="alert-dialog-title">
{'Tracker : '}
<b>{name}</b>
</DialogTitle>
<DialogContent>
<DialogContentText>[Masquer tracker] En cours de développement...</DialogContentText>
<DialogContentText>Voulez-vous masquer ce tracker ?</DialogContentText>
</DialogContent>
<DialogActions>
<Button autoFocus>En cours de développement...</Button>
<Button onClick={onValidation} autoFocus>
Masquer
</Button>
</DialogActions>
</Dialog>
);
Expand Down
8 changes: 5 additions & 3 deletions src/components/TrackerValidationDialog/MakeVisibleDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ interface Props {
}

const MakeVisibleValidationDialog: FC<Props> = ({ dialogProps, onValidation, tracker }) => {
const { name, requiredCompletions } = tracker;
const { name } = tracker;
return (
<Dialog {...dialogProps}>
<DialogTitle id="alert-dialog-title">
{'Tracker : '}
<b>{name}</b>
</DialogTitle>
<DialogContent>
<DialogContentText>[Rendre visible] En cours de développement...</DialogContentText>
<DialogContentText>Voulez-vous afficher ce tracker ?</DialogContentText>
</DialogContent>
<DialogActions>
<Button autoFocus>En cours de développement...</Button>
<Button onClick={onValidation} autoFocus>
Afficher
</Button>
</DialogActions>
</Dialog>
);
Expand Down
3 changes: 2 additions & 1 deletion src/store/trackers/trackers.selectors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ describe('selectHiddenTrackers()', () => {
trackers: [
{ ...testTracker1, dateHidden: new Date().toString() },
testTracker2,
{ ...testTracker3, dateHidden: new Date().toString() }
{ ...testTracker3, dateHidden: new Date().toString() },
{ ...testTracker3, dateHidden: subDays(new Date(), 2).toString() } // Should not be selected because it was hidden in the pas
]
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/store/trackers/trackers.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const selectHiddenTrackers = (state: RootState) => {
};

const selectTrackersDone = (state: RootState) => {
const newTrackers = formatTrackers(state.trackers.trackers).filter(
(t) => t.status === TrackerStatus.done
const newTrackers = removeHiddenTrackers(
formatTrackers(state.trackers.trackers).filter((t) => t.status === TrackerStatus.done)
);

return {
Expand Down
139 changes: 89 additions & 50 deletions src/store/trackers/trackersSlice.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import trackersReducer, {
completelyValidate,
createTracker,
customValidate,
deleteTracker
deleteTracker,
hideTracker,
makeTrackerVisible
} from './trackersSlice';

describe('trackers reducer', () => {
Expand All @@ -15,58 +17,95 @@ describe('trackers reducer', () => {
trackers: []
});
});
it('should handle a tracker complete validation', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
completelyValidate(testTracker1Id)
);

const res = finalState.trackers[0];
expect(res).toBeDefined();
const entries = res?.entries;
expect(entries?.length).toEqual(1);
const entry = entries?.[0];
expect(entry?.completions).toEqual(testTracker1.requiredCompletions);
expect(entry?.trackerId).toEqual(testTracker1.id);
});
it('should handle a tracker custom validation', () => {
const partialCompletions = [
{
quantity: 5,
unit: 'push-ups'
},
{
quantity: 20,
unit: 'squats'
}
];
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
customValidate({ id: testTracker1Id, completions: partialCompletions })
);
describe('Tracker validation', () => {
it('should handle a tracker complete validation', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
completelyValidate(testTracker1Id)
);

const res = finalState.trackers[0];
expect(res).toBeDefined();
const entries = res?.entries;
expect(entries?.length).toEqual(1);
const entry = entries?.[0];
expect(entry?.completions).toEqual(testTracker1.requiredCompletions);
expect(entry?.trackerId).toEqual(testTracker1.id);
});

const res = finalState.trackers[0];
expect(res).toBeDefined();
const entries = res?.entries;
expect(entries?.length).toEqual(1);
const entry = entries?.[0];
expect(entry?.completions).toEqual(partialCompletions);
expect(entry?.trackerId).toEqual(testTracker1.id);
it('should handle a tracker custom validation', () => {
const partialCompletions = [
{
quantity: 5,
unit: 'push-ups'
},
{
quantity: 20,
unit: 'squats'
}
];
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
customValidate({ id: testTracker1Id, completions: partialCompletions })
);

const res = finalState.trackers[0];
expect(res).toBeDefined();
const entries = res?.entries;
expect(entries?.length).toEqual(1);
const entry = entries?.[0];
expect(entry?.completions).toEqual(partialCompletions);
expect(entry?.trackerId).toEqual(testTracker1.id);
});
});
it('should handle a tracker deletion', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
deleteTracker(testTracker1Id)
);
expect(finalState.trackers.length).toEqual(0);
describe('Tracker deletion', () => {
it('should handle a tracker deletion', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
deleteTracker(testTracker1Id)
);
expect(finalState.trackers.length).toEqual(0);
});
});
it('should handle a tracker creation', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
createTracker(testTracker2)
);
expect(finalState.trackers.length).toEqual(2);
expect(finalState.trackers.find((t) => t.id === testTracker1Id)).toEqual(testTracker1);
expect(finalState.trackers.find((t) => t.id === testTracker2Id)).toEqual(testTracker2);
describe('Tracker creation', () => {
it('should handle a tracker creation', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1] },
createTracker(testTracker2)
);
expect(finalState.trackers.length).toEqual(2);
expect(finalState.trackers.find((t) => t.id === testTracker1Id)).toEqual(testTracker1);
expect(finalState.trackers.find((t) => t.id === testTracker2Id)).toEqual(testTracker2);
});
});
describe('Hide tracker', () => {
it('should hide a tracker', () => {
const finalState = trackersReducer(
{ error: {}, status: SliceStatus.idle, trackers: [testTracker1, testTracker2] },
hideTracker(testTracker1.id)
);
expect(
finalState.trackers.find((t) => t.id === testTracker1Id)?.dateHidden
).not.toBeUndefined();
expect(finalState.trackers.find((t) => t.id === testTracker2Id)?.dateHidden).toBeUndefined();
});
});
describe('Make a tracker visible', () => {
it('should make a tracker visible', () => {
const finalState = trackersReducer(
{
error: {},
status: SliceStatus.idle,
trackers: [
{ ...testTracker1, dateHidden: new Date().toString() },
{ ...testTracker2, dateHidden: new Date().toString() }
]
},
makeTrackerVisible(testTracker1.id)
);
expect(finalState.trackers.find((t) => t.id === testTracker1Id)?.dateHidden).toBeUndefined();
expect(finalState.trackers.find((t) => t.id == testTracker2Id)?.dateHidden).toBeDefined();
});
});
});
22 changes: 20 additions & 2 deletions src/store/trackers/trackersSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,31 @@ export const trackersSlice = createSlice({
...state,
trackers: filteredTrackers
};
},
hideTracker: (state, action: PayloadAction<Tracker['id']>) => {
const idx = state.trackers.findIndex((t) => t.id === action.payload);
if (idx !== -1) {
state.trackers[idx].dateHidden = new Date().toString();
}
},
makeTrackerVisible: (state, action: PayloadAction<Tracker['id']>) => {
const idx = state.trackers.findIndex((t) => t.id === action.payload);
if (idx !== -1) {
state.trackers[idx].dateHidden = undefined;
}
}
}
// The `extraReducers` field lets the slice handle actions defined elsewhere,
// including actions generated by createAsyncThunk or in other slices.
// extraReducers: (builder) => {})
});

export const { createTracker, completelyValidate, customValidate, deleteTracker } =
trackersSlice.actions;
export const {
createTracker,
completelyValidate,
customValidate,
deleteTracker,
hideTracker,
makeTrackerVisible
} = trackersSlice.actions;
export default trackersSlice.reducer;

0 comments on commit c4d7ca1

Please sign in to comment.