• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CBIIT / crdc-datahub-ui / 18789341118

24 Oct 2025 06:57PM UTC coverage: 78.178% (+15.5%) from 62.703%
18789341118

push

github

web-flow
Merge pull request #888 from CBIIT/3.4.0

3.4.0 Release

4977 of 5488 branches covered (90.69%)

Branch coverage included in aggregate %.

8210 of 9264 new or added lines in 257 files covered. (88.62%)

6307 existing lines in 120 files now uncovered.

30203 of 39512 relevant lines covered (76.44%)

213.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/hooks/useBuildReduxStore.ts
NEW
1
import { useLazyQuery } from "@apollo/client";
×
UNCOV
2
import {
×
3
  ddgraph,
4
  moduleReducers as submission,
5
  versionInfo,
6
  changelogInfo,
7
  iconMapInfo,
8
  getModelExploreData,
9
  getChangelog,
10
} from "data-model-navigator";
NEW
11
import { useState } from "react";
×
NEW
12
import { createStore, combineReducers, Store } from "redux";
×
13

NEW
14
import logo from "../assets/header/Logo.jpg";
×
UNCOV
15
import { baseConfiguration, defaultReadMeTitle, graphViewConfig } from "../config/ModelNavigator";
×
NEW
16
import { RETRIEVE_CDEs, RetrieveCDEsInput, RetrieveCDEsResp } from "../graphql";
×
UNCOV
17
import {
×
18
  buildAssetUrls,
19
  buildBaseFilterContainers,
20
  buildFilterOptionsList,
21
  Logger,
22
  extractSupportedCDEs,
23
  populateCDEData,
24
} from "../utils";
25

26
export type ReduxStoreStatus = "waiting" | "loading" | "error" | "success";
27

28
export type ReduxStoreData = {
29
  /**
30
   * The current status of the Redux store.
31
   */
32
  status: ReduxStoreStatus;
33
  /**
34
   * The Redux store instance.
35
   */
36
  store: Store;
37
};
38

39
export type ReduxStoreResult = [ReduxStoreData, (assets: DataCommon, modelVersion: string) => void];
40

41
const makeStore = (): Store => {
×
42
  const reducers = { ddgraph, versionInfo, submission, changelogInfo, iconMapInfo };
×
43
  const newStore = createStore(combineReducers(reducers));
×
44

45
  // @ts-ignore
46
  newStore.injectReducer = (key, reducer) => {
×
47
    reducers[key] = reducer;
×
48
    newStore.replaceReducer(combineReducers(reducers));
×
UNCOV
49
  };
×
50

51
  return newStore;
×
UNCOV
52
};
×
53

54
/**
55
 * A hook to build and populate the Redux store with DMN data
56
 *
57
 * @params {void}
58
 */
59
const useBuildReduxStore = (): ReduxStoreResult => {
×
60
  const [store] = useState<Store>(makeStore());
×
61
  const [status, setStatus] = useState<ReduxStoreStatus>("waiting");
×
62

NEW
63
  const [retrieveCDEs] = useLazyQuery<RetrieveCDEsResp, RetrieveCDEsInput>(RETRIEVE_CDEs, {
×
UNCOV
64
    context: { clientName: "backend" },
×
NEW
65
    fetchPolicy: "cache-first",
×
UNCOV
66
  });
×
67

68
  /**
69
   * Injects the Data Model into the store
70
   *
71
   * @param datacommon The Data Model to inject assets from
72
   * @param modelVersion The version of the Data Model to inject
73
   */
74
  const populateStore = async (datacommon: DataCommon, modelVersion: string) => {
×
75
    if (
×
UNCOV
76
      !datacommon?.name ||
×
UNCOV
77
      !datacommon?.assets ||
×
UNCOV
78
      !datacommon?.assets["current-version"] ||
×
UNCOV
79
      !datacommon?.assets["model-navigator-config"]
×
UNCOV
80
    ) {
×
81
      setStatus("error");
×
82
      return;
×
UNCOV
83
    }
×
84

85
    setStatus("loading");
×
86

87
    const assets = buildAssetUrls(datacommon, modelVersion);
×
88
    const dmnConfig = datacommon.assets["model-navigator-config"];
×
89

90
    const changelogMD = await getChangelog(assets?.changelog)?.catch((e) => {
×
91
      Logger.error(e);
×
92
      return null;
×
UNCOV
93
    });
×
94

NEW
95
    const { data: dictionary, version } =
×
NEW
96
      (await getModelExploreData(...assets.model_files)?.catch((e) => {
×
NEW
97
        Logger.error(e);
×
NEW
98
        return {};
×
NEW
99
      })) || {};
×
100

NEW
101
    if (!dictionary || !version) {
×
102
      setStatus("error");
×
103
      return;
×
UNCOV
104
    }
×
105

NEW
106
    const allCDEs = extractSupportedCDEs(dictionary);
×
NEW
107
    if (allCDEs.length > 0) {
×
108
      try {
×
109
        const CDEs = await retrieveCDEs({
×
UNCOV
110
          variables: {
×
NEW
111
            cdeInfo: allCDEs.map(({ CDECode, CDEVersion }) => ({ CDECode, CDEVersion })),
×
UNCOV
112
          },
×
UNCOV
113
        });
×
NEW
114
        populateCDEData(dictionary, CDEs?.data?.retrieveCDEs || []);
×
115
      } catch (error) {
×
NEW
116
        populateCDEData(dictionary, []);
×
UNCOV
117
      }
×
UNCOV
118
    }
×
119

NEW
120
    store.dispatch({ type: "RECEIVE_VERSION_INFO", data: version });
×
121

122
    store.dispatch({
×
UNCOV
123
      type: "REACT_FLOW_GRAPH_DICTIONARY",
×
UNCOV
124
      dictionary,
×
UNCOV
125
      pdfDownloadConfig: {
×
UNCOV
126
        iconSrc: logo,
×
UNCOV
127
        ...dmnConfig.pdfConfig,
×
UNCOV
128
      },
×
UNCOV
129
      graphViewConfig,
×
UNCOV
130
    });
×
131

132
    store.dispatch({
×
UNCOV
133
      type: "RECEIVE_DICTIONARY",
×
UNCOV
134
      payload: {
×
UNCOV
135
        data: dictionary,
×
UNCOV
136
        facetfilterConfig: {
×
UNCOV
137
          ...baseConfiguration,
×
UNCOV
138
          facetSearchData: dmnConfig.facetFilterSearchData,
×
UNCOV
139
          facetSectionVariables: dmnConfig.facetFilterSectionVariables,
×
UNCOV
140
          baseFilters: buildBaseFilterContainers(dmnConfig),
×
141
          filterSections: dmnConfig.facetFilterSearchData.map((s) => s?.datafield),
×
UNCOV
142
          filterOptions: buildFilterOptionsList(dmnConfig),
×
UNCOV
143
        },
×
UNCOV
144
        pageConfig: {
×
UNCOV
145
          title: dmnConfig.pageTitle,
×
UNCOV
146
          iconSrc: assets.navigator_icon,
×
UNCOV
147
        },
×
UNCOV
148
        readMeConfig: {
×
UNCOV
149
          readMeUrl: assets.readme,
×
UNCOV
150
          readMeTitle: dmnConfig?.readMeTitle || defaultReadMeTitle,
×
UNCOV
151
          allowDownload: false,
×
UNCOV
152
        },
×
UNCOV
153
        pdfDownloadConfig: dmnConfig.pdfConfig,
×
UNCOV
154
        loadingExampleConfig: {
×
UNCOV
155
          type: "static",
×
UNCOV
156
          url: assets.loading_file,
×
UNCOV
157
        },
×
UNCOV
158
      },
×
UNCOV
159
    });
×
160

161
    store.dispatch({
×
UNCOV
162
      type: "RECEIVE_CHANGELOG_INFO",
×
UNCOV
163
      data: {
×
UNCOV
164
        changelogMD,
×
UNCOV
165
        changelogTabName: "Version History",
×
UNCOV
166
      },
×
UNCOV
167
    });
×
168

169
    if (datacommon?.assets?.["model-navigator-config"]?.iconMap) {
×
170
      store.dispatch({
×
UNCOV
171
        type: "RECEIVE_ICON_MAP",
×
UNCOV
172
        data: datacommon?.assets?.["model-navigator-config"]?.iconMap,
×
UNCOV
173
      });
×
UNCOV
174
    }
×
175

176
    // MVP-2 M2 NOTE: This resets the search history to prevent the data models
177
    // from overlapping on searches. A future improvement would be to isolate
178
    // the localStorage history key to the data model based on a config option.
179
    store.dispatch({ type: "SEARCH_CLEAR_HISTORY" });
×
180

181
    setStatus("success");
×
UNCOV
182
  };
×
183

184
  return [{ status, store }, populateStore];
×
UNCOV
185
};
×
186

UNCOV
187
export default useBuildReduxStore;
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc