From 33f31ad3c880d043b90644a43a943f9aa8b5f712 Mon Sep 17 00:00:00 2001 From: Robert Bond Date: Fri, 17 Apr 2026 10:07:52 +0000 Subject: [PATCH] Merged PR 2255: refactor(representations): extract deterministic data-resolution helpers for... refactor(representations): extract deterministic data-resolution helpers for representation flow (Slice R6, behaviour-preserving) Related work items: #22441 --- components/case/representation/index.js | 98 ++++++++----------- .../representation/utils/dataResolution.js | 93 ++++++++++++++++++ context/representations-refactor-tracker.md | 23 ++++- 3 files changed, 155 insertions(+), 59 deletions(-) create mode 100644 components/case/representation/utils/dataResolution.js diff --git a/components/case/representation/index.js b/components/case/representation/index.js index 155e197c..449822d6 100644 --- a/components/case/representation/index.js +++ b/components/case/representation/index.js @@ -39,6 +39,13 @@ import { resolveRepresentationControlKey, resolveSubmitTransition } from "./utils/stepResolution"; +import { + findDetailsObjForSubmit, + findDetailsObjForView, + findResultsObjForCurrentReference, + resolveInitialCaseDataSources, + resolveSubmitCaseDetailsSource +} from "./utils/dataResolution"; let MakeRepresentation = (props) => { let { t } = useTranslation(); @@ -261,52 +268,31 @@ let MakeRepresentation = (props) => { const isEditState = router.query.state === "edit"; const hasState = router.query.hasOwnProperty("state"); - const getCaseDetailsObj = () => { - if (hasState) { - return isEditState - ? props.props.myRepresentations.myRepresentations - : props.props.searchResultsObj.searchDetailsObj; - } - return props.currentType === "watchedCases" - ? props.props.watchedCases.watchedCasesDetails - : props.props.searchResultsObj.searchDetailsObj; - }; + const { caseDetailsSource, caseResultsSource } = + resolveInitialCaseDataSources({ + hasState, + isEditState, + currentType: props.currentType, + myRepresentations: props.props.myRepresentations.myRepresentations, + searchDetailsObj: props.props.searchResultsObj.searchDetailsObj, + searchResultsObj: props.props.searchResultsObj.searchResultsObj, + watchedCasesDetails: props.props.watchedCases.watchedCasesDetails + }); - const getCaseResultsObj = () => { - if (hasState) { - return isEditState - ? props.props.myRepresentations.myRepresentations - : props.props.searchResultsObj.searchResultsObj; - } - return props.currentType === "watchedCases" - ? props.props.watchedCases.watchedCasesDetails - : props.props.searchResultsObj.searchResultsObj; - }; - - const setCaseDetailsObj = getCaseDetailsObj(); - const setCaseResultsObj = getCaseResultsObj(); - - let resultsObj = jsonpath({ - path: `$..[?(@ && @.ticketnumber=="${currentView.caseReference.currentReference}")]`, - json: setCaseResultsObj, - eval: true - })[0]; + let resultsObj = findResultsObjForCurrentReference({ + "currentReference": currentView.caseReference.currentReference, + "caseResultsSource": caseResultsSource + }); // let detailsObj; - if (hasState && isEditState) { - detailsObj = jsonpath({ - path: `$..[?(@ && @.repfile_name=="${router.query.created}")]`, - json: setCaseDetailsObj, - eval: true - })[0]; - } else { - detailsObj = jsonpath({ - path: `$..[?(@ && @.ticketnumber=="${currentView.caseReference.ticketnumber}")]`, - json: setCaseDetailsObj, - eval: true - })[0]; - } + detailsObj = findDetailsObjForView({ + hasState, + isEditState, + "queryCreated": router.query.created, + "ticketnumber": currentView.caseReference.ticketnumber, + "caseDetailsSource": caseDetailsSource + }); const safeDetailsObj = detailsObj || {}; const safeResultsObj = resultsObj || {}; @@ -963,24 +949,20 @@ let MakeRepresentation = (props) => { return; } - // Determine case data source - const getCaseDetailsSource = () => { - if (router.query?.state === "edit") { - return props.props.myRepresentations.myRepresentations; - } - return props.currentType === "watchedCases" - ? props.props.watchedCases.watchedCasesDetails - : props.props.searchResultsObj.searchDetailsObj; - }; - - const setCaseDetailsObj = getCaseDetailsSource(); + const caseDetailsSource = resolveSubmitCaseDetailsSource({ + "isEditState": router.query?.state === "edit", + "currentType": props.currentType, + "myRepresentations": + props.props.myRepresentations.myRepresentations, + "watchedCasesDetails": props.props.watchedCases.watchedCasesDetails, + "searchDetailsObj": props.props.searchResultsObj.searchDetailsObj + }); // Find correct case details - let detailsObj = jsonpath({ - path: `$..[?(@ && @.ticketnumber=="${ticketnumber}")]`, - json: setCaseDetailsObj, - eval: true - })[0]; + let detailsObj = findDetailsObjForSubmit({ + ticketnumber, + caseDetailsSource + }); // Cancel submit status if editing if (router.query?.state === "edit") { diff --git a/components/case/representation/utils/dataResolution.js b/components/case/representation/utils/dataResolution.js new file mode 100644 index 00000000..75409420 --- /dev/null +++ b/components/case/representation/utils/dataResolution.js @@ -0,0 +1,93 @@ +import { JSONPath as jsonpath } from "jsonpath-plus"; + +export const resolveInitialCaseDataSources = ({ + hasState, + isEditState, + currentType, + myRepresentations, + searchDetailsObj, + searchResultsObj, + watchedCasesDetails +}) => { + if (hasState) { + return { + "caseDetailsSource": isEditState + ? myRepresentations + : searchDetailsObj, + "caseResultsSource": isEditState + ? myRepresentations + : searchResultsObj + }; + } + + return { + "caseDetailsSource": + currentType === "watchedCases" + ? watchedCasesDetails + : searchDetailsObj, + "caseResultsSource": + currentType === "watchedCases" + ? watchedCasesDetails + : searchResultsObj + }; +}; + +export const findResultsObjForCurrentReference = ({ + currentReference, + caseResultsSource +}) => { + return jsonpath({ + path: `$..[?(@ && @.ticketnumber=="${currentReference}")]`, + "json": caseResultsSource, + "eval": true + })[0]; +}; + +export const findDetailsObjForView = ({ + hasState, + isEditState, + queryCreated, + ticketnumber, + caseDetailsSource +}) => { + if (hasState && isEditState) { + return jsonpath({ + path: `$..[?(@ && @.repfile_name=="${queryCreated}")]`, + "json": caseDetailsSource, + "eval": true + })[0]; + } + + return jsonpath({ + path: `$..[?(@ && @.ticketnumber=="${ticketnumber}")]`, + "json": caseDetailsSource, + "eval": true + })[0]; +}; + +export const resolveSubmitCaseDetailsSource = ({ + isEditState, + currentType, + myRepresentations, + watchedCasesDetails, + searchDetailsObj +}) => { + if (isEditState) { + return myRepresentations; + } + + return currentType === "watchedCases" + ? watchedCasesDetails + : searchDetailsObj; +}; + +export const findDetailsObjForSubmit = ({ + ticketnumber, + caseDetailsSource +}) => { + return jsonpath({ + path: `$..[?(@ && @.ticketnumber=="${ticketnumber}")]`, + "json": caseDetailsSource, + "eval": true + })[0]; +}; diff --git a/context/representations-refactor-tracker.md b/context/representations-refactor-tracker.md index 0e48d46a..f66f3913 100644 --- a/context/representations-refactor-tracker.md +++ b/context/representations-refactor-tracker.md @@ -6,7 +6,7 @@ Base branch: `refactor` ## Status -Current slice: Slice R5 — Representation Elements Normalisation +Current slice: Slice R6 — Async Data / Service Layer Cleanup Status: COMPLETE --- @@ -181,6 +181,27 @@ Reduce duplication and coupling in data fetching. - blob/file retrieval - representation detail aggregation +**Completion notes (this slice):** + +- Implemented on feature branch created from `refactor`: `rep-slice-r6-data-service-cleanup`. +- Added deterministic representation-specific data-resolution helpers in: + - `components/case/representation/utils/dataResolution.js` +- Updated `components/case/representation/index.js` to use extracted helper functions for: + - initial case details/results source resolution + - details/results lookup by current context (state/edit/ticket/created) + - submit-path details source resolution and details lookup +- Preserved slice boundary constraints: + - no service/API call execution movement + - no dispatch sequencing changes + - no loader branch redesign + - no blob retrieval orchestration changes + - no payload contract/Redux/route/query/EN-CY changes +- Validation evidence: + - `npm run lint` completed (warnings only, no new errors). + - `npm run test:reps` completed: **7 passed**. + - Manual APP/IP/Agent/LPA checks: **passed**. + - Manual EN/CY parity checks: **passed**. + --- ### Slice R7 — Summary / Case-Type Rendering Simplification (Optional)