Skip to content

Commit

Permalink
Refactor: split code in useFormLayoutHistory to smaller chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
mjulstein committed Jul 26, 2022
1 parent 4bd1a5b commit 514915b
Showing 1 changed file with 87 additions and 35 deletions.
122 changes: 87 additions & 35 deletions src/altinn-app-frontend/src/common/hooks/useFormLayoutHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { useAppDispatch } from 'src/common/hooks/useAppDispatch';
import { FormLayoutActions } from 'src/features/form/layout/formLayoutSlice';
import type { IUpdateCurrentView } from 'src/features/form/layout/formLayoutTypes';

enum HistoryAction {
BackOrForward = 'POP',
}

/**
* @param activePageId the formLayout page id that is currently active in the app
* @return matchRootUrl: Matches the location pathname of the history root. If not, an empty string.
Expand All @@ -16,46 +20,94 @@ export const useFormLayoutHistoryAndMatchInstanceLocation = ({
}): { matchRootUrl: string } => {
const matchRoot = useRouteMatch<string>('/instance/:partyId/:instanceGuid');
const matchRootUrl = matchRoot?.url || '';
const history = useHistory();
const dispatch = useAppDispatch();
const dispatchAction = FormLayoutActions.updateCurrentView;
const doDispatch = useCallback(
(payload: IUpdateCurrentView) => {
dispatch(dispatchAction(payload));
dispatch(FormLayoutActions.updateCurrentView(payload));
},
[dispatch, dispatchAction],
[dispatch],
);
useFormLayoutHistory({
renderedPageId: activePageId,
renderFunc: doDispatch,
pathToRoute: matchRootUrl,
});
return { matchRootUrl };
};

function useFormLayoutHistory({
renderedPageId,
renderFunc,
pathToRoute,
}: {
pathToRoute: string;
renderedPageId: string;
renderFunc: (IUpdateCurrentView) => void;
}) {
const history = useHistory();
useEffect(() => {
const pageIdFromLocation = history.location.pathname.replace(
`${matchRootUrl}/`,
'',
);
const locationIsRoot =
!pageIdFromLocation || pageIdFromLocation === matchRootUrl;
if (activePageId) {
if (locationIsRoot) {
history.replace(`${matchRootUrl}/${activePageId}`);
return;
} else if (activePageId !== pageIdFromLocation) {
history.push(`${matchRootUrl}/${activePageId}`);
}
return history.listen((_location, action) => {
const isBrowserBackOrForwardPressed = action === 'POP';
if (isBrowserBackOrForwardPressed) {
// newView will not be the same as pageIdFromLocation as this happens in the listener
const newView = history.location.pathname.replace(
`${matchRootUrl}/`,
'',
);
if (newView && newView !== activePageId) {
doDispatch({ newView });
}
}
});
} else if (!locationIsRoot) {
doDispatch({ newView: pageIdFromLocation });
return formLayoutHistory({
history,
renderedPageId,
renderFunc,
pathToRoute,
});
}, [history, renderedPageId, renderFunc, pathToRoute]);
}

function formLayoutHistory({
history,
renderedPageId,
renderFunc,
pathToRoute,
}: {
history;
pathToRoute: string;
renderedPageId: string;
renderFunc: (IUpdateCurrentView) => void;
}) {
const pageIdFromLocation = getPageIdFromLocation(
history.location,
pathToRoute,
);
const browserIsOnRootPath =
!pageIdFromLocation || pageIdFromLocation === pathToRoute;
if (renderedPageId) {
if (browserIsOnRootPath) {
// The location path should be changed to the rendered page
history.replace(`${pathToRoute}/${renderedPageId}`);
return;
}
if (renderedPageId !== pageIdFromLocation) {
history.push(`${pathToRoute}/${renderedPageId}`);
}
}, [activePageId, doDispatch, history, matchRootUrl]);
return listenForHistoryAction(
{
action: HistoryAction.BackOrForward,
history,
},
(location) => {
const newView = getPageIdFromLocation(location, pathToRoute);
if (newView && newView !== renderedPageId) {
renderFunc({ newView });
}
},
);
}
if (!browserIsOnRootPath) {
// Render the view correlating to the path
renderFunc({ newView: pageIdFromLocation });
}
}

return { matchRootUrl };
};
function getPageIdFromLocation({ pathname }, removePath) {
return pathname.replace(`${removePath}/`, '');
}

function listenForHistoryAction({ history, action }, callBack) {
return history.listen((location, historyAction) => {
if (historyAction === action) {
callBack(location, historyAction);
}
});
}

0 comments on commit 514915b

Please sign in to comment.