orc-shared 1.5.0-dev.9 → 1.5.1-dev.2
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/dist/actions/navigation.js +16 -1
- package/dist/actions/requestsApi.js +1 -0
- package/dist/actions/tasks.js +190 -0
- package/dist/buildStore.js +3 -1
- package/dist/components/AppFrame/Sidebar.js +4 -8
- package/dist/components/CategoryList.js +6 -0
- package/dist/components/MaterialUI/DataDisplay/PredefinedElements/DiscountedPrice.js +1 -0
- package/dist/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.js +13 -5
- package/dist/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +4 -2
- package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +43 -46
- package/dist/components/MaterialUI/hocs/withDeferredTooltip.js +3 -2
- package/dist/components/Navigation/index.js +0 -1
- package/dist/components/Routing/Page.js +4 -1
- package/dist/components/Routing/SegmentPage.js +4 -1
- package/dist/components/Routing/SubPage.js +5 -6
- package/dist/components/Routing/withWaypointing.js +1 -1
- package/dist/components/TaskDetailsModal.js +193 -0
- package/dist/constants.js +16 -1
- package/dist/reducers/navigation.js +16 -0
- package/dist/reducers/request.js +4 -0
- package/dist/reducers/tasks.js +99 -0
- package/dist/selectors/authentication.js +17 -1
- package/dist/selectors/tasks.js +66 -0
- package/dist/sharedMessages.js +17 -1
- package/dist/utils/propertyHelper.js +35 -0
- package/dist/whyDidYouRerender.js +1 -0
- package/package.json +5 -5
- package/src/actions/navigation.js +7 -0
- package/src/actions/navigation.test.js +12 -0
- package/src/actions/tasks.js +77 -0
- package/src/actions/tasks.test.js +169 -0
- package/src/buildStore.js +2 -0
- package/src/components/AppFrame/About.test.js +3 -3
- package/src/components/AppFrame/Sidebar.js +4 -3
- package/src/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.js +15 -3
- package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +2 -1
- package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +39 -27
- package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.test.js +39 -34
- package/src/components/MaterialUI/hocs/withDeferredTooltip.js +2 -1
- package/src/components/MaterialUI/hocs/withDeferredTooltip.test.js +52 -0
- package/src/components/Routing/Page.js +12 -1
- package/src/components/Routing/SegmentPage.js +12 -1
- package/src/components/Routing/SubPage.js +4 -7
- package/src/components/Routing/SubPage.test.js +46 -0
- package/src/components/TaskDetailsModal.js +132 -0
- package/src/components/TaskDetailsModal.test.js +317 -0
- package/src/components/Text.test.js +44 -59
- package/src/constants.js +13 -0
- package/src/hooks/useLabelMessage.test.js +16 -10
- package/src/reducers/navigation.js +24 -0
- package/src/reducers/navigation.test.js +38 -0
- package/src/reducers/request.js +4 -0
- package/src/reducers/request.test.js +11 -0
- package/src/reducers/tasks.js +56 -0
- package/src/reducers/tasks.test.js +404 -0
- package/src/selectors/authentication.js +13 -0
- package/src/selectors/authentication.test.js +322 -0
- package/src/selectors/tasks.js +16 -0
- package/src/selectors/tasks.test.js +60 -0
- package/src/sharedMessages.js +17 -1
- package/src/translations/en-US.json +16 -12
- package/src/translations/fr-CA.json +16 -12
- package/src/utils/propertyHelper.js +38 -0
- package/src/utils/propertyHelper.test.js +160 -0
- package/src/utils/timezoneHelper.test.js +4 -2
|
@@ -155,4 +155,56 @@ describe("withDeferredTooltip", () => {
|
|
|
155
155
|
|
|
156
156
|
expect(wrapper.prop("onMouseEnter"), "to be", undefined);
|
|
157
157
|
});
|
|
158
|
+
|
|
159
|
+
it("Always displays passed title in tooltip with tooltip classes when specified", () => {
|
|
160
|
+
const Wrapper = props => <ComponentToBeTooltipped {...props} />;
|
|
161
|
+
|
|
162
|
+
const TooltippedCompponent = withDeferredTooltip(Wrapper);
|
|
163
|
+
|
|
164
|
+
const mountedTooltippedComponent = shallow(
|
|
165
|
+
<TooltippedCompponent alwaysDisplay titleValue="test" tooltipClasses={{ classTest: "testMyMojo" }} />,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const event = {
|
|
169
|
+
target: {
|
|
170
|
+
offsetWidth: 100,
|
|
171
|
+
scrollWidth: 100,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
mountedTooltippedComponent.find(Wrapper).invoke("onMouseEnter")(event);
|
|
176
|
+
|
|
177
|
+
let expected = (
|
|
178
|
+
<MuiTooltip title="test" classes={{ classTest: "testMyMojo" }}>
|
|
179
|
+
<Wrapper />
|
|
180
|
+
</MuiTooltip>
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
expect(mountedTooltippedComponent.containsMatchingElement(expected), "to be true");
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("Always displays passed title in tooltip without tooltip classes when not specified", () => {
|
|
187
|
+
const Wrapper = props => <ComponentToBeTooltipped {...props} />;
|
|
188
|
+
|
|
189
|
+
const TooltippedCompponent = withDeferredTooltip(Wrapper);
|
|
190
|
+
|
|
191
|
+
const mountedTooltippedComponent = shallow(<TooltippedCompponent alwaysDisplay titleValue="test" />);
|
|
192
|
+
|
|
193
|
+
const event = {
|
|
194
|
+
target: {
|
|
195
|
+
offsetWidth: 100,
|
|
196
|
+
scrollWidth: 100,
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
mountedTooltippedComponent.find(Wrapper).invoke("onMouseEnter")(event);
|
|
201
|
+
|
|
202
|
+
let expected = (
|
|
203
|
+
<MuiTooltip title="test" classes={null}>
|
|
204
|
+
<Wrapper />
|
|
205
|
+
</MuiTooltip>
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
expect(mountedTooltippedComponent.containsMatchingElement(expected), "to be true");
|
|
209
|
+
});
|
|
158
210
|
});
|
|
@@ -4,9 +4,12 @@ import withErrorBoundary from "../../hocs/withErrorBoundary";
|
|
|
4
4
|
import FullPage from "./FullPage";
|
|
5
5
|
import SubPage from "./SubPage";
|
|
6
6
|
import withWaypointing from "./withWaypointing";
|
|
7
|
+
import UrlPattern from "url-pattern";
|
|
7
8
|
|
|
8
9
|
const Page = ({ component: View, path, pages = {}, subpages = {}, modulePrependPath, isVisible = true }) => {
|
|
9
10
|
const WrappedView = useMemo(() => withErrorBoundary(path)(withWaypointing(View, isVisible)), [path, View, isVisible]);
|
|
11
|
+
const parentUrlPattern = new UrlPattern(path);
|
|
12
|
+
|
|
10
13
|
return (
|
|
11
14
|
<React.Fragment>
|
|
12
15
|
<Switch>
|
|
@@ -38,7 +41,15 @@ const Page = ({ component: View, path, pages = {}, subpages = {}, modulePrependP
|
|
|
38
41
|
<Route
|
|
39
42
|
key={subpath}
|
|
40
43
|
path={path + subpath}
|
|
41
|
-
render={route =>
|
|
44
|
+
render={route => (
|
|
45
|
+
<SubPage
|
|
46
|
+
root={path}
|
|
47
|
+
config={config}
|
|
48
|
+
parentUrlPattern={parentUrlPattern}
|
|
49
|
+
{...route}
|
|
50
|
+
modulePrependPath={modulePrependPath}
|
|
51
|
+
/>
|
|
52
|
+
)}
|
|
42
53
|
/>
|
|
43
54
|
))}
|
|
44
55
|
</Switch>
|
|
@@ -197,6 +197,9 @@ const SegmentPage = ({
|
|
|
197
197
|
);
|
|
198
198
|
}
|
|
199
199
|
if (config.subpages) {
|
|
200
|
+
const parentUrl = path + segpath;
|
|
201
|
+
const parentUrlPattern = new UrlPattern(parentUrl);
|
|
202
|
+
|
|
200
203
|
subpages.push(
|
|
201
204
|
...Object.entries(config.subpages).map(([subpath, config]) => {
|
|
202
205
|
const pagePath = segpath + subpath;
|
|
@@ -204,7 +207,15 @@ const SegmentPage = ({
|
|
|
204
207
|
<Route
|
|
205
208
|
key={pagePath}
|
|
206
209
|
path={path + pagePath}
|
|
207
|
-
render={route =>
|
|
210
|
+
render={route => (
|
|
211
|
+
<SubPage
|
|
212
|
+
root={path}
|
|
213
|
+
config={config}
|
|
214
|
+
parentUrlPattern={parentUrlPattern}
|
|
215
|
+
{...route}
|
|
216
|
+
modulePrependPath={modulePrependPath}
|
|
217
|
+
/>
|
|
218
|
+
)}
|
|
208
219
|
/>
|
|
209
220
|
);
|
|
210
221
|
}),
|
|
@@ -20,22 +20,19 @@ const useStyles = makeStyles(theme => ({
|
|
|
20
20
|
},
|
|
21
21
|
}));
|
|
22
22
|
|
|
23
|
-
export const SubPage = ({ config, match, location, history, root, modulePrependPath }) => {
|
|
23
|
+
export const SubPage = ({ config, match, location, history, root, modulePrependPath, parentUrlPattern }) => {
|
|
24
24
|
const classes = useStyles();
|
|
25
25
|
const dispatch = useDispatch();
|
|
26
26
|
let { component: View, ...props } = config;
|
|
27
27
|
const pattern = new UrlPattern(root);
|
|
28
28
|
const baseHref = pattern.stringify(match.params);
|
|
29
|
-
|
|
30
29
|
const path = location.pathname;
|
|
31
30
|
|
|
32
|
-
const basePathArr = path.split("/");
|
|
33
|
-
basePathArr.pop();
|
|
34
|
-
const basePath = basePathArr.join("/");
|
|
35
31
|
const WrappedView = useMemo(() => withErrorBoundary(path)(withWaypointing(View)), [path, View]);
|
|
36
32
|
const closeSubPage = () => {
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
const parentHref = parentUrlPattern.stringify(match.params);
|
|
34
|
+
history.push(parentHref);
|
|
35
|
+
dispatch(mapHref(parentHref, parentHref));
|
|
39
36
|
};
|
|
40
37
|
|
|
41
38
|
const message = (
|
|
@@ -13,6 +13,7 @@ import Button from "@material-ui/core/Button";
|
|
|
13
13
|
import translations from "~/translations/en-US.json";
|
|
14
14
|
import { TestWrapper, createMuiTheme } from "../../utils/testUtils";
|
|
15
15
|
import sharedMessages from "../../sharedMessages";
|
|
16
|
+
import UrlPattern from "url-pattern";
|
|
16
17
|
|
|
17
18
|
const InnerView = ({ theme, pathname, search, mapFrom, match, location, routeIsAligned, set }) => (
|
|
18
19
|
<PropStruct
|
|
@@ -92,6 +93,7 @@ describe("SubPage", () => {
|
|
|
92
93
|
config={{ component: InnerView, set: true, title: "Item Details" }}
|
|
93
94
|
root="/foo"
|
|
94
95
|
path="/foo/bar"
|
|
96
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
95
97
|
{...route}
|
|
96
98
|
/>
|
|
97
99
|
)}
|
|
@@ -140,6 +142,7 @@ describe("SubPage", () => {
|
|
|
140
142
|
config={{ component: InnerView, set: true, title: sharedMessages.confirmation }}
|
|
141
143
|
root="/foo"
|
|
142
144
|
path="/foo/bar"
|
|
145
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
143
146
|
{...route}
|
|
144
147
|
/>
|
|
145
148
|
)}
|
|
@@ -164,6 +167,7 @@ describe("SubPage", () => {
|
|
|
164
167
|
config={{ component: InnerView, set: true, title: "Item Details" }}
|
|
165
168
|
root="/foo"
|
|
166
169
|
path="/foo/bar"
|
|
170
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
167
171
|
{...route}
|
|
168
172
|
/>
|
|
169
173
|
)}
|
|
@@ -180,6 +184,42 @@ describe("SubPage", () => {
|
|
|
180
184
|
expect(history.push, "to have calls satisfying", [{ args: ["/foo"] }]);
|
|
181
185
|
expect(dispatch, "to have calls satisfying", [{ args: [mapHref("/foo", "/foo")] }]);
|
|
182
186
|
});
|
|
187
|
+
it("closing the dialog navigate to the parentUrlPattern with parameters", () => {
|
|
188
|
+
history = createMemoryHistory({ initialEntries: ["/foo/bar/123/456"] });
|
|
189
|
+
sinon.spy(history, "push");
|
|
190
|
+
history.push.named("history.push");
|
|
191
|
+
dispatch.resetHistory();
|
|
192
|
+
|
|
193
|
+
const component = (
|
|
194
|
+
<TestWrapper provider={{ store }} intlProvider={intlProvider} stylesProvider muiThemeProvider={{ theme }}>
|
|
195
|
+
<div>
|
|
196
|
+
<div id="outer" />
|
|
197
|
+
<Router history={history}>
|
|
198
|
+
<Route
|
|
199
|
+
path="/foo/bar/:parentId/:id"
|
|
200
|
+
render={route => (
|
|
201
|
+
<SubPage
|
|
202
|
+
config={{ component: InnerView, set: true, title: "Item Details" }}
|
|
203
|
+
root="/foo/bar/:parentId/:id"
|
|
204
|
+
path="/foo/bar/123/456"
|
|
205
|
+
parentUrlPattern={new UrlPattern("/foo/bar/:parentId")}
|
|
206
|
+
{...route}
|
|
207
|
+
/>
|
|
208
|
+
)}
|
|
209
|
+
/>
|
|
210
|
+
</Router>
|
|
211
|
+
</div>
|
|
212
|
+
</TestWrapper>
|
|
213
|
+
);
|
|
214
|
+
const mountedComponent = mount(component);
|
|
215
|
+
|
|
216
|
+
const closeButton = mountedComponent.find("button").at(0);
|
|
217
|
+
|
|
218
|
+
closeButton.invoke("onClick")();
|
|
219
|
+
expect(history.push, "to have calls satisfying", [{ args: ["/foo/bar/123"] }]);
|
|
220
|
+
expect(dispatch, "to have a call satisfying", { args: [mapHref("/foo/bar/123", "/foo/bar/123")] });
|
|
221
|
+
});
|
|
222
|
+
|
|
183
223
|
it("renders action panel passed from props", () => {
|
|
184
224
|
const actions = () => [{ label: sharedMessages.cancel }, { label: sharedMessages.applyChanges }];
|
|
185
225
|
|
|
@@ -200,6 +240,7 @@ describe("SubPage", () => {
|
|
|
200
240
|
}}
|
|
201
241
|
root="/foo"
|
|
202
242
|
path="/foo/bar"
|
|
243
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
203
244
|
{...route}
|
|
204
245
|
/>
|
|
205
246
|
)}
|
|
@@ -242,6 +283,7 @@ describe("SubPage", () => {
|
|
|
242
283
|
}}
|
|
243
284
|
root="/foo"
|
|
244
285
|
path="/foo/bar"
|
|
286
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
245
287
|
{...route}
|
|
246
288
|
/>
|
|
247
289
|
)}
|
|
@@ -286,6 +328,7 @@ describe("SubPage", () => {
|
|
|
286
328
|
}}
|
|
287
329
|
root="/foo"
|
|
288
330
|
path="/foo/bar"
|
|
331
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
289
332
|
{...route}
|
|
290
333
|
/>
|
|
291
334
|
)}
|
|
@@ -327,6 +370,7 @@ describe("SubPage", () => {
|
|
|
327
370
|
}}
|
|
328
371
|
root="/foo"
|
|
329
372
|
path="/foo/bar"
|
|
373
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
330
374
|
{...route}
|
|
331
375
|
/>
|
|
332
376
|
)}
|
|
@@ -368,6 +412,7 @@ describe("SubPage", () => {
|
|
|
368
412
|
}}
|
|
369
413
|
root="/foo"
|
|
370
414
|
path="/foo/bar"
|
|
415
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
371
416
|
{...route}
|
|
372
417
|
/>
|
|
373
418
|
)}
|
|
@@ -411,6 +456,7 @@ describe("SubPage", () => {
|
|
|
411
456
|
}}
|
|
412
457
|
root="/foo"
|
|
413
458
|
path="/foo/bar"
|
|
459
|
+
parentUrlPattern={new UrlPattern("/foo")}
|
|
414
460
|
{...route}
|
|
415
461
|
/>
|
|
416
462
|
)}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
3
|
+
import Button from "@material-ui/core/Button";
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { makeStyles } from "@material-ui/core/styles";
|
|
6
|
+
import { taskStatuses } from "../constants";
|
|
7
|
+
import useSelectorAndUnwrap from "../hooks/useSelectorAndUnwrap";
|
|
8
|
+
import InformationItem from "./MaterialUI/DataDisplay/PredefinedElements/InformationItem";
|
|
9
|
+
import { taskInfo, taskLogs } from "../selectors/tasks";
|
|
10
|
+
import { compareObjectProperty } from "../utils/propertyHelper";
|
|
11
|
+
import useLoader from "../hooks/useLoader";
|
|
12
|
+
import { clearTaskLog, getTaskInfo, getTaskLog } from "../actions/tasks";
|
|
13
|
+
import ModalProps from "./MaterialUI/DataDisplay/modalProps";
|
|
14
|
+
import Modal from "./MaterialUI/DataDisplay/Modal";
|
|
15
|
+
import { namedLookupLocalizedSelector } from "../selectors/metadata";
|
|
16
|
+
import sharedMessages from "../sharedMessages";
|
|
17
|
+
|
|
18
|
+
export const useStyles = makeStyles(theme => ({
|
|
19
|
+
actionPanel: {
|
|
20
|
+
display: "flex",
|
|
21
|
+
marginLeft: "auto",
|
|
22
|
+
flex: "1 1 0",
|
|
23
|
+
justifyContent: "flex-end",
|
|
24
|
+
},
|
|
25
|
+
taskContainer: {
|
|
26
|
+
display: "flex",
|
|
27
|
+
width: "100%",
|
|
28
|
+
flexDirection: "column",
|
|
29
|
+
"&>div": {
|
|
30
|
+
"&:last-child": {
|
|
31
|
+
flex: 1,
|
|
32
|
+
display: "flex",
|
|
33
|
+
flexDirection: "column",
|
|
34
|
+
"&>textarea": {
|
|
35
|
+
overflowY: "scroll",
|
|
36
|
+
resize: "none",
|
|
37
|
+
flex: 1,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
const isTaskCompleted = status => {
|
|
45
|
+
switch (status) {
|
|
46
|
+
case taskStatuses.faulted:
|
|
47
|
+
case taskStatuses.ranToCompletion:
|
|
48
|
+
case taskStatuses.canceled:
|
|
49
|
+
case taskStatuses.ignored:
|
|
50
|
+
return true;
|
|
51
|
+
default:
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const TaskDetailsModal = ({ taskId, open, closeModal }) => {
|
|
57
|
+
const classes = useStyles();
|
|
58
|
+
const dispatch = useDispatch();
|
|
59
|
+
|
|
60
|
+
const taskDetails = useSelectorAndUnwrap(taskInfo(taskId));
|
|
61
|
+
const logs = useSelectorAndUnwrap(taskLogs(taskId));
|
|
62
|
+
const logsText = logs
|
|
63
|
+
.sort((a, b) => compareObjectProperty(a, b, "executionTime"))
|
|
64
|
+
.reduce((accumulator, currentValue) => {
|
|
65
|
+
if (currentValue.message === null) {
|
|
66
|
+
return accumulator;
|
|
67
|
+
}
|
|
68
|
+
if (accumulator === "") {
|
|
69
|
+
return currentValue.message.trim();
|
|
70
|
+
}
|
|
71
|
+
return accumulator + "\n" + currentValue.message.trim();
|
|
72
|
+
}, "");
|
|
73
|
+
|
|
74
|
+
useLoader(getTaskInfo(taskId), () => taskDetails !== null);
|
|
75
|
+
|
|
76
|
+
const internalCloseModal = () => {
|
|
77
|
+
dispatch(clearTaskLog(taskId));
|
|
78
|
+
closeModal();
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const taskStatus = taskDetails?.status;
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
const timer = setInterval(() => {
|
|
85
|
+
if (!isTaskCompleted(taskStatus)) {
|
|
86
|
+
dispatch(getTaskInfo(taskId));
|
|
87
|
+
dispatch(getTaskLog(taskId, false));
|
|
88
|
+
}
|
|
89
|
+
}, 10000);
|
|
90
|
+
return () => clearInterval(timer);
|
|
91
|
+
}, [dispatch, taskId, taskStatus]);
|
|
92
|
+
|
|
93
|
+
const localizedStatus = useSelector(namedLookupLocalizedSelector("order", "TaskStatus", taskStatus));
|
|
94
|
+
const modalProps = new ModalProps();
|
|
95
|
+
const titleComponent = <FormattedMessage {...sharedMessages.taskInProgressModalTitle} />;
|
|
96
|
+
|
|
97
|
+
modalProps.set(ModalProps.propNames.title, titleComponent);
|
|
98
|
+
modalProps.set(ModalProps.propNames.open, open);
|
|
99
|
+
modalProps.set(ModalProps.propNames.type, "wide");
|
|
100
|
+
modalProps.set(ModalProps.propNames.backdropClickCallback, internalCloseModal);
|
|
101
|
+
|
|
102
|
+
const actionPanel = (
|
|
103
|
+
<div className={classes.actionPanel}>
|
|
104
|
+
<Button
|
|
105
|
+
key={sharedMessages.close.id}
|
|
106
|
+
data-qa={sharedMessages.close.id}
|
|
107
|
+
variant="contained"
|
|
108
|
+
color="primary"
|
|
109
|
+
disableElevation={true}
|
|
110
|
+
onClick={e => internalCloseModal(e)}
|
|
111
|
+
>
|
|
112
|
+
<FormattedMessage {...sharedMessages.close} />
|
|
113
|
+
</Button>
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
modalProps.set(ModalProps.propNames.actionPanel, actionPanel);
|
|
118
|
+
|
|
119
|
+
const taskContent = (
|
|
120
|
+
<div className={classes.taskContainer}>
|
|
121
|
+
<InformationItem label={sharedMessages.taskId}>{taskId}</InformationItem>
|
|
122
|
+
<InformationItem label={sharedMessages.taskStatus}>{localizedStatus}</InformationItem>
|
|
123
|
+
<InformationItem label={sharedMessages.taskLogs}>
|
|
124
|
+
<textarea readOnly value={logsText} />
|
|
125
|
+
</InformationItem>
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
return <Modal message={taskContent} modalProps={modalProps} />;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export default TaskDetailsModal;
|