@itwin/reports-config-widget-react 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.rush/temp/package-deps_rebuild.json +11 -9
- package/.rush/temp/shrinkwrap-deps.json +52 -56
- package/CHANGELOG.json +45 -0
- package/CHANGELOG.md +25 -1
- package/README.md +3 -3
- package/coverage/clover.xml +116 -112
- package/coverage/coverage-final.json +14 -14
- package/coverage/lcov-report/index.html +19 -19
- package/coverage/lcov-report/src/ReportsConfigWidget.ts.html +2 -2
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/test/index.html +1 -1
- package/coverage/lcov-report/src/test/test-utils.tsx.html +1 -1
- package/coverage/lcov-report/src/widget/ReportsConfigUiProvider.tsx.html +1 -1
- package/coverage/lcov-report/src/widget/components/ActionPanel.tsx.html +2 -2
- package/coverage/lcov-report/src/widget/components/AddMappingsModal.tsx.html +10 -10
- package/coverage/lcov-report/src/widget/components/DeleteModal.tsx.html +4 -4
- package/coverage/lcov-report/src/widget/components/Extraction.tsx.html +20 -20
- package/coverage/lcov-report/src/widget/components/HorizontalTile.tsx.html +2 -2
- package/coverage/lcov-report/src/widget/components/LocalizedTablePaginator.tsx.html +1 -1
- package/coverage/lcov-report/src/widget/components/ReportAction.tsx.html +10 -10
- package/coverage/lcov-report/src/widget/components/ReportMappings.tsx.html +21 -21
- package/coverage/lcov-report/src/widget/components/Reports.tsx.html +19 -19
- package/coverage/lcov-report/src/widget/components/ReportsContainer.tsx.html +53 -23
- package/coverage/lcov-report/src/widget/components/SearchBar.tsx.html +5 -5
- package/coverage/lcov-report/src/widget/components/SelectIModel.tsx.html +1 -1
- package/coverage/lcov-report/src/widget/components/index.html +19 -19
- package/coverage/lcov-report/src/widget/components/utils.tsx.html +5 -5
- package/coverage/lcov-report/src/widget/context/ReportsApiConfigContext.tsx.html +4 -4
- package/coverage/lcov-report/src/widget/context/index.html +1 -1
- package/coverage/lcov-report/src/widget/hooks/index.html +1 -1
- package/coverage/lcov-report/src/widget/hooks/useValidator.ts.html +11 -11
- package/coverage/lcov-report/src/widget/index.html +1 -1
- package/coverage/lcov.info +244 -230
- package/lib/cjs/test/ReportAction.test.js +3 -3
- package/lib/cjs/test/ReportAction.test.js.map +1 -1
- package/lib/cjs/test/ReportMappings.test.js +23 -25
- package/lib/cjs/test/ReportMappings.test.js.map +1 -1
- package/lib/cjs/test/Reports.test.js +3 -3
- package/lib/cjs/test/Reports.test.js.map +1 -1
- package/lib/cjs/tsconfig.tsbuildinfo +1 -1
- package/lib/cjs/widget/components/Extraction.js +1 -2
- package/lib/cjs/widget/components/Extraction.js.map +1 -1
- package/lib/cjs/widget/components/Extraction.scss +1 -1
- package/lib/cjs/widget/components/ReportsContainer.d.ts.map +1 -1
- package/lib/cjs/widget/components/ReportsContainer.js +16 -6
- package/lib/cjs/widget/components/ReportsContainer.js.map +1 -1
- package/lib/esm/test/ReportAction.test.js +3 -3
- package/lib/esm/test/ReportAction.test.js.map +1 -1
- package/lib/esm/test/ReportMappings.test.js +23 -25
- package/lib/esm/test/ReportMappings.test.js.map +1 -1
- package/lib/esm/test/Reports.test.js +3 -3
- package/lib/esm/test/Reports.test.js.map +1 -1
- package/lib/esm/tsconfig.tsbuildinfo +1 -1
- package/lib/esm/widget/components/Extraction.js +1 -2
- package/lib/esm/widget/components/Extraction.js.map +1 -1
- package/lib/esm/widget/components/Extraction.scss +1 -1
- package/lib/esm/widget/components/ReportsContainer.d.ts.map +1 -1
- package/lib/esm/widget/components/ReportsContainer.js +16 -6
- package/lib/esm/widget/components/ReportsContainer.js.map +1 -1
- package/package.json +4 -4
- package/reports-config-widget-react.build.error.log +4 -4
- package/reports-config-widget-react.build.log +9 -9
- package/src/test/ReportAction.test.tsx +3 -3
- package/src/test/ReportMappings.test.tsx +25 -30
- package/src/test/Reports.test.tsx +3 -3
- package/src/widget/components/Extraction.scss +1 -1
- package/src/widget/components/Extraction.tsx +2 -2
- package/src/widget/components/ReportsContainer.tsx +25 -15
|
@@ -128,7 +128,6 @@ export const Extraction = ({ iModels, setExtractingIModelId, extractionState, se
|
|
|
128
128
|
return () => window.clearInterval(intervalId.current);
|
|
129
129
|
}, [apiConfig, isRunning, jobId, setExtractionState]);
|
|
130
130
|
const iModelOptions = useMemo(() => {
|
|
131
|
-
// TODO Report ComboBox bug. Unique key error happens when the options list becomes reduced.
|
|
132
131
|
const newIModelOptions = [];
|
|
133
132
|
for (const [iModelId, iModelName] of iModels.entries()) {
|
|
134
133
|
newIModelOptions.push({
|
|
@@ -145,7 +144,7 @@ export const Extraction = ({ iModels, setExtractingIModelId, extractionState, se
|
|
|
145
144
|
React.createElement(Label, { htmlFor: "combo-input" }, ReportsConfigWidget.localization.getLocalizedString("ReportsConfigWidget:UpdateDataset")),
|
|
146
145
|
isLoading ? (React.createElement(SkeletonBlock, null)) : (React.createElement(ComboBox, { options: iModelOptions, value: currentIModelId, onChange: async (value) => {
|
|
147
146
|
setCurrentIModelId(value);
|
|
148
|
-
await runExtraction(value);
|
|
147
|
+
value && await runExtraction(value);
|
|
149
148
|
}, inputProps: {
|
|
150
149
|
id: "combo-input",
|
|
151
150
|
placeholder: ReportsConfigWidget.localization.getLocalizedString("ReportsConfigWidget:SelectIModel"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Extraction.js","sourceRoot":"","sources":["../../../../src/widget/components/Extraction.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { SelectOption } from \"@itwin/itwinui-react\";\nimport {\n ComboBox,\n Label,\n ProgressRadial,\n StatusMessage,\n} from \"@itwin/itwinui-react\";\nimport * as React from \"react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { REPORTING_BASE_PATH, ReportingClient } from \"@itwin/insights-client\";\nimport { generateUrl, handleError, SkeletonBlock } from \"./utils\";\nimport \"./Extraction.scss\";\nimport {\n SvgStatusError,\n SvgStatusPending,\n SvgStatusPendingHollow,\n SvgStatusSuccess,\n} from \"@itwin/itwinui-icons-color-react\";\nimport { useReportsApiConfig } from \"../context/ReportsApiConfigContext\";\nimport { ReportsConfigWidget } from \"../../ReportsConfigWidget\";\n\nexport const REFRESH_DELAY = 2000;\n\nexport enum ExtractionStates {\n None,\n Starting,\n FetchingUpdate,\n Queued,\n Running,\n Succeeded,\n Failed,\n}\ninterface ExtractionStatusProps {\n state: ExtractionStates;\n setExtractionState?: React.Dispatch<React.SetStateAction<ExtractionStates>>;\n children?: React.ReactNode;\n}\n\nexport const ExtractionStatus = ({\n state,\n children,\n setExtractionState,\n}: ExtractionStatusProps) => {\n const [fadeOut, setFadeOut] = useState<boolean>(false);\n\n const onAnimationEnd = () => {\n if (setExtractionState) {\n setExtractionState(ExtractionStates.None);\n setFadeOut(false);\n }\n };\n\n useEffect(() => {\n let timer: number;\n switch (state) {\n case ExtractionStates.Succeeded:\n case ExtractionStates.Failed:\n timer = window.setTimeout(() => setFadeOut(true), 5000);\n }\n return () => clearTimeout(timer);\n }, [state, setExtractionState]);\n\n switch (state) {\n case ExtractionStates.Starting:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Starting\"\n )}\n className=\"extraction-status\"\n >\n <div className=\"status-icon\">\n <SvgStatusPendingHollow />\n </div>\n </div>\n );\n case ExtractionStates.FetchingUpdate:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Loading\"\n )}\n className=\"extraction-status\"\n >\n <ProgressRadial size=\"x-small\" indeterminate />\n </div>\n );\n case ExtractionStates.Queued:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Queued\"\n )}\n className=\"extraction-status\"\n >\n <div className=\"status-icon\">\n <SvgStatusPending />\n </div>\n </div>\n );\n case ExtractionStates.Running:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Running\"\n )}\n className=\"extraction-status\"\n >\n <ProgressRadial size=\"x-small\" indeterminate />\n </div>\n );\n case ExtractionStates.Succeeded:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Success\"\n )}\n className=\"extraction-status\"\n >\n <div\n className={`status-icon`}\n style={{\n animationName: fadeOut ? \"rcw-fade-out\" : \"\",\n animationDelay: \"5s\",\n animationDuration: \"1s\",\n }}\n onAnimationEnd={onAnimationEnd}\n >\n <SvgStatusSuccess />\n </div>\n </div>\n );\n case ExtractionStates.Failed:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Failed\"\n )}\n className=\"extraction-status\"\n >\n <div\n className={`status-icon`}\n style={{\n animationName: fadeOut ? \"rcw-fade-out\" : \"\",\n animationDelay: \"5s\",\n animationDuration: \"1s\",\n }}\n onAnimationEnd={onAnimationEnd}\n >\n <SvgStatusError />\n </div>\n </div>\n );\n default:\n return <>{children}</>;\n }\n};\n\ninterface ExtractionProps {\n iModels: Map<string, string>;\n setExtractingIModelId: React.Dispatch<React.SetStateAction<string>>;\n extractionState: ExtractionStates;\n setExtractionState: React.Dispatch<React.SetStateAction<ExtractionStates>>;\n isLoading: boolean;\n}\n\nexport const Extraction = ({\n iModels,\n setExtractingIModelId,\n extractionState,\n setExtractionState,\n isLoading,\n}: ExtractionProps) => {\n const jobId = useRef<string>(\"\");\n const intervalId = useRef<number>();\n const [isRunning, setIsRunning] = useState<boolean>(false);\n const [currentIModelId, setCurrentIModelId] = useState<string>();\n const apiConfig = useReportsApiConfig();\n\n const runExtraction = async (iModelId: string) => {\n try {\n setExtractionState(ExtractionStates.Starting);\n setExtractingIModelId(iModelId);\n const reportingClientApi = new ReportingClient(\n generateUrl(REPORTING_BASE_PATH, apiConfig.baseUrl)\n );\n const accessToken = await apiConfig.getAccessToken();\n const response = await reportingClientApi.runExtraction(\n accessToken,\n iModelId\n );\n jobId.current = response.run?.id ?? \"\";\n setIsRunning(true);\n setExtractionState(ExtractionStates.FetchingUpdate);\n } catch (error: any) {\n handleError(error.status);\n setExtractionState(ExtractionStates.Failed);\n setIsRunning(false);\n setCurrentIModelId(undefined);\n }\n };\n\n useEffect(() => {\n if (!intervalId.current && isRunning) {\n const newIntervalId = window.setInterval(async () => {\n const reportingClientApi = new ReportingClient(\n generateUrl(REPORTING_BASE_PATH, apiConfig.baseUrl)\n );\n const accessToken = await apiConfig.getAccessToken();\n const response = await reportingClientApi.getExtractionStatus(\n accessToken,\n jobId.current\n );\n if (response.status?.state === \"Queued\") {\n setExtractionState(ExtractionStates.Queued);\n } else if (response.status?.state === \"Running\") {\n setExtractionState(ExtractionStates.Running);\n } else if (response.status?.state === \"Succeeded\") {\n setExtractionState(ExtractionStates.Succeeded);\n setIsRunning(false);\n setCurrentIModelId(undefined);\n } else if (response.status?.state === \"Failed\") {\n setExtractionState(ExtractionStates.Failed);\n setIsRunning(false);\n setCurrentIModelId(undefined);\n }\n }, REFRESH_DELAY);\n intervalId.current = newIntervalId;\n } else if (intervalId && !isRunning) {\n window.clearInterval(intervalId.current);\n intervalId.current = undefined;\n }\n return () => window.clearInterval(intervalId.current);\n }, [apiConfig, isRunning, jobId, setExtractionState]);\n\n const iModelOptions = useMemo(() => {\n // TODO Report ComboBox bug. Unique key error happens when the options list becomes reduced.\n const newIModelOptions: SelectOption<string>[] = [];\n\n for (const [iModelId, iModelName] of iModels.entries()) {\n newIModelOptions.push({\n label: iModelName,\n value: iModelId,\n key: iModelId,\n disabled: extractionState !== ExtractionStates.None,\n });\n }\n return newIModelOptions;\n }, [iModels, extractionState]);\n\n return (\n <div className=\"extraction-container\">\n <div className=\"extraction-combo-box\" data-testid=\"extraction-combo-box\">\n <Label htmlFor=\"combo-input\">\n {ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:UpdateDataset\"\n )}\n </Label>\n {isLoading ? (\n <SkeletonBlock />\n ) : (\n <ComboBox\n options={iModelOptions}\n value={currentIModelId}\n onChange={async (value) => {\n setCurrentIModelId(value);\n await runExtraction(value);\n }}\n inputProps={{\n id: \"combo-input\",\n placeholder: ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:SelectIModel\"\n ),\n }}\n message={\n extractionState !== ExtractionStates.None && (\n <StatusMessage>\n <div className=\"extraction-status-container\">\n <ExtractionStatus\n state={extractionState}\n setExtractionState={setExtractionState}\n />\n {(() => {\n switch (extractionState) {\n case ExtractionStates.Succeeded: {\n return ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Success\"\n );\n }\n case ExtractionStates.Failed: {\n return ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Failed\"\n );\n }\n default: {\n return ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:UpdateInProgress\"\n );\n }\n }\n })()}\n </div>\n </StatusMessage>\n )\n }\n />\n )}\n </div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"Extraction.js","sourceRoot":"","sources":["../../../../src/widget/components/Extraction.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { SelectOption } from \"@itwin/itwinui-react\";\nimport {\n ComboBox,\n Label,\n ProgressRadial,\n StatusMessage,\n} from \"@itwin/itwinui-react\";\nimport * as React from \"react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { REPORTING_BASE_PATH, ReportingClient } from \"@itwin/insights-client\";\nimport { generateUrl, handleError, SkeletonBlock } from \"./utils\";\nimport \"./Extraction.scss\";\nimport {\n SvgStatusError,\n SvgStatusPending,\n SvgStatusPendingHollow,\n SvgStatusSuccess,\n} from \"@itwin/itwinui-icons-color-react\";\nimport { useReportsApiConfig } from \"../context/ReportsApiConfigContext\";\nimport { ReportsConfigWidget } from \"../../ReportsConfigWidget\";\n\nexport const REFRESH_DELAY = 2000;\n\nexport enum ExtractionStates {\n None,\n Starting,\n FetchingUpdate,\n Queued,\n Running,\n Succeeded,\n Failed,\n}\ninterface ExtractionStatusProps {\n state: ExtractionStates;\n setExtractionState?: React.Dispatch<React.SetStateAction<ExtractionStates>>;\n children?: React.ReactNode;\n}\n\nexport const ExtractionStatus = ({\n state,\n children,\n setExtractionState,\n}: ExtractionStatusProps) => {\n const [fadeOut, setFadeOut] = useState<boolean>(false);\n\n const onAnimationEnd = () => {\n if (setExtractionState) {\n setExtractionState(ExtractionStates.None);\n setFadeOut(false);\n }\n };\n\n useEffect(() => {\n let timer: number;\n switch (state) {\n case ExtractionStates.Succeeded:\n case ExtractionStates.Failed:\n timer = window.setTimeout(() => setFadeOut(true), 5000);\n }\n return () => clearTimeout(timer);\n }, [state, setExtractionState]);\n\n switch (state) {\n case ExtractionStates.Starting:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Starting\"\n )}\n className=\"extraction-status\"\n >\n <div className=\"status-icon\">\n <SvgStatusPendingHollow />\n </div>\n </div>\n );\n case ExtractionStates.FetchingUpdate:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Loading\"\n )}\n className=\"extraction-status\"\n >\n <ProgressRadial size=\"x-small\" indeterminate />\n </div>\n );\n case ExtractionStates.Queued:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Queued\"\n )}\n className=\"extraction-status\"\n >\n <div className=\"status-icon\">\n <SvgStatusPending />\n </div>\n </div>\n );\n case ExtractionStates.Running:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Running\"\n )}\n className=\"extraction-status\"\n >\n <ProgressRadial size=\"x-small\" indeterminate />\n </div>\n );\n case ExtractionStates.Succeeded:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Success\"\n )}\n className=\"extraction-status\"\n >\n <div\n className={`status-icon`}\n style={{\n animationName: fadeOut ? \"rcw-fade-out\" : \"\",\n animationDelay: \"5s\",\n animationDuration: \"1s\",\n }}\n onAnimationEnd={onAnimationEnd}\n >\n <SvgStatusSuccess />\n </div>\n </div>\n );\n case ExtractionStates.Failed:\n return (\n <div\n title={ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Failed\"\n )}\n className=\"extraction-status\"\n >\n <div\n className={`status-icon`}\n style={{\n animationName: fadeOut ? \"rcw-fade-out\" : \"\",\n animationDelay: \"5s\",\n animationDuration: \"1s\",\n }}\n onAnimationEnd={onAnimationEnd}\n >\n <SvgStatusError />\n </div>\n </div>\n );\n default:\n return <>{children}</>;\n }\n};\n\ninterface ExtractionProps {\n iModels: Map<string, string>;\n setExtractingIModelId: React.Dispatch<React.SetStateAction<string>>;\n extractionState: ExtractionStates;\n setExtractionState: React.Dispatch<React.SetStateAction<ExtractionStates>>;\n isLoading: boolean;\n}\n\nexport const Extraction = ({\n iModels,\n setExtractingIModelId,\n extractionState,\n setExtractionState,\n isLoading,\n}: ExtractionProps) => {\n const jobId = useRef<string>(\"\");\n const intervalId = useRef<number>();\n const [isRunning, setIsRunning] = useState<boolean>(false);\n const [currentIModelId, setCurrentIModelId] = useState<string>();\n const apiConfig = useReportsApiConfig();\n\n const runExtraction = async (iModelId: string) => {\n try {\n setExtractionState(ExtractionStates.Starting);\n setExtractingIModelId(iModelId);\n const reportingClientApi = new ReportingClient(\n generateUrl(REPORTING_BASE_PATH, apiConfig.baseUrl)\n );\n const accessToken = await apiConfig.getAccessToken();\n const response = await reportingClientApi.runExtraction(\n accessToken,\n iModelId\n );\n jobId.current = response.run?.id ?? \"\";\n setIsRunning(true);\n setExtractionState(ExtractionStates.FetchingUpdate);\n } catch (error: any) {\n handleError(error.status);\n setExtractionState(ExtractionStates.Failed);\n setIsRunning(false);\n setCurrentIModelId(undefined);\n }\n };\n\n useEffect(() => {\n if (!intervalId.current && isRunning) {\n const newIntervalId = window.setInterval(async () => {\n const reportingClientApi = new ReportingClient(\n generateUrl(REPORTING_BASE_PATH, apiConfig.baseUrl)\n );\n const accessToken = await apiConfig.getAccessToken();\n const response = await reportingClientApi.getExtractionStatus(\n accessToken,\n jobId.current\n );\n if (response.status?.state === \"Queued\") {\n setExtractionState(ExtractionStates.Queued);\n } else if (response.status?.state === \"Running\") {\n setExtractionState(ExtractionStates.Running);\n } else if (response.status?.state === \"Succeeded\") {\n setExtractionState(ExtractionStates.Succeeded);\n setIsRunning(false);\n setCurrentIModelId(undefined);\n } else if (response.status?.state === \"Failed\") {\n setExtractionState(ExtractionStates.Failed);\n setIsRunning(false);\n setCurrentIModelId(undefined);\n }\n }, REFRESH_DELAY);\n intervalId.current = newIntervalId;\n } else if (intervalId && !isRunning) {\n window.clearInterval(intervalId.current);\n intervalId.current = undefined;\n }\n return () => window.clearInterval(intervalId.current);\n }, [apiConfig, isRunning, jobId, setExtractionState]);\n\n const iModelOptions = useMemo(() => {\n const newIModelOptions: SelectOption<string>[] = [];\n\n for (const [iModelId, iModelName] of iModels.entries()) {\n newIModelOptions.push({\n label: iModelName,\n value: iModelId,\n key: iModelId,\n disabled: extractionState !== ExtractionStates.None,\n });\n }\n\n return newIModelOptions;\n }, [iModels, extractionState]);\n\n return (\n <div className=\"extraction-container\">\n <div className=\"extraction-combo-box\" data-testid=\"extraction-combo-box\">\n <Label htmlFor=\"combo-input\">\n {ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:UpdateDataset\"\n )}\n </Label>\n {isLoading ? (\n <SkeletonBlock />\n ) : (\n <ComboBox\n options={iModelOptions}\n value={currentIModelId}\n onChange={async (value) => {\n setCurrentIModelId(value);\n value && await runExtraction(value);\n }}\n inputProps={{\n id: \"combo-input\",\n placeholder: ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:SelectIModel\"\n ),\n }}\n message={\n extractionState !== ExtractionStates.None && (\n <StatusMessage>\n <div className=\"extraction-status-container\">\n <ExtractionStatus\n state={extractionState}\n setExtractionState={setExtractionState}\n />\n {(() => {\n switch (extractionState) {\n case ExtractionStates.Succeeded: {\n return ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Success\"\n );\n }\n case ExtractionStates.Failed: {\n return ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:Failed\"\n );\n }\n default: {\n return ReportsConfigWidget.localization.getLocalizedString(\n \"ReportsConfigWidget:UpdateInProgress\"\n );\n }\n }\n })()}\n </div>\n </StatusMessage>\n )\n }\n />\n )}\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportsContainer.d.ts","sourceRoot":"","sources":["../../../../src/widget/components/ReportsContainer.tsx"],"names":[],"mappings":";AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ReportsContainer.d.ts","sourceRoot":"","sources":["../../../../src/widget/components/ReportsContainer.tsx"],"names":[],"mappings":";AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvD,OAAO,yBAAyB,CAAC;AAEjC,UAAU,qBAAqB;IAC7B,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,QAAA,MAAM,gBAAgB,iCAGnB,qBAAqB,gBAoBvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { IModelApp } from "@itwin/core-frontend";
|
|
2
|
-
import
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
3
|
import { Reports } from "../components/Reports";
|
|
4
4
|
import { ReportsApiConfigContext } from "../context/ReportsApiConfigContext";
|
|
5
5
|
import "./ReportsContainer.scss";
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const authorizationClientGetAccessToken = async () => { var _a, _b; return (_b = (await ((_a = IModelApp.authorizationClient) === null || _a === void 0 ? void 0 : _a.getAccessToken()))) !== null && _b !== void 0 ? _b : ""; };
|
|
7
|
+
const ReportsContainer = ({ getAccessToken, baseUrl, }) => {
|
|
8
|
+
const [apiConfig, setApiConfig] = useState({
|
|
9
|
+
getAccessToken: getAccessToken !== null && getAccessToken !== void 0 ? getAccessToken : authorizationClientGetAccessToken,
|
|
8
10
|
baseUrl,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
});
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
setApiConfig(() => ({
|
|
14
|
+
baseUrl,
|
|
15
|
+
getAccessToken: getAccessToken !== null && getAccessToken !== void 0 ? getAccessToken : authorizationClientGetAccessToken,
|
|
16
|
+
}));
|
|
17
|
+
}, [getAccessToken, baseUrl]);
|
|
18
|
+
return (React.createElement(ReportsApiConfigContext.Provider, { value: apiConfig },
|
|
19
|
+
React.createElement("div", { className: "reports-container" },
|
|
20
|
+
React.createElement(Reports, null))));
|
|
21
|
+
};
|
|
12
22
|
export default ReportsContainer;
|
|
13
23
|
//# sourceMappingURL=ReportsContainer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportsContainer.js","sourceRoot":"","sources":["../../../../src/widget/components/ReportsContainer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ReportsContainer.js","sourceRoot":"","sources":["../../../../src/widget/components/ReportsContainer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,yBAAyB,CAAC;AAOjC,MAAM,iCAAiC,GAAG,KAAK,IAAI,EAAE,eACnD,OAAA,MAAA,CAAC,MAAM,CAAA,MAAA,SAAS,CAAC,mBAAmB,0CAAE,cAAc,EAAE,CAAA,CAAC,mCAAI,EAAE,CAAA,EAAA,CAAC;AAEhE,MAAM,gBAAgB,GAAG,CAAC,EACxB,cAAc,EACd,OAAO,GACe,EAAE,EAAE;IAC1B,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAmB;QAC3D,cAAc,EAAE,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,iCAAiC;QACnE,OAAO;KACR,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC;YAClB,OAAO;YACP,cAAc,EAAE,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,iCAAiC;SACpE,CAAC,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IAE9B,OAAO,CACL,oBAAC,uBAAuB,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS;QAChD,6BAAK,SAAS,EAAC,mBAAmB;YAChC,oBAAC,OAAO,OAAG,CACP,CAC2B,CACpC,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { AccessToken } from \"@itwin/core-bentley\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport React, { useEffect, useState } from \"react\";\nimport { Reports } from \"../components/Reports\";\nimport type { ReportsApiConfig } from \"../context/ReportsApiConfigContext\";\nimport { ReportsApiConfigContext } from \"../context/ReportsApiConfigContext\";\nimport \"./ReportsContainer.scss\";\n\ninterface ReportsContainerProps {\n getAccessToken?: () => Promise<AccessToken>;\n baseUrl: string;\n}\n\nconst authorizationClientGetAccessToken = async () =>\n (await IModelApp.authorizationClient?.getAccessToken()) ?? \"\";\n\nconst ReportsContainer = ({\n getAccessToken,\n baseUrl,\n}: ReportsContainerProps) => {\n const [apiConfig, setApiConfig] = useState<ReportsApiConfig>({\n getAccessToken: getAccessToken ?? authorizationClientGetAccessToken,\n baseUrl,\n });\n\n useEffect(() => {\n setApiConfig(() => ({\n baseUrl,\n getAccessToken: getAccessToken ?? authorizationClientGetAccessToken,\n }));\n }, [getAccessToken, baseUrl]);\n\n return (\n <ReportsApiConfigContext.Provider value={apiConfig}>\n <div className=\"reports-container\">\n <Reports />\n </div>\n </ReportsApiConfigContext.Provider>\n );\n};\n\nexport default ReportsContainer;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/reports-config-widget-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "An iTwin.js 3D Viewer Widget that interfaces with the iTwin Reporting Platform.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Bentley",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/imodeljs/viewer-components-react/tree/master/packages/itwin/reports-config-widget
|
|
15
|
+
"url": "https://github.com/imodeljs/viewer-components-react/tree/master/packages/itwin/reports-config-widget"
|
|
16
16
|
},
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"author": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@itwin/insights-client": "^0.2.0",
|
|
40
40
|
"@itwin/itwinui-icons-color-react": "^1.0.1",
|
|
41
41
|
"@itwin/itwinui-icons-react": "^1.7.0",
|
|
42
|
-
"@itwin/itwinui-react": "~1.
|
|
42
|
+
"@itwin/itwinui-react": "~1.42.0",
|
|
43
43
|
"simple-react-validator": "^1.6.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
@@ -120,5 +120,5 @@
|
|
|
120
120
|
"test": "jest",
|
|
121
121
|
"test:watch": "jest --watch "
|
|
122
122
|
},
|
|
123
|
-
"readme": "# @itwin/reports-config-widget-react\r\n\r\nCopyright © Bentley Systems, Incorporated. All rights reserved.\r\nThe Reports Config widget is a UI component for iTwin Viewer applications that simplifies how users (and developers) interface with the [Reporting Platform APIs](https://developer.bentley.com/apis/insights/overview/).\r\nThe reports-config-widget package provides a UiProvider class - `ReportsConfigProvider` - which can be passed into the `uiProviders` prop of the iTwin Viewer's `<Viewer />` component.\r\n\r\n## Getting Started\r\n\r\nThis is not a standalone UI and requires a parent iTwin Viewer application to work as intended.\r\nA guide on how to create a basic iTwin Viewer application can be found here: <https://www.itwinjs.org/learning/tutorials/develop-web-viewer/>.\r\nThis package provides a viewer 'widget'. Documentation on how to add a widget to your application can be found here: <https://developer.bentley.com/tutorials/itwin-viewer-hello-world/#2-your-first-ui-widget>.\r\n\r\n## Permissions and Scopes\r\n\r\nThe SPA client used by your iTwin viewer must have these additional scopes:\r\n\r\n- `insights:read`\r\n- `insights:modify`\r\n- `projects:read`\r\n\r\nIn addition, users must have the `imodels_read` and `imodels_write` [permissions](https://developer.bentley.com/apis/insights/operations/create-mapping/#authorization) assigned at either the Project or iModel level. Further instruction on how to create roles and assign permissions can be found in the [iTwin Platform Projects API documentation](https://developer.bentley.com/apis/projects/tutorials/).\r\n\r\n## Sample usage\r\n\r\n### Call ReportsConfigWidget.initialize() **_before_** making use of the provider\r\n\r\n```ts\r\nimport { ReportsConfigWidget } from '@itwin/reports-config-widget-react'\r\n\r\n...\r\n\r\nawait ReportsConfigWidget.initialize(IModelApp.localization);\r\n\r\n<Viewer\r\n ...\r\n uiProviders={[new ReportsConfigProvider()]}\r\n/>\r\n```\r\n"
|
|
123
|
+
"readme": "# @itwin/reports-config-widget-react\r\n\r\nCopyright © Bentley Systems, Incorporated. All rights reserved.\r\nThe Reports Config widget is a UI component for iTwin Viewer applications that simplifies how users (and developers) interface with the [Reporting Platform APIs](https://developer.bentley.com/apis/insights/overview/). This widget is one piece of the Reporting story that focuses on the configuration of Reports and the extraction thereof. It complements the [Grouping & Mapping Widget](https://www.npmjs.com/package/@itwin/grouping-mapping-widget).\r\nThe reports-config-widget-react package provides a UiProvider class - `ReportsConfigProvider` - which can be passed into the `uiProviders` prop of the iTwin Viewer's `<Viewer />` component.\r\n\r\n## Getting Started\r\n\r\nThis is not a standalone UI and requires a parent iTwin Viewer application to work as intended.\r\nA guide on how to create a basic iTwin Viewer application can be found here: <https://www.itwinjs.org/learning/tutorials/develop-web-viewer/>.\r\nThis package provides a viewer 'widget'. Documentation on how to add a widget to your application can be found here: <https://developer.bentley.com/tutorials/itwin-viewer-hello-world/#2-your-first-ui-widget>.\r\n\r\n## Permissions and Scopes\r\n\r\nThe SPA client used by your iTwin viewer must have these additional scopes:\r\n\r\n- `insights:read`\r\n- `insights:modify`\r\n- `projects:read`\r\n\r\nIn addition, users must have the `imodels_read` and `imodels_write` [permissions](https://developer.bentley.com/apis/insights/operations/create-mapping/#authorization) assigned at either the Project or iModel level. Further instruction on how to create roles and assign permissions can be found in the [iTwin Platform Projects API documentation](https://developer.bentley.com/apis/projects/tutorials/).\r\n\r\n## Sample usage\r\n\r\n### Call ReportsConfigWidget.initialize() **_before_** making use of the provider\r\n\r\n```ts\r\nimport { ReportsConfigProvider, ReportsConfigWidget } from '@itwin/reports-config-widget-react'\r\n\r\n...\r\n\r\nawait ReportsConfigWidget.initialize(IModelApp.localization);\r\n\r\n<Viewer\r\n ...\r\n uiProviders={[new ReportsConfigProvider()]}\r\n/>\r\n```\r\n"
|
|
124
124
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
PASS src/test/ReportMappings.test.tsx (
|
|
2
|
-
PASS src/test/Reports.test.tsx (
|
|
3
|
-
PASS src/test/ReportAction.test.tsx
|
|
1
|
+
PASS src/test/ReportMappings.test.tsx (33.455 s)
|
|
2
|
+
PASS src/test/Reports.test.tsx (7.981 s)
|
|
3
|
+
PASS src/test/ReportAction.test.tsx
|
|
4
4
|
PASS src/test/WidgetHeader.test.tsx
|
|
5
5
|
|
|
6
6
|
Test Suites: 4 passed, 4 total
|
|
7
7
|
Tests: 22 passed, 22 total
|
|
8
8
|
Snapshots: 0 total
|
|
9
|
-
Time:
|
|
9
|
+
Time: 49.335 s
|
|
10
10
|
Ran all test suites.
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
Invoking: npm test -- --coverage
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
> @itwin/reports-config-widget-react@0.0.
|
|
4
|
+
> @itwin/reports-config-widget-react@0.0.3 test /home/vsts/work/1/s/packages/itwin/reports-config-widget
|
|
5
5
|
> jest "--coverage"
|
|
6
6
|
|
|
7
|
-
PASS src/test/ReportMappings.test.tsx (
|
|
8
|
-
PASS src/test/Reports.test.tsx (
|
|
9
|
-
PASS src/test/ReportAction.test.tsx
|
|
7
|
+
PASS src/test/ReportMappings.test.tsx (33.455 s)
|
|
8
|
+
PASS src/test/Reports.test.tsx (7.981 s)
|
|
9
|
+
PASS src/test/ReportAction.test.tsx
|
|
10
10
|
PASS src/test/WidgetHeader.test.tsx
|
|
11
11
|
------------------------------|---------|----------|---------|---------|-------------------------------
|
|
12
12
|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
13
13
|
------------------------------|---------|----------|---------|---------|-------------------------------
|
|
14
|
-
All files | 87.
|
|
14
|
+
All files | 87.12 | 69.64 | 84.87 | 87.17 |
|
|
15
15
|
src | 100 | 75 | 100 | 100 |
|
|
16
16
|
ReportsConfigWidget.ts | 100 | 75 | 100 | 100 | 21
|
|
17
17
|
src/test | 100 | 66.66 | 100 | 100 |
|
|
18
18
|
test-utils.tsx | 100 | 66.66 | 100 | 100 | 56
|
|
19
19
|
src/widget | 40 | 0 | 0 | 40 |
|
|
20
20
|
ReportsConfigUiProvider.tsx | 40 | 0 | 0 | 40 | 23-65
|
|
21
|
-
src/widget/components |
|
|
21
|
+
src/widget/components | 87.42 | 70.8 | 85.85 | 87.58 |
|
|
22
22
|
ActionPanel.tsx | 100 | 77.77 | 100 | 100 | 25-26
|
|
23
23
|
AddMappingsModal.tsx | 91.66 | 80 | 88.88 | 93.47 | 40,120,134
|
|
24
24
|
DeleteModal.tsx | 85 | 100 | 50 | 84.21 | 42,56-87
|
|
25
|
-
Extraction.tsx | 85.41 |
|
|
25
|
+
Extraction.tsx | 85.41 | 73.01 | 85.71 | 85.71 | 51-53,138,200-203,226-229,295
|
|
26
26
|
HorizontalTile.tsx | 100 | 100 | 100 | 100 |
|
|
27
27
|
LocalizedTablePaginator.tsx | 100 | 50 | 100 | 100 | 25
|
|
28
28
|
ReportAction.tsx | 94.28 | 81.48 | 100 | 94.28 | 59-60
|
|
29
29
|
ReportMappings.tsx | 96.29 | 74.41 | 94.44 | 96.25 | 97,119,268
|
|
30
30
|
Reports.tsx | 97.14 | 78.68 | 100 | 98.52 | 65
|
|
31
|
-
ReportsContainer.tsx |
|
|
31
|
+
ReportsContainer.tsx | 57.14 | 0 | 0 | 61.53 | 19,25-37
|
|
32
32
|
SearchBar.tsx | 70.58 | 71.42 | 60 | 68.75 | 31-45
|
|
33
33
|
SelectIModel.tsx | 97.05 | 81.81 | 85.71 | 96.87 | 92
|
|
34
34
|
utils.tsx | 56.86 | 23.07 | 87.5 | 48.83 | 46-100
|
|
@@ -41,5 +41,5 @@ All files | 87.72 | 70.3 | 86.32 | 87.64 |
|
|
|
41
41
|
Test Suites: 4 passed, 4 total
|
|
42
42
|
Tests: 22 passed, 22 total
|
|
43
43
|
Snapshots: 0 total
|
|
44
|
-
Time:
|
|
44
|
+
Time: 49.335 s
|
|
45
45
|
Ran all test suites.
|
|
@@ -113,7 +113,7 @@ describe("Reports Action", () => {
|
|
|
113
113
|
it("should be able to add report", async () => {
|
|
114
114
|
const mockReport: Report = {
|
|
115
115
|
id: faker.datatype.uuid(),
|
|
116
|
-
displayName:
|
|
116
|
+
displayName: "mOcKRePoRt1",
|
|
117
117
|
description: "",
|
|
118
118
|
deleted: false,
|
|
119
119
|
_links: {
|
|
@@ -150,8 +150,8 @@ describe("Reports Action", () => {
|
|
|
150
150
|
name: /description/i,
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
-
await userEvent.type(nameInput,
|
|
154
|
-
await userEvent.type(descriptionInput,
|
|
153
|
+
await userEvent.type(nameInput, "mOcKTeXt");
|
|
154
|
+
await userEvent.type(descriptionInput, "moCk DeScRiPtIoN");
|
|
155
155
|
expect(cancelButton).toBeEnabled();
|
|
156
156
|
expect(addButton).toBeEnabled();
|
|
157
157
|
|
|
@@ -60,9 +60,9 @@ const mockIModelsResponse = [
|
|
|
60
60
|
{
|
|
61
61
|
iModel: {
|
|
62
62
|
id: mockIModelId1,
|
|
63
|
-
displayName:
|
|
64
|
-
name:
|
|
65
|
-
description:
|
|
63
|
+
displayName: "rAnDoMdIsPlAynAmE1",
|
|
64
|
+
name: "rAnDomName1",
|
|
65
|
+
description: "rAnDoMDeScRiPtIoN1",
|
|
66
66
|
createdDateTime: "2021-10-04T22:13:50.397Z",
|
|
67
67
|
state: IModelState.Initialized,
|
|
68
68
|
projectId: mockITwinId,
|
|
@@ -83,9 +83,9 @@ const mockIModelsResponse = [
|
|
|
83
83
|
{
|
|
84
84
|
iModel: {
|
|
85
85
|
id: mockIModelId2,
|
|
86
|
-
displayName:
|
|
87
|
-
name:
|
|
88
|
-
description:
|
|
86
|
+
displayName: "rAnDoMdIsPlAynAmE2",
|
|
87
|
+
name: "rAnDomName2",
|
|
88
|
+
description: "rAnDoMDeScRiPtIoN2",
|
|
89
89
|
createdDateTime: "2021-10-04T22:13:50.397Z",
|
|
90
90
|
state: IModelState.Initialized,
|
|
91
91
|
projectId: mockITwinId,
|
|
@@ -121,8 +121,8 @@ const mockProjectIModels = {
|
|
|
121
121
|
|
|
122
122
|
const mockReport: Report = {
|
|
123
123
|
id: mockReportId,
|
|
124
|
-
displayName:
|
|
125
|
-
description:
|
|
124
|
+
displayName: "mOcKRePoRt1",
|
|
125
|
+
description: "mOcKRePoRtDeScRiPtIoN1",
|
|
126
126
|
deleted: false,
|
|
127
127
|
_links: {
|
|
128
128
|
project: {
|
|
@@ -180,11 +180,11 @@ const mockMappingsFactory = (
|
|
|
180
180
|
mockReportMappings: ReportMappingCollection
|
|
181
181
|
): [MappingSingle[], RequestHandler[]] => {
|
|
182
182
|
const mockMappings: MappingSingle[] = mockReportMappings.mappings!.map(
|
|
183
|
-
(mapping) => ({
|
|
183
|
+
(mapping, index) => ({
|
|
184
184
|
mapping: {
|
|
185
185
|
id: mapping.mappingId,
|
|
186
|
-
mappingName:
|
|
187
|
-
description:
|
|
186
|
+
mappingName: `mOcKMaPpIngNaMe${index}`,
|
|
187
|
+
description: `mOcKmApPInGDeScRiPtIoN${index}`,
|
|
188
188
|
extractionEnabled: false,
|
|
189
189
|
createdOn: "",
|
|
190
190
|
createdBy: "",
|
|
@@ -202,8 +202,7 @@ const mockMappingsFactory = (
|
|
|
202
202
|
|
|
203
203
|
const iModelHandlers: RequestHandler[] = mockMappings.map((mapping) =>
|
|
204
204
|
rest.get(
|
|
205
|
-
`${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/imodels/${
|
|
206
|
-
mapping.mapping?._links?.imodel?.href ?? ""
|
|
205
|
+
`${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/imodels/${mapping.mapping?._links?.imodel?.href ?? ""
|
|
207
206
|
}/mappings/${mapping.mapping?.id}`,
|
|
208
207
|
async (_req, res, ctx) => {
|
|
209
208
|
return res(ctx.delay(), ctx.status(200), ctx.json(mapping));
|
|
@@ -456,8 +455,7 @@ describe("Report Mappings View", () => {
|
|
|
456
455
|
),
|
|
457
456
|
...iModelHandlers,
|
|
458
457
|
rest.delete(
|
|
459
|
-
`${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings/${
|
|
460
|
-
mockReportMappings.mappings![0].mappingId ?? ""
|
|
458
|
+
`${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings/${mockReportMappings.mappings![0].mappingId ?? ""
|
|
461
459
|
}`,
|
|
462
460
|
async (_req, res, ctx) => {
|
|
463
461
|
mockReportMappings.mappings = mockReportMappings.mappings!.filter(
|
|
@@ -509,13 +507,14 @@ describe("Report Mappings View", () => {
|
|
|
509
507
|
|
|
510
508
|
// Adding an extra unmapped mapping.
|
|
511
509
|
const extraMappingId = faker.datatype.uuid();
|
|
512
|
-
const extraMappingName =
|
|
510
|
+
const extraMappingName = "mOcKNaMeExTrA";
|
|
511
|
+
const extraMappingDescription = "mOcKDeScRiPtIoNeXtRa";
|
|
513
512
|
|
|
514
513
|
mockMappings.push({
|
|
515
514
|
mapping: {
|
|
516
515
|
id: extraMappingId,
|
|
517
516
|
mappingName: extraMappingName,
|
|
518
|
-
description:
|
|
517
|
+
description: extraMappingDescription,
|
|
519
518
|
extractionEnabled: false,
|
|
520
519
|
createdOn: "",
|
|
521
520
|
createdBy: "",
|
|
@@ -631,30 +630,25 @@ describe("Report Mappings View", () => {
|
|
|
631
630
|
for (let i = 0; i < mockMappings.length - 1; i++) {
|
|
632
631
|
const row = screen.getByRole("row", {
|
|
633
632
|
name: new RegExp(
|
|
634
|
-
|
|
633
|
+
`${mockMappings[i].mapping?.mappingName} ${mockMappings[i].mapping?.description}`,
|
|
635
634
|
"i"
|
|
636
635
|
),
|
|
637
636
|
});
|
|
638
637
|
|
|
639
|
-
const checkbox = within(row).getByRole("checkbox"
|
|
640
|
-
name: /toggle row selected/i,
|
|
641
|
-
});
|
|
638
|
+
const checkbox = within(row).getByRole("checkbox");
|
|
642
639
|
expect(checkbox).toBeDisabled();
|
|
643
640
|
}
|
|
644
641
|
|
|
645
642
|
// Click on checkbox on new mapping
|
|
646
643
|
const unmappedRow = screen.getByRole("row", {
|
|
647
644
|
name: new RegExp(
|
|
648
|
-
|
|
649
|
-
mockMappings[mockMappings.length - 1].mapping?.mappingName
|
|
645
|
+
`${mockMappings[mockMappings.length - 1].mapping?.mappingName
|
|
650
646
|
} ${mockMappings[mockMappings.length - 1].mapping?.description}`,
|
|
651
647
|
"i"
|
|
652
648
|
),
|
|
653
649
|
});
|
|
654
650
|
|
|
655
|
-
const enabledCheckbox = within(unmappedRow).getByRole("checkbox"
|
|
656
|
-
name: /toggle row selected/i,
|
|
657
|
-
});
|
|
651
|
+
const enabledCheckbox = within(unmappedRow).getByRole("checkbox");
|
|
658
652
|
|
|
659
653
|
await user.click(enabledCheckbox);
|
|
660
654
|
|
|
@@ -732,7 +726,7 @@ describe("Report Mappings View", () => {
|
|
|
732
726
|
const mockReportMappings = mockReportMappingsFactory();
|
|
733
727
|
const [_, iModelHandlers] = mockMappingsFactory(mockReportMappings);
|
|
734
728
|
|
|
735
|
-
const delay = REFRESH_DELAY;
|
|
729
|
+
const delay = REFRESH_DELAY + 1000;
|
|
736
730
|
|
|
737
731
|
// Faking timers currently makes all promise based queries from RTL become unpredictable.
|
|
738
732
|
// https://github.com/testing-library/dom-testing-library/issues/988
|
|
@@ -799,7 +793,7 @@ describe("Report Mappings View", () => {
|
|
|
799
793
|
`${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/imodels/${mockIModel.id}/extraction/run`,
|
|
800
794
|
async (_req, res, ctx) => {
|
|
801
795
|
return res(
|
|
802
|
-
ctx.delay(),
|
|
796
|
+
ctx.delay(800),
|
|
803
797
|
ctx.status(200),
|
|
804
798
|
ctx.json(mockExtractionResponse)
|
|
805
799
|
);
|
|
@@ -829,7 +823,7 @@ describe("Report Mappings View", () => {
|
|
|
829
823
|
});
|
|
830
824
|
await user.type(comboBox, mockIModel.displayName);
|
|
831
825
|
|
|
832
|
-
const option = screen.getByRole("
|
|
826
|
+
const option = screen.getByRole("menuitem", {
|
|
833
827
|
name: mockIModel.displayName,
|
|
834
828
|
});
|
|
835
829
|
|
|
@@ -842,7 +836,8 @@ describe("Report Mappings View", () => {
|
|
|
842
836
|
).toBeInTheDocument();
|
|
843
837
|
// Should be two in the document. One in the status and the other in the list.
|
|
844
838
|
// TODO Assert that it is in the correct HorizontalTile
|
|
845
|
-
|
|
839
|
+
const startingStates = await screen.findAllByTitle(/starting/i);
|
|
840
|
+
expect(startingStates).toHaveLength(2);
|
|
846
841
|
|
|
847
842
|
const loadingStates = await screen.findAllByTitle(/loading/i);
|
|
848
843
|
expect(loadingStates).toHaveLength(2);
|
|
@@ -42,10 +42,10 @@ const mockIModelId = faker.datatype.uuid();
|
|
|
42
42
|
const reportsFactory = (): ReportCollection => ({
|
|
43
43
|
reports: Array.from(
|
|
44
44
|
{ length: faker.datatype.number({ min: 3, max: 5 }) },
|
|
45
|
-
() => ({
|
|
45
|
+
(_, index) => ({
|
|
46
46
|
id: `${faker.datatype.uuid()}`,
|
|
47
|
-
displayName:
|
|
48
|
-
description:
|
|
47
|
+
displayName: `mOcKRePoRT${index}`,
|
|
48
|
+
description: `mOcKRePoRTDeScRiPtIoN${index}`,
|
|
49
49
|
})
|
|
50
50
|
),
|
|
51
51
|
_links: {
|
|
@@ -238,7 +238,6 @@ export const Extraction = ({
|
|
|
238
238
|
}, [apiConfig, isRunning, jobId, setExtractionState]);
|
|
239
239
|
|
|
240
240
|
const iModelOptions = useMemo(() => {
|
|
241
|
-
// TODO Report ComboBox bug. Unique key error happens when the options list becomes reduced.
|
|
242
241
|
const newIModelOptions: SelectOption<string>[] = [];
|
|
243
242
|
|
|
244
243
|
for (const [iModelId, iModelName] of iModels.entries()) {
|
|
@@ -249,6 +248,7 @@ export const Extraction = ({
|
|
|
249
248
|
disabled: extractionState !== ExtractionStates.None,
|
|
250
249
|
});
|
|
251
250
|
}
|
|
251
|
+
|
|
252
252
|
return newIModelOptions;
|
|
253
253
|
}, [iModels, extractionState]);
|
|
254
254
|
|
|
@@ -268,7 +268,7 @@ export const Extraction = ({
|
|
|
268
268
|
value={currentIModelId}
|
|
269
269
|
onChange={async (value) => {
|
|
270
270
|
setCurrentIModelId(value);
|
|
271
|
-
await runExtraction(value);
|
|
271
|
+
value && await runExtraction(value);
|
|
272
272
|
}}
|
|
273
273
|
inputProps={{
|
|
274
274
|
id: "combo-input",
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import type { AccessToken } from "@itwin/core-bentley";
|
|
6
6
|
import { IModelApp } from "@itwin/core-frontend";
|
|
7
|
-
import
|
|
7
|
+
import React, { useEffect, useState } from "react";
|
|
8
8
|
import { Reports } from "../components/Reports";
|
|
9
|
+
import type { ReportsApiConfig } from "../context/ReportsApiConfigContext";
|
|
9
10
|
import { ReportsApiConfigContext } from "../context/ReportsApiConfigContext";
|
|
10
11
|
import "./ReportsContainer.scss";
|
|
11
12
|
|
|
@@ -14,23 +15,32 @@ interface ReportsContainerProps {
|
|
|
14
15
|
baseUrl: string;
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
const authorizationClientGetAccessToken = async () =>
|
|
19
|
+
(await IModelApp.authorizationClient?.getAccessToken()) ?? "";
|
|
20
|
+
|
|
17
21
|
const ReportsContainer = ({
|
|
18
22
|
getAccessToken,
|
|
19
23
|
baseUrl,
|
|
20
|
-
}: ReportsContainerProps) =>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
}: ReportsContainerProps) => {
|
|
25
|
+
const [apiConfig, setApiConfig] = useState<ReportsApiConfig>({
|
|
26
|
+
getAccessToken: getAccessToken ?? authorizationClientGetAccessToken,
|
|
27
|
+
baseUrl,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setApiConfig(() => ({
|
|
27
32
|
baseUrl,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
getAccessToken: getAccessToken ?? authorizationClientGetAccessToken,
|
|
34
|
+
}));
|
|
35
|
+
}, [getAccessToken, baseUrl]);
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<ReportsApiConfigContext.Provider value={apiConfig}>
|
|
39
|
+
<div className="reports-container">
|
|
40
|
+
<Reports />
|
|
41
|
+
</div>
|
|
42
|
+
</ReportsApiConfigContext.Provider>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
35
45
|
|
|
36
46
|
export default ReportsContainer;
|