@kartverket/backstage-plugin-risk-scorecard 6.9.7 → 6.10.1
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/PluginRoot.esm.js +5 -1
- package/dist/PluginRoot.esm.js.map +1 -1
- package/dist/components/riScDialog/AppliesToField.esm.js +189 -0
- package/dist/components/riScDialog/AppliesToField.esm.js.map +1 -0
- package/dist/components/riScDialog/ConfigRiscInfo.esm.js +4 -0
- package/dist/components/riScDialog/ConfigRiscInfo.esm.js.map +1 -1
- package/dist/components/riScDialog/RiScDialog.esm.js +6 -3
- package/dist/components/riScDialog/RiScDialog.esm.js.map +1 -1
- package/dist/components/riScDialog/entityRefOptions.esm.js +25 -0
- package/dist/components/riScDialog/entityRefOptions.esm.js.map +1 -0
- package/dist/components/riScInfo/RiScSelectionCard.esm.js +20 -4
- package/dist/components/riScInfo/RiScSelectionCard.esm.js.map +1 -1
- package/dist/components/riScInfo/RiScSelectionCard.module.css.esm.js +2 -2
- package/dist/components/riScInfo/changeset/RiScAppliesToChange.esm.js +31 -0
- package/dist/components/riScInfo/changeset/RiScAppliesToChange.esm.js.map +1 -0
- package/dist/components/riScInfo/changeset/RiScChangeSet.esm.js +4 -1
- package/dist/components/riScInfo/changeset/RiScChangeSet.esm.js.map +1 -1
- package/dist/components/riScPlugin/RiScPlugin.esm.js +22 -3
- package/dist/components/riScPlugin/RiScPlugin.esm.js.map +1 -1
- package/dist/contexts/RiScContext.esm.js +36 -10
- package/dist/contexts/RiScContext.esm.js.map +1 -1
- package/dist/plugin.esm.js +7 -0
- package/dist/plugin.esm.js.map +1 -1
- package/dist/utils/DTOs.esm.js +5 -1
- package/dist/utils/DTOs.esm.js.map +1 -1
- package/dist/utils/constants.esm.js +1 -1
- package/dist/utils/constants.esm.js.map +1 -1
- package/dist/utils/featureFlags.esm.js +10 -0
- package/dist/utils/featureFlags.esm.js.map +1 -0
- package/dist/utils/hooks.esm.js +75 -2
- package/dist/utils/hooks.esm.js.map +1 -1
- package/dist/utils/translations.esm.js +33 -1
- package/dist/utils/translations.esm.js.map +1 -1
- package/dist/utils/types.esm.js.map +1 -1
- package/dist/utils/utilityfunctions.esm.js +4 -0
- package/dist/utils/utilityfunctions.esm.js.map +1 -1
- package/package.json +4 -2
package/dist/PluginRoot.esm.js
CHANGED
|
@@ -3,6 +3,8 @@ import { Routes, Route } from 'react-router-dom';
|
|
|
3
3
|
import { CacheProvider } from '@emotion/react';
|
|
4
4
|
import createCache from '@emotion/cache';
|
|
5
5
|
import { useMemo } from 'react';
|
|
6
|
+
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
7
|
+
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
6
8
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
7
9
|
import { RiScPlugin } from './components/riScPlugin/RiScPlugin.esm.js';
|
|
8
10
|
import { ScenarioProvider } from './contexts/ScenarioContext.esm.js';
|
|
@@ -26,7 +28,9 @@ function MuiThemeBridge({ children }) {
|
|
|
26
28
|
return /* @__PURE__ */ jsx(ThemeProvider, { theme, children });
|
|
27
29
|
}
|
|
28
30
|
function ProvidedPlugin() {
|
|
29
|
-
|
|
31
|
+
const { entity } = useEntity();
|
|
32
|
+
const entityKey = stringifyEntityRef(entity);
|
|
33
|
+
return /* @__PURE__ */ jsx(CacheProvider, { value: cache, children: /* @__PURE__ */ jsx(MuiThemeBridge, { children: /* @__PURE__ */ jsx(BackstageContextProvider, { children: /* @__PURE__ */ jsx(RiScProvider, { children: /* @__PURE__ */ jsx(DefaultRiScTypesProvider, { children: /* @__PURE__ */ jsx(ScenarioProvider, { children: /* @__PURE__ */ jsx(RiScPlugin, {}) }) }) }, entityKey) }) }) });
|
|
30
34
|
}
|
|
31
35
|
function PluginRoot() {
|
|
32
36
|
return /* @__PURE__ */ jsxs(Routes, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginRoot.esm.js","sources":["../src/PluginRoot.tsx"],"sourcesContent":["import { Route, Routes } from 'react-router-dom';\nimport { CacheProvider } from '@emotion/react';\nimport createCache from '@emotion/cache';\nimport { useMemo } from 'react';\nimport { createTheme, ThemeProvider } from '@mui/material/styles';\nimport { RiScPlugin } from './components/riScPlugin/RiScPlugin';\nimport { ScenarioProvider } from './contexts/ScenarioContext';\nimport { riScRouteRef, scenarioRouteRef } from './routes';\nimport { RiScProvider } from './contexts/RiScContext';\nimport 'remixicon/fonts/remixicon.css';\nimport { DefaultRiScTypesProvider } from './contexts/DefaultRiScTypesContext.tsx';\nimport { BackstageContextProvider } from './contexts/BackstageContext.tsx';\nimport { useBackstageThemeMode } from './hooks/useBackstageThemeMode.ts';\n\nconst emotionInsertionPoint = document.createElement('meta');\nemotionInsertionPoint.setAttribute('name', 'emotion-insertion-point');\ndocument.querySelector('head')?.appendChild(emotionInsertionPoint);\n\nconst cache = createCache({\n key: 'css',\n insertionPoint: emotionInsertionPoint,\n});\n\nfunction MuiThemeBridge({ children }: { children: React.ReactNode }) {\n const mode = useBackstageThemeMode();\n const theme = useMemo(() => createTheme({ palette: { mode } }), [mode]);\n return <ThemeProvider theme={theme}>{children}</ThemeProvider>;\n}\n\nfunction ProvidedPlugin() {\n return (\n <CacheProvider value={cache}>\n <MuiThemeBridge>\n <BackstageContextProvider>\n <RiScProvider>\n <DefaultRiScTypesProvider>\n <ScenarioProvider>\n <RiScPlugin />\n </ScenarioProvider>\n </DefaultRiScTypesProvider>\n </RiScProvider>\n </BackstageContextProvider>\n </MuiThemeBridge>\n </CacheProvider>\n );\n}\n\nexport function PluginRoot() {\n return (\n <Routes>\n <Route path=\"/\" element={<ProvidedPlugin />} />\n <Route path={riScRouteRef.path} element={<ProvidedPlugin />} />\n <Route path={scenarioRouteRef.path} element={<ProvidedPlugin />} />\n </Routes>\n );\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PluginRoot.esm.js","sources":["../src/PluginRoot.tsx"],"sourcesContent":["import { Route, Routes } from 'react-router-dom';\nimport { CacheProvider } from '@emotion/react';\nimport createCache from '@emotion/cache';\nimport { useMemo } from 'react';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { createTheme, ThemeProvider } from '@mui/material/styles';\nimport { RiScPlugin } from './components/riScPlugin/RiScPlugin';\nimport { ScenarioProvider } from './contexts/ScenarioContext';\nimport { riScRouteRef, scenarioRouteRef } from './routes';\nimport { RiScProvider } from './contexts/RiScContext';\nimport 'remixicon/fonts/remixicon.css';\nimport { DefaultRiScTypesProvider } from './contexts/DefaultRiScTypesContext.tsx';\nimport { BackstageContextProvider } from './contexts/BackstageContext.tsx';\nimport { useBackstageThemeMode } from './hooks/useBackstageThemeMode.ts';\n\nconst emotionInsertionPoint = document.createElement('meta');\nemotionInsertionPoint.setAttribute('name', 'emotion-insertion-point');\ndocument.querySelector('head')?.appendChild(emotionInsertionPoint);\n\nconst cache = createCache({\n key: 'css',\n insertionPoint: emotionInsertionPoint,\n});\n\nfunction MuiThemeBridge({ children }: { children: React.ReactNode }) {\n const mode = useBackstageThemeMode();\n const theme = useMemo(() => createTheme({ palette: { mode } }), [mode]);\n return <ThemeProvider theme={theme}>{children}</ThemeProvider>;\n}\n\nfunction ProvidedPlugin() {\n const { entity } = useEntity();\n const entityKey = stringifyEntityRef(entity);\n\n return (\n <CacheProvider value={cache}>\n <MuiThemeBridge>\n <BackstageContextProvider>\n <RiScProvider key={entityKey}>\n <DefaultRiScTypesProvider>\n <ScenarioProvider>\n <RiScPlugin />\n </ScenarioProvider>\n </DefaultRiScTypesProvider>\n </RiScProvider>\n </BackstageContextProvider>\n </MuiThemeBridge>\n </CacheProvider>\n );\n}\n\nexport function PluginRoot() {\n return (\n <Routes>\n <Route path=\"/\" element={<ProvidedPlugin />} />\n <Route path={riScRouteRef.path} element={<ProvidedPlugin />} />\n <Route path={scenarioRouteRef.path} element={<ProvidedPlugin />} />\n </Routes>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAM,qBAAA,GAAwB,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA;AAC3D,qBAAA,CAAsB,YAAA,CAAa,QAAQ,yBAAyB,CAAA;AACpE,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA,EAAG,WAAA,CAAY,qBAAqB,CAAA;AAEjE,MAAM,QAAQ,WAAA,CAAY;AAAA,EACxB,GAAA,EAAK,KAAA;AAAA,EACL,cAAA,EAAgB;AAClB,CAAC,CAAA;AAED,SAAS,cAAA,CAAe,EAAE,QAAA,EAAS,EAAkC;AACnE,EAAA,MAAM,OAAO,qBAAA,EAAsB;AACnC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAM,WAAA,CAAY,EAAE,OAAA,EAAS,EAAE,IAAA,EAAK,EAAG,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACtE,EAAA,uBAAO,GAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAe,QAAA,EAAS,CAAA;AAChD;AAEA,SAAS,cAAA,GAAiB;AACxB,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,SAAA,GAAY,mBAAmB,MAAM,CAAA;AAE3C,EAAA,uBACE,GAAA,CAAC,iBAAc,KAAA,EAAO,KAAA,EACpB,8BAAC,cAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,wBAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,4BACC,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EACC,8BAAC,UAAA,EAAA,EAAW,CAAA,EACd,GACF,CAAA,EAAA,EALiB,SAMnB,CAAA,EACF,CAAA,EACF,CAAA,EACF,CAAA;AAEJ;AAEO,SAAS,UAAA,GAAa;AAC3B,EAAA,4BACG,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAM,IAAA,EAAK,GAAA,EAAI,OAAA,kBAAS,GAAA,CAAC,kBAAe,CAAA,EAAI,CAAA;AAAA,oBAC7C,GAAA,CAAC,SAAM,IAAA,EAAM,YAAA,CAAa,MAAM,OAAA,kBAAS,GAAA,CAAC,kBAAe,CAAA,EAAI,CAAA;AAAA,oBAC7D,GAAA,CAAC,SAAM,IAAA,EAAM,gBAAA,CAAiB,MAAM,OAAA,kBAAS,GAAA,CAAC,kBAAe,CAAA,EAAI;AAAA,GAAA,EACnE,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
3
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
4
|
+
import { stringifyEntityRef, RELATION_PART_OF } from '@backstage/catalog-model';
|
|
5
|
+
import { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';
|
|
6
|
+
import { Alert } from '@backstage/ui';
|
|
7
|
+
import Autocomplete from '@mui/material/Autocomplete';
|
|
8
|
+
import Chip from '@mui/material/Chip';
|
|
9
|
+
import FormControl from '@mui/material/FormControl';
|
|
10
|
+
import FormHelperText from '@mui/material/FormHelperText';
|
|
11
|
+
import FormLabel from '@mui/material/FormLabel';
|
|
12
|
+
import TextField from '@mui/material/TextField';
|
|
13
|
+
import { useState, useEffect } from 'react';
|
|
14
|
+
import { useController } from 'react-hook-form';
|
|
15
|
+
import { pluginRiScTranslationRef } from '../../utils/translations.esm.js';
|
|
16
|
+
import formStyles from '../common/formStyles.module.css.esm.js';
|
|
17
|
+
import { getCurrentSystemRef, entityRefOptionFields } from './entityRefOptions.esm.js';
|
|
18
|
+
|
|
19
|
+
const backstageAppliesToPrefix = "backstage:";
|
|
20
|
+
function AppliesToField({ control }) {
|
|
21
|
+
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
22
|
+
const catalogApi = useApi(catalogApiRef);
|
|
23
|
+
const configApi = useApi(configApiRef);
|
|
24
|
+
const includeAllEntities = configApi.getOptionalBoolean(
|
|
25
|
+
"riskScorecard.appliesTo.includeAllEntities"
|
|
26
|
+
) ?? false;
|
|
27
|
+
const [catalogEntityRefs, setCatalogEntityRefs] = useState([]);
|
|
28
|
+
const [isLoadingOptions, setIsLoadingOptions] = useState(false);
|
|
29
|
+
const { field, fieldState } = useController({
|
|
30
|
+
control,
|
|
31
|
+
name: "content.unencryptedMetadata.appliesTo"
|
|
32
|
+
});
|
|
33
|
+
const { entity } = useEntity();
|
|
34
|
+
const currentEntityRef = stringifyEntityRef(entity);
|
|
35
|
+
const currentPrefixedEntityRef = backstageAppliesToPrefix + currentEntityRef;
|
|
36
|
+
const selectedEntityRefs = field.value ?? [currentPrefixedEntityRef];
|
|
37
|
+
const isMissingCurrentEntityRef = getIsMissingCurrentEntityRef(
|
|
38
|
+
selectedEntityRefs,
|
|
39
|
+
currentPrefixedEntityRef
|
|
40
|
+
);
|
|
41
|
+
const missingEntityRefs = catalogEntityRefs.length > 0 ? getMissingEntityRefs(
|
|
42
|
+
selectedEntityRefs.filter((ref) => ref !== currentPrefixedEntityRef),
|
|
43
|
+
catalogEntityRefs
|
|
44
|
+
) : [];
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
let cancelled = false;
|
|
47
|
+
const currentSystemRef = getCurrentSystemRef(entity);
|
|
48
|
+
setIsLoadingOptions(true);
|
|
49
|
+
setCatalogEntityRefs([]);
|
|
50
|
+
const sameSystemEntitiesPromise = currentSystemRef ? catalogApi.getEntities({
|
|
51
|
+
fields: entityRefOptionFields,
|
|
52
|
+
filter: {
|
|
53
|
+
[`relations.${RELATION_PART_OF}`]: currentSystemRef
|
|
54
|
+
}
|
|
55
|
+
}).catch(() => ({ items: [] })) : Promise.resolve({ items: [] });
|
|
56
|
+
Promise.all([
|
|
57
|
+
sameSystemEntitiesPromise,
|
|
58
|
+
includeAllEntities ? catalogApi.getEntities({
|
|
59
|
+
fields: entityRefOptionFields
|
|
60
|
+
}) : Promise.resolve({ items: [] })
|
|
61
|
+
]).then(([sameSystemEntitiesResponse, allEntitiesResponse]) => {
|
|
62
|
+
if (cancelled) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
setCatalogEntityRefs(
|
|
66
|
+
Array.from(
|
|
67
|
+
new Set(
|
|
68
|
+
[
|
|
69
|
+
...sameSystemEntitiesResponse.items,
|
|
70
|
+
...allEntitiesResponse.items
|
|
71
|
+
].map(
|
|
72
|
+
(optionEntity) => backstageAppliesToPrefix + stringifyEntityRef(optionEntity)
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
}).catch(() => {
|
|
78
|
+
if (!cancelled) {
|
|
79
|
+
setCatalogEntityRefs([]);
|
|
80
|
+
}
|
|
81
|
+
}).finally(() => {
|
|
82
|
+
if (!cancelled) {
|
|
83
|
+
setIsLoadingOptions(false);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return () => {
|
|
87
|
+
cancelled = true;
|
|
88
|
+
};
|
|
89
|
+
}, [catalogApi, entity, includeAllEntities]);
|
|
90
|
+
function handleChange(_, value) {
|
|
91
|
+
field.onChange(
|
|
92
|
+
ensureNullOrCurrentEntityRefAsHead(value, currentPrefixedEntityRef)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return /* @__PURE__ */ jsxs(FormControl, { className: formStyles.formControl, children: [
|
|
96
|
+
/* @__PURE__ */ jsx(FormLabel, { className: formStyles.formLabel, children: t("rosDialog.appliesTo") }),
|
|
97
|
+
/* @__PURE__ */ jsx(FormHelperText, { className: formStyles.formHelperText, children: t("rosDialog.appliesToDescription") }),
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
Autocomplete,
|
|
100
|
+
{
|
|
101
|
+
multiple: true,
|
|
102
|
+
disablePortal: true,
|
|
103
|
+
filterSelectedOptions: true,
|
|
104
|
+
loading: isLoadingOptions,
|
|
105
|
+
options: catalogEntityRefs,
|
|
106
|
+
value: selectedEntityRefs,
|
|
107
|
+
getOptionLabel: formatBackstageAppliesTo,
|
|
108
|
+
isOptionEqualToValue: (option, value) => option === value,
|
|
109
|
+
onChange: handleChange,
|
|
110
|
+
renderValue: (value, getItemProps) => value.map((prefixedEntityRef, index) => {
|
|
111
|
+
const tagProps = getItemProps({ index });
|
|
112
|
+
const { key, onDelete, ...restTagProps } = tagProps;
|
|
113
|
+
const isCurrentEntity = prefixedEntityRef === currentPrefixedEntityRef;
|
|
114
|
+
return /* @__PURE__ */ jsx(
|
|
115
|
+
Chip,
|
|
116
|
+
{
|
|
117
|
+
label: formatBackstageAppliesTo(prefixedEntityRef),
|
|
118
|
+
color: isCurrentEntity ? "primary" : "default",
|
|
119
|
+
variant: isCurrentEntity ? "filled" : "outlined",
|
|
120
|
+
onDelete: isCurrentEntity ? void 0 : onDelete,
|
|
121
|
+
...restTagProps
|
|
122
|
+
},
|
|
123
|
+
key
|
|
124
|
+
);
|
|
125
|
+
}),
|
|
126
|
+
renderInput: (params) => /* @__PURE__ */ jsx(
|
|
127
|
+
TextField,
|
|
128
|
+
{
|
|
129
|
+
...params,
|
|
130
|
+
placeholder: t("rosDialog.appliesToPlaceholder")
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
loadingText: t("rosDialog.appliesToLoading"),
|
|
134
|
+
noOptionsText: t("rosDialog.appliesToNoOptions")
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
selectedEntityRefs.length > 1 && /* @__PURE__ */ jsx(FormHelperText, { children: t("rosDialog.appliesToSystemRosHint") }),
|
|
138
|
+
fieldState.isDirty && /* @__PURE__ */ jsx(
|
|
139
|
+
Alert,
|
|
140
|
+
{
|
|
141
|
+
status: "info",
|
|
142
|
+
icon: true,
|
|
143
|
+
description: t("rosDialog.appliesToNightlyRefreshHint")
|
|
144
|
+
}
|
|
145
|
+
),
|
|
146
|
+
isMissingCurrentEntityRef && /* @__PURE__ */ jsx(
|
|
147
|
+
Alert,
|
|
148
|
+
{
|
|
149
|
+
status: "warning",
|
|
150
|
+
icon: true,
|
|
151
|
+
description: t("rosDialog.appliesToMissingCurrentEntity", {
|
|
152
|
+
entityRef: currentEntityRef
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
),
|
|
156
|
+
missingEntityRefs.length > 0 && /* @__PURE__ */ jsx(
|
|
157
|
+
Alert,
|
|
158
|
+
{
|
|
159
|
+
status: "warning",
|
|
160
|
+
icon: true,
|
|
161
|
+
description: t("rosDialog.appliesToMissingEntities", {
|
|
162
|
+
entityRefs: missingEntityRefs.map(formatBackstageAppliesTo).join(", ")
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
] });
|
|
167
|
+
}
|
|
168
|
+
function ensureNullOrCurrentEntityRefAsHead(entityRefs, currentEntityRef) {
|
|
169
|
+
const currentValue = [
|
|
170
|
+
currentEntityRef,
|
|
171
|
+
...new Set(entityRefs.filter((it) => it !== currentEntityRef))
|
|
172
|
+
];
|
|
173
|
+
if (currentValue.length === 1) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
return currentValue;
|
|
177
|
+
}
|
|
178
|
+
function formatBackstageAppliesTo(appliesTo) {
|
|
179
|
+
return appliesTo.startsWith(backstageAppliesToPrefix) ? appliesTo.slice(backstageAppliesToPrefix.length) : appliesTo;
|
|
180
|
+
}
|
|
181
|
+
function getIsMissingCurrentEntityRef(entityRefs, currentEntityRef) {
|
|
182
|
+
return entityRefs.length > 0 && !entityRefs.includes(currentEntityRef);
|
|
183
|
+
}
|
|
184
|
+
function getMissingEntityRefs(entityRefs, catalogEntityRefs) {
|
|
185
|
+
return entityRefs.filter((entityRef) => !catalogEntityRefs.includes(entityRef));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export { AppliesToField };
|
|
189
|
+
//# sourceMappingURL=AppliesToField.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppliesToField.esm.js","sources":["../../../src/components/riScDialog/AppliesToField.tsx"],"sourcesContent":["import { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { RELATION_PART_OF, stringifyEntityRef } from '@backstage/catalog-model';\nimport { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { Alert } from '@backstage/ui';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Chip from '@mui/material/Chip';\nimport FormControl from '@mui/material/FormControl';\nimport FormHelperText from '@mui/material/FormHelperText';\nimport FormLabel from '@mui/material/FormLabel';\nimport TextField from '@mui/material/TextField';\nimport { useEffect, useState } from 'react';\nimport { Control, useController } from 'react-hook-form';\nimport { pluginRiScTranslationRef } from '../../utils/translations';\nimport { RiScWithMetadata } from '../../utils/types';\nimport formStyles from '../common/formStyles.module.css';\nimport { entityRefOptionFields, getCurrentSystemRef } from './entityRefOptions';\n\nconst backstageAppliesToPrefix = 'backstage:';\n\ntype AppliesToFieldProps = {\n control: Control<RiScWithMetadata>;\n};\n\nexport function AppliesToField({ control }: AppliesToFieldProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n const catalogApi = useApi(catalogApiRef);\n const configApi = useApi(configApiRef);\n const includeAllEntities =\n configApi.getOptionalBoolean(\n 'riskScorecard.appliesTo.includeAllEntities',\n ) ?? false;\n const [catalogEntityRefs, setCatalogEntityRefs] = useState<string[]>([]);\n const [isLoadingOptions, setIsLoadingOptions] = useState(false);\n const { field, fieldState } = useController({\n control,\n name: 'content.unencryptedMetadata.appliesTo',\n });\n const { entity } = useEntity();\n const currentEntityRef = stringifyEntityRef(entity);\n const currentPrefixedEntityRef = backstageAppliesToPrefix + currentEntityRef;\n // Ensure that it always looks as if currentRef is saved, but we only save it if at least two refs are selected\n const selectedEntityRefs = field.value ?? [currentPrefixedEntityRef];\n const isMissingCurrentEntityRef = getIsMissingCurrentEntityRef(\n selectedEntityRefs,\n currentPrefixedEntityRef,\n );\n // Avoid missing-entity warnings until catalog refs have loaded. On an entity\n // page, a successful fetch should at least contain the current entity.\n const missingEntityRefs =\n catalogEntityRefs.length > 0\n ? getMissingEntityRefs(\n selectedEntityRefs.filter(ref => ref !== currentPrefixedEntityRef),\n catalogEntityRefs,\n )\n : [];\n\n useEffect(() => {\n let cancelled = false;\n const currentSystemRef = getCurrentSystemRef(entity);\n setIsLoadingOptions(true);\n setCatalogEntityRefs([]);\n\n const sameSystemEntitiesPromise = currentSystemRef\n ? catalogApi\n .getEntities({\n fields: entityRefOptionFields,\n filter: {\n [`relations.${RELATION_PART_OF}`]: currentSystemRef,\n },\n })\n .catch(() => ({ items: [] }))\n : Promise.resolve({ items: [] });\n\n Promise.all([\n sameSystemEntitiesPromise,\n includeAllEntities\n ? catalogApi.getEntities({\n fields: entityRefOptionFields,\n })\n : Promise.resolve({ items: [] }),\n ])\n .then(([sameSystemEntitiesResponse, allEntitiesResponse]) => {\n if (cancelled) {\n return;\n }\n\n setCatalogEntityRefs(\n Array.from(\n new Set(\n [\n ...sameSystemEntitiesResponse.items,\n ...allEntitiesResponse.items,\n ].map(\n optionEntity =>\n backstageAppliesToPrefix + stringifyEntityRef(optionEntity),\n ),\n ),\n ),\n );\n })\n .catch(() => {\n if (!cancelled) {\n setCatalogEntityRefs([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoadingOptions(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [catalogApi, entity, includeAllEntities]);\n\n function handleChange(_: unknown, value: string[]) {\n field.onChange(\n ensureNullOrCurrentEntityRefAsHead(value, currentPrefixedEntityRef),\n );\n }\n\n return (\n <FormControl className={formStyles.formControl}>\n <FormLabel className={formStyles.formLabel}>\n {t('rosDialog.appliesTo')}\n </FormLabel>\n <FormHelperText className={formStyles.formHelperText}>\n {t('rosDialog.appliesToDescription')}\n </FormHelperText>\n <Autocomplete<string, true, false, false>\n multiple\n disablePortal\n filterSelectedOptions\n loading={isLoadingOptions}\n options={catalogEntityRefs}\n value={selectedEntityRefs}\n getOptionLabel={formatBackstageAppliesTo}\n isOptionEqualToValue={(option, value) => option === value}\n onChange={handleChange}\n renderValue={(value, getItemProps) =>\n value.map((prefixedEntityRef, index) => {\n const tagProps = getItemProps({ index });\n const { key, onDelete, ...restTagProps } = tagProps;\n const isCurrentEntity =\n prefixedEntityRef === currentPrefixedEntityRef;\n\n return (\n <Chip\n key={key}\n label={formatBackstageAppliesTo(prefixedEntityRef)}\n color={isCurrentEntity ? 'primary' : 'default'}\n variant={isCurrentEntity ? 'filled' : 'outlined'}\n onDelete={isCurrentEntity ? undefined : onDelete}\n {...restTagProps}\n />\n );\n })\n }\n renderInput={params => (\n <TextField\n {...params}\n placeholder={t('rosDialog.appliesToPlaceholder')}\n />\n )}\n loadingText={t('rosDialog.appliesToLoading')}\n noOptionsText={t('rosDialog.appliesToNoOptions')}\n />\n {selectedEntityRefs.length > 1 && (\n <FormHelperText>{t('rosDialog.appliesToSystemRosHint')}</FormHelperText>\n )}\n {fieldState.isDirty && (\n <Alert\n status=\"info\"\n icon\n description={t('rosDialog.appliesToNightlyRefreshHint')}\n />\n )}\n {isMissingCurrentEntityRef && (\n <Alert\n status=\"warning\"\n icon\n description={t('rosDialog.appliesToMissingCurrentEntity', {\n entityRef: currentEntityRef,\n })}\n />\n )}\n {missingEntityRefs.length > 0 && (\n <Alert\n status=\"warning\"\n icon\n description={t('rosDialog.appliesToMissingEntities', {\n entityRefs: missingEntityRefs\n .map(formatBackstageAppliesTo)\n .join(', '),\n })}\n />\n )}\n </FormControl>\n );\n}\n\nfunction ensureNullOrCurrentEntityRefAsHead(\n entityRefs: string[],\n currentEntityRef: string,\n): string[] | null {\n const currentValue = [\n currentEntityRef,\n ...new Set(entityRefs.filter(it => it !== currentEntityRef)),\n ];\n if (currentValue.length === 1) {\n // React Hook Form does not support undefined field values; DTO serialization normalizes null by omitting appliesTo.\n return null;\n }\n\n return currentValue;\n}\n\nfunction formatBackstageAppliesTo(appliesTo: string): string {\n return appliesTo.startsWith(backstageAppliesToPrefix)\n ? appliesTo.slice(backstageAppliesToPrefix.length)\n : appliesTo;\n}\n\nfunction getIsMissingCurrentEntityRef(\n entityRefs: string[],\n currentEntityRef: string,\n): boolean {\n return entityRefs.length > 0 && !entityRefs.includes(currentEntityRef);\n}\n\nfunction getMissingEntityRefs(\n entityRefs: string[],\n catalogEntityRefs: string[],\n): string[] {\n return entityRefs.filter(entityRef => !catalogEntityRefs.includes(entityRef));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAM,wBAAA,GAA2B,YAAA;AAM1B,SAAS,cAAA,CAAe,EAAE,OAAA,EAAQ,EAAwB;AAC/D,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AACxD,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,qBACJ,SAAA,CAAU,kBAAA;AAAA,IACR;AAAA,GACF,IAAK,KAAA;AACP,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AACvE,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9D,EAAA,MAAM,EAAE,KAAA,EAAO,UAAA,EAAW,GAAI,aAAA,CAAc;AAAA,IAC1C,OAAA;AAAA,IACA,IAAA,EAAM;AAAA,GACP,CAAA;AACD,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,gBAAA,GAAmB,mBAAmB,MAAM,CAAA;AAClD,EAAA,MAAM,2BAA2B,wBAAA,GAA2B,gBAAA;AAE5D,EAAA,MAAM,kBAAA,GAAqB,KAAA,CAAM,KAAA,IAAS,CAAC,wBAAwB,CAAA;AACnE,EAAA,MAAM,yBAAA,GAA4B,4BAAA;AAAA,IAChC,kBAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,MAAM,iBAAA,GACJ,iBAAA,CAAkB,MAAA,GAAS,CAAA,GACvB,oBAAA;AAAA,IACE,kBAAA,CAAmB,MAAA,CAAO,CAAA,GAAA,KAAO,GAAA,KAAQ,wBAAwB,CAAA;AAAA,IACjE;AAAA,MAEF,EAAC;AAEP,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,MAAM,gBAAA,GAAmB,oBAAoB,MAAM,CAAA;AACnD,IAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,IAAA,oBAAA,CAAqB,EAAE,CAAA;AAEvB,IAAA,MAAM,yBAAA,GAA4B,gBAAA,GAC9B,UAAA,CACG,WAAA,CAAY;AAAA,MACX,MAAA,EAAQ,qBAAA;AAAA,MACR,MAAA,EAAQ;AAAA,QACN,CAAC,CAAA,UAAA,EAAa,gBAAgB,CAAA,CAAE,GAAG;AAAA;AACrC,KACD,CAAA,CACA,KAAA,CAAM,OAAO,EAAE,OAAO,EAAC,EAAE,CAAE,CAAA,GAC9B,QAAQ,OAAA,CAAQ,EAAE,KAAA,EAAO,IAAI,CAAA;AAEjC,IAAA,OAAA,CAAQ,GAAA,CAAI;AAAA,MACV,yBAAA;AAAA,MACA,kBAAA,GACI,WAAW,WAAA,CAAY;AAAA,QACrB,MAAA,EAAQ;AAAA,OACT,IACD,OAAA,CAAQ,OAAA,CAAQ,EAAE,KAAA,EAAO,IAAI;AAAA,KAClC,CAAA,CACE,IAAA,CAAK,CAAC,CAAC,0BAAA,EAA4B,mBAAmB,CAAA,KAAM;AAC3D,MAAA,IAAI,SAAA,EAAW;AACb,QAAA;AAAA,MACF;AAEA,MAAA,oBAAA;AAAA,QACE,KAAA,CAAM,IAAA;AAAA,UACJ,IAAI,GAAA;AAAA,YACF;AAAA,cACE,GAAG,0BAAA,CAA2B,KAAA;AAAA,cAC9B,GAAG,mBAAA,CAAoB;AAAA,aACzB,CAAE,GAAA;AAAA,cACA,CAAA,YAAA,KACE,wBAAA,GAA2B,kBAAA,CAAmB,YAAY;AAAA;AAC9D;AACF;AACF,OACF;AAAA,IACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,oBAAA,CAAqB,EAAE,CAAA;AAAA,MACzB;AAAA,IACF,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,mBAAA,CAAoB,KAAK,CAAA;AAAA,MAC3B;AAAA,IACF,CAAC,CAAA;AAEH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,MAAA,EAAQ,kBAAkB,CAAC,CAAA;AAE3C,EAAA,SAAS,YAAA,CAAa,GAAY,KAAA,EAAiB;AACjD,IAAA,KAAA,CAAM,QAAA;AAAA,MACJ,kCAAA,CAAmC,OAAO,wBAAwB;AAAA,KACpE;AAAA,EACF;AAEA,EAAA,uBACE,IAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAW,UAAA,CAAW,WAAA,EACjC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,aAAU,SAAA,EAAW,UAAA,CAAW,SAAA,EAC9B,QAAA,EAAA,CAAA,CAAE,qBAAqB,CAAA,EAC1B,CAAA;AAAA,wBACC,cAAA,EAAA,EAAe,SAAA,EAAW,WAAW,cAAA,EACnC,QAAA,EAAA,CAAA,CAAE,gCAAgC,CAAA,EACrC,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAQ,IAAA;AAAA,QACR,aAAA,EAAa,IAAA;AAAA,QACb,qBAAA,EAAqB,IAAA;AAAA,QACrB,OAAA,EAAS,gBAAA;AAAA,QACT,OAAA,EAAS,iBAAA;AAAA,QACT,KAAA,EAAO,kBAAA;AAAA,QACP,cAAA,EAAgB,wBAAA;AAAA,QAChB,oBAAA,EAAsB,CAAC,MAAA,EAAQ,KAAA,KAAU,MAAA,KAAW,KAAA;AAAA,QACpD,QAAA,EAAU,YAAA;AAAA,QACV,WAAA,EAAa,CAAC,KAAA,EAAO,YAAA,KACnB,MAAM,GAAA,CAAI,CAAC,mBAAmB,KAAA,KAAU;AACtC,UAAA,MAAM,QAAA,GAAW,YAAA,CAAa,EAAE,KAAA,EAAO,CAAA;AACvC,UAAA,MAAM,EAAE,GAAA,EAAK,QAAA,EAAU,GAAG,cAAa,GAAI,QAAA;AAC3C,UAAA,MAAM,kBACJ,iBAAA,KAAsB,wBAAA;AAExB,UAAA,uBACE,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cAEC,KAAA,EAAO,yBAAyB,iBAAiB,CAAA;AAAA,cACjD,KAAA,EAAO,kBAAkB,SAAA,GAAY,SAAA;AAAA,cACrC,OAAA,EAAS,kBAAkB,QAAA,GAAW,UAAA;AAAA,cACtC,QAAA,EAAU,kBAAkB,MAAA,GAAY,QAAA;AAAA,cACvC,GAAG;AAAA,aAAA;AAAA,YALC;AAAA,WAMP;AAAA,QAEJ,CAAC,CAAA;AAAA,QAEH,aAAa,CAAA,MAAA,qBACX,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACE,GAAG,MAAA;AAAA,YACJ,WAAA,EAAa,EAAE,gCAAgC;AAAA;AAAA,SACjD;AAAA,QAEF,WAAA,EAAa,EAAE,4BAA4B,CAAA;AAAA,QAC3C,aAAA,EAAe,EAAE,8BAA8B;AAAA;AAAA,KACjD;AAAA,IACC,mBAAmB,MAAA,GAAS,CAAA,wBAC1B,cAAA,EAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,kCAAkC,CAAA,EAAE,CAAA;AAAA,IAExD,WAAW,OAAA,oBACV,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAO,MAAA;AAAA,QACP,IAAA,EAAI,IAAA;AAAA,QACJ,WAAA,EAAa,EAAE,uCAAuC;AAAA;AAAA,KACxD;AAAA,IAED,yBAAA,oBACC,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAI,IAAA;AAAA,QACJ,WAAA,EAAa,EAAE,yCAAA,EAA2C;AAAA,UACxD,SAAA,EAAW;AAAA,SACZ;AAAA;AAAA,KACH;AAAA,IAED,iBAAA,CAAkB,SAAS,CAAA,oBAC1B,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAI,IAAA;AAAA,QACJ,WAAA,EAAa,EAAE,oCAAA,EAAsC;AAAA,UACnD,YAAY,iBAAA,CACT,GAAA,CAAI,wBAAwB,CAAA,CAC5B,KAAK,IAAI;AAAA,SACb;AAAA;AAAA;AACH,GAAA,EAEJ,CAAA;AAEJ;AAEA,SAAS,kCAAA,CACP,YACA,gBAAA,EACiB;AACjB,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,gBAAA;AAAA,IACA,GAAG,IAAI,GAAA,CAAI,UAAA,CAAW,OAAO,CAAA,EAAA,KAAM,EAAA,KAAO,gBAAgB,CAAC;AAAA,GAC7D;AACA,EAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAE7B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,yBAAyB,SAAA,EAA2B;AAC3D,EAAA,OAAO,SAAA,CAAU,WAAW,wBAAwB,CAAA,GAChD,UAAU,KAAA,CAAM,wBAAA,CAAyB,MAAM,CAAA,GAC/C,SAAA;AACN;AAEA,SAAS,4BAAA,CACP,YACA,gBAAA,EACS;AACT,EAAA,OAAO,WAAW,MAAA,GAAS,CAAA,IAAK,CAAC,UAAA,CAAW,SAAS,gBAAgB,CAAA;AACvE;AAEA,SAAS,oBAAA,CACP,YACA,iBAAA,EACU;AACV,EAAA,OAAO,WAAW,MAAA,CAAO,CAAA,SAAA,KAAa,CAAC,iBAAA,CAAkB,QAAA,CAAS,SAAS,CAAC,CAAA;AAC9E;;;;"}
|
|
@@ -4,9 +4,12 @@ import { Input } from '../common/Input.esm.js';
|
|
|
4
4
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
5
5
|
import { pluginRiScTranslationRef } from '../../utils/translations.esm.js';
|
|
6
6
|
import { Flex } from '@backstage/ui';
|
|
7
|
+
import { AppliesToField } from './AppliesToField.esm.js';
|
|
8
|
+
import { useSystemRiScsFeatureFlag } from '../../utils/featureFlags.esm.js';
|
|
7
9
|
|
|
8
10
|
function ConfigRiscInfo(props) {
|
|
9
11
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
12
|
+
const isSystemRiScsEnabled = useSystemRiScsFeatureFlag();
|
|
10
13
|
const currentScope = props.watch("content.scope");
|
|
11
14
|
return /* @__PURE__ */ jsxs(Flex, { gap: "16px", direction: "column", px: "1px", children: [
|
|
12
15
|
/* @__PURE__ */ jsx(
|
|
@@ -19,6 +22,7 @@ function ConfigRiscInfo(props) {
|
|
|
19
22
|
helperText: props.errors?.content?.title && t("rosDialog.titleError")
|
|
20
23
|
}
|
|
21
24
|
),
|
|
25
|
+
isSystemRiScsEnabled && /* @__PURE__ */ jsx(AppliesToField, { control: props.control }),
|
|
22
26
|
/* @__PURE__ */ jsx(
|
|
23
27
|
MarkdownInput,
|
|
24
28
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigRiscInfo.esm.js","sources":["../../../src/components/riScDialog/ConfigRiscInfo.tsx"],"sourcesContent":["import { MarkdownInput } from '../common/MarkdownInput';\nimport { Input } from '../common/Input';\nimport {\n UseFormRegister,\n UseFormSetValue,\n UseFormWatch,\n} from 'react-hook-form';\nimport { RiScWithMetadata } from '../../utils/types';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations';\nimport { FieldErrors } from 'react-hook-form';\nimport { Flex } from '@backstage/ui';\n\ninterface ConfigRiscInfoProps {\n register: UseFormRegister<RiScWithMetadata>;\n errors: FieldErrors<RiScWithMetadata>;\n setValue: UseFormSetValue<RiScWithMetadata>;\n watch: UseFormWatch<RiScWithMetadata>;\n}\n\nfunction ConfigRiscInfo(props: ConfigRiscInfoProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n const currentScope = props.watch('content.scope');\n return (\n <Flex gap=\"16px\" direction=\"column\" px=\"1px\">\n <Input\n required\n {...props.register('content.title', { required: true })}\n error={props.errors?.content?.title !== undefined}\n label={t('dictionary.title')}\n helperText={props.errors?.content?.title && t('rosDialog.titleError')}\n />\n <MarkdownInput\n {...props.register('content.scope')}\n value={currentScope}\n label={t('dictionary.scope')}\n sublabel={t('rosDialog.scopeDescription')}\n error={props.errors?.content?.scope !== undefined}\n minRows={8}\n onMarkdownChange={value => props.setValue('content.scope', value)}\n />\n </Flex>\n );\n}\n\nexport default ConfigRiscInfo;\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConfigRiscInfo.esm.js","sources":["../../../src/components/riScDialog/ConfigRiscInfo.tsx"],"sourcesContent":["import { MarkdownInput } from '../common/MarkdownInput';\nimport { Input } from '../common/Input';\nimport {\n Control,\n UseFormRegister,\n UseFormSetValue,\n UseFormWatch,\n} from 'react-hook-form';\nimport { RiScWithMetadata } from '../../utils/types';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations';\nimport { FieldErrors } from 'react-hook-form';\nimport { Flex } from '@backstage/ui';\nimport { AppliesToField } from './AppliesToField';\nimport { useSystemRiScsFeatureFlag } from '../../utils/featureFlags';\n\ninterface ConfigRiscInfoProps {\n register: UseFormRegister<RiScWithMetadata>;\n errors: FieldErrors<RiScWithMetadata>;\n setValue: UseFormSetValue<RiScWithMetadata>;\n watch: UseFormWatch<RiScWithMetadata>;\n control: Control<RiScWithMetadata>;\n}\n\nfunction ConfigRiscInfo(props: ConfigRiscInfoProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n const isSystemRiScsEnabled = useSystemRiScsFeatureFlag();\n const currentScope = props.watch('content.scope');\n\n return (\n <Flex gap=\"16px\" direction=\"column\" px=\"1px\">\n <Input\n required\n {...props.register('content.title', { required: true })}\n error={props.errors?.content?.title !== undefined}\n label={t('dictionary.title')}\n helperText={props.errors?.content?.title && t('rosDialog.titleError')}\n />\n {isSystemRiScsEnabled && <AppliesToField control={props.control} />}\n <MarkdownInput\n {...props.register('content.scope')}\n value={currentScope}\n label={t('dictionary.scope')}\n sublabel={t('rosDialog.scopeDescription')}\n error={props.errors?.content?.scope !== undefined}\n minRows={8}\n onMarkdownChange={value => props.setValue('content.scope', value)}\n />\n </Flex>\n );\n}\n\nexport default ConfigRiscInfo;\n"],"names":[],"mappings":";;;;;;;;;AAwBA,SAAS,eAAe,KAAA,EAA4B;AAClD,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AACxD,EAAA,MAAM,uBAAuB,yBAAA,EAA0B;AACvD,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,KAAA,CAAM,eAAe,CAAA;AAEhD,EAAA,4BACG,IAAA,EAAA,EAAK,GAAA,EAAI,QAAO,SAAA,EAAU,QAAA,EAAS,IAAG,KAAA,EACrC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAQ,IAAA;AAAA,QACP,GAAG,KAAA,CAAM,QAAA,CAAS,iBAAiB,EAAE,QAAA,EAAU,MAAM,CAAA;AAAA,QACtD,KAAA,EAAO,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,KAAU,MAAA;AAAA,QACxC,KAAA,EAAO,EAAE,kBAAkB,CAAA;AAAA,QAC3B,YAAY,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,IAAS,EAAE,sBAAsB;AAAA;AAAA,KACtE;AAAA,IACC,oBAAA,oBAAwB,GAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAS,MAAM,OAAA,EAAS,CAAA;AAAA,oBACjE,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA,CAAM,QAAA,CAAS,eAAe,CAAA;AAAA,QAClC,KAAA,EAAO,YAAA;AAAA,QACP,KAAA,EAAO,EAAE,kBAAkB,CAAA;AAAA,QAC3B,QAAA,EAAU,EAAE,4BAA4B,CAAA;AAAA,QACxC,KAAA,EAAO,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,KAAU,MAAA;AAAA,QACxC,OAAA,EAAS,CAAA;AAAA,QACT,gBAAA,EAAkB,CAAA,KAAA,KAAS,KAAA,CAAM,QAAA,CAAS,iBAAiB,KAAK;AAAA;AAAA;AAClE,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -52,7 +52,8 @@ function RiScDialog({
|
|
|
52
52
|
handleSubmit,
|
|
53
53
|
watch,
|
|
54
54
|
formState: { errors },
|
|
55
|
-
setValue
|
|
55
|
+
setValue,
|
|
56
|
+
control
|
|
56
57
|
} = useForm({
|
|
57
58
|
defaultValues: dialogState === 2 /* EditRiscInfo */ || dialogState === 4 /* EditEncryption */ ? selectedRiSc : {
|
|
58
59
|
content: emptyRiSc(),
|
|
@@ -164,7 +165,8 @@ function RiScDialog({
|
|
|
164
165
|
register,
|
|
165
166
|
errors,
|
|
166
167
|
setValue,
|
|
167
|
-
watch
|
|
168
|
+
watch,
|
|
169
|
+
control
|
|
168
170
|
}
|
|
169
171
|
),
|
|
170
172
|
activeStep === 2 && /* @__PURE__ */ jsx(
|
|
@@ -230,7 +232,8 @@ function RiScDialog({
|
|
|
230
232
|
register,
|
|
231
233
|
errors,
|
|
232
234
|
setValue,
|
|
233
|
-
watch
|
|
235
|
+
watch,
|
|
236
|
+
control
|
|
234
237
|
}
|
|
235
238
|
),
|
|
236
239
|
/* @__PURE__ */ jsxs(Flex, { justify: "between", pt: "16px", children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RiScDialog.esm.js","sources":["../../../src/components/riScDialog/RiScDialog.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { RiScWithMetadata } from '../../utils/types';\nimport { emptyRiSc, isDeeplyEqual } from '../../utils/utilityfunctions';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations';\nimport { useRiScs } from '../../contexts/RiScContext';\nimport { useForm } from 'react-hook-form';\nimport { Step, StepLabel, Stepper } from '@mui/material';\nimport ConfigEncryptionDialog from './ConfigEncryptionDialog';\nimport ConfigRiscInfo from './ConfigRiscInfo';\nimport ConfigInitialRisc from './ConfigInitialRisc';\nimport { Flex, Button, Text } from '@backstage/ui';\nimport styles from './RiScDialog.module.css';\nimport { useDefaultRiScTypeDescriptors } from '../../contexts/DefaultRiScTypesContext.tsx';\nimport DialogComponent from '../dialog/DialogComponent.tsx';\n\nexport enum RiScDialogStates {\n Closed = 0,\n Create = 1,\n EditRiscInfo = 2,\n SelectInitialRisc = 3,\n EditEncryption = 4,\n Delete = 5,\n}\n\ninterface RiScDialogProps {\n onClose: () => void;\n dialogState: RiScDialogStates;\n onDelete: () => void;\n}\n\nfunction RiScStepper({ activeStep }: { activeStep: number }) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const steps = [\n t('rosDialog.initialRiscTitle'),\n t('rosDialog.stepRiscDetails'),\n t('rosDialog.stepEncryption'),\n ];\n return (\n <Stepper activeStep={activeStep} alternativeLabel>\n {steps.map(label => (\n <Step key={label}>\n <StepLabel>\n <Text>{label}</Text>\n </StepLabel>\n </Step>\n ))}\n </Stepper>\n );\n}\n\nexport function RiScDialog({\n onClose,\n dialogState,\n onDelete,\n}: RiScDialogProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const {\n selectedRiSc,\n riScs,\n selectRiSc,\n createNewRiSc,\n deleteRiSc,\n updateRiSc,\n gcpCryptoKeys,\n } = useRiScs();\n const {\n register,\n handleSubmit,\n watch,\n formState: { errors },\n setValue,\n } = useForm<RiScWithMetadata>({\n defaultValues:\n dialogState === RiScDialogStates.EditRiscInfo ||\n dialogState === RiScDialogStates.EditEncryption\n ? selectedRiSc!\n : {\n content: emptyRiSc(),\n sopsConfig: {\n shamir_threshold: 2,\n },\n },\n mode: 'onBlur',\n });\n\n const [activeStep, setActiveStep] = useState(0);\n\n const [switchOn, setSwitchOn] = useState(false);\n\n const { riScSelectedByDefault } = useDefaultRiScTypeDescriptors();\n const [selectedRiScId, setSelectedRiScId] = useState<string | undefined>(\n riScSelectedByDefault?.id,\n );\n useEffect(() => {\n setSelectedRiScId(riScSelectedByDefault?.id);\n }, [riScSelectedByDefault]);\n\n const handleNext = handleSubmit(\n () => {\n if (activeStep === 0) {\n setActiveStep(1);\n }\n if (activeStep === 1) {\n setActiveStep(2);\n }\n },\n // Continue to step 1 even if there are errors, as long as there are no errors in step 0 (the content)\n validationErrors => {\n if (validationErrors.content === undefined) {\n if (activeStep === 0) setActiveStep(1);\n if (activeStep === 1) setActiveStep(2);\n }\n },\n );\n\n function handleBack() {\n if (activeStep === 1) setActiveStep(0);\n if (activeStep === 2) setActiveStep(1);\n }\n\n const handleFinish = handleSubmit((data: RiScWithMetadata) => {\n if (dialogState === RiScDialogStates.Create) {\n createNewRiSc(data, switchOn, selectedRiScId);\n } else if (dialogState === RiScDialogStates.Delete) {\n deleteRiSc(() =>\n selectRiSc(riScs && riScs.length > 0 ? riScs[0].id : ''),\n );\n } else {\n // Do manual comparison of contents, as the sopsConfig field contains many values from the backend that are not\n // used or set by the frontend.\n // Check if the additional Age keys are equal, using the single important field, `recipient`\n const areAgeKeysEqual = isDeeplyEqual(\n data.sopsConfig.age?.map(age => age.recipient).sort(),\n selectedRiSc?.sopsConfig.age?.map(age => age.recipient).sort(),\n );\n\n // Check if the GCP keys are equal, using the two important fields, `resource_id` and `created_at`.\n // Comparison uses dictionaries, where resource ids are keys and created at dates are values\n const areGCPKeysEqual = isDeeplyEqual(\n Object.fromEntries(\n data.sopsConfig.gcp_kms?.map(key => [\n key.resource_id,\n key.created_at,\n ]) ?? [],\n ),\n Object.fromEntries(\n selectedRiSc?.sopsConfig.gcp_kms?.map(key => [\n key.resource_id,\n key.created_at,\n ]) ?? [],\n ),\n );\n\n // Only update the risc if it has changed\n if (\n !isDeeplyEqual(data, selectedRiSc, ['sopsConfig']) ||\n !areGCPKeysEqual ||\n !areAgeKeysEqual\n ) {\n updateRiSc(data);\n }\n }\n onClose();\n });\n\n if (dialogState === RiScDialogStates.Create) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('rosDialog.titleNew')}\n className={styles.createRiscDialog}\n >\n <RiScStepper activeStep={activeStep} />\n <Text\n as=\"h2\"\n variant=\"title-x-small\"\n weight=\"bold\"\n className={styles.subtitle}\n >\n {activeStep === 0 && t('rosDialog.initialRiscTitle')}\n {activeStep === 1 && t('rosDialog.titleAndScope')}\n {activeStep === 2 && t('rosDialog.stepEncryption')}\n </Text>\n {activeStep === 0 && (\n <ConfigInitialRisc\n switchOn={switchOn}\n setSwitchOn={setSwitchOn}\n setValue={setValue}\n selectedRiScId={selectedRiScId}\n setSelectedRiScId={setSelectedRiScId}\n />\n )}\n {activeStep === 1 && (\n <ConfigRiscInfo\n register={register}\n errors={errors}\n setValue={setValue}\n watch={watch}\n />\n )}\n {activeStep === 2 && (\n <ConfigEncryptionDialog\n gcpCryptoKeys={gcpCryptoKeys}\n setValue={setValue}\n state={dialogState}\n register={register}\n errors={errors}\n />\n )}\n <Flex pt=\"16px\" justify=\"between\">\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Flex>\n <Button\n size=\"medium\"\n variant=\"secondary\"\n isDisabled={activeStep === 0}\n onClick={handleBack}\n >\n {t('dictionary.previous')}\n </Button>\n {activeStep < 2 ? (\n <Button size=\"medium\" variant=\"primary\" onClick={handleNext}>\n {t('dictionary.next')}\n </Button>\n ) : (\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.save')}\n </Button>\n )}\n </Flex>\n </Flex>\n </DialogComponent>\n );\n }\n\n if (dialogState === RiScDialogStates.Delete) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('deleteDialog.title')}\n className={styles.createRiscDialog}\n >\n <Flex direction=\"column\">\n {t('deleteDialog.confirmationMessage')}\n <Flex justify=\"between\" pt=\"16px\">\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.delete')}\n </Button>\n </Flex>\n </Flex>\n </DialogComponent>\n );\n }\n\n if (dialogState === RiScDialogStates.EditRiscInfo) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('rosDialog.titleEdit')}\n className={styles.createRiscDialog}\n >\n <ConfigRiscInfo\n register={register}\n errors={errors}\n setValue={setValue}\n watch={watch}\n />\n <Flex justify=\"between\" pt=\"16px\">\n <Button\n size=\"medium\"\n variant=\"tertiary\"\n onClick={onDelete}\n className={styles.deleteButton}\n >\n <i className={`ri-delete-bin-line ${styles.deleteButtonIcon}`} />\n {t('contentHeader.deleteButton')}\n </Button>\n <Flex>\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.save')}\n </Button>\n </Flex>\n </Flex>\n </DialogComponent>\n );\n }\n\n if (dialogState === RiScDialogStates.EditEncryption) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('rosDialog.editEncryption')}\n className={styles.createRiscDialog}\n >\n <ConfigEncryptionDialog\n gcpCryptoKeys={gcpCryptoKeys}\n sopsData={selectedRiSc?.sopsConfig}\n setValue={setValue}\n state={dialogState}\n register={register}\n errors={errors}\n />\n <Flex justify=\"between\" pt=\"16px\">\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.save')}\n </Button>\n </Flex>\n </DialogComponent>\n );\n }\n\n return null;\n}\n"],"names":["RiScDialogStates","styles"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RiScDialog.esm.js","sources":["../../../src/components/riScDialog/RiScDialog.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { RiScWithMetadata } from '../../utils/types';\nimport { emptyRiSc, isDeeplyEqual } from '../../utils/utilityfunctions';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations';\nimport { useRiScs } from '../../contexts/RiScContext';\nimport { useForm } from 'react-hook-form';\nimport { Step, StepLabel, Stepper } from '@mui/material';\nimport ConfigEncryptionDialog from './ConfigEncryptionDialog';\nimport ConfigRiscInfo from './ConfigRiscInfo';\nimport ConfigInitialRisc from './ConfigInitialRisc';\nimport { Flex, Button, Text } from '@backstage/ui';\nimport styles from './RiScDialog.module.css';\nimport { useDefaultRiScTypeDescriptors } from '../../contexts/DefaultRiScTypesContext.tsx';\nimport DialogComponent from '../dialog/DialogComponent.tsx';\n\nexport enum RiScDialogStates {\n Closed = 0,\n Create = 1,\n EditRiscInfo = 2,\n SelectInitialRisc = 3,\n EditEncryption = 4,\n Delete = 5,\n}\n\ninterface RiScDialogProps {\n onClose: () => void;\n dialogState: RiScDialogStates;\n onDelete: () => void;\n}\n\nfunction RiScStepper({ activeStep }: { activeStep: number }) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const steps = [\n t('rosDialog.initialRiscTitle'),\n t('rosDialog.stepRiscDetails'),\n t('rosDialog.stepEncryption'),\n ];\n return (\n <Stepper activeStep={activeStep} alternativeLabel>\n {steps.map(label => (\n <Step key={label}>\n <StepLabel>\n <Text>{label}</Text>\n </StepLabel>\n </Step>\n ))}\n </Stepper>\n );\n}\n\nexport function RiScDialog({\n onClose,\n dialogState,\n onDelete,\n}: RiScDialogProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const {\n selectedRiSc,\n riScs,\n selectRiSc,\n createNewRiSc,\n deleteRiSc,\n updateRiSc,\n gcpCryptoKeys,\n } = useRiScs();\n const {\n register,\n handleSubmit,\n watch,\n formState: { errors },\n setValue,\n control,\n } = useForm<RiScWithMetadata>({\n defaultValues:\n dialogState === RiScDialogStates.EditRiscInfo ||\n dialogState === RiScDialogStates.EditEncryption\n ? selectedRiSc!\n : {\n content: emptyRiSc(),\n sopsConfig: {\n shamir_threshold: 2,\n },\n },\n mode: 'onBlur',\n });\n\n const [activeStep, setActiveStep] = useState(0);\n\n const [switchOn, setSwitchOn] = useState(false);\n\n const { riScSelectedByDefault } = useDefaultRiScTypeDescriptors();\n const [selectedRiScId, setSelectedRiScId] = useState<string | undefined>(\n riScSelectedByDefault?.id,\n );\n useEffect(() => {\n setSelectedRiScId(riScSelectedByDefault?.id);\n }, [riScSelectedByDefault]);\n\n const handleNext = handleSubmit(\n () => {\n if (activeStep === 0) {\n setActiveStep(1);\n }\n if (activeStep === 1) {\n setActiveStep(2);\n }\n },\n // Continue to step 1 even if there are errors, as long as there are no errors in step 0 (the content)\n validationErrors => {\n if (validationErrors.content === undefined) {\n if (activeStep === 0) setActiveStep(1);\n if (activeStep === 1) setActiveStep(2);\n }\n },\n );\n\n function handleBack() {\n if (activeStep === 1) setActiveStep(0);\n if (activeStep === 2) setActiveStep(1);\n }\n\n const handleFinish = handleSubmit((data: RiScWithMetadata) => {\n if (dialogState === RiScDialogStates.Create) {\n createNewRiSc(data, switchOn, selectedRiScId);\n } else if (dialogState === RiScDialogStates.Delete) {\n deleteRiSc(() =>\n selectRiSc(riScs && riScs.length > 0 ? riScs[0].id : ''),\n );\n } else {\n // Do manual comparison of contents, as the sopsConfig field contains many values from the backend that are not\n // used or set by the frontend.\n // Check if the additional Age keys are equal, using the single important field, `recipient`\n const areAgeKeysEqual = isDeeplyEqual(\n data.sopsConfig.age?.map(age => age.recipient).sort(),\n selectedRiSc?.sopsConfig.age?.map(age => age.recipient).sort(),\n );\n\n // Check if the GCP keys are equal, using the two important fields, `resource_id` and `created_at`.\n // Comparison uses dictionaries, where resource ids are keys and created at dates are values\n const areGCPKeysEqual = isDeeplyEqual(\n Object.fromEntries(\n data.sopsConfig.gcp_kms?.map(key => [\n key.resource_id,\n key.created_at,\n ]) ?? [],\n ),\n Object.fromEntries(\n selectedRiSc?.sopsConfig.gcp_kms?.map(key => [\n key.resource_id,\n key.created_at,\n ]) ?? [],\n ),\n );\n\n // Only update the risc if it has changed\n if (\n !isDeeplyEqual(data, selectedRiSc, ['sopsConfig']) ||\n !areGCPKeysEqual ||\n !areAgeKeysEqual\n ) {\n updateRiSc(data);\n }\n }\n onClose();\n });\n\n if (dialogState === RiScDialogStates.Create) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('rosDialog.titleNew')}\n className={styles.createRiscDialog}\n >\n <RiScStepper activeStep={activeStep} />\n <Text\n as=\"h2\"\n variant=\"title-x-small\"\n weight=\"bold\"\n className={styles.subtitle}\n >\n {activeStep === 0 && t('rosDialog.initialRiscTitle')}\n {activeStep === 1 && t('rosDialog.titleAndScope')}\n {activeStep === 2 && t('rosDialog.stepEncryption')}\n </Text>\n {activeStep === 0 && (\n <ConfigInitialRisc\n switchOn={switchOn}\n setSwitchOn={setSwitchOn}\n setValue={setValue}\n selectedRiScId={selectedRiScId}\n setSelectedRiScId={setSelectedRiScId}\n />\n )}\n {activeStep === 1 && (\n <ConfigRiscInfo\n register={register}\n errors={errors}\n setValue={setValue}\n watch={watch}\n control={control}\n />\n )}\n {activeStep === 2 && (\n <ConfigEncryptionDialog\n gcpCryptoKeys={gcpCryptoKeys}\n setValue={setValue}\n state={dialogState}\n register={register}\n errors={errors}\n />\n )}\n <Flex pt=\"16px\" justify=\"between\">\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Flex>\n <Button\n size=\"medium\"\n variant=\"secondary\"\n isDisabled={activeStep === 0}\n onClick={handleBack}\n >\n {t('dictionary.previous')}\n </Button>\n {activeStep < 2 ? (\n <Button size=\"medium\" variant=\"primary\" onClick={handleNext}>\n {t('dictionary.next')}\n </Button>\n ) : (\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.save')}\n </Button>\n )}\n </Flex>\n </Flex>\n </DialogComponent>\n );\n }\n\n if (dialogState === RiScDialogStates.Delete) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('deleteDialog.title')}\n className={styles.createRiscDialog}\n >\n <Flex direction=\"column\">\n {t('deleteDialog.confirmationMessage')}\n <Flex justify=\"between\" pt=\"16px\">\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.delete')}\n </Button>\n </Flex>\n </Flex>\n </DialogComponent>\n );\n }\n\n if (dialogState === RiScDialogStates.EditRiscInfo) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('rosDialog.titleEdit')}\n className={styles.createRiscDialog}\n >\n <ConfigRiscInfo\n register={register}\n errors={errors}\n setValue={setValue}\n watch={watch}\n control={control}\n />\n <Flex justify=\"between\" pt=\"16px\">\n <Button\n size=\"medium\"\n variant=\"tertiary\"\n onClick={onDelete}\n className={styles.deleteButton}\n >\n <i className={`ri-delete-bin-line ${styles.deleteButtonIcon}`} />\n {t('contentHeader.deleteButton')}\n </Button>\n <Flex>\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.save')}\n </Button>\n </Flex>\n </Flex>\n </DialogComponent>\n );\n }\n\n if (dialogState === RiScDialogStates.EditEncryption) {\n return (\n <DialogComponent\n isOpen={true}\n onClick={onClose}\n header={t('rosDialog.editEncryption')}\n className={styles.createRiscDialog}\n >\n <ConfigEncryptionDialog\n gcpCryptoKeys={gcpCryptoKeys}\n sopsData={selectedRiSc?.sopsConfig}\n setValue={setValue}\n state={dialogState}\n register={register}\n errors={errors}\n />\n <Flex justify=\"between\" pt=\"16px\">\n <Button size=\"medium\" variant=\"secondary\" onClick={onClose}>\n {t('dictionary.cancel')}\n </Button>\n <Button size=\"medium\" variant=\"primary\" onClick={handleFinish}>\n {t('dictionary.save')}\n </Button>\n </Flex>\n </DialogComponent>\n );\n }\n\n return null;\n}\n"],"names":["RiScDialogStates","styles"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { stringifyEntityRef, parseEntityRef } from '@backstage/catalog-model';
|
|
2
|
+
|
|
3
|
+
const entityRefOptionFields = [
|
|
4
|
+
"kind",
|
|
5
|
+
"metadata.name",
|
|
6
|
+
"metadata.namespace"
|
|
7
|
+
];
|
|
8
|
+
function getCurrentSystemRef(entity) {
|
|
9
|
+
if (entity.kind === "System") {
|
|
10
|
+
return stringifyEntityRef(entity);
|
|
11
|
+
}
|
|
12
|
+
const specSystem = entity.spec?.system;
|
|
13
|
+
if (typeof specSystem !== "string" || specSystem.trim() === "") {
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
return stringifyEntityRef(
|
|
17
|
+
parseEntityRef(specSystem, {
|
|
18
|
+
defaultKind: "System",
|
|
19
|
+
defaultNamespace: entity.metadata.namespace ?? "default"
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { entityRefOptionFields, getCurrentSystemRef };
|
|
25
|
+
//# sourceMappingURL=entityRefOptions.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entityRefOptions.esm.js","sources":["../../../src/components/riScDialog/entityRefOptions.ts"],"sourcesContent":["import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport type { Entity } from '@backstage/catalog-model';\n\nexport const entityRefOptionFields = [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n];\n\nexport function getCurrentSystemRef(entity: Entity): string | undefined {\n if (entity.kind === 'System') {\n return stringifyEntityRef(entity);\n }\n\n const specSystem = entity.spec?.system;\n if (typeof specSystem !== 'string' || specSystem.trim() === '') {\n return undefined;\n }\n\n return stringifyEntityRef(\n parseEntityRef(specSystem, {\n defaultKind: 'System',\n defaultNamespace: entity.metadata.namespace ?? 'default',\n }),\n );\n}\n"],"names":[],"mappings":";;AAGO,MAAM,qBAAA,GAAwB;AAAA,EACnC,MAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF;AAEO,SAAS,oBAAoB,MAAA,EAAoC;AACtE,EAAA,IAAI,MAAA,CAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,OAAO,mBAAmB,MAAM,CAAA;AAAA,EAClC;AAEA,EAAA,MAAM,UAAA,GAAa,OAAO,IAAA,EAAM,MAAA;AAChC,EAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,UAAA,CAAW,IAAA,OAAW,EAAA,EAAI;AAC9D,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,kBAAA;AAAA,IACL,eAAe,UAAA,EAAY;AAAA,MACzB,WAAA,EAAa,QAAA;AAAA,MACb,gBAAA,EAAkB,MAAA,CAAO,QAAA,CAAS,SAAA,IAAa;AAAA,KAChD;AAAA,GACH;AACF;;;;"}
|
|
@@ -10,22 +10,38 @@ import MUISelect from '@mui/material/Select';
|
|
|
10
10
|
import riscStyles from './RiScSelectionCard.module.css.esm.js';
|
|
11
11
|
|
|
12
12
|
function RiScSelectionCard() {
|
|
13
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
riScs,
|
|
15
|
+
lockedRiScs,
|
|
16
|
+
systemRiScs,
|
|
17
|
+
selectedRiSc,
|
|
18
|
+
selectedLockedRiSc,
|
|
19
|
+
selectedSystemRiSc,
|
|
20
|
+
selectRiSc
|
|
21
|
+
} = useRiScs();
|
|
14
22
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
15
|
-
const hasOptions = riScs !== null && riScs.length !== 0 || lockedRiScs.length !== 0;
|
|
23
|
+
const hasOptions = riScs !== null && riScs.length !== 0 || systemRiScs.length !== 0 || lockedRiScs.length !== 0;
|
|
16
24
|
return /* @__PURE__ */ jsx(Flex, { direction: "column", gap: "24px", children: hasOptions && /* @__PURE__ */ jsx(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsxs(
|
|
17
25
|
MUISelect,
|
|
18
26
|
{
|
|
19
|
-
value: selectedRiSc?.id ?? selectedLockedRiSc?.id ?? "",
|
|
27
|
+
value: selectedRiSc?.id ?? selectedSystemRiSc?.riScId ?? selectedLockedRiSc?.id ?? "",
|
|
20
28
|
onChange: (e) => selectRiSc(e.target.value),
|
|
21
29
|
inputProps: { "aria-label": t("contentHeader.multipleRiScs") },
|
|
22
30
|
MenuProps: { disablePortal: true },
|
|
23
31
|
children: [
|
|
24
32
|
(riScs ?? []).map((riSc) => /* @__PURE__ */ jsx(MenuItem, { value: riSc.id, children: riSc.content.title }, riSc.id)),
|
|
33
|
+
systemRiScs.length > 0 && /* @__PURE__ */ jsx(
|
|
34
|
+
ListSubheader,
|
|
35
|
+
{
|
|
36
|
+
className: `${riscStyles.sectionHeader} ${riScs && riScs.length > 0 ? riscStyles.sectionHeaderWithDivider : ""}`,
|
|
37
|
+
children: t("contentHeader.systemRiScsSection")
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
systemRiScs.map((riSc) => /* @__PURE__ */ jsx(MenuItem, { value: riSc.riScId, children: riSc.riScId }, riSc.riScId)),
|
|
25
41
|
lockedRiScs.length > 0 && /* @__PURE__ */ jsx(
|
|
26
42
|
ListSubheader,
|
|
27
43
|
{
|
|
28
|
-
className: `${riscStyles.
|
|
44
|
+
className: `${riscStyles.sectionHeader} ${riScs && riScs.length > 0 || systemRiScs.length > 0 ? riscStyles.sectionHeaderWithDivider : ""}`,
|
|
29
45
|
children: t("contentHeader.lockedRiScsSection")
|
|
30
46
|
}
|
|
31
47
|
),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RiScSelectionCard.esm.js","sources":["../../../src/components/riScInfo/RiScSelectionCard.tsx"],"sourcesContent":["import { useRiScs } from '../../contexts/RiScContext.tsx';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations.ts';\nimport { Flex } from '@backstage/ui';\nimport FormControl from '@mui/material/FormControl';\nimport ListSubheader from '@mui/material/ListSubheader';\nimport MenuItem from '@mui/material/MenuItem';\nimport MUISelect from '@mui/material/Select';\nimport styles from './RiScSelectionCard.module.css';\n\nexport function RiScSelectionCard() {\n const {
|
|
1
|
+
{"version":3,"file":"RiScSelectionCard.esm.js","sources":["../../../src/components/riScInfo/RiScSelectionCard.tsx"],"sourcesContent":["import { useRiScs } from '../../contexts/RiScContext.tsx';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations.ts';\nimport { Flex } from '@backstage/ui';\nimport FormControl from '@mui/material/FormControl';\nimport ListSubheader from '@mui/material/ListSubheader';\nimport MenuItem from '@mui/material/MenuItem';\nimport MUISelect from '@mui/material/Select';\nimport styles from './RiScSelectionCard.module.css';\n\nexport function RiScSelectionCard() {\n const {\n riScs,\n lockedRiScs,\n systemRiScs,\n selectedRiSc,\n selectedLockedRiSc,\n selectedSystemRiSc,\n selectRiSc,\n } = useRiScs();\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const hasOptions =\n (riScs !== null && riScs.length !== 0) ||\n systemRiScs.length !== 0 ||\n lockedRiScs.length !== 0;\n\n return (\n <Flex direction=\"column\" gap=\"24px\">\n {hasOptions && (\n <FormControl fullWidth size=\"small\">\n <MUISelect\n value={\n selectedRiSc?.id ??\n selectedSystemRiSc?.riScId ??\n selectedLockedRiSc?.id ??\n ''\n }\n onChange={e => selectRiSc(e.target.value)}\n inputProps={{ 'aria-label': t('contentHeader.multipleRiScs') }}\n MenuProps={{ disablePortal: true }}\n >\n {(riScs ?? []).map(riSc => (\n <MenuItem key={riSc.id} value={riSc.id}>\n {riSc.content.title}\n </MenuItem>\n ))}\n {systemRiScs.length > 0 && (\n <ListSubheader\n className={`${styles.sectionHeader} ${riScs && riScs.length > 0 ? styles.sectionHeaderWithDivider : ''}`}\n >\n {t('contentHeader.systemRiScsSection')}\n </ListSubheader>\n )}\n {systemRiScs.map(riSc => (\n <MenuItem key={riSc.riScId} value={riSc.riScId}>\n {riSc.riScId}\n </MenuItem>\n ))}\n {lockedRiScs.length > 0 && (\n <ListSubheader\n className={`${styles.sectionHeader} ${\n (riScs && riScs.length > 0) || systemRiScs.length > 0\n ? styles.sectionHeaderWithDivider\n : ''\n }`}\n >\n {t('contentHeader.lockedRiScsSection')}\n </ListSubheader>\n )}\n {lockedRiScs.map(riSc => (\n <MenuItem key={riSc.id} value={riSc.id}>\n 🔒 {riSc.id}\n </MenuItem>\n ))}\n </MUISelect>\n </FormControl>\n )}\n </Flex>\n );\n}\n"],"names":["styles"],"mappings":";;;;;;;;;;;AAUO,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,MACE,QAAA,EAAS;AACb,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,MAAM,UAAA,GACH,KAAA,KAAU,IAAA,IAAQ,KAAA,CAAM,MAAA,KAAW,KACpC,WAAA,CAAY,MAAA,KAAW,CAAA,IACvB,WAAA,CAAY,MAAA,KAAW,CAAA;AAEzB,EAAA,uBACE,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,GAAA,EAAI,MAAA,EAC1B,QAAA,EAAA,UAAA,oBACC,GAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAS,IAAA,EAAC,IAAA,EAAK,OAAA,EAC1B,QAAA,kBAAA,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,OACE,YAAA,EAAc,EAAA,IACd,kBAAA,EAAoB,MAAA,IACpB,oBAAoB,EAAA,IACpB,EAAA;AAAA,MAEF,QAAA,EAAU,CAAA,CAAA,KAAK,UAAA,CAAW,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,MACxC,UAAA,EAAY,EAAE,YAAA,EAAc,CAAA,CAAE,6BAA6B,CAAA,EAAE;AAAA,MAC7D,SAAA,EAAW,EAAE,aAAA,EAAe,IAAA,EAAK;AAAA,MAE/B,QAAA,EAAA;AAAA,QAAA,CAAA,KAAA,IAAS,EAAC,EAAG,GAAA,CAAI,CAAA,IAAA,yBAChB,QAAA,EAAA,EAAuB,KAAA,EAAO,IAAA,CAAK,EAAA,EACjC,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAA,EADD,IAAA,CAAK,EAEpB,CACD,CAAA;AAAA,QACA,WAAA,CAAY,SAAS,CAAA,oBACpB,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,CAAA,EAAGA,UAAA,CAAO,aAAa,CAAA,CAAA,EAAI,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,GAAIA,UAAA,CAAO,wBAAA,GAA2B,EAAE,CAAA,CAAA;AAAA,YAErG,YAAE,kCAAkC;AAAA;AAAA,SACvC;AAAA,QAED,WAAA,CAAY,GAAA,CAAI,CAAA,IAAA,qBACf,GAAA,CAAC,QAAA,EAAA,EAA2B,KAAA,EAAO,IAAA,CAAK,MAAA,EACrC,QAAA,EAAA,IAAA,CAAK,MAAA,EAAA,EADO,IAAA,CAAK,MAEpB,CACD,CAAA;AAAA,QACA,WAAA,CAAY,SAAS,CAAA,oBACpB,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,CAAA,EAAGA,UAAA,CAAO,aAAa,IAC/B,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,IAAM,WAAA,CAAY,MAAA,GAAS,CAAA,GAChDA,UAAA,CAAO,2BACP,EACN,CAAA,CAAA;AAAA,YAEC,YAAE,kCAAkC;AAAA;AAAA,SACvC;AAAA,QAED,YAAY,GAAA,CAAI,CAAA,IAAA,0BACd,QAAA,EAAA,EAAuB,KAAA,EAAO,KAAK,EAAA,EAAI,QAAA,EAAA;AAAA,UAAA,YAAA;AAAA,UAClC,IAAA,CAAK;AAAA,SAAA,EAAA,EADI,IAAA,CAAK,EAEpB,CACD;AAAA;AAAA;AAAA,KAEL,CAAA,EAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".
|
|
4
|
-
var riscStyles = {"
|
|
3
|
+
var css_248z = ".RiScSelectionCard_sectionHeader__2c941d3e94 {\n font-weight: 700;\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n background-color: inherit !important;\n}\n\n.RiScSelectionCard_sectionHeaderWithDivider__2c941d3e94 {\n border-top: 1px solid var(--ros-gray-200);\n margin-top: 4px;\n padding-top: 8px;\n}\n\n[role='listbox'] {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.RiScSelectionCard_riScInfoDialog__2c941d3e94 {\n padding: 24px;\n border-radius: 4px;\n width: 800px;\n}\n\n.RiScSelectionCard_riscSelectionDialogHeader__2c941d3e94 {\n padding: 0 0 16px 0;\n}\n\n.RiScSelectionCard_riscSelectionDialogBody__2c941d3e94 {\n gap: 16px;\n padding: 16px 0 0 0;\n}\n\n.RiScSelectionCard_riscDescriptionComponent__2c941d3e94 {\n padding-bottom: 10px;\n}\n.RiScSelectionCard_componentLayout__2c941d3e94 {\n height: 60%;\n}\n\n.RiScSelectionCard_riscDescriptionContainer__2c941d3e94 {\n margin-bottom: 16px;\n}\n\n.RiScSelectionCard_riScInfoDialog__2c941d3e94 {\n background-color: var(--bui-bg-app);\n}\n";
|
|
4
|
+
var riscStyles = {"sectionHeader":"RiScSelectionCard_sectionHeader__2c941d3e94","sectionHeaderWithDivider":"RiScSelectionCard_sectionHeaderWithDivider__2c941d3e94","riScInfoDialog":"RiScSelectionCard_riScInfoDialog__2c941d3e94","riscDescriptionComponent":"RiScSelectionCard_riscDescriptionComponent__2c941d3e94","componentLayout":"RiScSelectionCard_componentLayout__2c941d3e94","riscDescriptionContainer":"RiScSelectionCard_riscDescriptionContainer__2c941d3e94"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { riscStyles as default };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { ChangeSetBox } from './components/ChangeSetBox.esm.js';
|
|
3
|
+
import { ChangeSetBoxTitle } from './components/ChangeSetBoxTitle.esm.js';
|
|
4
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
5
|
+
import { pluginRiScTranslationRef } from '../../../utils/translations.esm.js';
|
|
6
|
+
import { ChangeSetAddedValue } from './components/ChangeSetAddedValue.esm.js';
|
|
7
|
+
import { ChangeSetRemovedValue } from './components/ChangeSetRemovedValue.esm.js';
|
|
8
|
+
import { ChangeSetSimpleBox } from './components/ChangeSetSimpleBox.esm.js';
|
|
9
|
+
|
|
10
|
+
function RiScAppliesToChange({
|
|
11
|
+
appliesToChanges
|
|
12
|
+
}) {
|
|
13
|
+
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
14
|
+
return /* @__PURE__ */ jsxs(ChangeSetBox, { type: "primary", children: [
|
|
15
|
+
/* @__PURE__ */ jsx(ChangeSetBoxTitle, { title: t("dictionary.appliesTo") }),
|
|
16
|
+
appliesToChanges.map((entityChange) => /* @__PURE__ */ jsxs("div", { children: [
|
|
17
|
+
entityChange.type === "ADDED" && /* @__PURE__ */ jsx(ChangeSetAddedValue, { newValue: entityChange.newValue }),
|
|
18
|
+
entityChange.type === "DELETED" && /* @__PURE__ */ jsx(ChangeSetRemovedValue, { oldValue: entityChange.oldValue }),
|
|
19
|
+
entityChange.type === "CONTENT_CHANGED" && /* @__PURE__ */ jsx(
|
|
20
|
+
ChangeSetSimpleBox,
|
|
21
|
+
{
|
|
22
|
+
prop: entityChange,
|
|
23
|
+
title: t("dictionary.appliesTo")
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
] }, JSON.stringify(entityChange)))
|
|
27
|
+
] });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { RiScAppliesToChange };
|
|
31
|
+
//# sourceMappingURL=RiScAppliesToChange.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RiScAppliesToChange.esm.js","sources":["../../../../src/components/riScInfo/changeset/RiScAppliesToChange.tsx"],"sourcesContent":["import { SimpleTrackedProperty } from '../../../utils/types.ts';\nimport { ChangeSetBox } from './components/ChangeSetBox.tsx';\nimport { ChangeSetBoxTitle } from './components/ChangeSetBoxTitle.tsx';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../../utils/translations.ts';\nimport { ChangeSetAddedValue } from './components/ChangeSetAddedValue.tsx';\nimport { ChangeSetRemovedValue } from './components/ChangeSetRemovedValue.tsx';\nimport { ChangeSetSimpleBox } from './components/ChangeSetSimpleBox.tsx';\n\ninterface RiScAppliesToChangeProps {\n appliesToChanges: SimpleTrackedProperty<string>[];\n}\n\nexport function RiScAppliesToChange({\n appliesToChanges,\n}: RiScAppliesToChangeProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n return (\n <ChangeSetBox type=\"primary\">\n <ChangeSetBoxTitle title={t('dictionary.appliesTo')} />\n {appliesToChanges.map(entityChange => (\n <div key={JSON.stringify(entityChange)}>\n {entityChange.type === 'ADDED' && (\n <ChangeSetAddedValue newValue={entityChange.newValue} />\n )}\n {entityChange.type === 'DELETED' && (\n <ChangeSetRemovedValue oldValue={entityChange.oldValue} />\n )}\n {entityChange.type === 'CONTENT_CHANGED' && (\n <ChangeSetSimpleBox\n prop={entityChange}\n title={t('dictionary.appliesTo')}\n />\n )}\n </div>\n ))}\n </ChangeSetBox>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAaO,SAAS,mBAAA,CAAoB;AAAA,EAClC;AACF,CAAA,EAA6B;AAC3B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AACxD,EAAA,uBACE,IAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAK,SAAA,EACjB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,CAAA,CAAE,sBAAsB,CAAA,EAAG,CAAA;AAAA,IACpD,gBAAA,CAAiB,GAAA,CAAI,CAAA,YAAA,qBACpB,IAAA,CAAC,KAAA,EAAA,EACE,QAAA,EAAA;AAAA,MAAA,YAAA,CAAa,SAAS,OAAA,oBACrB,GAAA,CAAC,mBAAA,EAAA,EAAoB,QAAA,EAAU,aAAa,QAAA,EAAU,CAAA;AAAA,MAEvD,aAAa,IAAA,KAAS,SAAA,wBACpB,qBAAA,EAAA,EAAsB,QAAA,EAAU,aAAa,QAAA,EAAU,CAAA;AAAA,MAEzD,YAAA,CAAa,SAAS,iBAAA,oBACrB,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAM,YAAA;AAAA,UACN,KAAA,EAAO,EAAE,sBAAsB;AAAA;AAAA;AACjC,KAAA,EAAA,EAXM,IAAA,CAAK,SAAA,CAAU,YAAY,CAarC,CACD;AAAA,GAAA,EACH,CAAA;AAEJ;;;;"}
|
|
@@ -7,12 +7,14 @@ import { dtoToScenario } from '../../../utils/DTOs.esm.js';
|
|
|
7
7
|
import { ChangeSetSimpleBox } from './components/ChangeSetSimpleBox.esm.js';
|
|
8
8
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
9
9
|
import { pluginRiScTranslationRef } from '../../../utils/translations.esm.js';
|
|
10
|
+
import { RiScAppliesToChange } from './RiScAppliesToChange.esm.js';
|
|
10
11
|
|
|
11
12
|
function RiScChangeSet({ changeset }) {
|
|
12
13
|
const { t } = useTranslationRef(pluginRiScTranslationRef);
|
|
13
14
|
const migrationChanges = changeset.differenceState.migrationChanges;
|
|
14
15
|
const changes = changeset.differenceState;
|
|
15
|
-
const
|
|
16
|
+
const appliesToChanges = changes.appliesTo ?? [];
|
|
17
|
+
const hasChanges = changes.scenarios.length > 0 || changes.valuations.length > 0 || changes.title || changes.scope || appliesToChanges.length > 0;
|
|
16
18
|
const hasAnyChanges = changes.migrationChanges.migrationChanges || hasChanges;
|
|
17
19
|
if (!hasAnyChanges) {
|
|
18
20
|
return /* @__PURE__ */ jsx("i", { children: t("comparisonDialog.noChanges") });
|
|
@@ -35,6 +37,7 @@ function RiScChangeSet({ changeset }) {
|
|
|
35
37
|
title: t("dictionary.scope")
|
|
36
38
|
}
|
|
37
39
|
),
|
|
40
|
+
appliesToChanges.length > 1 && /* @__PURE__ */ jsx(RiScAppliesToChange, { appliesToChanges }),
|
|
38
41
|
changes.scenarios.map((scenario) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
39
42
|
(scenario.type === "ADDED" || scenario.type === "DELETED") && /* @__PURE__ */ jsx(
|
|
40
43
|
RiScScenarioChange,
|