@kartverket/backstage-plugin-risk-scorecard 1.0.13 → 1.0.14
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/README.md +8 -5
- package/dist/esm/{index-e091ae7d.esm.js → index-b5d09407.esm.js} +161 -35
- package/dist/esm/index-b5d09407.esm.js.map +1 -0
- package/dist/esm/{index-7e0035e6.esm.js → index-d8d91dc1.esm.js} +41 -5
- package/dist/esm/index-d8d91dc1.esm.js.map +1 -0
- package/dist/index.esm.js +1 -1
- package/package.json +2 -4
- package/config.d.ts +0 -9
- package/dist/esm/index-7e0035e6.esm.js.map +0 -1
- package/dist/esm/index-e091ae7d.esm.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,11 +4,14 @@ This is a plugin for Backstage that helps you and your team when working continu
|
|
|
4
4
|
The plugin is dependent on a backend service in order to decrypt and communicate with GitHub, and some configuration is
|
|
5
5
|
necessary for them to communicate.
|
|
6
6
|
|
|
7
|
-
Add the
|
|
7
|
+
Add the following configuration to the proxy-block in your app-config. Modify the `target` to the root url of your running backend service.
|
|
8
8
|
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
```yaml
|
|
10
|
+
proxy:
|
|
11
|
+
endpoints:
|
|
12
|
+
'/risc-proxy':
|
|
13
|
+
target: http://localhost:8080
|
|
14
|
+
allowedHeaders: ['Authorization', 'GCP-Access-Token']
|
|
12
15
|
```
|
|
13
16
|
|
|
14
17
|
The backend uses EntraID id-tokens to validate the user, and GCP access tokens to federate access to the GCP KMS.
|
|
@@ -18,4 +21,4 @@ for both:
|
|
|
18
21
|
1. Add discovery of organization data for Microsoft Org
|
|
19
22
|
2. Add authentication for both providers
|
|
20
23
|
|
|
21
|
-
Happy RiSc-ing 🌹
|
|
24
|
+
Happy RiSc-ing 🌹
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useState, useEffect, useCallback, createContext, useContext, Fragment, useRef } from 'react';
|
|
2
|
-
import { makeStyles, FormControl, FormLabel, FormHelperText, TextField as TextField$1, Grid, Typography, Box as Box$1, useTheme, Paper, Button, Radio, CircularProgress, Dialog, DialogTitle, DialogActions, Stepper, Step, StepButton, Divider as Divider$1, Drawer, List, ListSubheader, ListItem, ListItemText as ListItemText$1, ClickAwayListener, Tooltip, DialogContent, DialogContentText, IconButton, Tab } from '@material-ui/core';
|
|
2
|
+
import { makeStyles, FormControl, FormLabel, FormHelperText, TextField as TextField$1, Grid, Typography, Box as Box$1, useTheme, Paper, Button, Radio, CircularProgress, Dialog, DialogTitle, DialogActions, Stepper, Step, StepButton, Divider as Divider$1, Drawer, List, ListSubheader, ListItem, ListItemText as ListItemText$1, ClickAwayListener, Tooltip, DialogContent, DialogContentText, IconButton, Tab, LinearProgress } from '@material-ui/core';
|
|
3
3
|
import { InfoCard, ContentHeader, SupportButton } from '@backstage/core-components';
|
|
4
4
|
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
5
5
|
import { useRouteRef, useApi, googleAuthApiRef, identityApiRef, fetchApiRef, configApiRef } from '@backstage/core-plugin-api';
|
|
6
|
-
import { s as scenarioRouteRef, r as riScRouteRef, p as pluginRiScTranslationRef } from './index-
|
|
6
|
+
import { s as scenarioRouteRef, r as riScRouteRef, p as pluginRiScTranslationRef } from './index-d8d91dc1.esm.js';
|
|
7
7
|
import { useNavigate, useLocation, useParams } from 'react-router';
|
|
8
8
|
import { useEffectOnce } from 'react-use';
|
|
9
9
|
import { useSearchParams, Routes, Route } from 'react-router-dom';
|
|
@@ -453,7 +453,7 @@ const requiresNewApproval = (oldRiSc, updatedRiSc) => {
|
|
|
453
453
|
return true;
|
|
454
454
|
}
|
|
455
455
|
let requiresApproval = false;
|
|
456
|
-
oldRiSc.scenarios.
|
|
456
|
+
oldRiSc.scenarios.forEach((oldScenario, index) => {
|
|
457
457
|
const updatedScenario = updatedRiSc.scenarios[index];
|
|
458
458
|
if (oldScenario.threatActors !== updatedScenario.threatActors)
|
|
459
459
|
requiresApproval = true;
|
|
@@ -469,10 +469,14 @@ const requiresNewApproval = (oldRiSc, updatedRiSc) => {
|
|
|
469
469
|
requiresApproval = true;
|
|
470
470
|
if (oldScenario.remainingRisk.consequence !== updatedScenario.remainingRisk.consequence)
|
|
471
471
|
requiresApproval = true;
|
|
472
|
-
oldScenario.actions.
|
|
473
|
-
|
|
474
|
-
|
|
472
|
+
oldScenario.actions.forEach((oldAction, i) => {
|
|
473
|
+
if (updatedScenario.actions[i] !== void 0) {
|
|
474
|
+
const updatedAction = updatedScenario.actions[i];
|
|
475
|
+
if (oldAction.deadline !== updatedAction.deadline)
|
|
476
|
+
requiresApproval = true;
|
|
477
|
+
} else {
|
|
475
478
|
requiresApproval = true;
|
|
479
|
+
}
|
|
476
480
|
});
|
|
477
481
|
});
|
|
478
482
|
return requiresApproval;
|
|
@@ -599,12 +603,12 @@ const useFetch = () => {
|
|
|
599
603
|
const googleApi = useApi(googleAuthApiRef);
|
|
600
604
|
const identityApi = useApi(identityApiRef);
|
|
601
605
|
const { fetch: fetchApi } = useApi(fetchApiRef);
|
|
602
|
-
const
|
|
603
|
-
const riScUri = `${
|
|
606
|
+
const backendUrl = useApi(configApiRef).getString("backend.baseUrl");
|
|
607
|
+
const riScUri = `${backendUrl}/api/proxy/risc-proxy/api/risc/${repoInformation.owner}/${repoInformation.name}`;
|
|
604
608
|
const uriToFetchAllRiScs = () => `${riScUri}/all`;
|
|
605
609
|
const uriToFetchRiSc = (id) => `${riScUri}/${id}`;
|
|
606
610
|
const uriToPublishRiSc = (id) => `${riScUri}/publish/${id}`;
|
|
607
|
-
const uriToFetchLatestJSONSchema = () => `${
|
|
611
|
+
const uriToFetchLatestJSONSchema = () => `${backendUrl}/api/proxy/risc-proxy/api/risc/schemas/latest`;
|
|
608
612
|
const [response, setResponse] = useResponse();
|
|
609
613
|
const fetch = (uri, method, onSuccess, onError, body) => {
|
|
610
614
|
Promise.all([
|
|
@@ -934,6 +938,7 @@ const useFetchRiScs = (riScIdFromParams) => {
|
|
|
934
938
|
const location = useLocation();
|
|
935
939
|
const navigate = useNavigate();
|
|
936
940
|
const getRiScPath = useRouteRef(riScRouteRef);
|
|
941
|
+
const [isRequesting, setIsRequesting] = useState(false);
|
|
937
942
|
const {
|
|
938
943
|
fetchRiScs,
|
|
939
944
|
postRiScs,
|
|
@@ -1114,6 +1119,7 @@ const useFetchRiScs = (riScIdFromParams) => {
|
|
|
1114
1119
|
isError: false,
|
|
1115
1120
|
isSuccess: false
|
|
1116
1121
|
});
|
|
1122
|
+
setIsRequesting(true);
|
|
1117
1123
|
putRiScs(
|
|
1118
1124
|
updatedRiSc,
|
|
1119
1125
|
() => {
|
|
@@ -1126,6 +1132,7 @@ const useFetchRiScs = (riScIdFromParams) => {
|
|
|
1126
1132
|
setRiScs(
|
|
1127
1133
|
riScs.map((r) => r.id === selectedRiSc.id ? updatedRiSc : r)
|
|
1128
1134
|
);
|
|
1135
|
+
setIsRequesting(false);
|
|
1129
1136
|
},
|
|
1130
1137
|
() => {
|
|
1131
1138
|
setUpdateRiScStatus({
|
|
@@ -1133,6 +1140,7 @@ const useFetchRiScs = (riScIdFromParams) => {
|
|
|
1133
1140
|
isError: true,
|
|
1134
1141
|
isSuccess: false
|
|
1135
1142
|
});
|
|
1143
|
+
setIsRequesting(false);
|
|
1136
1144
|
}
|
|
1137
1145
|
);
|
|
1138
1146
|
}
|
|
@@ -1159,7 +1167,8 @@ const useFetchRiScs = (riScIdFromParams) => {
|
|
|
1159
1167
|
createNewRiSc,
|
|
1160
1168
|
updateRiSc,
|
|
1161
1169
|
approveRiSc,
|
|
1162
|
-
response
|
|
1170
|
+
response,
|
|
1171
|
+
isRequesting
|
|
1163
1172
|
};
|
|
1164
1173
|
};
|
|
1165
1174
|
|
|
@@ -1264,7 +1273,7 @@ const useInputFieldStyles = makeStyles((theme) => ({
|
|
|
1264
1273
|
paper: {
|
|
1265
1274
|
padding: theme.spacing(2),
|
|
1266
1275
|
marginBottom: theme.spacing(2),
|
|
1267
|
-
backgroundColor: theme.palette.type === "dark" ? "#404040" : "#
|
|
1276
|
+
backgroundColor: theme.palette.type === "dark" ? "#404040" : "#FFFFFF"
|
|
1268
1277
|
},
|
|
1269
1278
|
root: {
|
|
1270
1279
|
"&.Mui-disabled": {
|
|
@@ -1323,10 +1332,23 @@ const Dropdown = ({
|
|
|
1323
1332
|
handleChange,
|
|
1324
1333
|
error,
|
|
1325
1334
|
required,
|
|
1326
|
-
variant = "outlined"
|
|
1335
|
+
variant = "outlined",
|
|
1336
|
+
renderSelectedValue
|
|
1327
1337
|
}) => {
|
|
1328
1338
|
const { formLabel, formControl } = useInputFieldStyles();
|
|
1329
1339
|
const multiple = Array.isArray(selectedValues);
|
|
1340
|
+
function getOptionsValue(option) {
|
|
1341
|
+
return typeof option === "string" ? option : option.value;
|
|
1342
|
+
}
|
|
1343
|
+
function getOptionsRenderValue(option) {
|
|
1344
|
+
return typeof option === "string" ? option : option.renderedValue;
|
|
1345
|
+
}
|
|
1346
|
+
function renderSelectedValueHandler(value) {
|
|
1347
|
+
if (renderSelectedValue) {
|
|
1348
|
+
return renderSelectedValue(value);
|
|
1349
|
+
}
|
|
1350
|
+
return value;
|
|
1351
|
+
}
|
|
1330
1352
|
const onChange = (event) => handleChange(event.target.value);
|
|
1331
1353
|
const renderValue = (selected) => multiple ? /* @__PURE__ */ React.createElement(
|
|
1332
1354
|
Box,
|
|
@@ -1338,7 +1360,7 @@ const Dropdown = ({
|
|
|
1338
1360
|
paddingBottom: 0
|
|
1339
1361
|
}
|
|
1340
1362
|
},
|
|
1341
|
-
selected.map((value) => /* @__PURE__ */ React.createElement(Chip, { key: value, label: value }))
|
|
1363
|
+
selected.map((value) => /* @__PURE__ */ React.createElement(Chip, { key: value, label: renderSelectedValueHandler(value) }))
|
|
1342
1364
|
) : selected;
|
|
1343
1365
|
return /* @__PURE__ */ React.createElement(FormControl$1, { className: formControl }, label && /* @__PURE__ */ React.createElement(FormLabel$1, { className: formLabel, required }, label), /* @__PURE__ */ React.createElement(
|
|
1344
1366
|
Select,
|
|
@@ -1358,7 +1380,7 @@ const Dropdown = ({
|
|
|
1358
1380
|
}
|
|
1359
1381
|
} : {}
|
|
1360
1382
|
},
|
|
1361
|
-
options.map((name) => /* @__PURE__ */ React.createElement(MenuItem, { key: name, value: name }, multiple && /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Checkbox, { checked: selectedValues.indexOf(name) > -1 })), /* @__PURE__ */ React.createElement(ListItemText, { primary: name })))
|
|
1383
|
+
options.map((name) => /* @__PURE__ */ React.createElement(MenuItem, { key: getOptionsValue(name), value: getOptionsValue(name) }, multiple && /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Checkbox, { checked: selectedValues.indexOf(getOptionsValue(name)) > -1 })), /* @__PURE__ */ React.createElement(ListItemText, { primary: getOptionsRenderValue(name) })))
|
|
1362
1384
|
), error && /* @__PURE__ */ React.createElement(FormHelperText, { error: true }, error));
|
|
1363
1385
|
};
|
|
1364
1386
|
|
|
@@ -1375,6 +1397,20 @@ const ScenarioStep = () => {
|
|
|
1375
1397
|
setThreatActors,
|
|
1376
1398
|
setVulnerabilities
|
|
1377
1399
|
} = useContext(ScenarioContext);
|
|
1400
|
+
const translatedThreatActors = threatActorsOptions.map((threatActor) => {
|
|
1401
|
+
return {
|
|
1402
|
+
value: threatActor,
|
|
1403
|
+
/* @ts-ignore Because ts can't typecheck strings agains our keys */
|
|
1404
|
+
renderedValue: t(`threatActors.${threatActor}`)
|
|
1405
|
+
};
|
|
1406
|
+
});
|
|
1407
|
+
const translatedVulnerabilities = vulnerabilitiesOptions.map((vulnerability) => {
|
|
1408
|
+
return {
|
|
1409
|
+
value: vulnerability,
|
|
1410
|
+
/* @ts-ignore Because ts can't typecheck strings agains our keys */
|
|
1411
|
+
renderedValue: t(`vulnerabilities.${vulnerability}`)
|
|
1412
|
+
};
|
|
1413
|
+
});
|
|
1378
1414
|
return /* @__PURE__ */ React.createElement(Grid, { container: true }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { className: h2 }, t("scenarioDrawer.title")), /* @__PURE__ */ React.createElement(Typography, { className: subtitle2 }, t("scenarioDrawer.subtitle"))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
|
|
1379
1415
|
TextField,
|
|
1380
1416
|
{
|
|
@@ -1401,8 +1437,11 @@ const ScenarioStep = () => {
|
|
|
1401
1437
|
Dropdown,
|
|
1402
1438
|
{
|
|
1403
1439
|
selectedValues: scenario.threatActors,
|
|
1404
|
-
options:
|
|
1405
|
-
handleChange: setThreatActors
|
|
1440
|
+
options: translatedThreatActors,
|
|
1441
|
+
handleChange: setThreatActors,
|
|
1442
|
+
renderSelectedValue: (value) => {
|
|
1443
|
+
return t(`threatActors.${value}`);
|
|
1444
|
+
}
|
|
1406
1445
|
}
|
|
1407
1446
|
)
|
|
1408
1447
|
), /* @__PURE__ */ React.createElement(
|
|
@@ -1421,8 +1460,11 @@ const ScenarioStep = () => {
|
|
|
1421
1460
|
Dropdown,
|
|
1422
1461
|
{
|
|
1423
1462
|
selectedValues: scenario.vulnerabilities,
|
|
1424
|
-
options:
|
|
1425
|
-
handleChange: setVulnerabilities
|
|
1463
|
+
options: translatedVulnerabilities,
|
|
1464
|
+
handleChange: setVulnerabilities,
|
|
1465
|
+
renderSelectedValue: (value) => {
|
|
1466
|
+
return t(`vulnerabilities.${value}`);
|
|
1467
|
+
}
|
|
1426
1468
|
}
|
|
1427
1469
|
)
|
|
1428
1470
|
), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
|
|
@@ -1645,6 +1687,7 @@ const ProbabilityTable = ({
|
|
|
1645
1687
|
selectedValue,
|
|
1646
1688
|
handleChange
|
|
1647
1689
|
}) => {
|
|
1690
|
+
const theme = useTheme();
|
|
1648
1691
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
1649
1692
|
const { table, cell, radio } = useTableStyles$1();
|
|
1650
1693
|
const handleChangeRow = (row) => () => handleChange(row);
|
|
@@ -1653,7 +1696,10 @@ const ProbabilityTable = ({
|
|
|
1653
1696
|
{
|
|
1654
1697
|
checked: selectedValue === row,
|
|
1655
1698
|
onChange: handleChangeRow(row),
|
|
1656
|
-
style: {
|
|
1699
|
+
style: {
|
|
1700
|
+
padding: 0,
|
|
1701
|
+
color: theme.palette.type === "dark" ? "#9BC9FE" : theme.palette.primary.main
|
|
1702
|
+
}
|
|
1657
1703
|
}
|
|
1658
1704
|
), row, ": ", t(`probabilityTable.rows.${row}`)));
|
|
1659
1705
|
const contentCell = (row) => /* @__PURE__ */ React.createElement("td", { className: cell }, t(`probabilityTable.cells.${row}`));
|
|
@@ -1664,6 +1710,7 @@ const ConsequenceTable = ({
|
|
|
1664
1710
|
selectedValue,
|
|
1665
1711
|
handleChange
|
|
1666
1712
|
}) => {
|
|
1713
|
+
const theme = useTheme();
|
|
1667
1714
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
1668
1715
|
const { table, labelCell, cell, voidCell, radio } = useTableStyles$1();
|
|
1669
1716
|
const handleChangeRow = (row) => () => handleChange(row);
|
|
@@ -1673,7 +1720,10 @@ const ConsequenceTable = ({
|
|
|
1673
1720
|
{
|
|
1674
1721
|
checked: selectedValue === row,
|
|
1675
1722
|
onChange: handleChangeRow(row),
|
|
1676
|
-
style: {
|
|
1723
|
+
style: {
|
|
1724
|
+
padding: 0,
|
|
1725
|
+
color: theme.palette.type === "dark" ? theme.palette.primary.light : theme.palette.primary.main
|
|
1726
|
+
}
|
|
1677
1727
|
}
|
|
1678
1728
|
), row, ": ", t(`consequenceTable.rows.${row}`)));
|
|
1679
1729
|
};
|
|
@@ -1715,11 +1765,21 @@ const RiskStep = ({ riskType, restEqualsInitial }) => {
|
|
|
1715
1765
|
useEffect(() => {
|
|
1716
1766
|
if (restEqualsInitial)
|
|
1717
1767
|
setRemainingConsequence(getConsequenceLevel(scenario.risk));
|
|
1718
|
-
}, [
|
|
1768
|
+
}, [
|
|
1769
|
+
restEqualsInitial,
|
|
1770
|
+
scenario.risk,
|
|
1771
|
+
scenario.risk.consequence,
|
|
1772
|
+
setRemainingConsequence
|
|
1773
|
+
]);
|
|
1719
1774
|
useEffect(() => {
|
|
1720
1775
|
if (restEqualsInitial)
|
|
1721
1776
|
setRemainingProbability(getProbabilityLevel(scenario.risk));
|
|
1722
|
-
}, [
|
|
1777
|
+
}, [
|
|
1778
|
+
restEqualsInitial,
|
|
1779
|
+
scenario.risk,
|
|
1780
|
+
scenario.risk.probability,
|
|
1781
|
+
setRemainingProbability
|
|
1782
|
+
]);
|
|
1723
1783
|
const setC = riskType === "initial" ? setConsequence : setRemainingConsequence;
|
|
1724
1784
|
const setP = riskType === "initial" ? setProbability : setRemainingProbability;
|
|
1725
1785
|
return /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(Box, { className: box }, /* @__PURE__ */ React.createElement(Typography, { className: h2 }, t(`scenarioStepper.${resourceKey}.title`)), /* @__PURE__ */ React.createElement(Typography, { className: subtitle2 }, t(`scenarioStepper.${resourceKey}.subtitle`))), /* @__PURE__ */ React.createElement(Box, { className: box }, /* @__PURE__ */ React.createElement(Typography, { className: h3 }, t("dictionary.probability")), /* @__PURE__ */ React.createElement(Typography, { className: subtitle2 }, t(`scenarioStepper.${resourceKey}.probabilitySubtitle`))), /* @__PURE__ */ React.createElement(Box, { className: box }, /* @__PURE__ */ React.createElement(
|
|
@@ -1771,6 +1831,15 @@ const useWizardStyle = makeStyles((theme) => ({
|
|
|
1771
1831
|
saveAndNextButtons: {
|
|
1772
1832
|
display: "flex",
|
|
1773
1833
|
gap: theme.spacing(2)
|
|
1834
|
+
},
|
|
1835
|
+
button: {
|
|
1836
|
+
"&.MuiButton-outlined": {
|
|
1837
|
+
color: theme.palette.type === "dark" ? "#9CC9FF" : theme.palette.link,
|
|
1838
|
+
borderr: "1px solid rgba(25, 118, 210, 0.5)",
|
|
1839
|
+
"&:hover": {
|
|
1840
|
+
borderColor: theme.palette.type === "dark" ? "#9CC9FF" : theme.palette.linkHover
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1774
1843
|
}
|
|
1775
1844
|
}));
|
|
1776
1845
|
|
|
@@ -1808,6 +1877,7 @@ const ScenarioWizard = ({
|
|
|
1808
1877
|
header,
|
|
1809
1878
|
stepper,
|
|
1810
1879
|
steps,
|
|
1880
|
+
button,
|
|
1811
1881
|
buttonContainer,
|
|
1812
1882
|
buttonContainerRight,
|
|
1813
1883
|
saveAndNextButtons
|
|
@@ -1872,7 +1942,15 @@ const ScenarioWizard = ({
|
|
|
1872
1942
|
const isLastStep = () => {
|
|
1873
1943
|
return scenarioWizardSteps.indexOf(step) === scenarioWizardSteps.length - 1;
|
|
1874
1944
|
};
|
|
1875
|
-
return /* @__PURE__ */ React.createElement("div", { ref: wizardRef }, /* @__PURE__ */ React.createElement(Box, { className: root }, /* @__PURE__ */ React.createElement(Box, { className: container }, /* @__PURE__ */ React.createElement(Box, { className: header }, /* @__PURE__ */ React.createElement(Typography, { className: h1 }, t("scenarioDrawer.title")), /* @__PURE__ */ React.createElement(
|
|
1945
|
+
return /* @__PURE__ */ React.createElement("div", { ref: wizardRef }, /* @__PURE__ */ React.createElement(Box, { className: root }, /* @__PURE__ */ React.createElement(Box, { className: container }, /* @__PURE__ */ React.createElement(Box, { className: header }, /* @__PURE__ */ React.createElement(Typography, { className: h1 }, t("scenarioDrawer.title")), /* @__PURE__ */ React.createElement(
|
|
1946
|
+
Button$1,
|
|
1947
|
+
{
|
|
1948
|
+
variant: "outlined",
|
|
1949
|
+
className: button,
|
|
1950
|
+
onClick: handleCloseStepper
|
|
1951
|
+
},
|
|
1952
|
+
t("dictionary.cancel")
|
|
1953
|
+
)), /* @__PURE__ */ React.createElement(
|
|
1876
1954
|
Stepper,
|
|
1877
1955
|
{
|
|
1878
1956
|
className: stepper,
|
|
@@ -1920,6 +1998,7 @@ const ScenarioWizard = ({
|
|
|
1920
1998
|
/* @__PURE__ */ React.createElement(Box, { className: saveAndNextButtons }, /* @__PURE__ */ React.createElement(
|
|
1921
1999
|
Button$1,
|
|
1922
2000
|
{
|
|
2001
|
+
className: button,
|
|
1923
2002
|
variant: isLastStep() ? "contained" : "outlined",
|
|
1924
2003
|
onClick: saveAndClose,
|
|
1925
2004
|
disabled: updateStatus.isLoading
|
|
@@ -1981,7 +2060,6 @@ const useScenarioDrawerStyles = makeStyles((theme) => ({
|
|
|
1981
2060
|
backgroundColor: theme.palette.type === "dark" ? "#555555" : "#e0e0e0"
|
|
1982
2061
|
},
|
|
1983
2062
|
gridContainer: {
|
|
1984
|
-
padding: theme.spacing(2),
|
|
1985
2063
|
marginBottom: theme.palette.type === "dark" ? theme.spacing(1) : "7px",
|
|
1986
2064
|
backgroundColor: theme.palette.type === "dark" ? "#55555519" : "#e0e0e019"
|
|
1987
2065
|
},
|
|
@@ -2083,7 +2161,7 @@ const RiskSection = () => {
|
|
|
2083
2161
|
));
|
|
2084
2162
|
};
|
|
2085
2163
|
|
|
2086
|
-
const useActionBoxStyles = makeStyles((
|
|
2164
|
+
const useActionBoxStyles = makeStyles((theme) => ({
|
|
2087
2165
|
alignCenter: {
|
|
2088
2166
|
display: "flex",
|
|
2089
2167
|
alignItems: "center"
|
|
@@ -2091,6 +2169,28 @@ const useActionBoxStyles = makeStyles((_) => ({
|
|
|
2091
2169
|
justifyEnd: {
|
|
2092
2170
|
display: "flex",
|
|
2093
2171
|
justifyContent: "flex-end"
|
|
2172
|
+
},
|
|
2173
|
+
row: {
|
|
2174
|
+
display: "flex",
|
|
2175
|
+
flexDirection: "row",
|
|
2176
|
+
justifyContent: "space-between",
|
|
2177
|
+
padding: theme.spacing(1)
|
|
2178
|
+
},
|
|
2179
|
+
column: {
|
|
2180
|
+
display: "flex",
|
|
2181
|
+
flexDirection: "column",
|
|
2182
|
+
justifyContent: "center"
|
|
2183
|
+
},
|
|
2184
|
+
paddingTop: {
|
|
2185
|
+
paddingTop: theme.spacing(2)
|
|
2186
|
+
},
|
|
2187
|
+
actionDescription: {
|
|
2188
|
+
marginTop: theme.spacing(-2)
|
|
2189
|
+
},
|
|
2190
|
+
chipDropdown: {
|
|
2191
|
+
display: "flex",
|
|
2192
|
+
flexDirection: "row",
|
|
2193
|
+
justifyContent: "flex-end"
|
|
2094
2194
|
}
|
|
2095
2195
|
}));
|
|
2096
2196
|
|
|
@@ -2111,7 +2211,7 @@ const ChipDropdown = ({
|
|
|
2111
2211
|
style: {
|
|
2112
2212
|
margin: 0,
|
|
2113
2213
|
padding: 0,
|
|
2114
|
-
backgroundColor: "#D9D9D9",
|
|
2214
|
+
backgroundColor: selectedValue === "Completed" ? "#6BC6A4" : "#D9D9D9",
|
|
2115
2215
|
color: "#000000"
|
|
2116
2216
|
},
|
|
2117
2217
|
label: selectedValue,
|
|
@@ -2150,7 +2250,14 @@ const ActionBox = ({
|
|
|
2150
2250
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
2151
2251
|
const { body2, label } = useFontStyles();
|
|
2152
2252
|
const { gridContainer } = useScenarioDrawerStyles();
|
|
2153
|
-
const {
|
|
2253
|
+
const {
|
|
2254
|
+
alignCenter,
|
|
2255
|
+
row,
|
|
2256
|
+
paddingTop,
|
|
2257
|
+
actionDescription,
|
|
2258
|
+
column,
|
|
2259
|
+
chipDropdown
|
|
2260
|
+
} = useActionBoxStyles();
|
|
2154
2261
|
const [previousAction, setPreviousAction] = useState(action);
|
|
2155
2262
|
useEffect(() => {
|
|
2156
2263
|
if (previousAction !== action) {
|
|
@@ -2164,19 +2271,28 @@ const ActionBox = ({
|
|
|
2164
2271
|
status
|
|
2165
2272
|
});
|
|
2166
2273
|
};
|
|
2167
|
-
return /* @__PURE__ */ React.createElement(Grid, { container: true, className: gridContainer }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, className: alignCenter }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 6 }, /* @__PURE__ */ React.createElement(Typography, { className: label }, t("dictionary.measure"), " ", index)), /* @__PURE__ */ React.createElement(Grid, { item: true, xs:
|
|
2274
|
+
return /* @__PURE__ */ React.createElement(Grid, { container: true, className: gridContainer }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, className: alignCenter }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 6, className: paddingTop }, /* @__PURE__ */ React.createElement(Typography, { className: label }, t("dictionary.measure"), " ", index))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, className: actionDescription }, /* @__PURE__ */ React.createElement(Typography, { className: body2 }, action.description)), /* @__PURE__ */ React.createElement(Grid, { container: true, xs: 12, className: row }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 4 }, /* @__PURE__ */ React.createElement(Typography, { className: label }, t("dictionary.measureOwner")), /* @__PURE__ */ React.createElement(Typography, { className: body2 }, action.owner)), /* @__PURE__ */ React.createElement(Grid, { container: true, xs: 4, className: column }, /* @__PURE__ */ React.createElement(Typography, { className: label }, t("dictionary.deadline")), /* @__PURE__ */ React.createElement(Typography, { className: body2 }, formatDate(action.deadline))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 3, className: chipDropdown }, /* @__PURE__ */ React.createElement(
|
|
2168
2275
|
ChipDropdown,
|
|
2169
2276
|
{
|
|
2170
2277
|
options: actionStatusOptions,
|
|
2171
2278
|
selectedValue: action.status,
|
|
2172
2279
|
handleChange: setStatus
|
|
2173
2280
|
}
|
|
2174
|
-
)))
|
|
2281
|
+
))));
|
|
2282
|
+
};
|
|
2283
|
+
|
|
2284
|
+
const ExistingActionBox = ({
|
|
2285
|
+
existingAction
|
|
2286
|
+
}) => {
|
|
2287
|
+
const { body2 } = useFontStyles();
|
|
2288
|
+
const { gridContainer } = useScenarioDrawerStyles();
|
|
2289
|
+
const { alignCenter } = useActionBoxStyles();
|
|
2290
|
+
return /* @__PURE__ */ React.createElement(Grid, { container: true, className: gridContainer }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, className: alignCenter }, /* @__PURE__ */ React.createElement(Typography, { className: body2 }, existingAction)));
|
|
2175
2291
|
};
|
|
2176
2292
|
|
|
2177
2293
|
const ActionsSection = () => {
|
|
2178
2294
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
2179
|
-
const { h3, button } = useFontStyles();
|
|
2295
|
+
const { h3, button, label } = useFontStyles();
|
|
2180
2296
|
const { titleAndButton, section, editIcon } = useScenarioDrawerStyles();
|
|
2181
2297
|
const { scenario, editScenario, saveScenario, updateAction } = useContext(ScenarioContext);
|
|
2182
2298
|
return /* @__PURE__ */ React.createElement(Box$2, null, /* @__PURE__ */ React.createElement(Paper, { className: section, style: { padding: "1rem" } }, /* @__PURE__ */ React.createElement(
|
|
@@ -2189,7 +2305,7 @@ const ActionsSection = () => {
|
|
|
2189
2305
|
marginBottom: "12px"
|
|
2190
2306
|
}
|
|
2191
2307
|
},
|
|
2192
|
-
/* @__PURE__ */ React.createElement(Typography, { className: h3
|
|
2308
|
+
/* @__PURE__ */ React.createElement(Typography, { className: h3 }, t("scenarioDrawer.measureTab.actionsTitle")),
|
|
2193
2309
|
/* @__PURE__ */ React.createElement(
|
|
2194
2310
|
Button,
|
|
2195
2311
|
{
|
|
@@ -2200,7 +2316,7 @@ const ActionsSection = () => {
|
|
|
2200
2316
|
startIcon: /* @__PURE__ */ React.createElement(EditIcon, { className: editIcon, "aria-label": "Edit" })
|
|
2201
2317
|
}
|
|
2202
2318
|
)
|
|
2203
|
-
), scenario.actions.map((action, index) => /* @__PURE__ */ React.createElement(Fragment, { key: action.ID }, /* @__PURE__ */ React.createElement(
|
|
2319
|
+
), scenario.existingActions && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { className: label }, t("scenarioDrawer.measureTab.existingMeasure")), /* @__PURE__ */ React.createElement(ExistingActionBox, { existingAction: scenario.existingActions }), scenario.actions.length > 0 && /* @__PURE__ */ React.createElement(Divider$1, { variant: "fullWidth" })), scenario.actions.map((action, index) => /* @__PURE__ */ React.createElement(Fragment, { key: action.ID }, /* @__PURE__ */ React.createElement(
|
|
2204
2320
|
ActionBox,
|
|
2205
2321
|
{
|
|
2206
2322
|
action,
|
|
@@ -3143,10 +3259,19 @@ const RiScInfo = ({ riSc, approveRiSc, edit }) => {
|
|
|
3143
3259
|
), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, sm: 6, md: 4 }, /* @__PURE__ */ React.createElement(RiScStatusComponent, { selectedRiSc: riSc, publishRiScFn: approveRiSc })));
|
|
3144
3260
|
};
|
|
3145
3261
|
|
|
3262
|
+
const useLinearProgressStyle = makeStyles((theme) => ({
|
|
3263
|
+
linearProgress: {
|
|
3264
|
+
position: "sticky",
|
|
3265
|
+
top: 0,
|
|
3266
|
+
margin: theme.spacing(2)
|
|
3267
|
+
}
|
|
3268
|
+
}));
|
|
3269
|
+
|
|
3146
3270
|
const Plugin = () => {
|
|
3147
3271
|
var _a, _b;
|
|
3148
3272
|
const params = useParams();
|
|
3149
3273
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
3274
|
+
const { linearProgress } = useLinearProgressStyle();
|
|
3150
3275
|
const [RiScDialogState, setRiScDialogState] = useState(
|
|
3151
3276
|
RiScDialogStates.Closed
|
|
3152
3277
|
);
|
|
@@ -3163,7 +3288,8 @@ const Plugin = () => {
|
|
|
3163
3288
|
updateRiScStatus,
|
|
3164
3289
|
resetRiScStatus,
|
|
3165
3290
|
approveRiSc,
|
|
3166
|
-
response
|
|
3291
|
+
response,
|
|
3292
|
+
isRequesting
|
|
3167
3293
|
} = useFetchRiScs(params.riScId);
|
|
3168
3294
|
const scenario = useScenarioDrawer(
|
|
3169
3295
|
selectedRiSc != null ? selectedRiSc : null,
|
|
@@ -3176,7 +3302,7 @@ const Plugin = () => {
|
|
|
3176
3302
|
if (scenarioWizardStep !== null)
|
|
3177
3303
|
resetRiScStatus();
|
|
3178
3304
|
}, [resetRiScStatus, scenarioWizardStep]);
|
|
3179
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ScenarioContext.Provider, { value: scenario }, response && /* @__PURE__ */ React.createElement(Alert, { severity: getAlertSeverity(response.status) }, /* @__PURE__ */ React.createElement(Typography, null, response.statusMessage)), scenarioWizardStep !== null ? /* @__PURE__ */ React.createElement(
|
|
3305
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ScenarioContext.Provider, { value: scenario }, response && /* @__PURE__ */ React.createElement(Alert, { severity: getAlertSeverity(response.status) }, /* @__PURE__ */ React.createElement(Typography, null, response.statusMessage)), isRequesting && /* @__PURE__ */ React.createElement(LinearProgress, { className: linearProgress }), scenarioWizardStep !== null ? /* @__PURE__ */ React.createElement(
|
|
3180
3306
|
ScenarioWizard,
|
|
3181
3307
|
{
|
|
3182
3308
|
step: scenarioWizardStep,
|
|
@@ -3238,4 +3364,4 @@ const RiScPlugin = () => {
|
|
|
3238
3364
|
};
|
|
3239
3365
|
|
|
3240
3366
|
export { RiScPlugin };
|
|
3241
|
-
//# sourceMappingURL=index-
|
|
3367
|
+
//# sourceMappingURL=index-b5d09407.esm.js.map
|