@kartverket/backstage-plugin-risk-scorecard 6.6.1 → 6.7.0

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.
@@ -10,6 +10,7 @@ function ActionCountButtons(props) {
10
10
  {
11
11
  type: UpdatedStatusEnum.VERY_OUTDATED,
12
12
  count: props.veryOutdatedCount,
13
+ totalCount: props.totalCount,
13
14
  onActionCountClick: props.onActionCountClick,
14
15
  isSelected: props.updatedStatusToDisplay === UpdatedStatusEnum.VERY_OUTDATED
15
16
  }
@@ -19,6 +20,7 @@ function ActionCountButtons(props) {
19
20
  {
20
21
  type: UpdatedStatusEnum.OUTDATED,
21
22
  count: props.outdatedCount,
23
+ totalCount: props.totalCount,
22
24
  onActionCountClick: props.onActionCountClick,
23
25
  isSelected: props.updatedStatusToDisplay === UpdatedStatusEnum.OUTDATED
24
26
  }
@@ -28,6 +30,7 @@ function ActionCountButtons(props) {
28
30
  {
29
31
  type: UpdatedStatusEnum.UPDATED,
30
32
  count: props.updatedCount,
33
+ totalCount: props.totalCount,
31
34
  onActionCountClick: props.onActionCountClick,
32
35
  isSelected: props.updatedStatusToDisplay === UpdatedStatusEnum.UPDATED
33
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ActionCountButtons.esm.js","sources":["../../../src/components/scenarioTable/ActionCountButtons.tsx"],"sourcesContent":["import { Flex } from '@backstage/ui';\nimport {\n UpdatedStatusEnum,\n UpdatedStatusEnumType,\n} from '../../utils/utilityfunctions.ts';\nimport { ActionsCountButton } from './ActionsCountButton.tsx';\n\ntype ActionCountButtonsProps = {\n veryOutdatedCount: number;\n outdatedCount: number;\n updatedCount: number;\n onActionCountClick: (type: UpdatedStatusEnumType) => void;\n updatedStatusToDisplay: UpdatedStatusEnumType | null;\n};\nexport function ActionCountButtons(props: ActionCountButtonsProps) {\n return (\n <Flex mb=\"24px\" style={{ flexWrap: 'wrap' }}>\n {props.veryOutdatedCount > 0 && (\n <ActionsCountButton\n type={UpdatedStatusEnum.VERY_OUTDATED}\n count={props.veryOutdatedCount}\n onActionCountClick={props.onActionCountClick}\n isSelected={\n props.updatedStatusToDisplay === UpdatedStatusEnum.VERY_OUTDATED\n }\n />\n )}\n {props.outdatedCount > 0 && (\n <ActionsCountButton\n type={UpdatedStatusEnum.OUTDATED}\n count={props.outdatedCount}\n onActionCountClick={props.onActionCountClick}\n isSelected={\n props.updatedStatusToDisplay === UpdatedStatusEnum.OUTDATED\n }\n />\n )}\n {props.updatedCount > 0 && (\n <ActionsCountButton\n type={UpdatedStatusEnum.UPDATED}\n count={props.updatedCount}\n onActionCountClick={props.onActionCountClick}\n isSelected={\n props.updatedStatusToDisplay === UpdatedStatusEnum.UPDATED\n }\n />\n )}\n </Flex>\n );\n}\n"],"names":[],"mappings":";;;;;AAcO,SAAS,mBAAmB,KAAA,EAAgC;AACjE,EAAA,uBACE,IAAA,CAAC,QAAK,EAAA,EAAG,MAAA,EAAO,OAAO,EAAE,QAAA,EAAU,QAAO,EACvC,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,oBAAoB,CAAA,oBACzB,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAM,iBAAA,CAAkB,aAAA;AAAA,QACxB,OAAO,KAAA,CAAM,iBAAA;AAAA,QACb,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,UAAA,EACE,KAAA,CAAM,sBAAA,KAA2B,iBAAA,CAAkB;AAAA;AAAA,KAEvD;AAAA,IAED,KAAA,CAAM,gBAAgB,CAAA,oBACrB,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAM,iBAAA,CAAkB,QAAA;AAAA,QACxB,OAAO,KAAA,CAAM,aAAA;AAAA,QACb,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,UAAA,EACE,KAAA,CAAM,sBAAA,KAA2B,iBAAA,CAAkB;AAAA;AAAA,KAEvD;AAAA,IAED,KAAA,CAAM,eAAe,CAAA,oBACpB,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAM,iBAAA,CAAkB,OAAA;AAAA,QACxB,OAAO,KAAA,CAAM,YAAA;AAAA,QACb,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,UAAA,EACE,KAAA,CAAM,sBAAA,KAA2B,iBAAA,CAAkB;AAAA;AAAA;AAEvD,GAAA,EAEJ,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ActionCountButtons.esm.js","sources":["../../../src/components/scenarioTable/ActionCountButtons.tsx"],"sourcesContent":["import { Flex } from '@backstage/ui';\nimport {\n UpdatedStatusEnum,\n UpdatedStatusEnumType,\n} from '../../utils/utilityfunctions.ts';\nimport { ActionsCountButton } from './ActionsCountButton.tsx';\n\ntype ActionCountButtonsProps = {\n totalCount: number;\n veryOutdatedCount: number;\n outdatedCount: number;\n updatedCount: number;\n onActionCountClick: (type: UpdatedStatusEnumType) => void;\n updatedStatusToDisplay: UpdatedStatusEnumType | null;\n};\nexport function ActionCountButtons(props: ActionCountButtonsProps) {\n return (\n <Flex mb=\"24px\" style={{ flexWrap: 'wrap' }}>\n {props.veryOutdatedCount > 0 && (\n <ActionsCountButton\n type={UpdatedStatusEnum.VERY_OUTDATED}\n count={props.veryOutdatedCount}\n totalCount={props.totalCount}\n onActionCountClick={props.onActionCountClick}\n isSelected={\n props.updatedStatusToDisplay === UpdatedStatusEnum.VERY_OUTDATED\n }\n />\n )}\n {props.outdatedCount > 0 && (\n <ActionsCountButton\n type={UpdatedStatusEnum.OUTDATED}\n count={props.outdatedCount}\n totalCount={props.totalCount}\n onActionCountClick={props.onActionCountClick}\n isSelected={\n props.updatedStatusToDisplay === UpdatedStatusEnum.OUTDATED\n }\n />\n )}\n {props.updatedCount > 0 && (\n <ActionsCountButton\n type={UpdatedStatusEnum.UPDATED}\n count={props.updatedCount}\n totalCount={props.totalCount}\n onActionCountClick={props.onActionCountClick}\n isSelected={\n props.updatedStatusToDisplay === UpdatedStatusEnum.UPDATED\n }\n />\n )}\n </Flex>\n );\n}\n"],"names":[],"mappings":";;;;;AAeO,SAAS,mBAAmB,KAAA,EAAgC;AACjE,EAAA,uBACE,IAAA,CAAC,QAAK,EAAA,EAAG,MAAA,EAAO,OAAO,EAAE,QAAA,EAAU,QAAO,EACvC,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,oBAAoB,CAAA,oBACzB,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAM,iBAAA,CAAkB,aAAA;AAAA,QACxB,OAAO,KAAA,CAAM,iBAAA;AAAA,QACb,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,UAAA,EACE,KAAA,CAAM,sBAAA,KAA2B,iBAAA,CAAkB;AAAA;AAAA,KAEvD;AAAA,IAED,KAAA,CAAM,gBAAgB,CAAA,oBACrB,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAM,iBAAA,CAAkB,QAAA;AAAA,QACxB,OAAO,KAAA,CAAM,aAAA;AAAA,QACb,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,UAAA,EACE,KAAA,CAAM,sBAAA,KAA2B,iBAAA,CAAkB;AAAA;AAAA,KAEvD;AAAA,IAED,KAAA,CAAM,eAAe,CAAA,oBACpB,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAM,iBAAA,CAAkB,OAAA;AAAA,QACxB,OAAO,KAAA,CAAM,YAAA;AAAA,QACb,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,UAAA,EACE,KAAA,CAAM,sBAAA,KAA2B,iBAAA,CAAkB;AAAA;AAAA;AAEvD,GAAA,EAEJ,CAAA;AAEJ;;;;"}
@@ -38,6 +38,8 @@ function ActionsCountButton(props) {
38
38
  t(translationKey),
39
39
  " (",
40
40
  props.count,
41
+ "/",
42
+ props.totalCount,
41
43
  ")"
42
44
  ]
43
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsCountButton.esm.js","sources":["../../../src/components/scenarioTable/ActionsCountButton.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations.ts';\nimport { Button } from '@backstage/ui';\nimport {\n UpdatedStatusEnum,\n UpdatedStatusEnumType,\n} from '../../utils/utilityfunctions.ts';\nimport styles from './ActionsCountButton.module.css';\n\ntype ActionsCountButtonProps = {\n type: UpdatedStatusEnumType;\n count: number;\n onActionCountClick: (type: UpdatedStatusEnumType) => void;\n isSelected: boolean;\n};\nexport function ActionsCountButton(props: ActionsCountButtonProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const className = classNames(styles.OutdatedActionsCountButton, {\n [styles['OutdatedActionsCountButton--selected']]: props.isSelected,\n [styles['OutdatedActionsCountButton--very-outdated']]:\n props.type === UpdatedStatusEnum.VERY_OUTDATED,\n [styles['OutdatedActionsCountButton--outdated']]:\n props.type === UpdatedStatusEnum.OUTDATED,\n [styles['OutdatedActionsCountButton--updated']]:\n props.type === UpdatedStatusEnum.UPDATED,\n });\n\n const closeIndicatorClassName = classNames(\n styles.OutdatedActionsCountCloseIcon,\n 'ri-close-line ri-lg',\n );\n\n const closeIndicator = props.isSelected ? (\n <i className={closeIndicatorClassName} />\n ) : undefined;\n\n const translationKey = (() => {\n if (props.type === UpdatedStatusEnum.VERY_OUTDATED) {\n return 'filterButton.veryOutdated';\n } else if (props.type === UpdatedStatusEnum.OUTDATED) {\n return 'filterButton.outdated';\n }\n return 'filterButton.listUpdatedActions';\n })();\n\n return (\n <Button\n className={className}\n size=\"small\"\n onClick={() => props.onActionCountClick(props.type)}\n iconEnd={closeIndicator}\n >\n {t(translationKey)} ({props.count})\n </Button>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAgBO,SAAS,mBAAmB,KAAA,EAAgC;AACjE,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAA,CAAO,0BAAA,EAA4B;AAAA,IAC9D,CAAC,MAAA,CAAO,sCAAsC,CAAC,GAAG,KAAA,CAAM,UAAA;AAAA,IACxD,CAAC,MAAA,CAAO,2CAA2C,CAAC,GAClD,KAAA,CAAM,SAAS,iBAAA,CAAkB,aAAA;AAAA,IACnC,CAAC,MAAA,CAAO,sCAAsC,CAAC,GAC7C,KAAA,CAAM,SAAS,iBAAA,CAAkB,QAAA;AAAA,IACnC,CAAC,MAAA,CAAO,qCAAqC,CAAC,GAC5C,KAAA,CAAM,SAAS,iBAAA,CAAkB;AAAA,GACpC,CAAA;AAED,EAAA,MAAM,uBAAA,GAA0B,UAAA;AAAA,IAC9B,MAAA,CAAO,6BAAA;AAAA,IACP;AAAA,GACF;AAEA,EAAA,MAAM,iBAAiB,KAAA,CAAM,UAAA,uBAC1B,GAAA,EAAA,EAAE,SAAA,EAAW,yBAAyB,CAAA,GACrC,MAAA;AAEJ,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,iBAAA,CAAkB,aAAA,EAAe;AAClD,MAAA,OAAO,2BAAA;AAAA,IACT,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,iBAAA,CAAkB,QAAA,EAAU;AACpD,MAAA,OAAO,uBAAA;AAAA,IACT;AACA,IAAA,OAAO,iCAAA;AAAA,EACT,CAAA,GAAG;AAEH,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,IAAA,EAAK,OAAA;AAAA,MACL,OAAA,EAAS,MAAM,KAAA,CAAM,kBAAA,CAAmB,MAAM,IAAI,CAAA;AAAA,MAClD,OAAA,EAAS,cAAA;AAAA,MAER,QAAA,EAAA;AAAA,QAAA,CAAA,CAAE,cAAc,CAAA;AAAA,QAAE,IAAA;AAAA,QAAG,KAAA,CAAM,KAAA;AAAA,QAAM;AAAA;AAAA;AAAA,GACpC;AAEJ;;;;"}
1
+ {"version":3,"file":"ActionsCountButton.esm.js","sources":["../../../src/components/scenarioTable/ActionsCountButton.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { pluginRiScTranslationRef } from '../../utils/translations.ts';\nimport { Button } from '@backstage/ui';\nimport {\n UpdatedStatusEnum,\n UpdatedStatusEnumType,\n} from '../../utils/utilityfunctions.ts';\nimport styles from './ActionsCountButton.module.css';\n\ntype ActionsCountButtonProps = {\n type: UpdatedStatusEnumType;\n count: number;\n totalCount: number;\n onActionCountClick: (type: UpdatedStatusEnumType) => void;\n isSelected: boolean;\n};\nexport function ActionsCountButton(props: ActionsCountButtonProps) {\n const { t } = useTranslationRef(pluginRiScTranslationRef);\n\n const className = classNames(styles.OutdatedActionsCountButton, {\n [styles['OutdatedActionsCountButton--selected']]: props.isSelected,\n [styles['OutdatedActionsCountButton--very-outdated']]:\n props.type === UpdatedStatusEnum.VERY_OUTDATED,\n [styles['OutdatedActionsCountButton--outdated']]:\n props.type === UpdatedStatusEnum.OUTDATED,\n [styles['OutdatedActionsCountButton--updated']]:\n props.type === UpdatedStatusEnum.UPDATED,\n });\n\n const closeIndicatorClassName = classNames(\n styles.OutdatedActionsCountCloseIcon,\n 'ri-close-line ri-lg',\n );\n\n const closeIndicator = props.isSelected ? (\n <i className={closeIndicatorClassName} />\n ) : undefined;\n\n const translationKey = (() => {\n if (props.type === UpdatedStatusEnum.VERY_OUTDATED) {\n return 'filterButton.veryOutdated';\n } else if (props.type === UpdatedStatusEnum.OUTDATED) {\n return 'filterButton.outdated';\n }\n return 'filterButton.listUpdatedActions';\n })();\n\n return (\n <Button\n className={className}\n size=\"small\"\n onClick={() => props.onActionCountClick(props.type)}\n iconEnd={closeIndicator}\n >\n {t(translationKey)} ({props.count}/{props.totalCount})\n </Button>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAiBO,SAAS,mBAAmB,KAAA,EAAgC;AACjE,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAA,CAAO,0BAAA,EAA4B;AAAA,IAC9D,CAAC,MAAA,CAAO,sCAAsC,CAAC,GAAG,KAAA,CAAM,UAAA;AAAA,IACxD,CAAC,MAAA,CAAO,2CAA2C,CAAC,GAClD,KAAA,CAAM,SAAS,iBAAA,CAAkB,aAAA;AAAA,IACnC,CAAC,MAAA,CAAO,sCAAsC,CAAC,GAC7C,KAAA,CAAM,SAAS,iBAAA,CAAkB,QAAA;AAAA,IACnC,CAAC,MAAA,CAAO,qCAAqC,CAAC,GAC5C,KAAA,CAAM,SAAS,iBAAA,CAAkB;AAAA,GACpC,CAAA;AAED,EAAA,MAAM,uBAAA,GAA0B,UAAA;AAAA,IAC9B,MAAA,CAAO,6BAAA;AAAA,IACP;AAAA,GACF;AAEA,EAAA,MAAM,iBAAiB,KAAA,CAAM,UAAA,uBAC1B,GAAA,EAAA,EAAE,SAAA,EAAW,yBAAyB,CAAA,GACrC,MAAA;AAEJ,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,iBAAA,CAAkB,aAAA,EAAe;AAClD,MAAA,OAAO,2BAAA;AAAA,IACT,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,iBAAA,CAAkB,QAAA,EAAU;AACpD,MAAA,OAAO,uBAAA;AAAA,IACT;AACA,IAAA,OAAO,iCAAA;AAAA,EACT,CAAA,GAAG;AAEH,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,IAAA,EAAK,OAAA;AAAA,MACL,OAAA,EAAS,MAAM,KAAA,CAAM,kBAAA,CAAmB,MAAM,IAAI,CAAA;AAAA,MAClD,OAAA,EAAS,cAAA;AAAA,MAER,QAAA,EAAA;AAAA,QAAA,CAAA,CAAE,cAAc,CAAA;AAAA,QAAE,IAAA;AAAA,QAAG,KAAA,CAAM,KAAA;AAAA,QAAM,GAAA;AAAA,QAAE,KAAA,CAAM,UAAA;AAAA,QAAW;AAAA;AAAA;AAAA,GACvD;AAEJ;;;;"}
@@ -15,7 +15,7 @@ function ScenarioTableCard({
15
15
  }) {
16
16
  const { openNewScenarioWizard } = useScenario();
17
17
  const [isEditing, setIsEditing] = useState(false);
18
- const { veryOutdatedCount, outdatedCount, updatedCount } = computeStatusCount(riScWithMetadata);
18
+ const { totalCount, veryOutdatedCount, outdatedCount, updatedCount } = computeStatusCount(riScWithMetadata);
19
19
  const [selectedUpdatedStatus, setSelectedUpdatedStatus] = useState(null);
20
20
  const updatedStatusToDisplay = selectedUpdatedStatus === UpdatedStatusEnum.VERY_OUTDATED && veryOutdatedCount === 0 || selectedUpdatedStatus === UpdatedStatusEnum.OUTDATED && outdatedCount === 0 ? null : selectedUpdatedStatus;
21
21
  function handleActionCountClick(type) {
@@ -31,6 +31,7 @@ function ScenarioTableCard({
31
31
  (veryOutdatedCount > 0 || outdatedCount > 0) && /* @__PURE__ */ jsx(
32
32
  ActionCountButtons,
33
33
  {
34
+ totalCount,
34
35
  veryOutdatedCount,
35
36
  outdatedCount,
36
37
  updatedCount,
@@ -1 +1 @@
1
- {"version":3,"file":"ScenarioTableCard.esm.js","sources":["../../../src/components/scenarioTable/ScenarioTableCard.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { RiScWithMetadata } from '../../utils/types';\nimport {\n computeStatusCount,\n UpdatedStatusEnumType,\n UpdatedStatusEnum,\n} from '../../utils/utilityfunctions';\nimport { Card, CardBody, CardHeader, Flex } from '@backstage/ui';\nimport { ScenarioTableCardHeader } from './ScenarioTableCardHeader.tsx';\nimport { ActionCountButtons } from './ActionCountButtons.tsx';\nimport { AddScenarioButton } from './AddScenarioButton.tsx';\nimport { ScenarioTable } from './ScenarioTable.tsx';\nimport { useScenario } from '../../contexts/ScenarioContext.tsx';\nimport { ScenarioTableFilter } from './ScenarioTableFilter.tsx';\n\ninterface ScenarioTableProps {\n riScWithMetadata: RiScWithMetadata;\n editingAllowed: boolean;\n}\n\nexport function ScenarioTableCard({\n riScWithMetadata,\n editingAllowed,\n}: ScenarioTableProps) {\n const { openNewScenarioWizard } = useScenario();\n\n const [isEditing, setIsEditing] = useState<boolean>(false);\n\n const { veryOutdatedCount, outdatedCount, updatedCount } =\n computeStatusCount(riScWithMetadata);\n const [selectedUpdatedStatus, setSelectedUpdatedStatus] =\n useState<UpdatedStatusEnumType | null>(null);\n\n // Remove updated status selection if there is none to display\n const updatedStatusToDisplay =\n (selectedUpdatedStatus === UpdatedStatusEnum.VERY_OUTDATED &&\n veryOutdatedCount === 0) ||\n (selectedUpdatedStatus === UpdatedStatusEnum.OUTDATED &&\n outdatedCount === 0)\n ? null\n : selectedUpdatedStatus;\n\n function handleActionCountClick(type: UpdatedStatusEnumType) {\n setSelectedUpdatedStatus(prev => (prev === type ? null : type));\n }\n const [scenarioSortOrder, setScenarioSortOrder] = useState<string | null>(\n null,\n );\n\n const [actionSearchQuery, setActionSearchQuery] = useState<string>('');\n\n return (\n <Card>\n <CardHeader>\n <ScenarioTableCardHeader />\n </CardHeader>\n <CardBody style={{ paddingTop: '12px' }}>\n {(veryOutdatedCount > 0 || outdatedCount > 0) && (\n <ActionCountButtons\n veryOutdatedCount={veryOutdatedCount}\n outdatedCount={outdatedCount}\n updatedCount={updatedCount}\n onActionCountClick={handleActionCountClick}\n updatedStatusToDisplay={updatedStatusToDisplay}\n />\n )}\n {riScWithMetadata.content.scenarios.length === 0 && editingAllowed ? (\n <Flex justify=\"center\">\n <AddScenarioButton onNewScenario={openNewScenarioWizard} />\n </Flex>\n ) : (\n <>\n <ScenarioTableFilter\n scenarioSortOrder={scenarioSortOrder}\n onScenarioSortOrderChange={setScenarioSortOrder}\n isEditingScenarioTable={isEditing}\n actionSearchQuery={actionSearchQuery}\n onActionSearchQueryChange={setActionSearchQuery}\n isEditingScenarioTableAllowed={\n riScWithMetadata.content.scenarios.length > 0 && editingAllowed\n }\n onToggleEditScenarioTable={() =>\n isEditing ? setIsEditing(false) : setIsEditing(true)\n }\n onNewScenario={openNewScenarioWizard}\n />\n\n <ScenarioTable\n riScWithMetadata={riScWithMetadata}\n isEditingAllowed={editingAllowed}\n isEditing={isEditing}\n visibleType={updatedStatusToDisplay}\n actionSearchQuery={actionSearchQuery}\n scenarioSortOrder={scenarioSortOrder}\n />\n </>\n )}\n </CardBody>\n </Card>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBO,SAAS,iBAAA,CAAkB;AAAA,EAChC,gBAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,EAAE,qBAAA,EAAsB,GAAI,WAAA,EAAY;AAE9C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAkB,KAAK,CAAA;AAEzD,EAAA,MAAM,EAAE,iBAAA,EAAmB,aAAA,EAAe,YAAA,EAAa,GACrD,mBAAmB,gBAAgB,CAAA;AACrC,EAAA,MAAM,CAAC,qBAAA,EAAuB,wBAAwB,CAAA,GACpD,SAAuC,IAAI,CAAA;AAG7C,EAAA,MAAM,sBAAA,GACH,qBAAA,KAA0B,iBAAA,CAAkB,aAAA,IAC3C,iBAAA,KAAsB,CAAA,IACvB,qBAAA,KAA0B,iBAAA,CAAkB,QAAA,IAC3C,aAAA,KAAkB,CAAA,GAChB,IAAA,GACA,qBAAA;AAEN,EAAA,SAAS,uBAAuB,IAAA,EAA6B;AAC3D,IAAA,wBAAA,CAAyB,CAAA,IAAA,KAAS,IAAA,KAAS,IAAA,GAAO,IAAA,GAAO,IAAK,CAAA;AAAA,EAChE;AACA,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,QAAA;AAAA,IAChD;AAAA,GACF;AAEA,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,SAAiB,EAAE,CAAA;AAErE,EAAA,4BACG,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,uBAAA,EAAA,EAAwB,CAAA,EAC3B,CAAA;AAAA,yBACC,QAAA,EAAA,EAAS,KAAA,EAAO,EAAE,UAAA,EAAY,QAAO,EAClC,QAAA,EAAA;AAAA,MAAA,CAAA,iBAAA,GAAoB,CAAA,IAAK,gBAAgB,CAAA,qBACzC,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,iBAAA;AAAA,UACA,aAAA;AAAA,UACA,YAAA;AAAA,UACA,kBAAA,EAAoB,sBAAA;AAAA,UACpB;AAAA;AAAA,OACF;AAAA,MAED,iBAAiB,OAAA,CAAQ,SAAA,CAAU,MAAA,KAAW,CAAA,IAAK,iCAClD,GAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,QAAA,EACZ,8BAAC,iBAAA,EAAA,EAAkB,aAAA,EAAe,qBAAA,EAAuB,CAAA,EAC3D,oBAEA,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,mBAAA;AAAA,UAAA;AAAA,YACC,iBAAA;AAAA,YACA,yBAAA,EAA2B,oBAAA;AAAA,YAC3B,sBAAA,EAAwB,SAAA;AAAA,YACxB,iBAAA;AAAA,YACA,yBAAA,EAA2B,oBAAA;AAAA,YAC3B,6BAAA,EACE,gBAAA,CAAiB,OAAA,CAAQ,SAAA,CAAU,SAAS,CAAA,IAAK,cAAA;AAAA,YAEnD,2BAA2B,MACzB,SAAA,GAAY,aAAa,KAAK,CAAA,GAAI,aAAa,IAAI,CAAA;AAAA,YAErD,aAAA,EAAe;AAAA;AAAA,SACjB;AAAA,wBAEA,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,gBAAA;AAAA,YACA,gBAAA,EAAkB,cAAA;AAAA,YAClB,SAAA;AAAA,YACA,WAAA,EAAa,sBAAA;AAAA,YACb,iBAAA;AAAA,YACA;AAAA;AAAA;AACF,OAAA,EACF;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ScenarioTableCard.esm.js","sources":["../../../src/components/scenarioTable/ScenarioTableCard.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { RiScWithMetadata } from '../../utils/types';\nimport {\n computeStatusCount,\n UpdatedStatusEnumType,\n UpdatedStatusEnum,\n} from '../../utils/utilityfunctions';\nimport { Card, CardBody, CardHeader, Flex } from '@backstage/ui';\nimport { ScenarioTableCardHeader } from './ScenarioTableCardHeader.tsx';\nimport { ActionCountButtons } from './ActionCountButtons.tsx';\nimport { AddScenarioButton } from './AddScenarioButton.tsx';\nimport { ScenarioTable } from './ScenarioTable.tsx';\nimport { useScenario } from '../../contexts/ScenarioContext.tsx';\nimport { ScenarioTableFilter } from './ScenarioTableFilter.tsx';\n\ninterface ScenarioTableProps {\n riScWithMetadata: RiScWithMetadata;\n editingAllowed: boolean;\n}\n\nexport function ScenarioTableCard({\n riScWithMetadata,\n editingAllowed,\n}: ScenarioTableProps) {\n const { openNewScenarioWizard } = useScenario();\n\n const [isEditing, setIsEditing] = useState<boolean>(false);\n\n const { totalCount, veryOutdatedCount, outdatedCount, updatedCount } =\n computeStatusCount(riScWithMetadata);\n const [selectedUpdatedStatus, setSelectedUpdatedStatus] =\n useState<UpdatedStatusEnumType | null>(null);\n\n // Remove updated status selection if there is none to display\n const updatedStatusToDisplay =\n (selectedUpdatedStatus === UpdatedStatusEnum.VERY_OUTDATED &&\n veryOutdatedCount === 0) ||\n (selectedUpdatedStatus === UpdatedStatusEnum.OUTDATED &&\n outdatedCount === 0)\n ? null\n : selectedUpdatedStatus;\n\n function handleActionCountClick(type: UpdatedStatusEnumType) {\n setSelectedUpdatedStatus(prev => (prev === type ? null : type));\n }\n const [scenarioSortOrder, setScenarioSortOrder] = useState<string | null>(\n null,\n );\n\n const [actionSearchQuery, setActionSearchQuery] = useState<string>('');\n\n return (\n <Card>\n <CardHeader>\n <ScenarioTableCardHeader />\n </CardHeader>\n <CardBody style={{ paddingTop: '12px' }}>\n {(veryOutdatedCount > 0 || outdatedCount > 0) && (\n <ActionCountButtons\n totalCount={totalCount}\n veryOutdatedCount={veryOutdatedCount}\n outdatedCount={outdatedCount}\n updatedCount={updatedCount}\n onActionCountClick={handleActionCountClick}\n updatedStatusToDisplay={updatedStatusToDisplay}\n />\n )}\n {riScWithMetadata.content.scenarios.length === 0 && editingAllowed ? (\n <Flex justify=\"center\">\n <AddScenarioButton onNewScenario={openNewScenarioWizard} />\n </Flex>\n ) : (\n <>\n <ScenarioTableFilter\n scenarioSortOrder={scenarioSortOrder}\n onScenarioSortOrderChange={setScenarioSortOrder}\n isEditingScenarioTable={isEditing}\n actionSearchQuery={actionSearchQuery}\n onActionSearchQueryChange={setActionSearchQuery}\n isEditingScenarioTableAllowed={\n riScWithMetadata.content.scenarios.length > 0 && editingAllowed\n }\n onToggleEditScenarioTable={() =>\n isEditing ? setIsEditing(false) : setIsEditing(true)\n }\n onNewScenario={openNewScenarioWizard}\n />\n\n <ScenarioTable\n riScWithMetadata={riScWithMetadata}\n isEditingAllowed={editingAllowed}\n isEditing={isEditing}\n visibleType={updatedStatusToDisplay}\n actionSearchQuery={actionSearchQuery}\n scenarioSortOrder={scenarioSortOrder}\n />\n </>\n )}\n </CardBody>\n </Card>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBO,SAAS,iBAAA,CAAkB;AAAA,EAChC,gBAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,EAAE,qBAAA,EAAsB,GAAI,WAAA,EAAY;AAE9C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAkB,KAAK,CAAA;AAEzD,EAAA,MAAM,EAAE,UAAA,EAAY,iBAAA,EAAmB,eAAe,YAAA,EAAa,GACjE,mBAAmB,gBAAgB,CAAA;AACrC,EAAA,MAAM,CAAC,qBAAA,EAAuB,wBAAwB,CAAA,GACpD,SAAuC,IAAI,CAAA;AAG7C,EAAA,MAAM,sBAAA,GACH,qBAAA,KAA0B,iBAAA,CAAkB,aAAA,IAC3C,iBAAA,KAAsB,CAAA,IACvB,qBAAA,KAA0B,iBAAA,CAAkB,QAAA,IAC3C,aAAA,KAAkB,CAAA,GAChB,IAAA,GACA,qBAAA;AAEN,EAAA,SAAS,uBAAuB,IAAA,EAA6B;AAC3D,IAAA,wBAAA,CAAyB,CAAA,IAAA,KAAS,IAAA,KAAS,IAAA,GAAO,IAAA,GAAO,IAAK,CAAA;AAAA,EAChE;AACA,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,QAAA;AAAA,IAChD;AAAA,GACF;AAEA,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,SAAiB,EAAE,CAAA;AAErE,EAAA,4BACG,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,uBAAA,EAAA,EAAwB,CAAA,EAC3B,CAAA;AAAA,yBACC,QAAA,EAAA,EAAS,KAAA,EAAO,EAAE,UAAA,EAAY,QAAO,EAClC,QAAA,EAAA;AAAA,MAAA,CAAA,iBAAA,GAAoB,CAAA,IAAK,gBAAgB,CAAA,qBACzC,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,UAAA;AAAA,UACA,iBAAA;AAAA,UACA,aAAA;AAAA,UACA,YAAA;AAAA,UACA,kBAAA,EAAoB,sBAAA;AAAA,UACpB;AAAA;AAAA,OACF;AAAA,MAED,iBAAiB,OAAA,CAAQ,SAAA,CAAU,MAAA,KAAW,CAAA,IAAK,iCAClD,GAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,QAAA,EACZ,8BAAC,iBAAA,EAAA,EAAkB,aAAA,EAAe,qBAAA,EAAuB,CAAA,EAC3D,oBAEA,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,mBAAA;AAAA,UAAA;AAAA,YACC,iBAAA;AAAA,YACA,yBAAA,EAA2B,oBAAA;AAAA,YAC3B,sBAAA,EAAwB,SAAA;AAAA,YACxB,iBAAA;AAAA,YACA,yBAAA,EAA2B,oBAAA;AAAA,YAC3B,6BAAA,EACE,gBAAA,CAAiB,OAAA,CAAQ,SAAA,CAAU,SAAS,CAAA,IAAK,cAAA;AAAA,YAEnD,2BAA2B,MACzB,SAAA,GAAY,aAAa,KAAK,CAAA,GAAI,aAAa,IAAI,CAAA;AAAA,YAErD,aAAA,EAAe;AAAA;AAAA,SACjB;AAAA,wBAEA,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,gBAAA;AAAA,YACA,gBAAA,EAAkB,cAAA;AAAA,YAClB,SAAA;AAAA,YACA,WAAA,EAAa,sBAAA;AAAA,YACb,iBAAA;AAAA,YACA;AAAA;AAAA;AACF,OAAA,EACF;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
@@ -268,6 +268,7 @@ function computeStatusCount(riScWithMetadata) {
268
268
  };
269
269
  });
270
270
  const allActions = scenariosWithData.flatMap((scenario) => scenario.actions);
271
+ const totalCount = allActions.length;
271
272
  const veryOutdatedCount = allActions.filter(
272
273
  (action) => action.status === UpdatedStatusEnum.VERY_OUTDATED
273
274
  ).length;
@@ -277,7 +278,7 @@ function computeStatusCount(riScWithMetadata) {
277
278
  const updatedCount = allActions.filter(
278
279
  (action) => action.status === UpdatedStatusEnum.UPDATED
279
280
  ).length;
280
- return { veryOutdatedCount, outdatedCount, updatedCount };
281
+ return { totalCount, veryOutdatedCount, outdatedCount, updatedCount };
281
282
  }
282
283
  function getActiveTheme() {
283
284
  return document.body.getAttribute("data-theme-mode");
@@ -1 +1 @@
1
- {"version":3,"file":"utilityfunctions.esm.js","sources":["../../src/utils/utilityfunctions.ts"],"sourcesContent":["import { DateTime } from 'luxon';\nimport { UpdateStatus } from '../contexts/RiScContext';\nimport {\n ActionStatusOptions,\n BASE_NUMBER,\n CONSEQUENCE_SCALE_OFFSET,\n PROBABILITY_SCALE_OFFSET,\n ThreatActorsOptions,\n VulnerabilitiesOptions,\n latestSupportedVersion,\n riskMatrix,\n} from './constants';\nimport {\n RiSc,\n RiScWithMetadata,\n Risk,\n Scenario,\n SubmitResponseObject,\n} from './types';\n\nexport function generateRandomId(): string {\n return [...Array(5)]\n .map(() => {\n const randomChar = Math.random().toString(36)[2];\n return Math.random() < 0.5 ? randomChar.toUpperCase() : randomChar;\n })\n .join('');\n}\n\n/**\n * Gets value from a nested object based on input path to the value.\n * Example:\n * {\n * test: {\n * somethings: [\n * {\n * title: 'Test1',\n * name: 'Name1',\n * },\n * ...\n * ]\n * }\n * }\n * getValue(theObjectFromAbove, 'test.somethings.0.title') => 'Test1'\n *\n * @param obj Object to get value from\n * @param path Path to value\n */\nexport function getValue(obj: any, path: string) {\n return path.split('.').reduce((prev, curr) => {\n return prev?.[curr];\n }, obj);\n}\n\nconst formatter = new Intl.NumberFormat('nb-NO', {\n maximumFractionDigits: 0,\n});\n\nexport function formatNOK(amount: number): string {\n return formatter.format(amount);\n}\n\nexport function getAlertSeverity(\n updateStatus: UpdateStatus,\n response?: SubmitResponseObject,\n): 'error' | 'success' | 'warning' | 'info' {\n if (updateStatus.isLoading) {\n return 'info';\n }\n if (updateStatus.isSuccess) {\n return 'success';\n } else if (updateStatus.isError) {\n return 'error';\n }\n\n if (response && typeof response.status === 'string') {\n if (response.status.includes('Error')) return 'error';\n return 'success';\n }\n\n return 'warning';\n}\n\nexport function getRiskMatrixColor(risiko: Risk) {\n const sannsynlighet = findProbabilityIndex(risiko.probability);\n const konsekvens = findConsequenceIndex(risiko.consequence);\n return riskMatrix[4 - konsekvens][sannsynlighet];\n}\n\nexport function getProbabilityLevel(risiko: Risk) {\n return findProbabilityIndex(risiko.probability) + 1;\n}\n\nexport function getConsequenceLevel(risiko: Risk) {\n return findConsequenceIndex(risiko.consequence) + 1;\n}\n\nexport function emptyRiSc(): RiSc {\n return {\n schemaVersion: latestSupportedVersion,\n title: '',\n scope: '',\n scenarios: [],\n };\n}\n\nexport function shortenName(name: string, maxCharacters: number = 16) {\n if (name.length <= maxCharacters) return name;\n\n const parts = name.trim().split(/\\s+/);\n\n if (parts.length === 3) {\n const [first, middle, last] = parts;\n const candidates = [\n `${first} ${middle[0]}. ${last}`,\n `${first} ${last}`,\n `${first} ${last[0]}.`,\n first,\n ];\n return (\n candidates.find(c => c.length <= maxCharacters) ??\n first.slice(0, maxCharacters)\n );\n }\n\n if (parts.length === 2) {\n const [first, last] = parts;\n const candidates = [\n `${first} ${last}`,\n `${first} ${last[0]}.`,\n first,\n last,\n ];\n\n return (\n candidates.find(c => c.length <= maxCharacters) ??\n first.slice(0, maxCharacters)\n );\n }\n\n return parts[parts.length - 1].slice(0, maxCharacters);\n}\n\nexport function formatDate(date: Date | string): string {\n return DateTime.fromJSDate(new Date(date)).toFormat('dd.MM.yy');\n}\n\nexport function calculateDaysSince(dateString: Date) {\n const givenDate = dateString;\n const now = new Date();\n\n const diffTime = now.getTime() - givenDate.getTime();\n const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));\n\n return diffDays;\n}\n\nexport const UpdatedStatusEnum = {\n UPDATED: 'UPDATED',\n LITTLE_OUTDATED: 'LITTLE_OUTDATED',\n OUTDATED: 'OUTDATED',\n VERY_OUTDATED: 'VERY_OUTDATED',\n} as const;\n\nexport type UpdatedStatusEnumType =\n (typeof UpdatedStatusEnum)[keyof typeof UpdatedStatusEnum];\n\nexport function calculateUpdatedStatus(\n daysSinceLastModified: number,\n): UpdatedStatusEnumType {\n if (daysSinceLastModified <= 90) return UpdatedStatusEnum.UPDATED;\n if (daysSinceLastModified <= 180) return UpdatedStatusEnum.LITTLE_OUTDATED;\n if (daysSinceLastModified <= 270) return UpdatedStatusEnum.OUTDATED;\n return UpdatedStatusEnum.VERY_OUTDATED;\n}\n\nexport function requiresNewApproval(oldRiSc: RiSc, updatedRiSc: RiSc): boolean {\n return !isDeeplyEqual(\n oldRiSc.scenarios.sort(\n (scenario1, scenario2) => Number(scenario1.ID) - Number(scenario2.ID),\n ),\n updatedRiSc.scenarios.sort(\n (scenario1, scenario2) => Number(scenario1.ID) - Number(scenario2.ID),\n ),\n );\n}\n\nexport function formatNumber(\n cost: number,\n t: (s: any, c: any) => string,\n): string {\n function getTranslationWithCorrectUnit(\n costValue: number,\n threshold: number,\n unit: string,\n ): string {\n return t(`riskMatrix.estimatedRisk.suffix.${unit}`, {\n count: Number(((costValue / threshold) * 1000).toFixed(0)),\n });\n }\n\n if (cost < 1e4) {\n return formatNOK(cost);\n }\n if (cost < 1e6) {\n return getTranslationWithCorrectUnit(cost, 1e6, 'thousand');\n }\n if (cost < 1e9) {\n return getTranslationWithCorrectUnit(cost, 1e9, 'million');\n }\n if (cost < 1e12) {\n return getTranslationWithCorrectUnit(cost, 1e12, 'billion');\n }\n return getTranslationWithCorrectUnit(cost, 1e15, 'trillion');\n}\n\nexport function parseISODateFromEncryptedROS(date?: string): string | null {\n // Early return if date is null or too short for an ISO date string, could happen from recursion\n if (!date || date.length < 10) {\n return null;\n }\n\n try {\n const parsedDate = DateTime.fromISO(date, { setZone: true });\n\n if (!parsedDate.isValid) {\n return parseISODateFromEncryptedROS(date.substring(1, date.length - 1));\n }\n\n return parsedDate.toISO({ suppressMilliseconds: true });\n } catch (e) {\n return null;\n }\n}\n\nexport function getTranslationKey(\n type: string,\n key: string,\n t: (s: any, c?: any) => string,\n context?: any,\n): string {\n if (type === 'error') {\n return t(\n [`errorMessages.${key}`, 'errorMessages.DefaultErrorMessage'],\n context,\n );\n }\n return t(`infoMessages.${key}`, context);\n}\n\nexport function isPublicAgeKeyValid(publicAgeKey: string) {\n if (publicAgeKey.length !== 62) {\n return false;\n }\n\n if (!publicAgeKey.startsWith('age1')) {\n return false;\n }\n\n const ageKeyRegex = /^age1[ac-hj-np-z02-9]{58}$/;\n return ageKeyRegex.test(publicAgeKey);\n}\n\nexport function deleteScenario(\n riSc: RiScWithMetadata | null,\n updateRiSc: (\n riSc: RiScWithMetadata,\n onSuccess?: () => void,\n onError?: () => void,\n ) => void,\n scenario: Scenario,\n) {\n if (riSc) {\n const updatedScenarios = riSc.content.scenarios.filter(\n s => s.ID !== scenario.ID,\n );\n updateRiSc({\n ...riSc,\n content: { ...riSc.content, scenarios: updatedScenarios },\n });\n }\n}\n\n/**\n * A recursive method for determining if a and b are deeply equal. Keys in the ignoredKeys argument are ignored in the\n * comparison, i.e., they are considered non-existing in both a and b.\n */\nexport function isDeeplyEqual<T>(\n a: T,\n b: T,\n ignoredKeys: string[] = [],\n): boolean {\n // If objects are equal, there is no need compare them any further.\n if (a === b) return true;\n\n // Only do comparison on objects, ignoring null (which maps to object).\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n // Check if a and b are both arrays or not. If only one is, then a and b are not equal. It is necessary to perform\n // this check, as otherwise the method below will say that [] and {} are equal (or [0] and {0: 0}).\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n // Check if a and b have the same number of entries\n if (\n Object.keys(a).filter(key => !ignoredKeys.includes(key)).length !==\n Object.keys(b).filter(key => !ignoredKeys.includes(key)).length\n )\n return false;\n\n // Check if every key of a is a key of b and that the entry associated with the key is deeply the same in a and b.\n // Since a and b has the same number of entries, it is sufficient to check only the keys of a.\n return Object.entries(a).every(\n ([key, value]) =>\n ignoredKeys.includes(key) ||\n (Object.hasOwn(b, key as keyof T) &&\n isDeeplyEqual(value, b[key as keyof T])),\n );\n }\n\n // If a or b is null or a primitive type, then they are not equal as a === b should have returned true already.\n return false;\n}\n\nfunction logBase(value: number, base: number): number {\n return Math.log(value) / Math.log(base);\n}\n\n/*\n Probability is categorized in 5 levels on a logarithmic scale with base 20:\n 0 = 20^-2 = 1 / 400\n 1 = 20^-1 = 1 / 20\n 2 = 20^-0 = 1\n 3 = 20^1 = 20\n 4 = 20^2 = 400\n*/\nexport function findProbabilityIndex(probability: number): number {\n const probabilityIndex = Math.round(\n logBase(probability, BASE_NUMBER) - PROBABILITY_SCALE_OFFSET,\n );\n return Math.min(4, Math.max(0, probabilityIndex));\n}\n\n/*\n Consequence is categorized in 5 levels on a logarithmic scale with base 20:\n 0 = 20^3 = 8 000\n 1 = 20^4 = 160 000\n 2 = 20^5 = 3 200 000\n 3 = 20^6 = 64 000 000\n 4 = 20^7 = 1 280 000 000\n*/\nexport function findConsequenceIndex(consequence: number): number {\n const consequenceIndex = Math.round(\n logBase(consequence, BASE_NUMBER) - CONSEQUENCE_SCALE_OFFSET,\n );\n return Math.min(4, Math.max(0, consequenceIndex));\n}\n\n/*\n Logarithmically round the consequence to the nearest consequence option.\n*/\nexport function roundConsequenceToNearestConsequenceOption(\n consequence: number,\n): number {\n return Math.pow(BASE_NUMBER, findConsequenceIndex(consequence) + 3);\n}\n\n/*\n Logarithmically round the probability to the nearest probability option.\n*/\nexport function roundProbabilityToNearestProbabilityOption(\n probability: number,\n): number {\n return Math.pow(BASE_NUMBER, findProbabilityIndex(probability) - 2);\n}\n\nexport const consequenceIndexToTranslationKeys: Record<number, string> = {\n 0: 'infoDialog.consequenceDescription.oneworkday',\n 1: 'infoDialog.consequenceDescription.oneworkmonth',\n 2: 'infoDialog.consequenceDescription.oneworkyear',\n 3: 'infoDialog.consequenceDescription.20workyears',\n 4: 'infoDialog.consequenceDescription.400workyears',\n};\n\nexport const probabilityIndexToTranslationKeys: Record<number, string> = {\n 0: 'infoDialog.probabilityDescription.every400years',\n 1: 'infoDialog.probabilityDescription.every20years',\n 2: 'infoDialog.probabilityDescription.annualy',\n 3: 'infoDialog.probabilityDescription.monthly',\n 4: 'infoDialog.probabilityDescription.daily',\n};\n\nexport const actionStatusOptionsToTranslationKeys: Record<\n ActionStatusOptions,\n string\n> = {\n [ActionStatusOptions.OK]: 'actionStatus.OK',\n [ActionStatusOptions.NotOK]: 'actionStatus.Not OK',\n [ActionStatusOptions.NotRelevant]: 'actionStatus.Not relevant',\n};\n\nexport function getTranslatedActionStatus(\n status: string,\n t: (key: string, options?: any) => string,\n): string {\n if (\n Object.values(ActionStatusOptions).includes(status as ActionStatusOptions)\n ) {\n return t(\n actionStatusOptionsToTranslationKeys[status as ActionStatusOptions],\n );\n }\n\n return status;\n}\n\nexport const threatActorOptionsToTranslationKeys: Record<\n ThreatActorsOptions,\n string\n> = {\n [ThreatActorsOptions.ScriptKiddie]: 'threatActors.Script kiddie',\n [ThreatActorsOptions.Hacktivist]: 'threatActors.Hacktivist',\n [ThreatActorsOptions.RecklessEmployee]: 'threatActors.Reckless employee',\n [ThreatActorsOptions.Insider]: 'threatActors.Insider',\n [ThreatActorsOptions.OrganisedCrime]: 'threatActors.Organised crime',\n [ThreatActorsOptions.TerroristOrganisation]:\n 'threatActors.Terrorist organisation',\n [ThreatActorsOptions.NationGovernment]: 'threatActors.Nation/government',\n};\n\nexport const vulnerabiltiesOptionsToTranslationKeys: Record<\n VulnerabilitiesOptions,\n string\n> = {\n [VulnerabilitiesOptions.FlawedDesign]: 'vulnerabilities.Flawed design',\n [VulnerabilitiesOptions.Misconfiguration]: 'vulnerabilities.Misconfiguration',\n [VulnerabilitiesOptions.DependencyVulnerability]:\n 'vulnerabilities.Dependency vulnerability',\n [VulnerabilitiesOptions.UnauthorizedAccess]:\n 'vulnerabilities.Unauthorized access',\n [VulnerabilitiesOptions.UnmonitoredUse]: 'vulnerabilities.Unmonitored use',\n [VulnerabilitiesOptions.InputTampering]: 'vulnerabilities.Input tampering',\n [VulnerabilitiesOptions.InformationLeak]: 'vulnerabilities.Information leak',\n [VulnerabilitiesOptions.ExcessiveUse]: 'vulnerabilities.Excessive use',\n};\n\nexport function computeStatusCount(riScWithMetadata: RiScWithMetadata) {\n const scenariosWithData = riScWithMetadata.content.scenarios.map(scenario => {\n const actionsWithStatus = (scenario.actions ?? []).map(action => {\n if (!action.lastUpdated) {\n return { ...action, status: UpdatedStatusEnum.VERY_OUTDATED };\n }\n const daysSinceLastUpdate = action.lastUpdated\n ? calculateDaysSince(new Date(action.lastUpdated))\n : null;\n const status =\n daysSinceLastUpdate !== null\n ? calculateUpdatedStatus(daysSinceLastUpdate)\n : UpdatedStatusEnum.VERY_OUTDATED;\n\n return { ...action, status };\n });\n return {\n ...scenario,\n actions: actionsWithStatus,\n };\n });\n\n const allActions = scenariosWithData.flatMap(scenario => scenario.actions);\n const veryOutdatedCount = allActions.filter(\n action => action.status === UpdatedStatusEnum.VERY_OUTDATED,\n ).length;\n const outdatedCount = allActions.filter(\n action => action.status === UpdatedStatusEnum.OUTDATED,\n ).length;\n const updatedCount = allActions.filter(\n action => action.status === UpdatedStatusEnum.UPDATED,\n ).length;\n\n return { veryOutdatedCount, outdatedCount, updatedCount };\n}\n\nexport function getActiveTheme() {\n return document.body.getAttribute('data-theme-mode');\n}\n\nexport function validateRemainingRiskNotHigher(\n formData: {\n risk: { probability: number | string; consequence: number | string };\n remainingRisk: {\n probability: number | string;\n consequence: number | string;\n };\n },\n t: (key: string, options?: any) => string,\n): { isValid: boolean; errors: string[] } {\n const initialProbability = Number(formData.risk.probability);\n const initialConsequence = Number(formData.risk.consequence);\n const remainingProbability = Number(formData.remainingRisk.probability);\n const remainingConsequence = Number(formData.remainingRisk.consequence);\n\n const errors: string[] = [];\n\n if (remainingProbability > initialProbability) {\n errors.push(t('scenarioDrawer.errors.remainingProbabilityTooHigh'));\n }\n if (remainingConsequence > initialConsequence) {\n errors.push(t('scenarioDrawer.errors.remainingConsequenceTooHigh'));\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utilityfunctions.esm.js","sources":["../../src/utils/utilityfunctions.ts"],"sourcesContent":["import { DateTime } from 'luxon';\nimport { UpdateStatus } from '../contexts/RiScContext';\nimport {\n ActionStatusOptions,\n BASE_NUMBER,\n CONSEQUENCE_SCALE_OFFSET,\n PROBABILITY_SCALE_OFFSET,\n ThreatActorsOptions,\n VulnerabilitiesOptions,\n latestSupportedVersion,\n riskMatrix,\n} from './constants';\nimport {\n RiSc,\n RiScWithMetadata,\n Risk,\n Scenario,\n SubmitResponseObject,\n} from './types';\n\nexport function generateRandomId(): string {\n return [...Array(5)]\n .map(() => {\n const randomChar = Math.random().toString(36)[2];\n return Math.random() < 0.5 ? randomChar.toUpperCase() : randomChar;\n })\n .join('');\n}\n\n/**\n * Gets value from a nested object based on input path to the value.\n * Example:\n * {\n * test: {\n * somethings: [\n * {\n * title: 'Test1',\n * name: 'Name1',\n * },\n * ...\n * ]\n * }\n * }\n * getValue(theObjectFromAbove, 'test.somethings.0.title') => 'Test1'\n *\n * @param obj Object to get value from\n * @param path Path to value\n */\nexport function getValue(obj: any, path: string) {\n return path.split('.').reduce((prev, curr) => {\n return prev?.[curr];\n }, obj);\n}\n\nconst formatter = new Intl.NumberFormat('nb-NO', {\n maximumFractionDigits: 0,\n});\n\nexport function formatNOK(amount: number): string {\n return formatter.format(amount);\n}\n\nexport function getAlertSeverity(\n updateStatus: UpdateStatus,\n response?: SubmitResponseObject,\n): 'error' | 'success' | 'warning' | 'info' {\n if (updateStatus.isLoading) {\n return 'info';\n }\n if (updateStatus.isSuccess) {\n return 'success';\n } else if (updateStatus.isError) {\n return 'error';\n }\n\n if (response && typeof response.status === 'string') {\n if (response.status.includes('Error')) return 'error';\n return 'success';\n }\n\n return 'warning';\n}\n\nexport function getRiskMatrixColor(risiko: Risk) {\n const sannsynlighet = findProbabilityIndex(risiko.probability);\n const konsekvens = findConsequenceIndex(risiko.consequence);\n return riskMatrix[4 - konsekvens][sannsynlighet];\n}\n\nexport function getProbabilityLevel(risiko: Risk) {\n return findProbabilityIndex(risiko.probability) + 1;\n}\n\nexport function getConsequenceLevel(risiko: Risk) {\n return findConsequenceIndex(risiko.consequence) + 1;\n}\n\nexport function emptyRiSc(): RiSc {\n return {\n schemaVersion: latestSupportedVersion,\n title: '',\n scope: '',\n scenarios: [],\n };\n}\n\nexport function shortenName(name: string, maxCharacters: number = 16) {\n if (name.length <= maxCharacters) return name;\n\n const parts = name.trim().split(/\\s+/);\n\n if (parts.length === 3) {\n const [first, middle, last] = parts;\n const candidates = [\n `${first} ${middle[0]}. ${last}`,\n `${first} ${last}`,\n `${first} ${last[0]}.`,\n first,\n ];\n return (\n candidates.find(c => c.length <= maxCharacters) ??\n first.slice(0, maxCharacters)\n );\n }\n\n if (parts.length === 2) {\n const [first, last] = parts;\n const candidates = [\n `${first} ${last}`,\n `${first} ${last[0]}.`,\n first,\n last,\n ];\n\n return (\n candidates.find(c => c.length <= maxCharacters) ??\n first.slice(0, maxCharacters)\n );\n }\n\n return parts[parts.length - 1].slice(0, maxCharacters);\n}\n\nexport function formatDate(date: Date | string): string {\n return DateTime.fromJSDate(new Date(date)).toFormat('dd.MM.yy');\n}\n\nexport function calculateDaysSince(dateString: Date) {\n const givenDate = dateString;\n const now = new Date();\n\n const diffTime = now.getTime() - givenDate.getTime();\n const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));\n\n return diffDays;\n}\n\nexport const UpdatedStatusEnum = {\n UPDATED: 'UPDATED',\n LITTLE_OUTDATED: 'LITTLE_OUTDATED',\n OUTDATED: 'OUTDATED',\n VERY_OUTDATED: 'VERY_OUTDATED',\n} as const;\n\nexport type UpdatedStatusEnumType =\n (typeof UpdatedStatusEnum)[keyof typeof UpdatedStatusEnum];\n\nexport function calculateUpdatedStatus(\n daysSinceLastModified: number,\n): UpdatedStatusEnumType {\n if (daysSinceLastModified <= 90) return UpdatedStatusEnum.UPDATED;\n if (daysSinceLastModified <= 180) return UpdatedStatusEnum.LITTLE_OUTDATED;\n if (daysSinceLastModified <= 270) return UpdatedStatusEnum.OUTDATED;\n return UpdatedStatusEnum.VERY_OUTDATED;\n}\n\nexport function requiresNewApproval(oldRiSc: RiSc, updatedRiSc: RiSc): boolean {\n return !isDeeplyEqual(\n oldRiSc.scenarios.sort(\n (scenario1, scenario2) => Number(scenario1.ID) - Number(scenario2.ID),\n ),\n updatedRiSc.scenarios.sort(\n (scenario1, scenario2) => Number(scenario1.ID) - Number(scenario2.ID),\n ),\n );\n}\n\nexport function formatNumber(\n cost: number,\n t: (s: any, c: any) => string,\n): string {\n function getTranslationWithCorrectUnit(\n costValue: number,\n threshold: number,\n unit: string,\n ): string {\n return t(`riskMatrix.estimatedRisk.suffix.${unit}`, {\n count: Number(((costValue / threshold) * 1000).toFixed(0)),\n });\n }\n\n if (cost < 1e4) {\n return formatNOK(cost);\n }\n if (cost < 1e6) {\n return getTranslationWithCorrectUnit(cost, 1e6, 'thousand');\n }\n if (cost < 1e9) {\n return getTranslationWithCorrectUnit(cost, 1e9, 'million');\n }\n if (cost < 1e12) {\n return getTranslationWithCorrectUnit(cost, 1e12, 'billion');\n }\n return getTranslationWithCorrectUnit(cost, 1e15, 'trillion');\n}\n\nexport function parseISODateFromEncryptedROS(date?: string): string | null {\n // Early return if date is null or too short for an ISO date string, could happen from recursion\n if (!date || date.length < 10) {\n return null;\n }\n\n try {\n const parsedDate = DateTime.fromISO(date, { setZone: true });\n\n if (!parsedDate.isValid) {\n return parseISODateFromEncryptedROS(date.substring(1, date.length - 1));\n }\n\n return parsedDate.toISO({ suppressMilliseconds: true });\n } catch (e) {\n return null;\n }\n}\n\nexport function getTranslationKey(\n type: string,\n key: string,\n t: (s: any, c?: any) => string,\n context?: any,\n): string {\n if (type === 'error') {\n return t(\n [`errorMessages.${key}`, 'errorMessages.DefaultErrorMessage'],\n context,\n );\n }\n return t(`infoMessages.${key}`, context);\n}\n\nexport function isPublicAgeKeyValid(publicAgeKey: string) {\n if (publicAgeKey.length !== 62) {\n return false;\n }\n\n if (!publicAgeKey.startsWith('age1')) {\n return false;\n }\n\n const ageKeyRegex = /^age1[ac-hj-np-z02-9]{58}$/;\n return ageKeyRegex.test(publicAgeKey);\n}\n\nexport function deleteScenario(\n riSc: RiScWithMetadata | null,\n updateRiSc: (\n riSc: RiScWithMetadata,\n onSuccess?: () => void,\n onError?: () => void,\n ) => void,\n scenario: Scenario,\n) {\n if (riSc) {\n const updatedScenarios = riSc.content.scenarios.filter(\n s => s.ID !== scenario.ID,\n );\n updateRiSc({\n ...riSc,\n content: { ...riSc.content, scenarios: updatedScenarios },\n });\n }\n}\n\n/**\n * A recursive method for determining if a and b are deeply equal. Keys in the ignoredKeys argument are ignored in the\n * comparison, i.e., they are considered non-existing in both a and b.\n */\nexport function isDeeplyEqual<T>(\n a: T,\n b: T,\n ignoredKeys: string[] = [],\n): boolean {\n // If objects are equal, there is no need compare them any further.\n if (a === b) return true;\n\n // Only do comparison on objects, ignoring null (which maps to object).\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n // Check if a and b are both arrays or not. If only one is, then a and b are not equal. It is necessary to perform\n // this check, as otherwise the method below will say that [] and {} are equal (or [0] and {0: 0}).\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n // Check if a and b have the same number of entries\n if (\n Object.keys(a).filter(key => !ignoredKeys.includes(key)).length !==\n Object.keys(b).filter(key => !ignoredKeys.includes(key)).length\n )\n return false;\n\n // Check if every key of a is a key of b and that the entry associated with the key is deeply the same in a and b.\n // Since a and b has the same number of entries, it is sufficient to check only the keys of a.\n return Object.entries(a).every(\n ([key, value]) =>\n ignoredKeys.includes(key) ||\n (Object.hasOwn(b, key as keyof T) &&\n isDeeplyEqual(value, b[key as keyof T])),\n );\n }\n\n // If a or b is null or a primitive type, then they are not equal as a === b should have returned true already.\n return false;\n}\n\nfunction logBase(value: number, base: number): number {\n return Math.log(value) / Math.log(base);\n}\n\n/*\n Probability is categorized in 5 levels on a logarithmic scale with base 20:\n 0 = 20^-2 = 1 / 400\n 1 = 20^-1 = 1 / 20\n 2 = 20^-0 = 1\n 3 = 20^1 = 20\n 4 = 20^2 = 400\n*/\nexport function findProbabilityIndex(probability: number): number {\n const probabilityIndex = Math.round(\n logBase(probability, BASE_NUMBER) - PROBABILITY_SCALE_OFFSET,\n );\n return Math.min(4, Math.max(0, probabilityIndex));\n}\n\n/*\n Consequence is categorized in 5 levels on a logarithmic scale with base 20:\n 0 = 20^3 = 8 000\n 1 = 20^4 = 160 000\n 2 = 20^5 = 3 200 000\n 3 = 20^6 = 64 000 000\n 4 = 20^7 = 1 280 000 000\n*/\nexport function findConsequenceIndex(consequence: number): number {\n const consequenceIndex = Math.round(\n logBase(consequence, BASE_NUMBER) - CONSEQUENCE_SCALE_OFFSET,\n );\n return Math.min(4, Math.max(0, consequenceIndex));\n}\n\n/*\n Logarithmically round the consequence to the nearest consequence option.\n*/\nexport function roundConsequenceToNearestConsequenceOption(\n consequence: number,\n): number {\n return Math.pow(BASE_NUMBER, findConsequenceIndex(consequence) + 3);\n}\n\n/*\n Logarithmically round the probability to the nearest probability option.\n*/\nexport function roundProbabilityToNearestProbabilityOption(\n probability: number,\n): number {\n return Math.pow(BASE_NUMBER, findProbabilityIndex(probability) - 2);\n}\n\nexport const consequenceIndexToTranslationKeys: Record<number, string> = {\n 0: 'infoDialog.consequenceDescription.oneworkday',\n 1: 'infoDialog.consequenceDescription.oneworkmonth',\n 2: 'infoDialog.consequenceDescription.oneworkyear',\n 3: 'infoDialog.consequenceDescription.20workyears',\n 4: 'infoDialog.consequenceDescription.400workyears',\n};\n\nexport const probabilityIndexToTranslationKeys: Record<number, string> = {\n 0: 'infoDialog.probabilityDescription.every400years',\n 1: 'infoDialog.probabilityDescription.every20years',\n 2: 'infoDialog.probabilityDescription.annualy',\n 3: 'infoDialog.probabilityDescription.monthly',\n 4: 'infoDialog.probabilityDescription.daily',\n};\n\nexport const actionStatusOptionsToTranslationKeys: Record<\n ActionStatusOptions,\n string\n> = {\n [ActionStatusOptions.OK]: 'actionStatus.OK',\n [ActionStatusOptions.NotOK]: 'actionStatus.Not OK',\n [ActionStatusOptions.NotRelevant]: 'actionStatus.Not relevant',\n};\n\nexport function getTranslatedActionStatus(\n status: string,\n t: (key: string, options?: any) => string,\n): string {\n if (\n Object.values(ActionStatusOptions).includes(status as ActionStatusOptions)\n ) {\n return t(\n actionStatusOptionsToTranslationKeys[status as ActionStatusOptions],\n );\n }\n\n return status;\n}\n\nexport const threatActorOptionsToTranslationKeys: Record<\n ThreatActorsOptions,\n string\n> = {\n [ThreatActorsOptions.ScriptKiddie]: 'threatActors.Script kiddie',\n [ThreatActorsOptions.Hacktivist]: 'threatActors.Hacktivist',\n [ThreatActorsOptions.RecklessEmployee]: 'threatActors.Reckless employee',\n [ThreatActorsOptions.Insider]: 'threatActors.Insider',\n [ThreatActorsOptions.OrganisedCrime]: 'threatActors.Organised crime',\n [ThreatActorsOptions.TerroristOrganisation]:\n 'threatActors.Terrorist organisation',\n [ThreatActorsOptions.NationGovernment]: 'threatActors.Nation/government',\n};\n\nexport const vulnerabiltiesOptionsToTranslationKeys: Record<\n VulnerabilitiesOptions,\n string\n> = {\n [VulnerabilitiesOptions.FlawedDesign]: 'vulnerabilities.Flawed design',\n [VulnerabilitiesOptions.Misconfiguration]: 'vulnerabilities.Misconfiguration',\n [VulnerabilitiesOptions.DependencyVulnerability]:\n 'vulnerabilities.Dependency vulnerability',\n [VulnerabilitiesOptions.UnauthorizedAccess]:\n 'vulnerabilities.Unauthorized access',\n [VulnerabilitiesOptions.UnmonitoredUse]: 'vulnerabilities.Unmonitored use',\n [VulnerabilitiesOptions.InputTampering]: 'vulnerabilities.Input tampering',\n [VulnerabilitiesOptions.InformationLeak]: 'vulnerabilities.Information leak',\n [VulnerabilitiesOptions.ExcessiveUse]: 'vulnerabilities.Excessive use',\n};\n\nexport function computeStatusCount(riScWithMetadata: RiScWithMetadata) {\n const scenariosWithData = riScWithMetadata.content.scenarios.map(scenario => {\n const actionsWithStatus = (scenario.actions ?? []).map(action => {\n if (!action.lastUpdated) {\n return { ...action, status: UpdatedStatusEnum.VERY_OUTDATED };\n }\n const daysSinceLastUpdate = action.lastUpdated\n ? calculateDaysSince(new Date(action.lastUpdated))\n : null;\n const status =\n daysSinceLastUpdate !== null\n ? calculateUpdatedStatus(daysSinceLastUpdate)\n : UpdatedStatusEnum.VERY_OUTDATED;\n\n return { ...action, status };\n });\n return {\n ...scenario,\n actions: actionsWithStatus,\n };\n });\n\n const allActions = scenariosWithData.flatMap(scenario => scenario.actions);\n const totalCount = allActions.length;\n const veryOutdatedCount = allActions.filter(\n action => action.status === UpdatedStatusEnum.VERY_OUTDATED,\n ).length;\n const outdatedCount = allActions.filter(\n action => action.status === UpdatedStatusEnum.OUTDATED,\n ).length;\n const updatedCount = allActions.filter(\n action => action.status === UpdatedStatusEnum.UPDATED,\n ).length;\n\n return { totalCount, veryOutdatedCount, outdatedCount, updatedCount };\n}\n\nexport function getActiveTheme() {\n return document.body.getAttribute('data-theme-mode');\n}\n\nexport function validateRemainingRiskNotHigher(\n formData: {\n risk: { probability: number | string; consequence: number | string };\n remainingRisk: {\n probability: number | string;\n consequence: number | string;\n };\n },\n t: (key: string, options?: any) => string,\n): { isValid: boolean; errors: string[] } {\n const initialProbability = Number(formData.risk.probability);\n const initialConsequence = Number(formData.risk.consequence);\n const remainingProbability = Number(formData.remainingRisk.probability);\n const remainingConsequence = Number(formData.remainingRisk.consequence);\n\n const errors: string[] = [];\n\n if (remainingProbability > initialProbability) {\n errors.push(t('scenarioDrawer.errors.remainingProbabilityTooHigh'));\n }\n if (remainingConsequence > initialConsequence) {\n errors.push(t('scenarioDrawer.errors.remainingConsequenceTooHigh'));\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kartverket/backstage-plugin-risk-scorecard",
3
- "version": "6.6.1",
3
+ "version": "6.7.0",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "MIT",