@kyverno/backstage-plugin-policy-reporter 2.6.0 → 2.8.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/alpha/plugin.esm.js +70 -0
  3. package/dist/alpha/plugin.esm.js.map +1 -0
  4. package/dist/alpha.d.ts +129 -0
  5. package/dist/alpha.esm.js +2 -0
  6. package/dist/alpha.esm.js.map +1 -0
  7. package/dist/api/PolicyReporterClient.esm.js.map +1 -1
  8. package/dist/components/EntityCustomPoliciesContent/EntityCustomPoliciesContent.esm.js +48 -80
  9. package/dist/components/EntityCustomPoliciesContent/EntityCustomPoliciesContent.esm.js.map +1 -1
  10. package/dist/components/EntityCustomPoliciesContent/index.esm.js +5 -1
  11. package/dist/components/EntityCustomPoliciesContent/index.esm.js.map +1 -1
  12. package/dist/components/EntityKyvernoPoliciesContent/EntityKyvernoPoliciesContent.esm.js +48 -80
  13. package/dist/components/EntityKyvernoPoliciesContent/EntityKyvernoPoliciesContent.esm.js.map +1 -1
  14. package/dist/components/EntityKyvernoPoliciesContent/index.esm.js +5 -1
  15. package/dist/components/EntityKyvernoPoliciesContent/index.esm.js.map +1 -1
  16. package/dist/components/MissingEnvironmentsEmptyState/MissingEnvironmentsEmptyState.esm.js +1 -1
  17. package/dist/components/MissingEnvironmentsEmptyState/MissingEnvironmentsEmptyState.esm.js.map +1 -1
  18. package/dist/components/PolicyReportsDrawerComponent/PolicyReportsDrawerComponent.esm.js +1 -1
  19. package/dist/components/PolicyReportsDrawerComponent/PolicyReportsDrawerComponent.esm.js.map +1 -1
  20. package/dist/components/PolicyReportsPage/PolicyReportsPage.esm.js +41 -64
  21. package/dist/components/PolicyReportsPage/PolicyReportsPage.esm.js.map +1 -1
  22. package/dist/components/PolicyReportsPage/index.esm.js +5 -1
  23. package/dist/components/PolicyReportsPage/index.esm.js.map +1 -1
  24. package/dist/components/PolicyReportsTable/PolicyReportsTable.esm.js +85 -111
  25. package/dist/components/PolicyReportsTable/PolicyReportsTable.esm.js.map +1 -1
  26. package/dist/components/SearchField/SearchField.esm.js +33 -0
  27. package/dist/components/SearchField/SearchField.esm.js.map +1 -0
  28. package/dist/components/SelectEnvironment/SelectEnvironment.esm.js +22 -41
  29. package/dist/components/SelectEnvironment/SelectEnvironment.esm.js.map +1 -1
  30. package/dist/components/SelectNamespace/SelectNamespace.esm.js +35 -45
  31. package/dist/components/SelectNamespace/SelectNamespace.esm.js.map +1 -1
  32. package/dist/components/SelectSeverity/SelectSeverity.esm.js +40 -51
  33. package/dist/components/SelectSeverity/SelectSeverity.esm.js.map +1 -1
  34. package/dist/components/SelectStatus/SelectStatus.esm.js +40 -51
  35. package/dist/components/SelectStatus/SelectStatus.esm.js.map +1 -1
  36. package/dist/components/SeverityComponent/SeverityComponent.esm.js +11 -35
  37. package/dist/components/SeverityComponent/SeverityComponent.esm.js.map +1 -1
  38. package/dist/components/StatusComponent/StatusComponent.esm.js.map +1 -1
  39. package/dist/hooks/useEntityEnvironment.esm.js +1 -9
  40. package/dist/hooks/useEntityEnvironment.esm.js.map +1 -1
  41. package/dist/hooks/useEnvironments.esm.js +17 -30
  42. package/dist/hooks/useEnvironments.esm.js.map +1 -1
  43. package/dist/hooks/useNamespaces.esm.js +4 -4
  44. package/dist/hooks/useNamespaces.esm.js.map +1 -1
  45. package/dist/hooks/usePolicyReportsFilters.esm.js +90 -0
  46. package/dist/hooks/usePolicyReportsFilters.esm.js.map +1 -0
  47. package/dist/index.d.ts +1 -1
  48. package/dist/package.json.esm.js +110 -0
  49. package/dist/package.json.esm.js.map +1 -0
  50. package/dist/plugin.esm.js +1 -1
  51. package/dist/plugin.esm.js.map +1 -1
  52. package/dist/routes.esm.js.map +1 -1
  53. package/dist/utils/annotations.esm.js +1 -1
  54. package/dist/utils/annotations.esm.js.map +1 -1
  55. package/package.json +46 -21
  56. package/dist/hooks/usePaginatedPolicies.esm.js +0 -51
  57. package/dist/hooks/usePaginatedPolicies.esm.js.map +0 -1
@@ -1,41 +1,17 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import Chip from '@material-ui/core/Chip';
3
- import makeStyles from '@material-ui/core/styles/makeStyles';
2
+ import { Badge } from '@backstage/ui';
4
3
 
5
- const useStyles = makeStyles((theme) => ({
6
- error: {
7
- backgroundColor: theme.palette.error.main,
8
- color: theme.palette.error.contrastText
9
- },
10
- success: {
11
- backgroundColor: theme.palette.success.main,
12
- color: theme.palette.success.contrastText
13
- },
14
- warning: {
15
- backgroundColor: theme.palette.warning.main,
16
- color: theme.palette.warning.contrastText
17
- },
18
- info: {
19
- backgroundColor: theme.palette.info.main,
20
- color: theme.palette.info.contrastText
21
- }
22
- }));
4
+ const severityStyles = {
5
+ high: { backgroundColor: "var(--bui-bg-danger)" },
6
+ critical: { backgroundColor: "var(--bui-bg-danger)" },
7
+ medium: { backgroundColor: "var(--bui-bg-warning)" },
8
+ low: { backgroundColor: "var(--bui-bg-success)" },
9
+ info: { backgroundColor: "var(--bui-bg-info)" },
10
+ unknown: {}
11
+ };
23
12
  const SeverityComponent = ({ severity }) => {
24
- const classes = useStyles();
25
- switch (severity) {
26
- case "high":
27
- return /* @__PURE__ */ jsx(Chip, { label: severity, className: classes.error });
28
- case "low":
29
- return /* @__PURE__ */ jsx(Chip, { label: severity, className: classes.success });
30
- case "medium":
31
- return /* @__PURE__ */ jsx(Chip, { label: severity, className: classes.warning });
32
- case "info":
33
- return /* @__PURE__ */ jsx(Chip, { label: severity, className: classes.info });
34
- case "critical":
35
- return /* @__PURE__ */ jsx(Chip, { label: severity, className: classes.error });
36
- default:
37
- return null;
38
- }
13
+ if (!severity) return null;
14
+ return /* @__PURE__ */ jsx(Badge, { style: severityStyles[severity], children: severity });
39
15
  };
40
16
 
41
17
  export { SeverityComponent };
@@ -1 +1 @@
1
- {"version":3,"file":"SeverityComponent.esm.js","sources":["../../../src/components/SeverityComponent/SeverityComponent.tsx"],"sourcesContent":["import Chip from '@material-ui/core/Chip';\nimport { Severity } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport makeStyles from '@material-ui/core/styles/makeStyles';\n\nconst useStyles = makeStyles((theme: any) => ({\n error: {\n backgroundColor: theme.palette.error.main,\n color: theme.palette.error.contrastText,\n },\n success: {\n backgroundColor: theme.palette.success.main,\n color: theme.palette.success.contrastText,\n },\n warning: {\n backgroundColor: theme.palette.warning.main,\n color: theme.palette.warning.contrastText,\n },\n info: {\n backgroundColor: theme.palette.info.main,\n color: theme.palette.info.contrastText,\n },\n}));\n\ntype SeverityComponentProps = {\n severity: Severity | null;\n};\n\nexport const SeverityComponent = ({ severity }: SeverityComponentProps) => {\n const classes = useStyles();\n switch (severity) {\n case 'high':\n return <Chip label={severity} className={classes.error} />;\n case 'low':\n return <Chip label={severity} className={classes.success} />;\n case 'medium':\n return <Chip label={severity} className={classes.warning} />;\n case 'info':\n return <Chip label={severity} className={classes.info} />;\n case 'critical':\n return <Chip label={severity} className={classes.error} />;\n default:\n return null;\n }\n};\n"],"names":[],"mappings":";;;;AAIA,MAAM,SAAA,GAAY,UAAW,CAAA,CAAC,KAAgB,MAAA;AAAA,EAC5C,KAAO,EAAA;AAAA,IACL,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,KAAM,CAAA,IAAA;AAAA,IACrC,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,KAAM,CAAA;AAAA,GAC7B;AAAA,EACA,OAAS,EAAA;AAAA,IACP,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA;AAAA,IACvC,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA;AAAA,GAC/B;AAAA,EACA,OAAS,EAAA;AAAA,IACP,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA;AAAA,IACvC,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA;AAAA,GAC/B;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,IAAA;AAAA,IACpC,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA;AAAA;AAE9B,CAAE,CAAA,CAAA;AAMK,MAAM,iBAAoB,GAAA,CAAC,EAAE,QAAA,EAAuC,KAAA;AACzE,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,QAAQ,QAAU;AAAA,IAChB,KAAK,MAAA;AACH,MAAA,2BAAQ,IAAK,EAAA,EAAA,KAAA,EAAO,QAAU,EAAA,SAAA,EAAW,QAAQ,KAAO,EAAA,CAAA;AAAA,IAC1D,KAAK,KAAA;AACH,MAAA,2BAAQ,IAAK,EAAA,EAAA,KAAA,EAAO,QAAU,EAAA,SAAA,EAAW,QAAQ,OAAS,EAAA,CAAA;AAAA,IAC5D,KAAK,QAAA;AACH,MAAA,2BAAQ,IAAK,EAAA,EAAA,KAAA,EAAO,QAAU,EAAA,SAAA,EAAW,QAAQ,OAAS,EAAA,CAAA;AAAA,IAC5D,KAAK,MAAA;AACH,MAAA,2BAAQ,IAAK,EAAA,EAAA,KAAA,EAAO,QAAU,EAAA,SAAA,EAAW,QAAQ,IAAM,EAAA,CAAA;AAAA,IACzD,KAAK,UAAA;AACH,MAAA,2BAAQ,IAAK,EAAA,EAAA,KAAA,EAAO,QAAU,EAAA,SAAA,EAAW,QAAQ,KAAO,EAAA,CAAA;AAAA,IAC1D;AACE,MAAO,OAAA,IAAA;AAAA;AAEb;;;;"}
1
+ {"version":3,"file":"SeverityComponent.esm.js","sources":["../../../src/components/SeverityComponent/SeverityComponent.tsx"],"sourcesContent":["import { Badge } from '@backstage/ui';\nimport { Severity } from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype SeverityComponentProps = {\n severity: Severity | null;\n};\n\nconst severityStyles: Record<string, React.CSSProperties> = {\n high: { backgroundColor: 'var(--bui-bg-danger)' },\n critical: { backgroundColor: 'var(--bui-bg-danger)' },\n medium: { backgroundColor: 'var(--bui-bg-warning)' },\n low: { backgroundColor: 'var(--bui-bg-success)' },\n info: { backgroundColor: 'var(--bui-bg-info)' },\n unknown: {},\n};\n\nexport const SeverityComponent = ({ severity }: SeverityComponentProps) => {\n if (!severity) return null;\n return <Badge style={severityStyles[severity]}>{severity}</Badge>;\n};\n"],"names":[],"mappings":";;;AAOA,MAAM,cAAA,GAAsD;AAAA,EAC1D,IAAA,EAAM,EAAE,eAAA,EAAiB,sBAAA,EAAuB;AAAA,EAChD,QAAA,EAAU,EAAE,eAAA,EAAiB,sBAAA,EAAuB;AAAA,EACpD,MAAA,EAAQ,EAAE,eAAA,EAAiB,uBAAA,EAAwB;AAAA,EACnD,GAAA,EAAK,EAAE,eAAA,EAAiB,uBAAA,EAAwB;AAAA,EAChD,IAAA,EAAM,EAAE,eAAA,EAAiB,oBAAA,EAAqB;AAAA,EAC9C,SAAS;AACX,CAAA;AAEO,MAAM,iBAAA,GAAoB,CAAC,EAAE,QAAA,EAAS,KAA8B;AACzE,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,2BAAQ,KAAA,EAAA,EAAM,KAAA,EAAO,cAAA,CAAe,QAAQ,GAAI,QAAA,EAAA,QAAA,EAAS,CAAA;AAC3D;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"StatusComponent.esm.js","sources":["../../../src/components/StatusComponent/StatusComponent.tsx"],"sourcesContent":["import {\n StatusAborted,\n StatusError,\n StatusOK,\n StatusWarning,\n} from '@backstage/core-components';\nimport type { Status } from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype StatusComponentProps = {\n status: Status;\n};\n\nexport const StatusComponent = ({ status }: StatusComponentProps) => {\n switch (status) {\n case 'pass':\n return <StatusOK>PASS</StatusOK>;\n case 'error':\n return <StatusError>ERROR</StatusError>;\n case 'fail':\n return <StatusError>FAIL</StatusError>;\n case 'skip':\n return <StatusAborted>SKIP</StatusAborted>;\n case 'warn':\n return <StatusWarning>WARN</StatusWarning>;\n default:\n return null;\n }\n};\n"],"names":[],"mappings":";;;AAYO,MAAM,eAAkB,GAAA,CAAC,EAAE,MAAA,EAAmC,KAAA;AACnE,EAAA,QAAQ,MAAQ;AAAA,IACd,KAAK,MAAA;AACH,MAAO,uBAAA,GAAA,CAAC,YAAS,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,IACvB,KAAK,OAAA;AACH,MAAO,uBAAA,GAAA,CAAC,eAAY,QAAK,EAAA,OAAA,EAAA,CAAA;AAAA,IAC3B,KAAK,MAAA;AACH,MAAO,uBAAA,GAAA,CAAC,eAAY,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,IAC1B,KAAK,MAAA;AACH,MAAO,uBAAA,GAAA,CAAC,iBAAc,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,IAC5B,KAAK,MAAA;AACH,MAAO,uBAAA,GAAA,CAAC,iBAAc,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,IAC5B;AACE,MAAO,OAAA,IAAA;AAAA;AAEb;;;;"}
1
+ {"version":3,"file":"StatusComponent.esm.js","sources":["../../../src/components/StatusComponent/StatusComponent.tsx"],"sourcesContent":["import {\n StatusAborted,\n StatusError,\n StatusOK,\n StatusWarning,\n} from '@backstage/core-components';\nimport type { Status } from '@kyverno/backstage-plugin-policy-reporter-common';\n\ntype StatusComponentProps = {\n status: Status;\n};\n\nexport const StatusComponent = ({ status }: StatusComponentProps) => {\n switch (status) {\n case 'pass':\n return <StatusOK>PASS</StatusOK>;\n case 'error':\n return <StatusError>ERROR</StatusError>;\n case 'fail':\n return <StatusError>FAIL</StatusError>;\n case 'skip':\n return <StatusAborted>SKIP</StatusAborted>;\n case 'warn':\n return <StatusWarning>WARN</StatusWarning>;\n default:\n return null;\n }\n};\n"],"names":[],"mappings":";;;AAYO,MAAM,eAAA,GAAkB,CAAC,EAAE,MAAA,EAAO,KAA4B;AACnE,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,MAAA;AACH,MAAA,uBAAO,GAAA,CAAC,YAAS,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IACvB,KAAK,OAAA;AACH,MAAA,uBAAO,GAAA,CAAC,eAAY,QAAA,EAAA,OAAA,EAAK,CAAA;AAAA,IAC3B,KAAK,MAAA;AACH,MAAA,uBAAO,GAAA,CAAC,eAAY,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IAC1B,KAAK,MAAA;AACH,MAAA,uBAAO,GAAA,CAAC,iBAAc,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IAC5B,KAAK,MAAA;AACH,MAAA,uBAAO,GAAA,CAAC,iBAAc,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IAC5B;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;;;;"}
@@ -1,11 +1,9 @@
1
- import { useState } from 'react';
2
1
  import { useAsync } from 'react-use';
3
2
  import { catalogApiRef, CATALOG_FILTER_EXISTS } from '@backstage/plugin-catalog-react';
4
3
  import { useApi } from '@backstage/core-plugin-api';
5
4
 
6
5
  const useEntityEnvironment = (entity, annotationsState) => {
7
6
  const catalogApi = useApi(catalogApiRef);
8
- const [currentEnvironment, setCurrentEnvironment] = useState(void 0);
9
7
  const { value: environments, loading: environmentsLoading } = useAsync(async () => {
10
8
  if (!annotationsState) return void 0;
11
9
  const dependencies = entity.spec?.dependsOn;
@@ -29,15 +27,9 @@ const useEntityEnvironment = (entity, annotationsState) => {
29
27
  });
30
28
  }
31
29
  });
32
- setCurrentEnvironment(environmentList[0]);
33
30
  return environmentList;
34
31
  }, [entity]);
35
- return {
36
- environments,
37
- environmentsLoading,
38
- currentEnvironment,
39
- setCurrentEnvironment
40
- };
32
+ return { environments, environmentsLoading };
41
33
  };
42
34
 
43
35
  export { useEntityEnvironment };
@@ -1 +1 @@
1
- {"version":3,"file":"useEntityEnvironment.esm.js","sources":["../../src/hooks/useEntityEnvironment.ts"],"sourcesContent":["import { useState } from 'react';\nimport { useAsync } from 'react-use';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport {\n CATALOG_FILTER_EXISTS,\n catalogApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Entity } from '@backstage/catalog-model';\n\nexport const useEntityEnvironment = (\n entity: Entity,\n annotationsState: boolean,\n) => {\n const catalogApi = useApi(catalogApiRef);\n const [currentEnvironment, setCurrentEnvironment] = useState<\n Environment | undefined\n >(undefined);\n\n const { value: environments, loading: environmentsLoading } =\n useAsync(async (): Promise<Environment[] | undefined> => {\n if (!annotationsState) return undefined;\n\n const dependencies = entity.spec?.dependsOn as string[];\n if (!dependencies) return undefined;\n\n const entities = await catalogApi.getEntitiesByRefs({\n entityRefs: dependencies as string[],\n fields: ['metadata.name'],\n filter: {\n kind: 'Resource',\n 'spec.type': 'kubernetes-cluster',\n 'metadata.annotations.kyverno.io/endpoint': CATALOG_FILTER_EXISTS,\n },\n });\n\n const environmentList: Environment[] = [];\n\n dependencies.forEach((dependency, index) => {\n if (entities.items[index]) {\n environmentList.push({\n id: environmentList.length,\n entityRef: dependency,\n name: entities.items[index]?.metadata.name as string,\n });\n }\n });\n\n setCurrentEnvironment(environmentList[0]);\n\n return environmentList;\n }, [entity]);\n\n return {\n environments,\n environmentsLoading,\n currentEnvironment,\n setCurrentEnvironment,\n };\n};\n"],"names":[],"mappings":";;;;;AAUa,MAAA,oBAAA,GAAuB,CAClC,MAAA,EACA,gBACG,KAAA;AACH,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAI,SAElD,KAAS,CAAA,CAAA;AAEX,EAAA,MAAM,EAAE,KAAO,EAAA,YAAA,EAAc,SAAS,mBAAoB,EAAA,GACxD,SAAS,YAAgD;AACvD,IAAI,IAAA,CAAC,kBAAyB,OAAA,KAAA,CAAA;AAE9B,IAAM,MAAA,YAAA,GAAe,OAAO,IAAM,EAAA,SAAA;AAClC,IAAI,IAAA,CAAC,cAAqB,OAAA,KAAA,CAAA;AAE1B,IAAM,MAAA,QAAA,GAAW,MAAM,UAAA,CAAW,iBAAkB,CAAA;AAAA,MAClD,UAAY,EAAA,YAAA;AAAA,MACZ,MAAA,EAAQ,CAAC,eAAe,CAAA;AAAA,MACxB,MAAQ,EAAA;AAAA,QACN,IAAM,EAAA,UAAA;AAAA,QACN,WAAa,EAAA,oBAAA;AAAA,QACb,0CAA4C,EAAA;AAAA;AAC9C,KACD,CAAA;AAED,IAAA,MAAM,kBAAiC,EAAC;AAExC,IAAa,YAAA,CAAA,OAAA,CAAQ,CAAC,UAAA,EAAY,KAAU,KAAA;AAC1C,MAAI,IAAA,QAAA,CAAS,KAAM,CAAA,KAAK,CAAG,EAAA;AACzB,QAAA,eAAA,CAAgB,IAAK,CAAA;AAAA,UACnB,IAAI,eAAgB,CAAA,MAAA;AAAA,UACpB,SAAW,EAAA,UAAA;AAAA,UACX,IAAM,EAAA,QAAA,CAAS,KAAM,CAAA,KAAK,GAAG,QAAS,CAAA;AAAA,SACvC,CAAA;AAAA;AACH,KACD,CAAA;AAED,IAAsB,qBAAA,CAAA,eAAA,CAAgB,CAAC,CAAC,CAAA;AAExC,IAAO,OAAA,eAAA;AAAA,GACT,EAAG,CAAC,MAAM,CAAC,CAAA;AAEb,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"useEntityEnvironment.esm.js","sources":["../../src/hooks/useEntityEnvironment.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport {\n CATALOG_FILTER_EXISTS,\n catalogApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Entity } from '@backstage/catalog-model';\n\nexport const useEntityEnvironment = (\n entity: Entity,\n annotationsState: boolean,\n) => {\n const catalogApi = useApi(catalogApiRef);\n\n const { value: environments, loading: environmentsLoading } =\n useAsync(async (): Promise<Environment[] | undefined> => {\n if (!annotationsState) return undefined;\n\n const dependencies = entity.spec?.dependsOn as string[];\n if (!dependencies) return undefined;\n\n const entities = await catalogApi.getEntitiesByRefs({\n entityRefs: dependencies as string[],\n fields: ['metadata.name'],\n filter: {\n kind: 'Resource',\n 'spec.type': 'kubernetes-cluster',\n 'metadata.annotations.kyverno.io/endpoint': CATALOG_FILTER_EXISTS,\n },\n });\n\n const environmentList: Environment[] = [];\n\n dependencies.forEach((dependency, index) => {\n if (entities.items[index]) {\n environmentList.push({\n id: environmentList.length,\n entityRef: dependency,\n name: entities.items[index]?.metadata.name as string,\n });\n }\n });\n\n return environmentList;\n }, [entity]);\n\n return { environments, environmentsLoading };\n};\n"],"names":[],"mappings":";;;;AASO,MAAM,oBAAA,GAAuB,CAClC,MAAA,EACA,gBAAA,KACG;AACH,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AAEvC,EAAA,MAAM,EAAE,KAAA,EAAO,YAAA,EAAc,SAAS,mBAAA,EAAoB,GACxD,SAAS,YAAgD;AACvD,IAAA,IAAI,CAAC,kBAAkB,OAAO,MAAA;AAE9B,IAAA,MAAM,YAAA,GAAe,OAAO,IAAA,EAAM,SAAA;AAClC,IAAA,IAAI,CAAC,cAAc,OAAO,MAAA;AAE1B,IAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,iBAAA,CAAkB;AAAA,MAClD,UAAA,EAAY,YAAA;AAAA,MACZ,MAAA,EAAQ,CAAC,eAAe,CAAA;AAAA,MACxB,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,UAAA;AAAA,QACN,WAAA,EAAa,oBAAA;AAAA,QACb,0CAAA,EAA4C;AAAA;AAC9C,KACD,CAAA;AAED,IAAA,MAAM,kBAAiC,EAAC;AAExC,IAAA,YAAA,CAAa,OAAA,CAAQ,CAAC,UAAA,EAAY,KAAA,KAAU;AAC1C,MAAA,IAAI,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA,EAAG;AACzB,QAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,UACnB,IAAI,eAAA,CAAgB,MAAA;AAAA,UACpB,SAAA,EAAW,UAAA;AAAA,UACX,IAAA,EAAM,QAAA,CAAS,KAAA,CAAM,KAAK,GAAG,QAAA,CAAS;AAAA,SACvC,CAAA;AAAA,MACH;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,eAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEb,EAAA,OAAO,EAAE,cAAc,mBAAA,EAAoB;AAC7C;;;;"}
@@ -1,39 +1,26 @@
1
- import { useState } from 'react';
2
1
  import { useAsync } from 'react-use';
3
2
  import { catalogApiRef, CATALOG_FILTER_EXISTS } from '@backstage/plugin-catalog-react';
4
3
  import { useApi } from '@backstage/core-plugin-api';
5
4
 
6
5
  const useEnvironments = () => {
7
6
  const catalogApi = useApi(catalogApiRef);
8
- const [currentEnvironment, setCurrentEnvironment] = useState(void 0);
9
- const { value: environments, loading: environmentsLoading } = useAsync(
10
- async () => {
11
- const entities = await catalogApi.getEntities({
12
- fields: ["metadata.name", "metadata.namespace", "kind"],
13
- filter: {
14
- kind: "Resource",
15
- "spec.type": "kubernetes-cluster",
16
- "metadata.annotations.kyverno.io/endpoint": CATALOG_FILTER_EXISTS
17
- }
18
- });
19
- if (!entities) return void 0;
20
- const environmentList = entities.items.map(
21
- (entity, index) => ({
22
- id: index,
23
- entityRef: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`,
24
- name: entity.metadata.name
25
- })
26
- );
27
- setCurrentEnvironment(environmentList[0]);
28
- return environmentList;
29
- }
30
- );
31
- return {
32
- environments,
33
- environmentsLoading,
34
- currentEnvironment,
35
- setCurrentEnvironment
36
- };
7
+ const { value: environments, loading: environmentsLoading } = useAsync(async () => {
8
+ const entities = await catalogApi.getEntities({
9
+ fields: ["metadata.name", "metadata.namespace", "kind"],
10
+ filter: {
11
+ kind: "Resource",
12
+ "spec.type": "kubernetes-cluster",
13
+ "metadata.annotations.kyverno.io/endpoint": CATALOG_FILTER_EXISTS
14
+ }
15
+ });
16
+ if (!entities) return void 0;
17
+ return entities.items.map((entity, index) => ({
18
+ id: index,
19
+ entityRef: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`,
20
+ name: entity.metadata.name
21
+ }));
22
+ }, []);
23
+ return { environments, environmentsLoading };
37
24
  };
38
25
 
39
26
  export { useEnvironments };
@@ -1 +1 @@
1
- {"version":3,"file":"useEnvironments.esm.js","sources":["../../src/hooks/useEnvironments.ts"],"sourcesContent":["import { useState } from 'react';\nimport { useAsync } from 'react-use';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport {\n CATALOG_FILTER_EXISTS,\n catalogApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\n\nexport const useEnvironments = () => {\n const catalogApi = useApi(catalogApiRef);\n const [currentEnvironment, setCurrentEnvironment] = useState<\n Environment | undefined\n >(undefined);\n\n const { value: environments, loading: environmentsLoading } = useAsync(\n async (): Promise<Environment[] | undefined> => {\n const entities = await catalogApi.getEntities({\n fields: ['metadata.name', 'metadata.namespace', 'kind'],\n filter: {\n kind: 'Resource',\n 'spec.type': 'kubernetes-cluster',\n 'metadata.annotations.kyverno.io/endpoint': CATALOG_FILTER_EXISTS,\n },\n });\n\n if (!entities) return undefined;\n\n const environmentList: Environment[] = entities.items.map(\n (entity, index) => ({\n id: index,\n entityRef: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`,\n name: entity.metadata.name,\n }),\n );\n\n setCurrentEnvironment(environmentList[0]);\n\n return environmentList;\n },\n );\n\n return {\n environments,\n environmentsLoading,\n currentEnvironment,\n setCurrentEnvironment,\n };\n};\n"],"names":[],"mappings":";;;;;AASO,MAAM,kBAAkB,MAAM;AACnC,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAI,SAElD,KAAS,CAAA,CAAA;AAEX,EAAA,MAAM,EAAE,KAAA,EAAO,YAAc,EAAA,OAAA,EAAS,qBAAwB,GAAA,QAAA;AAAA,IAC5D,YAAgD;AAC9C,MAAM,MAAA,QAAA,GAAW,MAAM,UAAA,CAAW,WAAY,CAAA;AAAA,QAC5C,MAAQ,EAAA,CAAC,eAAiB,EAAA,oBAAA,EAAsB,MAAM,CAAA;AAAA,QACtD,MAAQ,EAAA;AAAA,UACN,IAAM,EAAA,UAAA;AAAA,UACN,WAAa,EAAA,oBAAA;AAAA,UACb,0CAA4C,EAAA;AAAA;AAC9C,OACD,CAAA;AAED,MAAI,IAAA,CAAC,UAAiB,OAAA,KAAA,CAAA;AAEtB,MAAM,MAAA,eAAA,GAAiC,SAAS,KAAM,CAAA,GAAA;AAAA,QACpD,CAAC,QAAQ,KAAW,MAAA;AAAA,UAClB,EAAI,EAAA,KAAA;AAAA,UACJ,SAAA,EAAW,CAAG,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,MAAO,CAAA,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,MAAO,CAAA,QAAA,CAAS,IAAI,CAAA,CAAA;AAAA,UAC9E,IAAA,EAAM,OAAO,QAAS,CAAA;AAAA,SACxB;AAAA,OACF;AAEA,MAAsB,qBAAA,CAAA,eAAA,CAAgB,CAAC,CAAC,CAAA;AAExC,MAAO,OAAA,eAAA;AAAA;AACT,GACF;AAEA,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"useEnvironments.esm.js","sources":["../../src/hooks/useEnvironments.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport {\n CATALOG_FILTER_EXISTS,\n catalogApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\n\nexport const useEnvironments = () => {\n const catalogApi = useApi(catalogApiRef);\n\n const { value: environments, loading: environmentsLoading } =\n useAsync(async (): Promise<Environment[] | undefined> => {\n const entities = await catalogApi.getEntities({\n fields: ['metadata.name', 'metadata.namespace', 'kind'],\n filter: {\n kind: 'Resource',\n 'spec.type': 'kubernetes-cluster',\n 'metadata.annotations.kyverno.io/endpoint': CATALOG_FILTER_EXISTS,\n },\n });\n\n if (!entities) return undefined;\n\n return entities.items.map((entity, index) => ({\n id: index,\n entityRef: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`,\n name: entity.metadata.name,\n }));\n }, []);\n\n return { environments, environmentsLoading };\n};\n"],"names":[],"mappings":";;;;AAQO,MAAM,kBAAkB,MAAM;AACnC,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AAEvC,EAAA,MAAM,EAAE,KAAA,EAAO,YAAA,EAAc,SAAS,mBAAA,EAAoB,GACxD,SAAS,YAAgD;AACvD,IAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,WAAA,CAAY;AAAA,MAC5C,MAAA,EAAQ,CAAC,eAAA,EAAiB,oBAAA,EAAsB,MAAM,CAAA;AAAA,MACtD,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,UAAA;AAAA,QACN,WAAA,EAAa,oBAAA;AAAA,QACb,0CAAA,EAA4C;AAAA;AAC9C,KACD,CAAA;AAED,IAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AAEtB,IAAA,OAAO,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,CAAC,QAAQ,KAAA,MAAW;AAAA,MAC5C,EAAA,EAAI,KAAA;AAAA,MACJ,SAAA,EAAW,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,CAAA;AAAA,MAC9E,IAAA,EAAM,OAAO,QAAA,CAAS;AAAA,KACxB,CAAE,CAAA;AAAA,EACJ,CAAA,EAAG,EAAE,CAAA;AAEP,EAAA,OAAO,EAAE,cAAc,mBAAA,EAAoB;AAC7C;;;;"}
@@ -2,21 +2,21 @@ import { useAsync } from 'react-use';
2
2
  import { useApi } from '@backstage/core-plugin-api';
3
3
  import { policyReporterApiRef } from '../api/PolicyReporterClient.esm.js';
4
4
 
5
- const useNamespaces = (currentEnvironment) => {
5
+ const useNamespaces = (entityRef) => {
6
6
  const api = useApi(policyReporterApiRef);
7
7
  const {
8
8
  value: namespaces,
9
9
  loading,
10
10
  error
11
11
  } = useAsync(async () => {
12
- if (!currentEnvironment) {
12
+ if (!entityRef) {
13
13
  return [];
14
14
  }
15
15
  const response = await api.getNamespaces({
16
- query: { environment: currentEnvironment.entityRef }
16
+ query: { environment: entityRef }
17
17
  });
18
18
  return response.json();
19
- }, [api, currentEnvironment]);
19
+ }, [api, entityRef]);
20
20
  return {
21
21
  namespaces: namespaces ?? [],
22
22
  loading,
@@ -1 +1 @@
1
- {"version":3,"file":"useNamespaces.esm.js","sources":["../../src/hooks/useNamespaces.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { policyReporterApiRef } from '../api';\nimport { Environment } from '@kyverno/backstage-plugin-policy-reporter-common';\n\nexport const useNamespaces = (currentEnvironment?: Environment) => {\n const api = useApi(policyReporterApiRef);\n\n const {\n value: namespaces,\n loading,\n error,\n } = useAsync(async () => {\n if (!currentEnvironment) {\n return [];\n }\n\n const response = await api.getNamespaces({\n query: { environment: currentEnvironment.entityRef },\n });\n return response.json();\n }, [api, currentEnvironment]);\n\n return {\n namespaces: namespaces ?? [],\n loading,\n error,\n };\n};\n"],"names":[],"mappings":";;;;AAKa,MAAA,aAAA,GAAgB,CAAC,kBAAqC,KAAA;AACjE,EAAM,MAAA,GAAA,GAAM,OAAO,oBAAoB,CAAA;AAEvC,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,UAAA;AAAA,IACP,OAAA;AAAA,IACA;AAAA,GACF,GAAI,SAAS,YAAY;AACvB,IAAA,IAAI,CAAC,kBAAoB,EAAA;AACvB,MAAA,OAAO,EAAC;AAAA;AAGV,IAAM,MAAA,QAAA,GAAW,MAAM,GAAA,CAAI,aAAc,CAAA;AAAA,MACvC,KAAO,EAAA,EAAE,WAAa,EAAA,kBAAA,CAAmB,SAAU;AAAA,KACpD,CAAA;AACD,IAAA,OAAO,SAAS,IAAK,EAAA;AAAA,GACpB,EAAA,CAAC,GAAK,EAAA,kBAAkB,CAAC,CAAA;AAE5B,EAAO,OAAA;AAAA,IACL,UAAA,EAAY,cAAc,EAAC;AAAA,IAC3B,OAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"useNamespaces.esm.js","sources":["../../src/hooks/useNamespaces.ts"],"sourcesContent":["import { useAsync } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { policyReporterApiRef } from '../api';\n\nexport const useNamespaces = (entityRef?: string) => {\n const api = useApi(policyReporterApiRef);\n\n const {\n value: namespaces,\n loading,\n error,\n } = useAsync(async () => {\n if (!entityRef) {\n return [];\n }\n\n const response = await api.getNamespaces({\n query: { environment: entityRef },\n });\n return response.json();\n }, [api, entityRef]);\n\n return {\n namespaces: namespaces ?? [],\n loading,\n error,\n };\n};\n"],"names":[],"mappings":";;;;AAIO,MAAM,aAAA,GAAgB,CAAC,SAAA,KAAuB;AACnD,EAAA,MAAM,GAAA,GAAM,OAAO,oBAAoB,CAAA;AAEvC,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,UAAA;AAAA,IACP,OAAA;AAAA,IACA;AAAA,GACF,GAAI,SAAS,YAAY;AACvB,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc;AAAA,MACvC,KAAA,EAAO,EAAE,WAAA,EAAa,SAAA;AAAU,KACjC,CAAA;AACD,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB,CAAA,EAAG,CAAC,GAAA,EAAK,SAAS,CAAC,CAAA;AAEnB,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,cAAc,EAAC;AAAA,IAC3B,OAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -0,0 +1,90 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import qs from 'qs';
3
+ import { useMemo, useCallback, useLayoutEffect, createContext, useContext } from 'react';
4
+ import { useSearchParams } from 'react-router-dom';
5
+
6
+ const PolicyReportsFiltersContext = createContext(void 0);
7
+ const PolicyReportsFiltersProvider = ({
8
+ children,
9
+ defaultFilters,
10
+ defaultEnvironment
11
+ }) => {
12
+ const [searchParams, setSearchParams] = useSearchParams();
13
+ const parsed = useMemo(
14
+ () => qs.parse(searchParams.toString()),
15
+ [searchParams]
16
+ );
17
+ const urlEnvironment = useMemo(
18
+ () => parsed.environment?.toString(),
19
+ [parsed]
20
+ );
21
+ const filter = useMemo(
22
+ () => urlEnvironment ? parsed.filter ?? {} : defaultFilters ?? {},
23
+ [parsed, urlEnvironment, defaultFilters]
24
+ );
25
+ const environment = useMemo(
26
+ () => urlEnvironment ?? defaultEnvironment,
27
+ [urlEnvironment, defaultEnvironment]
28
+ );
29
+ const updateParams = useCallback(
30
+ (update) => {
31
+ setSearchParams(
32
+ (prev) => {
33
+ const prevParsed = qs.parse(prev.toString());
34
+ const next = typeof update === "function" ? update(prevParsed) : update;
35
+ return qs.stringify(next, {
36
+ arrayFormat: "indices",
37
+ skipNulls: true
38
+ });
39
+ },
40
+ { replace: true }
41
+ );
42
+ },
43
+ [setSearchParams]
44
+ );
45
+ useLayoutEffect(() => {
46
+ if (!urlEnvironment) {
47
+ updateParams({
48
+ filter: defaultFilters,
49
+ environment: defaultEnvironment
50
+ });
51
+ }
52
+ }, [defaultEnvironment, urlEnvironment, defaultFilters]);
53
+ const updateFilter = useCallback(
54
+ (update) => {
55
+ updateParams((prev) => ({
56
+ ...prev,
57
+ filter: { ...prev.filter, ...update }
58
+ }));
59
+ },
60
+ [updateParams]
61
+ );
62
+ const setEnvironment = useCallback(
63
+ (entityRef) => {
64
+ updateParams((prev) => ({ ...prev, environment: entityRef }));
65
+ },
66
+ [updateParams]
67
+ );
68
+ const value = useMemo(
69
+ () => ({
70
+ filter,
71
+ updateFilter,
72
+ environment,
73
+ setEnvironment
74
+ }),
75
+ [filter, updateFilter, environment, setEnvironment]
76
+ );
77
+ return /* @__PURE__ */ jsx(PolicyReportsFiltersContext.Provider, { value, children });
78
+ };
79
+ const usePolicyReportsFilters = () => {
80
+ const ctx = useContext(PolicyReportsFiltersContext);
81
+ if (!ctx) {
82
+ throw new Error(
83
+ "usePolicyReportsFilters must be used within PolicyReportsFiltersProvider"
84
+ );
85
+ }
86
+ return ctx;
87
+ };
88
+
89
+ export { PolicyReportsFiltersProvider, usePolicyReportsFilters };
90
+ //# sourceMappingURL=usePolicyReportsFilters.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePolicyReportsFilters.esm.js","sources":["../../src/hooks/usePolicyReportsFilters.tsx"],"sourcesContent":["import qs from 'qs';\nimport {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useLayoutEffect,\n useMemo,\n} from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport type { Filter } from '@kyverno/backstage-plugin-policy-reporter-common';\n\nexport type PolicyReportsFiltersContextValue = {\n filter: Filter;\n updateFilter: (update: Partial<Filter>) => void;\n environment: string;\n setEnvironment: (entityRef: string) => void;\n};\n\nconst PolicyReportsFiltersContext = createContext<\n PolicyReportsFiltersContextValue | undefined\n>(undefined);\n\nexport type PolicyReportsFiltersProviderProps = PropsWithChildren<{\n /**\n * Default filter values written to the URL\n */\n defaultFilters?: Partial<Filter>;\n /**\n * The entityRef of the environment to use\n * when no ?environment= param is present in the URL.\n */\n defaultEnvironment: string;\n}>;\n\n/**\n * Provides shared filter state and selected environment for all policy report\n * filter components.\n */\nexport const PolicyReportsFiltersProvider = ({\n children,\n defaultFilters,\n defaultEnvironment,\n}: PolicyReportsFiltersProviderProps) => {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const parsed = useMemo(\n () => qs.parse(searchParams.toString()),\n [searchParams],\n );\n\n const urlEnvironment = useMemo(\n () => parsed.environment?.toString(),\n [parsed],\n );\n\n // Use defaultFilters until the URL has been initialised (urlEnvironment set).\n // After that, always read from the URL so an explicit empty filter is valid.\n const filter = useMemo(\n () =>\n urlEnvironment ? ((parsed.filter ?? {}) as Filter) : defaultFilters ?? {},\n [parsed, urlEnvironment, defaultFilters],\n );\n\n const environment = useMemo(\n () => urlEnvironment ?? defaultEnvironment,\n [urlEnvironment, defaultEnvironment],\n );\n\n const updateParams = useCallback(\n (\n update:\n | Record<string, unknown>\n | ((prev: Record<string, unknown>) => Record<string, unknown>),\n ) => {\n setSearchParams(\n prev => {\n const prevParsed = qs.parse(prev.toString());\n const next =\n typeof update === 'function' ? update(prevParsed) : update;\n return qs.stringify(next, {\n arrayFormat: 'indices',\n skipNulls: true,\n });\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n useLayoutEffect(() => {\n if (!urlEnvironment) {\n updateParams({\n filter: defaultFilters,\n environment: defaultEnvironment,\n });\n }\n // setSearchParams isn't stable, hence disabling the exhaustive-deps check\n // for more info please visit https://github.com/remix-run/react-router/issues/9991\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [defaultEnvironment, urlEnvironment, defaultFilters]);\n\n const updateFilter = useCallback(\n (update: Partial<Filter>) => {\n updateParams(prev => ({\n ...prev,\n filter: { ...(prev.filter as object), ...update },\n }));\n },\n [updateParams],\n );\n\n const setEnvironment = useCallback(\n (entityRef: string) => {\n updateParams(prev => ({ ...prev, environment: entityRef }));\n },\n [updateParams],\n );\n\n const value = useMemo(\n () => ({\n filter,\n updateFilter,\n environment,\n setEnvironment,\n }),\n [filter, updateFilter, environment, setEnvironment],\n );\n\n return (\n <PolicyReportsFiltersContext.Provider value={value}>\n {children}\n </PolicyReportsFiltersContext.Provider>\n );\n};\n\n/**\n * Hook for reading and updating policy report filters and the selected\n * environment. Must be used within a PolicyReportsFiltersProvider.\n */\nexport const usePolicyReportsFilters = (): PolicyReportsFiltersContextValue => {\n const ctx = useContext(PolicyReportsFiltersContext);\n if (!ctx) {\n throw new Error(\n 'usePolicyReportsFilters must be used within PolicyReportsFiltersProvider',\n );\n }\n return ctx;\n};\n"],"names":[],"mappings":";;;;;AAmBA,MAAM,2BAAA,GAA8B,cAElC,MAAS,CAAA;AAkBJ,MAAM,+BAA+B,CAAC;AAAA,EAC3C,QAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,KAAyC;AACvC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,eAAA,EAAgB;AAExD,EAAA,MAAM,MAAA,GAAS,OAAA;AAAA,IACb,MAAM,EAAA,CAAG,KAAA,CAAM,YAAA,CAAa,UAAU,CAAA;AAAA,IACtC,CAAC,YAAY;AAAA,GACf;AAEA,EAAA,MAAM,cAAA,GAAiB,OAAA;AAAA,IACrB,MAAM,MAAA,CAAO,WAAA,EAAa,QAAA,EAAS;AAAA,IACnC,CAAC,MAAM;AAAA,GACT;AAIA,EAAA,MAAM,MAAA,GAAS,OAAA;AAAA,IACb,MACE,cAAA,GAAmB,MAAA,CAAO,UAAU,EAAC,GAAgB,kBAAkB,EAAC;AAAA,IAC1E,CAAC,MAAA,EAAQ,cAAA,EAAgB,cAAc;AAAA,GACzC;AAEA,EAAA,MAAM,WAAA,GAAc,OAAA;AAAA,IAClB,MAAM,cAAA,IAAkB,kBAAA;AAAA,IACxB,CAAC,gBAAgB,kBAAkB;AAAA,GACrC;AAEA,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CACE,MAAA,KAGG;AACH,MAAA,eAAA;AAAA,QACE,CAAA,IAAA,KAAQ;AACN,UAAA,MAAM,UAAA,GAAa,EAAA,CAAG,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA;AAC3C,UAAA,MAAM,OACJ,OAAO,MAAA,KAAW,UAAA,GAAa,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA;AACtD,UAAA,OAAO,EAAA,CAAG,UAAU,IAAA,EAAM;AAAA,YACxB,WAAA,EAAa,SAAA;AAAA,YACb,SAAA,EAAW;AAAA,WACZ,CAAA;AAAA,QACH,CAAA;AAAA,QACA,EAAE,SAAS,IAAA;AAAK,OAClB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,eAAe;AAAA,GAClB;AAEA,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,MAAA,YAAA,CAAa;AAAA,QACX,MAAA,EAAQ,cAAA;AAAA,QACR,WAAA,EAAa;AAAA,OACd,CAAA;AAAA,IACH;AAAA,EAIF,CAAA,EAAG,CAAC,kBAAA,EAAoB,cAAA,EAAgB,cAAc,CAAC,CAAA;AAEvD,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,MAAA,KAA4B;AAC3B,MAAA,YAAA,CAAa,CAAA,IAAA,MAAS;AAAA,QACpB,GAAG,IAAA;AAAA,QACH,QAAQ,EAAE,GAAI,IAAA,CAAK,MAAA,EAAmB,GAAG,MAAA;AAAO,OAClD,CAAE,CAAA;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,YAAY;AAAA,GACf;AAEA,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,CAAC,SAAA,KAAsB;AACrB,MAAA,YAAA,CAAa,WAAS,EAAE,GAAG,IAAA,EAAM,WAAA,EAAa,WAAU,CAAE,CAAA;AAAA,IAC5D,CAAA;AAAA,IACA,CAAC,YAAY;AAAA,GACf;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO;AAAA,MACL,MAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,MAAA,EAAQ,YAAA,EAAc,WAAA,EAAa,cAAc;AAAA,GACpD;AAEA,EAAA,uBACE,GAAA,CAAC,2BAAA,CAA4B,QAAA,EAA5B,EAAqC,OACnC,QAAA,EACH,CAAA;AAEJ;AAMO,MAAM,0BAA0B,MAAwC;AAC7E,EAAA,MAAM,GAAA,GAAM,WAAW,2BAA2B,CAAA;AAClD,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;;;;"}
package/dist/index.d.ts CHANGED
@@ -18,6 +18,6 @@ declare const EntityCustomPoliciesContent: ({ annotationsDocumentationUrl, polic
18
18
  sources: string[];
19
19
  title: string;
20
20
  }) => react_jsx_runtime.JSX.Element;
21
- declare const PolicyReportsPage: ({ title, subtitle, policyDocumentationUrl, }: PolicyReportsPageProps) => react_jsx_runtime.JSX.Element;
21
+ declare const PolicyReportsPage: ({ title, policyDocumentationUrl, }: PolicyReportsPageProps) => react_jsx_runtime.JSX.Element;
22
22
 
23
23
  export { EntityCustomPoliciesContent, EntityKyvernoPoliciesContent, PolicyReportsPage, policyReporterPlugin };
@@ -0,0 +1,110 @@
1
+ var name = "@kyverno/backstage-plugin-policy-reporter";
2
+ var version = "2.8.0";
3
+ var main = "src/index.ts";
4
+ var types = "src/index.ts";
5
+ var license = "Apache-2.0";
6
+ var keywords = [
7
+ "backstage",
8
+ "kyverno",
9
+ "policy-reporter"
10
+ ];
11
+ var backstage = {
12
+ role: "frontend-plugin",
13
+ pluginId: "policy-reporter",
14
+ pluginPackages: [
15
+ "@kyverno/backstage-plugin-policy-reporter",
16
+ "@kyverno/backstage-plugin-policy-reporter-backend",
17
+ "@kyverno/backstage-plugin-policy-reporter-common"
18
+ ]
19
+ };
20
+ var publishConfig = {
21
+ access: "public",
22
+ main: "dist/index.esm.js",
23
+ types: "dist/index.d.ts"
24
+ };
25
+ var exports$1 = {
26
+ ".": "./src/index.ts",
27
+ "./alpha": "./src/alpha.ts",
28
+ "./package.json": "./package.json"
29
+ };
30
+ var typesVersions = {
31
+ "*": {
32
+ alpha: [
33
+ "src/alpha.ts"
34
+ ],
35
+ "package.json": [
36
+ "package.json"
37
+ ]
38
+ }
39
+ };
40
+ var sideEffects = false;
41
+ var scripts = {
42
+ start: "backstage-cli package start",
43
+ build: "backstage-cli package build",
44
+ lint: "backstage-cli package lint",
45
+ test: "backstage-cli package test",
46
+ clean: "backstage-cli package clean",
47
+ prepack: "backstage-cli package prepack",
48
+ postpack: "backstage-cli package postpack"
49
+ };
50
+ var repository = {
51
+ type: "git",
52
+ url: "https://github.com/kyverno/backstage-policy-reporter-plugin",
53
+ directory: "plugins/policy-reporter"
54
+ };
55
+ var dependencies = {
56
+ "@backstage/catalog-client": "backstage:^",
57
+ "@backstage/catalog-model": "backstage:^",
58
+ "@backstage/core-components": "backstage:^",
59
+ "@backstage/core-plugin-api": "backstage:^",
60
+ "@backstage/frontend-plugin-api": "backstage:^",
61
+ "@backstage/plugin-catalog-react": "backstage:^",
62
+ "@backstage/theme": "backstage:^",
63
+ "@backstage/ui": "backstage:^",
64
+ "@kyverno/backstage-plugin-policy-reporter-common": "workspace:^",
65
+ "@material-ui/core": "^4.12.4",
66
+ "@material-ui/icons": "^4.11.3",
67
+ "@material-ui/lab": "4.0.0-alpha.61",
68
+ qs: "^6.15.0",
69
+ "react-use": "^17.6.0"
70
+ };
71
+ var peerDependencies = {
72
+ react: "^16.13.1 || ^17.0.0 || ^18.0.0",
73
+ "react-router-dom": "^6.0.0"
74
+ };
75
+ var devDependencies = {
76
+ "@backstage/cli": "backstage:^",
77
+ "@backstage/core-app-api": "backstage:^",
78
+ "@backstage/dev-utils": "backstage:^",
79
+ "@backstage/test-utils": "backstage:^",
80
+ "@testing-library/jest-dom": "^6.0.0",
81
+ "@testing-library/react": "^14.0.0",
82
+ "@testing-library/user-event": "^14.0.0",
83
+ "@types/qs": "^6.15.0",
84
+ msw: "^1.0.0"
85
+ };
86
+ var files = [
87
+ "dist"
88
+ ];
89
+ var _package = {
90
+ name: name,
91
+ version: version,
92
+ main: main,
93
+ types: types,
94
+ license: license,
95
+ keywords: keywords,
96
+ backstage: backstage,
97
+ publishConfig: publishConfig,
98
+ exports: exports$1,
99
+ typesVersions: typesVersions,
100
+ sideEffects: sideEffects,
101
+ scripts: scripts,
102
+ repository: repository,
103
+ dependencies: dependencies,
104
+ peerDependencies: peerDependencies,
105
+ devDependencies: devDependencies,
106
+ files: files
107
+ };
108
+
109
+ export { backstage, _package as default, dependencies, devDependencies, exports$1 as exports, files, keywords, license, main, name, peerDependencies, publishConfig, repository, scripts, sideEffects, types, typesVersions, version };
110
+ //# sourceMappingURL=package.json.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
1
+ import { createPlugin, createApiFactory, discoveryApiRef, fetchApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
2
2
  import { rootRouteRef } from './routes.esm.js';
3
3
  import { DefaultApiClient } from '@kyverno/backstage-plugin-policy-reporter-common';
4
4
  import { policyReporterApiRef } from './api/PolicyReporterClient.esm.js';
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { DefaultApiClient } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { policyReporterApiRef } from './api';\n\nexport const policyReporterPlugin = createPlugin({\n id: 'policy-reporter',\n apis: [\n createApiFactory({\n api: policyReporterApiRef,\n deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new DefaultApiClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\nexport const EntityKyvernoPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityKyvernoPoliciesContent',\n component: () =>\n import('./components/EntityKyvernoPoliciesContent').then(\n m => m.EntityKyvernoPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const EntityCustomPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityCustomPoliciesContent',\n component: () =>\n import('./components/EntityCustomPoliciesContent').then(\n m => m.EntityCustomPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const PolicyReportsPage = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'PolicyReportsPage',\n component: () =>\n import('./components/PolicyReportsPage').then(m => m.PolicyReportsPage),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":";;;;;AAYO,MAAM,uBAAuB,YAAa,CAAA;AAAA,EAC/C,EAAI,EAAA,iBAAA;AAAA,EACJ,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,oBAAA;AAAA,MACL,IAAM,EAAA,EAAE,QAAU,EAAA,WAAA,EAAa,cAAc,eAAgB,EAAA;AAAA,MAC7D,OAAA,EAAS,CAAC,EAAE,YAAc,EAAA,QAAA,EACxB,KAAA,IAAI,gBAAiB,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU;AAAA,KAClD;AAAA;AAEL,CAAC;AAEM,MAAM,+BAA+B,oBAAqB,CAAA,OAAA;AAAA,EAC/D,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,8BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,wDAA2C,CAAE,CAAA,IAAA;AAAA,MAClD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAEO,MAAM,8BAA8B,oBAAqB,CAAA,OAAA;AAAA,EAC9D,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,6BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,uDAA0C,CAAE,CAAA,IAAA;AAAA,MACjD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAEO,MAAM,oBAAoB,oBAAqB,CAAA,OAAA;AAAA,EACpD,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,mBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,6CAAgC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,iBAAiB,CAAA;AAAA,IACxE,UAAY,EAAA;AAAA,GACb;AACH;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { DefaultApiClient } from '@kyverno/backstage-plugin-policy-reporter-common';\nimport { policyReporterApiRef } from './api';\n\nexport const policyReporterPlugin = createPlugin({\n id: 'policy-reporter',\n apis: [\n createApiFactory({\n api: policyReporterApiRef,\n deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new DefaultApiClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\nexport const EntityKyvernoPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityKyvernoPoliciesContent',\n component: () =>\n import('./components/EntityKyvernoPoliciesContent').then(\n m => m.EntityKyvernoPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const EntityCustomPoliciesContent = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'EntityCustomPoliciesContent',\n component: () =>\n import('./components/EntityCustomPoliciesContent').then(\n m => m.EntityCustomPoliciesContent,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const PolicyReportsPage = policyReporterPlugin.provide(\n createRoutableExtension({\n name: 'PolicyReportsPage',\n component: () =>\n import('./components/PolicyReportsPage').then(m => m.PolicyReportsPage),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":";;;;;AAYO,MAAM,uBAAuB,YAAA,CAAa;AAAA,EAC/C,EAAA,EAAI,iBAAA;AAAA,EACJ,IAAA,EAAM;AAAA,IACJ,gBAAA,CAAiB;AAAA,MACf,GAAA,EAAK,oBAAA;AAAA,MACL,IAAA,EAAM,EAAE,QAAA,EAAU,WAAA,EAAa,cAAc,eAAA,EAAgB;AAAA,MAC7D,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,QAAA,EAAS,KACjC,IAAI,gBAAA,CAAiB,EAAE,YAAA,EAAc,QAAA,EAAU;AAAA,KAClD;AAAA;AAEL,CAAC;AAEM,MAAM,+BAA+B,oBAAA,CAAqB,OAAA;AAAA,EAC/D,uBAAA,CAAwB;AAAA,IACtB,IAAA,EAAM,8BAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,wDAA2C,CAAA,CAAE,IAAA;AAAA,MAClD,OAAK,CAAA,CAAE;AAAA,KACT;AAAA,IACF,UAAA,EAAY;AAAA,GACb;AACH;AAEO,MAAM,8BAA8B,oBAAA,CAAqB,OAAA;AAAA,EAC9D,uBAAA,CAAwB;AAAA,IACtB,IAAA,EAAM,6BAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,uDAA0C,CAAA,CAAE,IAAA;AAAA,MACjD,OAAK,CAAA,CAAE;AAAA,KACT;AAAA,IACF,UAAA,EAAY;AAAA,GACb;AACH;AAEO,MAAM,oBAAoB,oBAAA,CAAqB,OAAA;AAAA,EACpD,uBAAA,CAAwB;AAAA,IACtB,IAAA,EAAM,mBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,6CAAgC,EAAE,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,iBAAiB,CAAA;AAAA,IACxE,UAAA,EAAY;AAAA,GACb;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'policy-reporter',\n});\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA;AACN,CAAC;;;;"}
1
+ {"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'policy-reporter',\n});\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAA,CAAe;AAAA,EACzC,EAAA,EAAI;AACN,CAAC;;;;"}
@@ -1,4 +1,4 @@
1
- import { KYVERNO_RESOURCE_NAME_ANNOTATION, KYVERNO_NAMESPACE_ANNOTATION, KUBERNETES_NAMESPACE_ANNOTATION, KYVERNO_KIND_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
1
+ import { KYVERNO_RESOURCE_NAME_ANNOTATION, KYVERNO_KIND_ANNOTATION, KYVERNO_NAMESPACE_ANNOTATION, KUBERNETES_NAMESPACE_ANNOTATION } from '@kyverno/backstage-plugin-policy-reporter-common';
2
2
 
3
3
  const isPolicyReporterAvailable = (entity) => Boolean(entity.metadata.annotations?.[KYVERNO_RESOURCE_NAME_ANNOTATION]);
4
4
  const getNamespaces = (annotations) => {
@@ -1 +1 @@
1
- {"version":3,"file":"annotations.esm.js","sources":["../../src/utils/annotations.ts"],"sourcesContent":["import { Entity } from '@backstage/catalog-model';\nimport {\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n KUBERNETES_NAMESPACE_ANNOTATION,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\n/**\n * Utility functions for working with Backstage entity annotations\n * specifically for Kyverno policy reporter plugin integration\n */\n\n/**\n * Validates that an annotations object contains all required annotation keys\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @param required - Array of required annotation keys to check for\n * @returns true if all required keys exist in annotations, false otherwise\n */\nexport const containsRequiredAnnotations = (\n annotations: Record<string, string> | undefined,\n required: string[],\n): boolean => {\n return annotations ? required.every(key => key in annotations) : false;\n};\n\n/**\n * Validates that an entity has configured policy reporter\n * @param entity - The the Backstage entity\n * @returns true if policy reporter is configured.\n */\nexport const isPolicyReporterAvailable = (entity: Entity) =>\n Boolean(entity.metadata.annotations?.[KYVERNO_RESOURCE_NAME_ANNOTATION]);\n\n/**\n * Extracts namespace values from annotations, supporting both Kyverno and Kubernetes formats\n * Priority: Kyverno namespace annotation (comma-separated) > Kubernetes namespace annotation (single value)\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Array of namespace strings, empty array if no namespace annotations found\n */\nexport const getNamespaces = (\n annotations: Record<string, string> | undefined,\n): string[] => {\n if (!annotations) return [];\n\n // Check for Kyverno-specific namespace annotation (supports multiple namespaces)\n if (annotations[KYVERNO_NAMESPACE_ANNOTATION]) {\n return annotations[KYVERNO_NAMESPACE_ANNOTATION].split(',').map(item =>\n item.trim(),\n );\n }\n\n // Fall back to standard Kubernetes namespace annotation (single namespace)\n if (annotations[KUBERNETES_NAMESPACE_ANNOTATION]) {\n return [annotations[KUBERNETES_NAMESPACE_ANNOTATION]];\n }\n\n return [];\n};\n\n/**\n * Extracts Kubernetes resource kinds from Kyverno-specific annotation\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Array of Kubernetes resource kind strings (e.g., ['Pod', 'Service']), empty array if not found\n */\nexport const getKinds = (\n annotations: Record<string, string> | undefined,\n): string[] => {\n if (!annotations) return [];\n\n // Parse comma-separated list of Kubernetes resource kinds\n if (annotations[KYVERNO_KIND_ANNOTATION]) {\n return annotations[KYVERNO_KIND_ANNOTATION].split(',').map(item =>\n item.trim(),\n );\n }\n\n return [];\n};\n\n/**\n * Extracts a specific resource name from Kyverno annotation\n * Used to target a particular Kubernetes resource for policy evaluation\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Resource name string, empty string if annotation not found\n */\nexport const getResourceName = (\n annotations: Record<string, string> | undefined,\n): string => {\n if (!annotations) return '';\n\n return annotations[KYVERNO_RESOURCE_NAME_ANNOTATION] || '';\n};\n"],"names":[],"mappings":";;AA+Ba,MAAA,yBAAA,GAA4B,CAAC,MACxC,KAAA,OAAA,CAAQ,OAAO,QAAS,CAAA,WAAA,GAAc,gCAAgC,CAAC;AAQ5D,MAAA,aAAA,GAAgB,CAC3B,WACa,KAAA;AACb,EAAI,IAAA,CAAC,WAAa,EAAA,OAAO,EAAC;AAG1B,EAAI,IAAA,WAAA,CAAY,4BAA4B,CAAG,EAAA;AAC7C,IAAA,OAAO,WAAY,CAAA,4BAA4B,CAAE,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,GAAA;AAAA,MAAI,CAAA,IAAA,KAC9D,KAAK,IAAK;AAAA,KACZ;AAAA;AAIF,EAAI,IAAA,WAAA,CAAY,+BAA+B,CAAG,EAAA;AAChD,IAAO,OAAA,CAAC,WAAY,CAAA,+BAA+B,CAAC,CAAA;AAAA;AAGtD,EAAA,OAAO,EAAC;AACV;AAOa,MAAA,QAAA,GAAW,CACtB,WACa,KAAA;AACb,EAAI,IAAA,CAAC,WAAa,EAAA,OAAO,EAAC;AAG1B,EAAI,IAAA,WAAA,CAAY,uBAAuB,CAAG,EAAA;AACxC,IAAA,OAAO,WAAY,CAAA,uBAAuB,CAAE,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,GAAA;AAAA,MAAI,CAAA,IAAA,KACzD,KAAK,IAAK;AAAA,KACZ;AAAA;AAGF,EAAA,OAAO,EAAC;AACV;AAQa,MAAA,eAAA,GAAkB,CAC7B,WACW,KAAA;AACX,EAAI,IAAA,CAAC,aAAoB,OAAA,EAAA;AAEzB,EAAO,OAAA,WAAA,CAAY,gCAAgC,CAAK,IAAA,EAAA;AAC1D;;;;"}
1
+ {"version":3,"file":"annotations.esm.js","sources":["../../src/utils/annotations.ts"],"sourcesContent":["import { Entity } from '@backstage/catalog-model';\nimport {\n KYVERNO_KIND_ANNOTATION,\n KYVERNO_NAMESPACE_ANNOTATION,\n KYVERNO_RESOURCE_NAME_ANNOTATION,\n KUBERNETES_NAMESPACE_ANNOTATION,\n} from '@kyverno/backstage-plugin-policy-reporter-common';\n\n/**\n * Utility functions for working with Backstage entity annotations\n * specifically for Kyverno policy reporter plugin integration\n */\n\n/**\n * Validates that an annotations object contains all required annotation keys\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @param required - Array of required annotation keys to check for\n * @returns true if all required keys exist in annotations, false otherwise\n */\nexport const containsRequiredAnnotations = (\n annotations: Record<string, string> | undefined,\n required: string[],\n): boolean => {\n return annotations ? required.every(key => key in annotations) : false;\n};\n\n/**\n * Validates that an entity has configured policy reporter\n * @param entity - The the Backstage entity\n * @returns true if policy reporter is configured.\n */\nexport const isPolicyReporterAvailable = (entity: Entity) =>\n Boolean(entity.metadata.annotations?.[KYVERNO_RESOURCE_NAME_ANNOTATION]);\n\n/**\n * Extracts namespace values from annotations, supporting both Kyverno and Kubernetes formats\n * Priority: Kyverno namespace annotation (comma-separated) > Kubernetes namespace annotation (single value)\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Array of namespace strings, empty array if no namespace annotations found\n */\nexport const getNamespaces = (\n annotations: Record<string, string> | undefined,\n): string[] => {\n if (!annotations) return [];\n\n // Check for Kyverno-specific namespace annotation (supports multiple namespaces)\n if (annotations[KYVERNO_NAMESPACE_ANNOTATION]) {\n return annotations[KYVERNO_NAMESPACE_ANNOTATION].split(',').map(item =>\n item.trim(),\n );\n }\n\n // Fall back to standard Kubernetes namespace annotation (single namespace)\n if (annotations[KUBERNETES_NAMESPACE_ANNOTATION]) {\n return [annotations[KUBERNETES_NAMESPACE_ANNOTATION]];\n }\n\n return [];\n};\n\n/**\n * Extracts Kubernetes resource kinds from Kyverno-specific annotation\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Array of Kubernetes resource kind strings (e.g., ['Pod', 'Service']), empty array if not found\n */\nexport const getKinds = (\n annotations: Record<string, string> | undefined,\n): string[] => {\n if (!annotations) return [];\n\n // Parse comma-separated list of Kubernetes resource kinds\n if (annotations[KYVERNO_KIND_ANNOTATION]) {\n return annotations[KYVERNO_KIND_ANNOTATION].split(',').map(item =>\n item.trim(),\n );\n }\n\n return [];\n};\n\n/**\n * Extracts a specific resource name from Kyverno annotation\n * Used to target a particular Kubernetes resource for policy evaluation\n * @param annotations - The annotations object from a Backstage entity (optional)\n * @returns Resource name string, empty string if annotation not found\n */\nexport const getResourceName = (\n annotations: Record<string, string> | undefined,\n): string => {\n if (!annotations) return '';\n\n return annotations[KYVERNO_RESOURCE_NAME_ANNOTATION] || '';\n};\n"],"names":[],"mappings":";;AA+BO,MAAM,yBAAA,GAA4B,CAAC,MAAA,KACxC,OAAA,CAAQ,OAAO,QAAA,CAAS,WAAA,GAAc,gCAAgC,CAAC;AAQlE,MAAM,aAAA,GAAgB,CAC3B,WAAA,KACa;AACb,EAAA,IAAI,CAAC,WAAA,EAAa,OAAO,EAAC;AAG1B,EAAA,IAAI,WAAA,CAAY,4BAA4B,CAAA,EAAG;AAC7C,IAAA,OAAO,WAAA,CAAY,4BAA4B,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA;AAAA,MAAI,CAAA,IAAA,KAC9D,KAAK,IAAA;AAAK,KACZ;AAAA,EACF;AAGA,EAAA,IAAI,WAAA,CAAY,+BAA+B,CAAA,EAAG;AAChD,IAAA,OAAO,CAAC,WAAA,CAAY,+BAA+B,CAAC,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,EAAC;AACV;AAOO,MAAM,QAAA,GAAW,CACtB,WAAA,KACa;AACb,EAAA,IAAI,CAAC,WAAA,EAAa,OAAO,EAAC;AAG1B,EAAA,IAAI,WAAA,CAAY,uBAAuB,CAAA,EAAG;AACxC,IAAA,OAAO,WAAA,CAAY,uBAAuB,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA;AAAA,MAAI,CAAA,IAAA,KACzD,KAAK,IAAA;AAAK,KACZ;AAAA,EACF;AAEA,EAAA,OAAO,EAAC;AACV;AAQO,MAAM,eAAA,GAAkB,CAC7B,WAAA,KACW;AACX,EAAA,IAAI,CAAC,aAAa,OAAO,EAAA;AAEzB,EAAA,OAAO,WAAA,CAAY,gCAAgC,CAAA,IAAK,EAAA;AAC1D;;;;"}