@kopexa/grc 0.0.5 → 0.0.7

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/index.js CHANGED
@@ -28,6 +28,7 @@ __export(index_exports, {
28
28
  MappedControls: () => MappedControls,
29
29
  Nis2Badge: () => Nis2Badge,
30
30
  RiskRatingDisplay: () => RiskRatingDisplay,
31
+ RiskTreatmentCard: () => RiskTreatmentCard,
31
32
  assetScale: () => assetScale,
32
33
  getRiskLevelFromRating: () => getRiskLevelFromRating,
33
34
  getScale: () => getScale,
@@ -37,7 +38,8 @@ __export(index_exports, {
37
38
  processScale: () => processScale,
38
39
  riskLevelConfig: () => riskLevelConfig,
39
40
  riskMessages: () => messages4,
40
- riskScale: () => riskScale
41
+ riskScale: () => riskScale,
42
+ riskTreatmentMessages: () => messages5
41
43
  });
42
44
  module.exports = __toCommonJS(index_exports);
43
45
 
@@ -931,6 +933,344 @@ function RiskRatingDisplay({
931
933
  }
932
934
  );
933
935
  }
936
+
937
+ // src/risk/messages.ts
938
+ var import_i18n9 = require("@kopexa/i18n");
939
+ var messages5 = (0, import_i18n9.defineMessages)({
940
+ // Card title
941
+ title: {
942
+ id: "grc.risk_treatment.title",
943
+ defaultMessage: "Risk Treatment"
944
+ },
945
+ // Strategy selection
946
+ strategy_label: {
947
+ id: "grc.risk_treatment.strategy_label",
948
+ defaultMessage: "Selected Strategy"
949
+ },
950
+ strategy_prompt: {
951
+ id: "grc.risk_treatment.strategy_prompt",
952
+ defaultMessage: "How do you want to handle this risk?"
953
+ },
954
+ // Treatment options - labels
955
+ accept_label: {
956
+ id: "grc.risk_treatment.accept.label",
957
+ defaultMessage: "Accept"
958
+ },
959
+ mitigate_label: {
960
+ id: "grc.risk_treatment.mitigate.label",
961
+ defaultMessage: "Mitigate"
962
+ },
963
+ transfer_label: {
964
+ id: "grc.risk_treatment.transfer.label",
965
+ defaultMessage: "Transfer"
966
+ },
967
+ avoid_label: {
968
+ id: "grc.risk_treatment.avoid.label",
969
+ defaultMessage: "Avoid"
970
+ },
971
+ not_defined_label: {
972
+ id: "grc.risk_treatment.not_defined.label",
973
+ defaultMessage: "No strategy defined"
974
+ },
975
+ // Treatment options - descriptions
976
+ accept_description: {
977
+ id: "grc.risk_treatment.accept.description",
978
+ defaultMessage: "Consciously accept the risk because treatment costs exceed potential damage or the risk is within acceptable limits."
979
+ },
980
+ mitigate_description: {
981
+ id: "grc.risk_treatment.mitigate.description",
982
+ defaultMessage: "Reduce the risk to an acceptable level through implementation of controls and measures."
983
+ },
984
+ transfer_description: {
985
+ id: "grc.risk_treatment.transfer.description",
986
+ defaultMessage: "Transfer the risk to third parties (e.g., insurance, outsourcing)."
987
+ },
988
+ avoid_description: {
989
+ id: "grc.risk_treatment.avoid.description",
990
+ defaultMessage: "Completely eliminate the risk by avoiding the risky activity or changing business processes."
991
+ },
992
+ // Treatment options - hints (requirements)
993
+ mitigate_hint: {
994
+ id: "grc.risk_treatment.mitigate.hint",
995
+ defaultMessage: "Requires: Action plan, Control mapping"
996
+ },
997
+ transfer_hint: {
998
+ id: "grc.risk_treatment.transfer.hint",
999
+ defaultMessage: "Requires: Contract documentation, Residual risk assessment"
1000
+ },
1001
+ avoid_hint: {
1002
+ id: "grc.risk_treatment.avoid.hint",
1003
+ defaultMessage: "Requires: Business Impact Analysis"
1004
+ },
1005
+ accept_hint: {
1006
+ id: "grc.risk_treatment.accept.hint",
1007
+ defaultMessage: "Requires: Documented approval"
1008
+ },
1009
+ // Rationale
1010
+ rationale_label: {
1011
+ id: "grc.risk_treatment.rationale_label",
1012
+ defaultMessage: "Rationale"
1013
+ },
1014
+ rationale_placeholder: {
1015
+ id: "grc.risk_treatment.rationale_placeholder",
1016
+ defaultMessage: "Document why this strategy was chosen..."
1017
+ },
1018
+ no_rationale: {
1019
+ id: "grc.risk_treatment.no_rationale",
1020
+ defaultMessage: "No rationale defined"
1021
+ },
1022
+ // Actions
1023
+ edit: {
1024
+ id: "grc.risk_treatment.edit",
1025
+ defaultMessage: "Edit"
1026
+ },
1027
+ cancel: {
1028
+ id: "grc.risk_treatment.cancel",
1029
+ defaultMessage: "Cancel"
1030
+ },
1031
+ save: {
1032
+ id: "grc.risk_treatment.save",
1033
+ defaultMessage: "Save"
1034
+ },
1035
+ // Recommendation badge
1036
+ recommended: {
1037
+ id: "grc.risk_treatment.recommended",
1038
+ defaultMessage: "Recommended"
1039
+ }
1040
+ });
1041
+
1042
+ // src/risk/risk-treatment-card.tsx
1043
+ var import_i18n10 = require("@kopexa/i18n");
1044
+ var import_icons3 = require("@kopexa/icons");
1045
+ var import_sight5 = require("@kopexa/sight");
1046
+ var import_react2 = require("react");
1047
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1048
+ function TreatmentOption({
1049
+ id,
1050
+ label,
1051
+ description,
1052
+ hint,
1053
+ isSelected,
1054
+ isRecommended,
1055
+ recommendedLabel,
1056
+ onSelect
1057
+ }) {
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1059
+ "button",
1060
+ {
1061
+ type: "button",
1062
+ onClick: () => onSelect(id),
1063
+ className: `
1064
+ w-full text-left p-4 rounded-lg border-2 transition-all
1065
+ ${isSelected ? "border-primary bg-primary/5" : "border-border hover:border-primary/50 hover:bg-muted/50"}
1066
+ `,
1067
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-start gap-3", children: [
1068
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1069
+ "div",
1070
+ {
1071
+ className: `
1072
+ mt-0.5 size-5 rounded-full border-2 flex items-center justify-center flex-shrink-0
1073
+ ${isSelected ? "border-primary bg-primary" : "border-muted-foreground"}
1074
+ `,
1075
+ children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "size-2 rounded-full bg-primary-foreground" })
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 min-w-0", children: [
1079
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2 flex-wrap", children: [
1080
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "font-medium", children: label }),
1081
+ isRecommended && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Chip, { size: "sm", color: "success", variant: "flat", children: recommendedLabel })
1082
+ ] }),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-muted-foreground mt-1", children: description }),
1084
+ hint && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-xs text-muted-foreground mt-2 flex items-center gap-1", children: [
1085
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-primary", children: "\u2192" }),
1086
+ hint
1087
+ ] })
1088
+ ] })
1089
+ ] })
1090
+ }
1091
+ );
1092
+ }
1093
+ var defaultValue = {
1094
+ treatment: "not_defined",
1095
+ rationale: void 0
1096
+ };
1097
+ function RiskTreatmentCard({
1098
+ value,
1099
+ onChange,
1100
+ readOnly = false,
1101
+ title,
1102
+ recommended
1103
+ }) {
1104
+ const intl = (0, import_i18n10.useSafeIntl)();
1105
+ const [isEditing, setIsEditing] = (0, import_react2.useState)(false);
1106
+ const [editValues, setEditValues] = (0, import_react2.useState)(
1107
+ value || defaultValue
1108
+ );
1109
+ const t = {
1110
+ title: intl.formatMessage(messages5.title),
1111
+ strategyLabel: intl.formatMessage(messages5.strategy_label),
1112
+ strategyPrompt: intl.formatMessage(messages5.strategy_prompt),
1113
+ rationaleLabel: intl.formatMessage(messages5.rationale_label),
1114
+ rationalePlaceholder: intl.formatMessage(messages5.rationale_placeholder),
1115
+ noRationale: intl.formatMessage(messages5.no_rationale),
1116
+ edit: intl.formatMessage(messages5.edit),
1117
+ cancel: intl.formatMessage(messages5.cancel),
1118
+ save: intl.formatMessage(messages5.save),
1119
+ recommended: intl.formatMessage(messages5.recommended),
1120
+ // Treatment labels
1121
+ acceptLabel: intl.formatMessage(messages5.accept_label),
1122
+ mitigateLabel: intl.formatMessage(messages5.mitigate_label),
1123
+ transferLabel: intl.formatMessage(messages5.transfer_label),
1124
+ avoidLabel: intl.formatMessage(messages5.avoid_label),
1125
+ notDefinedLabel: intl.formatMessage(messages5.not_defined_label),
1126
+ // Treatment descriptions
1127
+ acceptDescription: intl.formatMessage(messages5.accept_description),
1128
+ mitigateDescription: intl.formatMessage(messages5.mitigate_description),
1129
+ transferDescription: intl.formatMessage(messages5.transfer_description),
1130
+ avoidDescription: intl.formatMessage(messages5.avoid_description),
1131
+ // Treatment hints
1132
+ acceptHint: intl.formatMessage(messages5.accept_hint),
1133
+ mitigateHint: intl.formatMessage(messages5.mitigate_hint),
1134
+ transferHint: intl.formatMessage(messages5.transfer_hint),
1135
+ avoidHint: intl.formatMessage(messages5.avoid_hint)
1136
+ };
1137
+ const treatmentLabels = {
1138
+ accept: t.acceptLabel,
1139
+ mitigate: t.mitigateLabel,
1140
+ transfer: t.transferLabel,
1141
+ avoid: t.avoidLabel,
1142
+ not_defined: t.notDefinedLabel
1143
+ };
1144
+ const treatmentOptions = [
1145
+ {
1146
+ id: "accept",
1147
+ label: t.acceptLabel,
1148
+ description: t.acceptDescription,
1149
+ hint: t.acceptHint
1150
+ },
1151
+ {
1152
+ id: "mitigate",
1153
+ label: t.mitigateLabel,
1154
+ description: t.mitigateDescription,
1155
+ hint: t.mitigateHint
1156
+ },
1157
+ {
1158
+ id: "transfer",
1159
+ label: t.transferLabel,
1160
+ description: t.transferDescription,
1161
+ hint: t.transferHint
1162
+ },
1163
+ {
1164
+ id: "avoid",
1165
+ label: t.avoidLabel,
1166
+ description: t.avoidDescription,
1167
+ hint: t.avoidHint
1168
+ }
1169
+ ];
1170
+ const cardTitle = title != null ? title : t.title;
1171
+ const currentValue = isEditing ? editValues : value || defaultValue;
1172
+ const isNotDefined = currentValue.treatment === "not_defined";
1173
+ const handleSave = () => {
1174
+ onChange == null ? void 0 : onChange(editValues);
1175
+ setIsEditing(false);
1176
+ };
1177
+ const handleCancel = () => {
1178
+ setEditValues(value || defaultValue);
1179
+ setIsEditing(false);
1180
+ };
1181
+ const handleStartEdit = () => {
1182
+ setEditValues(value || defaultValue);
1183
+ setIsEditing(true);
1184
+ };
1185
+ const handleTreatmentSelect = (treatment) => {
1186
+ setEditValues((prev) => ({ ...prev, treatment }));
1187
+ };
1188
+ const handleRationaleChange = (rationale) => {
1189
+ setEditValues((prev) => ({ ...prev, rationale: rationale || void 0 }));
1190
+ };
1191
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_sight5.Card.Root, { variant: "accent", children: [
1192
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_sight5.Card.Header, { className: "flex flex-row items-center justify-between", children: [
1193
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
1194
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Heading, { level: "h3", className: "text-base", children: cardTitle }),
1195
+ isEditing && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Chip, { size: "sm", color: "primary", children: t.edit })
1196
+ ] }),
1197
+ !readOnly && (!isEditing ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1198
+ import_sight5.Button,
1199
+ {
1200
+ variant: "ghost",
1201
+ size: "sm",
1202
+ isIconOnly: true,
1203
+ onClick: handleStartEdit,
1204
+ "aria-label": t.edit,
1205
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons3.EditIcon, { className: "size-4" })
1206
+ }
1207
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
1208
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Button, { variant: "ghost", size: "sm", onClick: handleCancel, children: t.cancel }),
1209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Button, { size: "sm", onClick: handleSave, children: t.save })
1210
+ ] }))
1211
+ ] }),
1212
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Card.Body, { className: "space-y-4", children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1213
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-3", children: [
1214
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-muted-foreground", children: t.strategyPrompt }),
1215
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "grid gap-3", children: treatmentOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1216
+ TreatmentOption,
1217
+ {
1218
+ id: option.id,
1219
+ label: option.label,
1220
+ description: option.description,
1221
+ hint: option.hint,
1222
+ isSelected: editValues.treatment === option.id,
1223
+ isRecommended: recommended === option.id,
1224
+ recommendedLabel: t.recommended,
1225
+ onSelect: handleTreatmentSelect
1226
+ },
1227
+ option.id
1228
+ )) })
1229
+ ] }),
1230
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Separator, {}),
1231
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-2", children: [
1232
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1233
+ "label",
1234
+ {
1235
+ htmlFor: "treatment-rationale",
1236
+ className: "text-sm font-medium",
1237
+ children: t.rationaleLabel
1238
+ }
1239
+ ),
1240
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1241
+ import_sight5.Textarea,
1242
+ {
1243
+ id: "treatment-rationale",
1244
+ value: editValues.rationale || "",
1245
+ onChange: (e) => handleRationaleChange(e.target.value),
1246
+ placeholder: t.rationalePlaceholder,
1247
+ rows: 3,
1248
+ className: "text-sm"
1249
+ }
1250
+ )
1251
+ ] })
1252
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1253
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1254
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-medium mb-1", children: t.strategyLabel }),
1255
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
1256
+ !isNotDefined && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons3.CheckCirleIcon, { className: "size-4 text-success" }),
1257
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1258
+ "p",
1259
+ {
1260
+ className: `text-sm ${isNotDefined ? "text-muted-foreground" : ""}`,
1261
+ children: treatmentLabels[currentValue.treatment]
1262
+ }
1263
+ )
1264
+ ] })
1265
+ ] }),
1266
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_sight5.Separator, {}),
1267
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1268
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-medium mb-1", children: t.rationaleLabel }),
1269
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-muted-foreground", children: currentValue.rationale || t.noRationale })
1270
+ ] })
1271
+ ] }) })
1272
+ ] });
1273
+ }
934
1274
  // Annotate the CommonJS export names for ESM import in node:
935
1275
  0 && (module.exports = {
936
1276
  ComplianceBadges,
@@ -940,6 +1280,7 @@ function RiskRatingDisplay({
940
1280
  MappedControls,
941
1281
  Nis2Badge,
942
1282
  RiskRatingDisplay,
1283
+ RiskTreatmentCard,
943
1284
  assetScale,
944
1285
  getRiskLevelFromRating,
945
1286
  getScale,
@@ -949,5 +1290,6 @@ function RiskRatingDisplay({
949
1290
  processScale,
950
1291
  riskLevelConfig,
951
1292
  riskMessages,
952
- riskScale
1293
+ riskScale,
1294
+ riskTreatmentMessages
953
1295
  });
package/dist/index.mjs CHANGED
@@ -1,5 +1,19 @@
1
1
  "use client";
2
2
  import "./chunk-HJUSN7FD.mjs";
3
+ import "./chunk-GFABGXAO.mjs";
4
+ import {
5
+ ImpactCard
6
+ } from "./chunk-AGASJJ7X.mjs";
7
+ import {
8
+ assetScale,
9
+ getScale,
10
+ impactLevels,
11
+ processScale,
12
+ riskScale
13
+ } from "./chunk-KNGEZZFI.mjs";
14
+ import {
15
+ messages
16
+ } from "./chunk-GF3WJZVI.mjs";
3
17
  import "./chunk-HI7F2CF4.mjs";
4
18
  import {
5
19
  RiskRatingDisplay
@@ -13,32 +27,25 @@ import {
13
27
  riskLevelConfig
14
28
  } from "./chunk-VFX3DASQ.mjs";
15
29
  import "./chunk-TICWEZUI.mjs";
30
+ import {
31
+ ComplianceBadges,
32
+ DoraBadge,
33
+ Nis2Badge
34
+ } from "./chunk-7754RETD.mjs";
35
+ import "./chunk-B47KDUYY.mjs";
16
36
  import "./chunk-CND77GVC.mjs";
17
37
  import {
18
38
  ControlChip,
19
39
  MappedControls
20
40
  } from "./chunk-QDYL5ABK.mjs";
21
41
  import "./chunk-QS5S6V26.mjs";
22
- import "./chunk-GFABGXAO.mjs";
42
+ import "./chunk-BAC3SZJH.mjs";
23
43
  import {
24
- ImpactCard
25
- } from "./chunk-AGASJJ7X.mjs";
26
- import {
27
- assetScale,
28
- getScale,
29
- impactLevels,
30
- processScale,
31
- riskScale
32
- } from "./chunk-KNGEZZFI.mjs";
44
+ RiskTreatmentCard
45
+ } from "./chunk-GC6CS627.mjs";
33
46
  import {
34
- messages
35
- } from "./chunk-GF3WJZVI.mjs";
36
- import {
37
- ComplianceBadges,
38
- DoraBadge,
39
- Nis2Badge
40
- } from "./chunk-7754RETD.mjs";
41
- import "./chunk-B47KDUYY.mjs";
47
+ messages as messages3
48
+ } from "./chunk-AHKTFAZC.mjs";
42
49
  export {
43
50
  ComplianceBadges,
44
51
  ControlChip,
@@ -47,6 +54,7 @@ export {
47
54
  MappedControls,
48
55
  Nis2Badge,
49
56
  RiskRatingDisplay,
57
+ RiskTreatmentCard,
50
58
  assetScale,
51
59
  getRiskLevelFromRating,
52
60
  getScale,
@@ -56,5 +64,6 @@ export {
56
64
  processScale,
57
65
  riskLevelConfig,
58
66
  messages2 as riskMessages,
59
- riskScale
67
+ riskScale,
68
+ messages3 as riskTreatmentMessages
60
69
  };
@@ -1,2 +1,4 @@
1
-
2
- export { }
1
+ export { messages as riskTreatmentMessages } from './messages.mjs';
2
+ export { RiskTreatmentCard, RiskTreatmentCardProps } from './risk-treatment-card.mjs';
3
+ export { RiskTreatment, RiskTreatmentValue, TreatmentOption } from './types.mjs';
4
+ import 'react/jsx-runtime';
@@ -1,2 +1,4 @@
1
-
2
- export { }
1
+ export { messages as riskTreatmentMessages } from './messages.js';
2
+ export { RiskTreatmentCard, RiskTreatmentCardProps } from './risk-treatment-card.js';
3
+ export { RiskTreatment, RiskTreatmentValue, TreatmentOption } from './types.js';
4
+ import 'react/jsx-runtime';