@techdocs/cli 1.10.7-next.1 → 1.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/embedded-app/.config-schema.json +64 -31
  3. package/dist/embedded-app/index.html +1 -1
  4. package/dist/embedded-app/index.html.tmpl +1 -1
  5. package/dist/embedded-app/static/123.5e36a0db.chunk.js +2 -0
  6. package/dist/embedded-app/static/123.5e36a0db.chunk.js.map +1 -0
  7. package/dist/embedded-app/static/1659.76caecab.chunk.js +2 -0
  8. package/dist/embedded-app/static/1659.76caecab.chunk.js.map +1 -0
  9. package/dist/embedded-app/static/1733.d8004241.chunk.js +2 -0
  10. package/dist/embedded-app/static/1733.d8004241.chunk.js.map +1 -0
  11. package/dist/embedded-app/static/1749.3ab65683.chunk.js +2 -0
  12. package/dist/embedded-app/static/1749.3ab65683.chunk.js.map +1 -0
  13. package/dist/embedded-app/static/1994.78304f99.chunk.js +2 -0
  14. package/dist/embedded-app/static/1994.78304f99.chunk.js.map +1 -0
  15. package/dist/embedded-app/static/2295.a94805e5.chunk.js +5 -0
  16. package/dist/embedded-app/static/2295.a94805e5.chunk.js.map +1 -0
  17. package/dist/embedded-app/static/{3554.0ce35bc3.chunk.js → 3554.d745ad43.chunk.js} +2 -2
  18. package/dist/embedded-app/static/{3554.0ce35bc3.chunk.js.map → 3554.d745ad43.chunk.js.map} +1 -1
  19. package/dist/embedded-app/static/{4384.ae7b53b0.chunk.js → 4384.dc692f4f.chunk.js} +2 -2
  20. package/dist/embedded-app/static/{4384.ae7b53b0.chunk.js.map → 4384.dc692f4f.chunk.js.map} +1 -1
  21. package/dist/embedded-app/static/4587.85b7cf82.chunk.js +2 -0
  22. package/dist/embedded-app/static/4587.85b7cf82.chunk.js.map +1 -0
  23. package/dist/embedded-app/static/4648.e939339d.chunk.js +2 -0
  24. package/dist/embedded-app/static/4648.e939339d.chunk.js.map +1 -0
  25. package/dist/embedded-app/static/6138.d8ae40ee.chunk.js +2 -0
  26. package/dist/embedded-app/static/6138.d8ae40ee.chunk.js.map +1 -0
  27. package/dist/embedded-app/static/7203.1bd24814.chunk.js +2 -0
  28. package/dist/embedded-app/static/7203.1bd24814.chunk.js.map +1 -0
  29. package/dist/embedded-app/static/{7226.9f87f67d.chunk.js → 7226.bb48ee34.chunk.js} +2 -2
  30. package/dist/embedded-app/static/{7226.9f87f67d.chunk.js.map → 7226.bb48ee34.chunk.js.map} +1 -1
  31. package/dist/embedded-app/static/{8461.d5fe0648.chunk.js → 8461.0c3f2ac0.chunk.js} +3 -3
  32. package/dist/embedded-app/static/{8461.d5fe0648.chunk.js.map → 8461.0c3f2ac0.chunk.js.map} +1 -1
  33. package/dist/embedded-app/static/{8877.3f864531.chunk.js → 8877.a7ffabd9.chunk.js} +2 -2
  34. package/dist/embedded-app/static/{8877.3f864531.chunk.js.map → 8877.a7ffabd9.chunk.js.map} +1 -1
  35. package/dist/embedded-app/static/9050.69b458a6.chunk.js +2 -0
  36. package/dist/embedded-app/static/9050.69b458a6.chunk.js.map +1 -0
  37. package/dist/embedded-app/static/9230.23c1d5e0.chunk.js +2 -0
  38. package/dist/embedded-app/static/9230.23c1d5e0.chunk.js.map +1 -0
  39. package/dist/embedded-app/static/{main.161a9ecc.css → main.0657d08d.css} +2 -2
  40. package/dist/embedded-app/static/{main.161a9ecc.css.map → main.0657d08d.css.map} +1 -1
  41. package/dist/embedded-app/static/main.c9b00fd0.js +523 -0
  42. package/dist/embedded-app/static/main.c9b00fd0.js.map +1 -0
  43. package/dist/embedded-app/static/{module-react-aria-components.67232dc3.js → module-react-aria-components.c61f9ab4.js} +2 -2
  44. package/dist/embedded-app/static/{module-react-aria-components.67232dc3.js.map → module-react-aria-components.c61f9ab4.js.map} +1 -1
  45. package/dist/embedded-app/static/module-zod.b3376822.js +38 -0
  46. package/dist/embedded-app/static/module-zod.b3376822.js.map +1 -0
  47. package/dist/embedded-app/static/{runtime.c39b96cc.js → runtime.9896d1d9.js} +2 -2
  48. package/dist/embedded-app/static/{runtime.c39b96cc.js.map → runtime.9896d1d9.js.map} +1 -1
  49. package/dist/embedded-app/static/vendor.ff5541f5.js +6 -0
  50. package/dist/embedded-app/static/vendor.ff5541f5.js.map +1 -0
  51. package/dist/package.json.cjs.js +1 -1
  52. package/package.json +7 -7
  53. package/dist/embedded-app/static/123.97a62a60.chunk.js +0 -2
  54. package/dist/embedded-app/static/123.97a62a60.chunk.js.map +0 -1
  55. package/dist/embedded-app/static/1659.7dd5287b.chunk.js +0 -2
  56. package/dist/embedded-app/static/1659.7dd5287b.chunk.js.map +0 -1
  57. package/dist/embedded-app/static/1733.14c06ac4.chunk.js +0 -2
  58. package/dist/embedded-app/static/1733.14c06ac4.chunk.js.map +0 -1
  59. package/dist/embedded-app/static/1749.745aaeeb.chunk.js +0 -2
  60. package/dist/embedded-app/static/1749.745aaeeb.chunk.js.map +0 -1
  61. package/dist/embedded-app/static/1994.1f294712.chunk.js +0 -2
  62. package/dist/embedded-app/static/1994.1f294712.chunk.js.map +0 -1
  63. package/dist/embedded-app/static/2295.765b9f2e.chunk.js +0 -5
  64. package/dist/embedded-app/static/2295.765b9f2e.chunk.js.map +0 -1
  65. package/dist/embedded-app/static/4587.bf73bd77.chunk.js +0 -2
  66. package/dist/embedded-app/static/4587.bf73bd77.chunk.js.map +0 -1
  67. package/dist/embedded-app/static/4648.bd152b54.chunk.js +0 -2
  68. package/dist/embedded-app/static/4648.bd152b54.chunk.js.map +0 -1
  69. package/dist/embedded-app/static/6138.2560a5ba.chunk.js +0 -2
  70. package/dist/embedded-app/static/6138.2560a5ba.chunk.js.map +0 -1
  71. package/dist/embedded-app/static/7203.1ec93f6f.chunk.js +0 -2
  72. package/dist/embedded-app/static/7203.1ec93f6f.chunk.js.map +0 -1
  73. package/dist/embedded-app/static/9050.bab0c5db.chunk.js +0 -2
  74. package/dist/embedded-app/static/9050.bab0c5db.chunk.js.map +0 -1
  75. package/dist/embedded-app/static/9230.b3e5d612.chunk.js +0 -2
  76. package/dist/embedded-app/static/9230.b3e5d612.chunk.js.map +0 -1
  77. package/dist/embedded-app/static/main.cb460d15.js +0 -523
  78. package/dist/embedded-app/static/main.cb460d15.js.map +0 -1
  79. package/dist/embedded-app/static/module-zod.dd7f5a90.js +0 -2
  80. package/dist/embedded-app/static/module-zod.dd7f5a90.js.map +0 -1
  81. package/dist/embedded-app/static/vendor.65e7f165.js +0 -6
  82. package/dist/embedded-app/static/vendor.65e7f165.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"static/4384.ae7b53b0.chunk.js","sources":["webpack://techdocs-cli-embedded-app/../core-components/src/components/FavoriteToggle/FavoriteToggle.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/OverflowTooltip/OverflowTooltip.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/static/ClosedDropdown.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/static/OpenedDropdown.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/Select.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/Filters.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/TableLoadingBody.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/Table.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/apis/EntityPresentationApi/entityPresentationSnapshot.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/CatalogAutocomplete/CatalogAutocomplete.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityKindPicker/kindFilterUtils.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useFetchEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useQueryEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTable/TitleColumn.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useOwnedEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useAllEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useStarredEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/filters.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useEntityListProvider.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useStarredEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/utils/filters.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/CreateButton/CreateButton.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/DefaultFilters/DefaultFilters.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/columns.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CatalogTableToolbar.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CursorPaginatedCatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/index.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ComponentProps } from 'react';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport { StarIcon, UnstarredIcon } from '../../icons';\n\nconst useStyles = makeStyles<Theme>(\n () => ({\n icon: {\n color: '#f3ba37',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n iconBorder: {\n color: 'inherit',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n }),\n { name: 'BackstageFavoriteToggleIcon' },\n);\n\n/**\n * @public\n */\nexport type FavoriteToggleIconClassKey = 'icon' | 'iconBorder';\n\n/**\n * Icon used in FavoriteToggle component.\n *\n * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable}\n *\n * @public\n */\nexport function FavoriteToggleIcon(props: { isFavorite: boolean }) {\n const { isFavorite } = props;\n const classes = useStyles();\n\n return (\n <Typography\n component=\"span\"\n className={isFavorite ? classes.icon : classes.iconBorder}\n >\n {isFavorite ? <StarIcon /> : <UnstarredIcon />}\n </Typography>\n );\n}\n\n/**\n * Props for the {@link FavoriteToggle} component.\n *\n * @public\n */\nexport type FavoriteToggleProps = ComponentProps<typeof IconButton> & {\n id: string;\n title: string;\n isFavorite: boolean;\n onToggle: (value: boolean) => void;\n};\n\n/**\n * Toggle encapsulating logic for marking something as favorite,\n * primarily used in various instances of entity lists and cards but can be used elsewhere.\n *\n * This component can only be used in as a controlled toggle and does not keep internal state.\n *\n * @public\n */\nexport function FavoriteToggle(props: FavoriteToggleProps) {\n const {\n id,\n title,\n isFavorite: value,\n onToggle: onChange,\n ...iconButtonProps\n } = props;\n return (\n <Tooltip id={id} title={title}>\n <IconButton\n aria-label={title}\n id={id}\n onClick={() => onChange(!value)}\n color=\"inherit\"\n {...iconButtonProps}\n >\n <FavoriteToggleIcon isFavorite={value} />\n </IconButton>\n </Tooltip>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tooltip, { TooltipProps } from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\n\ntype Props = {\n text?: string | undefined;\n title?: TooltipProps['title'];\n line?: number | undefined;\n placement?: TooltipProps['placement'];\n tooltipClasses?: TooltipProps['classes'];\n};\n\nexport type OverflowTooltipClassKey = 'container';\n\nconst useStyles = makeStyles(\n {\n container: {\n overflow: 'visible !important',\n },\n typo: {\n fontSize: 'inherit',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: '-webkit-box',\n '-webkit-line-clamp': ({ line }: Props) => line || 1,\n '-webkit-box-orient': 'vertical',\n },\n },\n { name: 'BackstageOverflowTooltip' },\n);\n\nexport function OverflowTooltip(props: Props) {\n const classes = useStyles(props);\n\n return (\n <Tooltip\n title={props.title ?? (props.text || '')}\n placement={props.placement}\n classes={props.tooltipClasses}\n >\n <Typography className={classes.typo} variant=\"inherit\">\n {props.text}\n </Typography>\n </Tooltip>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\n/** @public */\nexport type ClosedDropdownClassKey = 'icon';\n\nconst useStyles = makeStyles(\n theme =>\n createStyles({\n icon: {\n position: 'absolute',\n right: theme.spacing(0.5),\n pointerEvents: 'none',\n color: '#616161',\n },\n }),\n { name: 'BackstageClosedDropdown' },\n);\n\nconst ClosedDropdown = () => {\n const classes = useStyles();\n return (\n <SvgIcon\n className={classes.icon}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7.5 8L6 9.5L12.0703 15.5703L18.1406 9.5L16.6406 8L12.0703 12.5703L7.5 8Z\"\n fill=\"currentColor\"\n />\n </SvgIcon>\n );\n};\n\nexport default ClosedDropdown;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\nexport type OpenedDropdownClassKey = 'icon';\n\nconst useStyles = makeStyles(\n theme =>\n createStyles({\n icon: {\n position: 'absolute',\n right: theme.spacing(0.5),\n pointerEvents: 'none',\n color: '#616161',\n },\n }),\n { name: 'BackstageOpenedDropdown' },\n);\n\nconst OpenedDropdown = () => {\n const classes = useStyles();\n return (\n <SvgIcon\n className={classes.icon}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M16.5 16L18 14.5L11.9297 8.42969L5.85938 14.5L7.35938 16L11.9297 11.4297L16.5 16Z\"\n fill=\"currentColor\"\n />\n </SvgIcon>\n );\n};\n\nexport default OpenedDropdown;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Chip from '@material-ui/core/Chip';\nimport FormControl from '@material-ui/core/FormControl';\nimport InputBase from '@material-ui/core/InputBase';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Select from '@material-ui/core/Select';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { ChangeEvent, useEffect, useState } from 'react';\n\nimport ClosedDropdown from './static/ClosedDropdown';\nimport OpenedDropdown from './static/OpenedDropdown';\n\n/** @public */\nexport type SelectInputBaseClassKey = 'root' | 'input';\n\nconst BootstrapInput = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {\n 'label + &': {\n marginTop: theme.spacing(3),\n },\n '&.Mui-focused > div[role=button]': {\n borderColor: theme.palette.primary.main,\n },\n },\n input: {\n borderRadius: theme.shape.borderRadius,\n position: 'relative',\n backgroundColor: theme.palette.background.paper,\n border: '1px solid #ced4da',\n fontSize: theme.typography.body1.fontSize,\n padding: theme.spacing(1.25, 3.25, 1.25, 1.5),\n transition: theme.transitions.create(['border-color', 'box-shadow']),\n '&:focus': {\n background: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n },\n },\n }),\n { name: 'BackstageSelectInputBase' },\n)(InputBase);\n\n/** @public */\nexport type SelectClassKey =\n | 'formControl'\n | 'label'\n | 'chips'\n | 'chip'\n | 'checkbox'\n | 'root';\n\nconst useStyles = makeStyles(\n (theme: Theme) =>\n createStyles({\n formControl: {\n margin: theme.spacing(1, 0),\n },\n label: {\n transform: 'initial',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '&.Mui-focused': {\n color: theme.palette.text.primary,\n },\n },\n formLabel: {\n transform: 'initial',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '&.Mui-focused': {\n color: theme.palette.text.primary,\n },\n },\n chips: {\n display: 'flex',\n flexWrap: 'wrap',\n },\n chip: {\n margin: 2,\n },\n checkbox: {},\n\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n }),\n { name: 'BackstageSelect' },\n);\n\n/** @public */\nexport type SelectItem = {\n label: string;\n value: string | number;\n};\n\n/** @public */\nexport type SelectedItems = string | string[] | number | number[];\n\nexport type SelectProps = {\n multiple?: boolean;\n items: SelectItem[];\n label: string;\n placeholder?: string;\n selected?: SelectedItems;\n onChange: (arg: SelectedItems) => void;\n triggerReset?: boolean;\n native?: boolean;\n disabled?: boolean;\n margin?: 'dense' | 'none';\n 'data-testid'?: string;\n};\n\n/** @public */\nexport function SelectComponent(props: SelectProps) {\n const {\n multiple,\n items,\n label,\n placeholder,\n selected,\n onChange,\n triggerReset,\n native = false,\n disabled = false,\n margin,\n 'data-testid': dataTestId = 'select',\n } = props;\n const classes = useStyles();\n const [value, setValue] = useState<SelectedItems>(\n selected || (multiple ? [] : ''),\n );\n const [isOpen, setOpen] = useState(false);\n\n useEffect(() => {\n setValue(multiple ? [] : '');\n }, [triggerReset, multiple]);\n\n useEffect(() => {\n setValue(selected || (multiple ? [] : ''));\n }, [selected, multiple]);\n\n const handleChange = (event: ChangeEvent<{ value: unknown }>) => {\n setValue(event.target.value as SelectedItems);\n onChange(event.target.value as SelectedItems);\n };\n\n const handleOpen = (event: ChangeEvent<any>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n setOpen(previous => {\n if (multiple && !(event.target instanceof HTMLElement)) {\n return true;\n }\n return !previous;\n });\n };\n\n const handleClose = () => {\n setOpen(false);\n };\n\n const handleDelete = (selectedValue: string | number) => () => {\n const newValue = (value as any[]).filter(chip => chip !== selectedValue);\n setValue(newValue);\n onChange(newValue);\n };\n\n return (\n <Box className={classes.root}>\n <FormControl className={classes.formControl}>\n <InputLabel className={classes.formLabel}>{label}</InputLabel>\n <Select\n aria-label={label}\n value={value}\n native={native}\n disabled={disabled}\n data-testid={dataTestId}\n displayEmpty\n multiple={multiple}\n margin={margin}\n onChange={handleChange}\n open={isOpen}\n onOpen={handleOpen}\n onClose={handleClose}\n input={<BootstrapInput />}\n label={label}\n renderValue={s =>\n multiple && (value as any[]).length !== 0 ? (\n <Box className={classes.chips}>\n {(s as string[]).map(selectedValue => {\n const item = items.find(el => el.value === selectedValue);\n return item ? (\n <Chip\n data-testid=\"chip\"\n key={item?.value}\n label={item?.label}\n clickable\n deleteIcon={\n <CancelIcon\n data-testid=\"cancel-icon\"\n onMouseDown={event => event.stopPropagation()}\n />\n }\n onDelete={handleDelete(selectedValue)}\n className={classes.chip}\n />\n ) : (\n false\n );\n })}\n </Box>\n ) : (\n <Typography>\n {(value as any[]).length === 0\n ? placeholder || ''\n : items.find(el => el.value === s)?.label}\n </Typography>\n )\n }\n IconComponent={() =>\n !isOpen ? <ClosedDropdown /> : <OpenedDropdown />\n }\n MenuProps={{\n anchorOrigin: {\n vertical: 'bottom',\n horizontal: 'left',\n },\n transformOrigin: {\n vertical: 'top',\n horizontal: 'left',\n },\n getContentAnchorEl: null,\n }}\n >\n {!!placeholder && !multiple && (\n <MenuItem value={[]}>{placeholder}</MenuItem>\n )}\n {native\n ? items &&\n items.map(item => (\n <option value={item.value} key={item.value}>\n {item.label}\n </option>\n ))\n : items &&\n items.map(item => (\n <MenuItem key={item.value} value={item.value}>\n {multiple && (\n <Checkbox\n color=\"primary\"\n checked={(value as any[]).includes(item.value) || false}\n className={classes.checkbox}\n />\n )}\n {item.label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useEffect, useState } from 'react';\n\nimport { Select } from '../Select';\nimport { SelectProps } from '../Select/Select';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport type TableFiltersClassKey = 'root' | 'value' | 'heder' | 'filters';\n\nconst useFilterStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n width: '315px',\n display: 'flex',\n flexDirection: 'column',\n marginRight: theme.spacing(3),\n },\n value: {\n fontWeight: 'bold',\n fontSize: 18,\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n height: theme.spacing(7.5),\n justifyContent: 'space-between',\n borderBottom: `1px solid ${theme.palette.grey[500]}`,\n },\n filters: {\n display: 'flex',\n flexDirection: 'column',\n '& > *': {\n marginTop: theme.spacing(2),\n },\n },\n }),\n { name: 'BackstageTableFilters' },\n);\n\nexport type Without<T, K> = Pick<T, Exclude<keyof T, K>>;\n\nexport type Filter = {\n type: 'select' | 'multiple-select';\n element: Without<SelectProps, 'onChange'>;\n};\n\nexport type SelectedFilters = {\n [key: string]: string | string[];\n};\n\ntype Props = {\n filters: Filter[];\n selectedFilters?: SelectedFilters;\n onChangeFilters: (arg: any) => any;\n};\n\nexport const Filters = (props: Props) => {\n const classes = useFilterStyles();\n\n const { onChangeFilters } = props;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const [selectedFilters, setSelectedFilters] = useState<SelectedFilters>({\n ...props.selectedFilters,\n });\n const [reset, triggerReset] = useState(false);\n\n // Trigger re-rendering\n const handleClick = () => {\n setSelectedFilters({});\n triggerReset(el => !el);\n };\n\n useEffect(() => {\n onChangeFilters(selectedFilters);\n }, [selectedFilters, onChangeFilters]);\n\n // As material table doesn't provide a way to add a column filter tab we will make our own filter logic\n return (\n <Box className={classes.root}>\n <Box className={classes.header}>\n <Box className={classes.value}>{t('table.filter.title')}</Box>\n <Button color=\"primary\" onClick={handleClick}>\n {t('table.filter.clearAll')}\n </Button>\n </Box>\n <Box className={classes.filters}>\n {props.filters?.length &&\n props.filters.map(filter => (\n <Select\n triggerReset={reset}\n key={filter.element.label}\n {...(filter.element as SelectProps)}\n selected={selectedFilters[filter.element.label]}\n onChange={el =>\n setSelectedFilters({\n ...selectedFilters,\n [filter.element.label]: el as any,\n })\n }\n />\n ))}\n </Box>\n </Box>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport CircularProgress from '@material-ui/core/CircularProgress';\n\n/**\n * @internal\n */\nexport function TableLoadingBody(props: { colSpan?: number }) {\n return (\n <tbody data-testid=\"loading-indicator\">\n <tr>\n <td colSpan={props.colSpan}>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n minHeight: '15rem',\n }}\n >\n <CircularProgress size=\"5rem\" />\n </Box>\n </td>\n </tr>\n </tbody>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport MTable, {\n Column,\n Icons,\n MaterialTableProps,\n MTableBody,\n MTableHeader,\n MTableToolbar,\n Options,\n} from '@material-table/core';\nimport Box from '@material-ui/core/Box';\nimport IconButton from '@material-ui/core/IconButton';\nimport {\n makeStyles,\n Theme,\n useTheme,\n withStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport AddBox from '@material-ui/icons/AddBox';\nimport ArrowUpward from '@material-ui/icons/ArrowUpward';\nimport Check from '@material-ui/icons/Check';\nimport ChevronLeft from '@material-ui/icons/ChevronLeft';\nimport ChevronRight from '@material-ui/icons/ChevronRight';\nimport Clear from '@material-ui/icons/Clear';\nimport DeleteOutline from '@material-ui/icons/DeleteOutline';\nimport Edit from '@material-ui/icons/Edit';\nimport FilterList from '@material-ui/icons/FilterList';\nimport Search from '@material-ui/icons/Search';\nimport FirstPage from '@material-ui/icons/FirstPage';\nimport LastPage from '@material-ui/icons/LastPage';\nimport Remove from '@material-ui/icons/Remove';\nimport SaveAlt from '@material-ui/icons/SaveAlt';\nimport ViewColumn from '@material-ui/icons/ViewColumn';\nimport { isEqual, transform } from 'lodash';\nimport {\n CSSProperties,\n forwardRef,\n MutableRefObject,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { SelectProps } from '../Select/Select';\nimport { Filter, Filters, SelectedFilters, Without } from './Filters';\nimport { TableLoadingBody } from './TableLoadingBody';\n\n// Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51\nconst tableIcons: Icons = {\n Add: forwardRef<SVGSVGElement>((props, ref) => (\n <AddBox {...props} ref={ref} />\n )),\n Check: forwardRef<SVGSVGElement>((props, ref) => (\n <Check {...props} ref={ref} />\n )),\n Clear: forwardRef<SVGSVGElement>((props, ref) => (\n <Clear {...props} ref={ref} />\n )),\n Delete: forwardRef<SVGSVGElement>((props, ref) => (\n <DeleteOutline {...props} ref={ref} />\n )),\n DetailPanel: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronRight {...props} ref={ref} />\n )),\n Edit: forwardRef<SVGSVGElement>((props, ref) => (\n <Edit {...props} ref={ref} />\n )),\n Export: forwardRef<SVGSVGElement>((props, ref) => (\n <SaveAlt {...props} ref={ref} />\n )),\n Filter: forwardRef<SVGSVGElement>((props, ref) => (\n <FilterList {...props} ref={ref} />\n )),\n FirstPage: forwardRef<SVGSVGElement>((props, ref) => (\n <FirstPage {...props} ref={ref} />\n )),\n LastPage: forwardRef<SVGSVGElement>((props, ref) => (\n <LastPage {...props} ref={ref} />\n )),\n NextPage: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronRight {...props} ref={ref} />\n )),\n PreviousPage: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronLeft {...props} ref={ref} />\n )),\n ResetSearch: forwardRef<SVGSVGElement>((props, ref) => (\n <Clear {...props} ref={ref} />\n )),\n Search: forwardRef<SVGSVGElement>((props, ref) => (\n <Search {...props} ref={ref} />\n )),\n SortArrow: forwardRef<SVGSVGElement>((props, ref) => (\n <ArrowUpward {...props} ref={ref} />\n )),\n ThirdStateCheck: forwardRef<SVGSVGElement>((props, ref) => (\n <Remove {...props} ref={ref} />\n )),\n ViewColumn: forwardRef<SVGSVGElement>((props, ref) => (\n <ViewColumn {...props} ref={ref} />\n )),\n};\n\n// TODO: Material table might already have such a function internally that we can use?\nfunction extractValueByField(data: any, field: string): any | undefined {\n const path = field.split('.');\n let value = data[path[0]];\n\n for (let i = 1; i < path.length; ++i) {\n if (value === undefined) {\n return value;\n }\n\n const f = path[i];\n value = value[f];\n }\n\n return value;\n}\n\nexport type TableHeaderClassKey = 'header';\n\nconst StyledMTableHeader = withStyles(\n theme => ({\n header: {\n padding: theme.spacing(1, 2, 1, 2.5),\n borderTop: `1px solid ${theme.palette.grey.A100}`,\n borderBottom: `1px solid ${theme.palette.grey.A100}`,\n // withStyles hasn't a generic overload for theme\n fontWeight: theme.typography.fontWeightBold,\n position: 'static',\n wordBreak: 'normal',\n textTransform: 'uppercase',\n },\n }),\n { name: 'BackstageTableHeader' },\n)(MTableHeader);\n\nexport type TableToolbarClassKey = 'root' | 'title' | 'searchField';\n\nconst StyledMTableToolbar = withStyles(\n theme => ({\n root: {\n padding: theme.spacing(3, 0, 2.5, 2.5),\n },\n title: {\n '& > h6': {\n fontWeight: theme.typography.fontWeightBold,\n },\n },\n searchField: {\n paddingRight: theme.spacing(2),\n },\n }),\n { name: 'BackstageTableToolbar' },\n)(MTableToolbar);\n\n/** @public */\nexport type FiltersContainerClassKey = 'root' | 'filterControls' | 'title';\n\nconst useFilterStyles = makeStyles(\n theme => ({\n root: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n },\n filterControls: {\n display: 'flex',\n alignItems: 'center',\n },\n title: {\n fontWeight: theme.typography.fontWeightBold,\n fontSize: 18,\n whiteSpace: 'nowrap',\n },\n }),\n { name: 'BackstageTableFiltersContainer' },\n);\n\nexport type TableClassKey = 'root';\n\nconst useTableStyles = makeStyles(\n () => ({\n root: {\n display: 'flex',\n alignItems: 'start',\n },\n }),\n { name: 'BackstageTable' },\n);\n\nfunction convertColumns<T extends object>(\n columns: TableColumn<T>[],\n theme: Theme,\n): TableColumn<T>[] {\n return columns.map(column => {\n const headerStyle: CSSProperties = column.headerStyle ?? {};\n\n let cellStyle = column.cellStyle || {};\n\n if (column.highlight) {\n headerStyle.color = theme.palette.textContrast;\n\n if (typeof cellStyle === 'object') {\n (cellStyle as CSSProperties).fontWeight =\n theme.typography.fontWeightBold;\n } else {\n const cellStyleFn = cellStyle as (\n data: any,\n rowData: T,\n column?: Column<T>,\n ) => CSSProperties;\n cellStyle = (data, rowData, rowColumn) => {\n const style = cellStyleFn(data, rowData, rowColumn);\n return { ...style, fontWeight: theme.typography.fontWeightBold };\n };\n }\n }\n\n return {\n ...column,\n headerStyle,\n cellStyle,\n };\n });\n}\n\nfunction removeDefaultValues(state: any, defaultState: any): any {\n return transform(state, (result, value, key) => {\n if (!isEqual(value, defaultState[key])) {\n result[key] = value;\n }\n });\n}\n\nconst defaultInitialState = {\n search: '',\n filtersOpen: false,\n filters: {},\n};\n\nexport interface TableColumn<T extends object = {}> extends Column<T> {\n highlight?: boolean;\n width?: string;\n}\n\nexport type TableFilter = {\n column: string;\n type: 'select' | 'multiple-select';\n};\n\nexport type TableState = {\n search?: string;\n filtersOpen?: boolean;\n filters?: SelectedFilters;\n};\n\nexport interface TableProps<T extends object = {}>\n extends MaterialTableProps<T> {\n columns: TableColumn<T>[];\n subtitle?: string;\n filters?: TableFilter[];\n initialState?: TableState;\n emptyContent?: ReactNode;\n isLoading?: boolean;\n onStateChange?: (state: TableState) => any;\n}\n\nexport interface TableOptions<T extends object = {}> extends Options<T> {}\n\nexport function TableToolbar(toolbarProps: {\n toolbarRef: MutableRefObject<any>;\n setSearch: (value: string) => void;\n onSearchChanged: (value: string) => void;\n toggleFilters: () => void;\n hasFilters: boolean;\n selectedFiltersLength: number;\n}) {\n const {\n toolbarRef,\n setSearch,\n hasFilters,\n selectedFiltersLength,\n toggleFilters,\n } = toolbarProps;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const filtersClasses = useFilterStyles();\n const onSearchChanged = useCallback(\n (searchText: string) => {\n toolbarProps.onSearchChanged(searchText);\n setSearch(searchText);\n },\n [toolbarProps, setSearch],\n );\n\n if (hasFilters) {\n return (\n <Box className={filtersClasses.root}>\n <Box className={filtersClasses.filterControls}>\n <IconButton onClick={toggleFilters} aria-label=\"filter list\">\n <FilterList />\n </IconButton>\n <Typography className={filtersClasses.title}>\n {t('table.filter.title')} ({selectedFiltersLength})\n </Typography>\n </Box>\n <StyledMTableToolbar\n {...toolbarProps}\n ref={toolbarRef}\n onSearchChanged={onSearchChanged}\n />\n </Box>\n );\n }\n\n return (\n <StyledMTableToolbar\n {...toolbarProps}\n ref={toolbarRef}\n onSearchChanged={onSearchChanged}\n />\n );\n}\n\n/**\n * @public\n */\nexport function Table<T extends object = {}>(props: TableProps<T>) {\n const {\n data,\n columns,\n emptyContent,\n options,\n title,\n subtitle,\n localization,\n filters,\n initialState,\n onStateChange,\n components,\n isLoading: loading,\n style,\n ...restProps\n } = props;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const tableClasses = useTableStyles();\n\n const theme = useTheme();\n\n const calculatedInitialState = { ...defaultInitialState, ...initialState };\n\n const [filtersOpen, setFiltersOpen] = useState(\n calculatedInitialState.filtersOpen,\n );\n const toggleFilters = useCallback(\n () => setFiltersOpen(v => !v),\n [setFiltersOpen],\n );\n\n const [selectedFilters, setSelectedFilters] = useState(\n calculatedInitialState.filters,\n );\n\n const [search, setSearch] = useState(calculatedInitialState.search);\n\n useEffect(() => {\n if (onStateChange) {\n const state = removeDefaultValues(\n {\n search,\n filtersOpen,\n filters: selectedFilters,\n },\n defaultInitialState,\n );\n\n onStateChange(state);\n }\n }, [search, filtersOpen, selectedFilters, onStateChange]);\n\n const getFieldByTitle = useCallback(\n (titleValue: string | keyof T) =>\n columns.find(el => el.title === titleValue)?.field,\n [columns],\n );\n\n const tableData = useMemo(() => {\n if (typeof data === 'function' || !selectedFilters) {\n return data;\n }\n\n const selectedFiltersArray = Object.values(selectedFilters);\n if (data && selectedFiltersArray.flat().length) {\n const newData = (data as any[]).filter(\n el =>\n !!Object.entries(selectedFilters)\n .filter(([, value]) => !!(value as { length?: number }).length)\n .every(([key, filterValue]) => {\n const fieldValue = extractValueByField(\n el,\n getFieldByTitle(key) as string,\n );\n\n if (Array.isArray(fieldValue) && Array.isArray(filterValue)) {\n return fieldValue.some(v => filterValue.includes(v));\n } else if (Array.isArray(fieldValue)) {\n return fieldValue.includes(filterValue);\n } else if (Array.isArray(filterValue)) {\n return filterValue.includes(fieldValue);\n }\n\n return fieldValue === filterValue;\n }),\n );\n return newData;\n }\n return data;\n }, [data, selectedFilters, getFieldByTitle]);\n\n const selectedFiltersLength = Object.values(selectedFilters).flat().length;\n\n const hasFilters = !!filters?.length;\n const Toolbar = useCallback(\n (toolbarProps: any /* no type for this in material-table */) => {\n return (\n <TableToolbar\n setSearch={setSearch}\n hasFilters={hasFilters}\n selectedFiltersLength={selectedFiltersLength}\n toggleFilters={toggleFilters}\n {...toolbarProps}\n />\n );\n },\n [toggleFilters, hasFilters, selectedFiltersLength, setSearch],\n );\n\n const hasNoRows = typeof data !== 'function' && data.length === 0;\n const columnCount = columns.length;\n const Body = useMemo(\n () => makeBody({ hasNoRows, emptyContent, columnCount, loading }),\n [hasNoRows, emptyContent, columnCount, loading],\n );\n\n return (\n <Box className={tableClasses.root}>\n {filtersOpen && data && typeof data !== 'function' && filters?.length && (\n <Filters\n filters={constructFilters(filters, data as any[], columns, t)}\n selectedFilters={selectedFilters}\n onChangeFilters={setSelectedFilters}\n />\n )}\n <MTable<T>\n components={{\n Header: StyledMTableHeader,\n Body,\n Toolbar,\n ...components,\n }}\n options={options}\n columns={convertColumns(columns, theme)}\n icons={tableIcons}\n title={\n <>\n <Typography variant=\"h5\" component=\"h2\">\n {title}\n </Typography>\n {subtitle && (\n <Typography color=\"textSecondary\" variant=\"body1\">\n {subtitle}\n </Typography>\n )}\n </>\n }\n data={tableData}\n style={{ width: '100%', ...style }}\n localization={{\n ...localization,\n body: {\n emptyDataSourceMessage: t('table.body.emptyDataSourceMessage'),\n ...localization?.body,\n },\n pagination: {\n firstTooltip: t('table.pagination.firstTooltip'),\n labelDisplayedRows: t('table.pagination.labelDisplayedRows'),\n labelRowsSelect: t('table.pagination.labelRowsSelect'),\n lastTooltip: t('table.pagination.lastTooltip'),\n nextTooltip: t('table.pagination.nextTooltip'),\n previousTooltip: t('table.pagination.previousTooltip'),\n ...localization?.pagination,\n },\n header: {\n actions: t('table.header.actions'),\n ...localization?.header,\n },\n toolbar: {\n searchPlaceholder: t('table.toolbar.search'),\n searchTooltip: t('table.toolbar.search'),\n ...localization?.toolbar,\n },\n }}\n {...restProps}\n />\n </Box>\n );\n}\n\nTable.icons = Object.freeze(tableIcons);\n\nfunction makeBody({\n columnCount,\n emptyContent,\n hasNoRows,\n loading,\n}: {\n hasNoRows: boolean;\n emptyContent: ReactNode;\n columnCount: number;\n loading?: boolean;\n}) {\n return (bodyProps: any /* no type for this in material-table */) => {\n if (loading) {\n return <TableLoadingBody colSpan={columnCount} />;\n }\n\n if (emptyContent && hasNoRows) {\n return (\n <tbody>\n <tr>\n <td colSpan={columnCount}>{emptyContent}</td>\n </tr>\n </tbody>\n );\n }\n\n return <MTableBody {...bodyProps} />;\n };\n}\n\nfunction constructFilters<T extends object>(\n filterConfig: TableFilter[],\n dataValue: any[] | undefined,\n columns: TableColumn<T>[],\n t: TranslationFunction<typeof coreComponentsTranslationRef.T>,\n): Filter[] {\n const extractDistinctValues = (field: string | keyof T): Set<any> => {\n const distinctValues = new Set<any>();\n const addValue = (value: any) => {\n if (value !== undefined && value !== null) {\n distinctValues.add(value);\n }\n };\n\n if (dataValue) {\n dataValue.forEach(el => {\n const value = extractValueByField(\n el,\n columns.find(c => c.title === field)?.field as string,\n );\n\n if (Array.isArray(value)) {\n (value as []).forEach(addValue);\n } else {\n addValue(value);\n }\n });\n }\n\n return distinctValues;\n };\n\n const constructSelect = (\n filter: TableFilter,\n ): Without<SelectProps, 'onChange'> => {\n return {\n placeholder: t('table.filter.placeholder'),\n label: filter.column,\n multiple: filter.type === 'multiple-select',\n items: [...extractDistinctValues(filter.column)].sort().map(value => ({\n label: value,\n value,\n })),\n };\n };\n\n return filterConfig.map(filter => ({\n type: filter.type,\n element: constructSelect(filter),\n }));\n}\n","/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CompoundEntityRef,\n Entity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n EntityPresentationApi,\n EntityRefPresentationSnapshot,\n} from './EntityPresentationApi';\nimport { defaultEntityPresentation } from './defaultEntityPresentation';\n\n/**\n * Returns a synchronous presentation snapshot for an entity in non-React\n * contexts.\n *\n * @remarks\n *\n * This is the synchronous, non-React counterpart to\n * {@link useEntityPresentation}. It handles `Entity`, `CompoundEntityRef`,\n * and string ref inputs uniformly, using the provided\n * {@link EntityPresentationApi} when available and falling back to\n * {@link defaultEntityPresentation} otherwise.\n *\n * Because this function is synchronous, it uses cached data from the\n * presentation API (via `.snapshot`). If the entity has been seen before,\n * the snapshot will contain the full resolved title; otherwise it falls\n * back to what can be extracted from the ref alone. This is the correct\n * trade-off for sort comparators, column factories, filter callbacks, and\n * data mappers where a synchronous return value is required.\n *\n * In async contexts such as data loaders where you can `await`, prefer\n * using the {@link EntityPresentationApi} directly via\n * `forEntity().promise` for the richest possible presentation.\n *\n * @public\n * @param entityOrRef - An entity, a compound entity ref, or a string entity ref.\n * @param context - Optional context that may affect the presentation.\n * @param entityPresentationApi - Optional presentation API instance. When not\n * provided, falls back to {@link defaultEntityPresentation}.\n */\nexport function entityPresentationSnapshot(\n entityOrRef: Entity | CompoundEntityRef | string,\n context?: { defaultKind?: string; defaultNamespace?: string },\n entityPresentationApi?: EntityPresentationApi,\n): EntityRefPresentationSnapshot {\n if (entityPresentationApi) {\n const ref =\n typeof entityOrRef === 'string' || 'metadata' in entityOrRef\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n return entityPresentationApi.forEntity(ref, context).snapshot;\n }\n return defaultEntityPresentation(entityOrRef, context);\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\n/**\n * Props for {@link CatalogAutocomplete}\n *\n * @public\n */\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\n/** @public */\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactNode, useState } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Theme, useTheme } from '@material-ui/core/styles';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport const Filters = (props: {\n children: ReactNode;\n options?: {\n drawerBreakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;\n drawerAnchor?: 'left' | 'right' | 'top' | 'bottom';\n };\n}) => {\n const isScreenSmallerThanBreakpoint = useMediaQuery(\n (theme: Theme) =>\n theme.breakpoints.down(props.options?.drawerBreakpoint ?? 'md'),\n { noSsr: true },\n );\n const theme = useTheme();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return isScreenSmallerThanBreakpoint ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n {t('catalogFilter.buttonTitle')}\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor={props.options?.drawerAnchor ?? 'left'}\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n {t('catalogFilter.title')}\n </Typography>\n {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const Content = (props: { children: ReactNode }) => {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const CatalogFilterLayout = (props: { children: ReactNode }) => {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.children}\n </Grid>\n );\n};\n\nCatalogFilterLayout.Filters = Filters;\nCatalogFilterLayout.Content = Content;\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { memo } from 'react';\n\ninterface Props {\n selected: boolean;\n value: string;\n availableOptions?: Record<string, number>;\n showCounts: boolean;\n}\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\nfunction OptionCheckbox({ selected }: { selected: boolean }) {\n return <Checkbox icon={icon} checkedIcon={checkedIcon} checked={selected} />;\n}\n\nexport const EntityAutocompletePickerOption = memo((props: Props) => {\n const { selected, value, availableOptions, showCounts } = props;\n const label = showCounts ? `${value} (${availableOptions?.[value]})` : value;\n\n return (\n <FormControlLabel\n control={<OptionCheckbox selected={selected} />}\n label={label}\n onClick={event => event.preventDefault()}\n />\n );\n});\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport { TextFieldProps } from '@material-ui/core/TextField';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils/filters';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\nimport { isEqual } from 'lodash';\n\n/** @public */\nexport type AllowedEntityFilters<T extends DefaultEntityFilters> = {\n [K in keyof T]-?: NonNullable<T[K]> extends EntityFilter & {\n values: string[];\n }\n ? K\n : never;\n}[keyof T];\n\n/** @public */\nexport type EntityAutocompletePickerProps<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n> = {\n label: string;\n name: Name;\n path: string;\n showCounts?: boolean;\n Filter: { new (values: string[]): NonNullable<T[Name]> };\n InputProps?: TextFieldProps;\n initialSelectedOptions?: string[];\n filtersForAvailableValues?: Array<keyof T>;\n hidden?: boolean;\n};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {\n textTransform: 'none',\n fontWeight: 'bold',\n },\n },\n { name: 'CatalogReactEntityAutocompletePicker' },\n);\n\n/** @public */\nexport function EntityAutocompletePicker<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n>(props: EntityAutocompletePickerProps<T, Name>) {\n const {\n label,\n name,\n path,\n showCounts,\n Filter,\n InputProps,\n initialSelectedOptions = [],\n filtersForAvailableValues = ['kind'],\n hidden,\n } = props;\n const classes = useStyles();\n\n const {\n updateFilters,\n filters,\n queryParameters: { [name]: queryParameter },\n } = useEntityList<T>();\n\n const catalogApi = useApi(catalogApiRef);\n const availableValuesFilters = filtersForAvailableValues.map(\n f => filters[f] as EntityFilter | undefined,\n );\n const { value: availableValues } = useAsync(async () => {\n const facet = path;\n const { facets } = await catalogApi.getEntityFacets({\n facets: [facet],\n filter: reduceBackendCatalogFilters(\n availableValuesFilters.filter(Boolean) as EntityFilter[],\n ),\n });\n\n return Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n }, [...availableValuesFilters]);\n\n const queryParameters = useMemo(\n () => [queryParameter].flat().filter(Boolean) as string[],\n [queryParameter],\n );\n\n const filteredOptions = (filters[name] as unknown as { values: string[] })\n ?.values;\n\n const [selectedOptions, setSelectedOptions] = useState(\n queryParameters.length\n ? queryParameters\n : filteredOptions ?? initialSelectedOptions,\n );\n\n // Set selected options on query parameter updates; this happens at initial page load and from\n // external updates to the page location\n useEffect(() => {\n if (queryParameters.length) {\n setSelectedOptions(queryParameters);\n }\n }, [queryParameters]);\n\n const availableOptions = Object.keys(availableValues ?? {});\n const shouldAddFilter = selectedOptions.length && availableOptions.length;\n\n // Update filter value when selectedOptions change\n useEffect(() => {\n updateFilters({\n [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined,\n } as Partial<T>);\n }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);\n\n // Update selected options when filter value changes\n useEffect(() => {\n if (!shouldAddFilter) return;\n\n const newSelectedOptions = filteredOptions ?? [];\n\n // Check value is actually different (not just a different reference) to prevent selectedOptions <> filters loop\n if (!isEqual(newSelectedOptions, selectedOptions)) {\n setSelectedOptions(newSelectedOptions);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Don't re-set filter value when selectedOptions changes\n }, [filteredOptions]);\n\n const filter = filters[name];\n if (\n (filter && typeof filter === 'object' && !('values' in filter)) ||\n !availableOptions.length\n ) {\n return null;\n }\n\n return hidden ? null : (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<string, true>\n multiple\n disableCloseOnSelect\n label={label}\n name={`${String(name)}-picker`}\n options={availableOptions}\n value={selectedOptions}\n TextFieldProps={InputProps}\n onChange={(_event: object, options: string[]) =>\n setSelectedOptions(options)\n }\n renderOption={(option, { selected }) => (\n <EntityAutocompletePickerOption\n selected={selected}\n value={option}\n availableOptions={availableValues}\n showCounts={!!showCounts}\n />\n )}\n />\n </Box>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Select } from '@backstage/core-components';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport { useEffect, useMemo, useState } from 'react';\nimport { EntityKindFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { filterKinds, useAllKinds } from './kindFilterUtils';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nfunction useEntityKindFilter(opts: { initialFilter: string }): {\n loading: boolean;\n error?: Error;\n allKinds: Map<string, string>;\n selectedKind: string;\n setSelectedKind: (kind: string) => void;\n} {\n const {\n filters,\n queryParameters: { kind: kindParameter },\n updateFilters,\n } = useEntityList();\n\n const queryParamKind = useMemo(\n () => [kindParameter].flat()[0],\n [kindParameter],\n );\n\n const [selectedKind, setSelectedKind] = useState(\n queryParamKind ?? filters.kind?.value ?? opts.initialFilter,\n );\n\n // Set selected kinds on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamKind) {\n setSelectedKind(queryParamKind);\n }\n }, [queryParamKind]);\n\n // Set selected kind from filters; this happens when the kind filter is\n // updated from another component\n useEffect(() => {\n if (filters.kind?.value) {\n setSelectedKind(filters.kind?.value);\n }\n }, [filters.kind]);\n\n const { allKinds, loading, error } = useAllKinds();\n const selectedKindLabel = allKinds.get(selectedKind) || selectedKind;\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind\n ? new EntityKindFilter(selectedKind, selectedKindLabel)\n : undefined,\n });\n }, [selectedKind, selectedKindLabel, updateFilters]);\n\n return {\n loading,\n error,\n allKinds,\n selectedKind,\n setSelectedKind,\n };\n}\n\n/**\n * Props for {@link EntityKindPicker}.\n *\n * @public\n */\nexport interface EntityKindPickerProps {\n /**\n * Entity kinds to show in the dropdown; by default all kinds are fetched from the catalog and\n * displayed.\n */\n allowedKinds?: string[];\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityKindPicker = (props: EntityKindPickerProps) => {\n const { allowedKinds, hidden, initialFilter = 'component' } = props;\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const alertApi = useApi(alertApiRef);\n\n const { error, allKinds, selectedKind, setSelectedKind } =\n useEntityKindFilter({\n initialFilter: initialFilter,\n });\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: t('entityKindPicker.errorMessage'),\n severity: 'error',\n });\n }\n }, [error, alertApi, t]);\n\n if (error) return null;\n\n const options = filterKinds(allKinds, allowedKinds, selectedKind);\n\n const items = [...options.entries()].map(([key, value]) => ({\n label: value,\n value: key,\n }));\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label={t('entityKindPicker.title')}\n items={items}\n selected={selectedKind.toLocaleLowerCase('en-US')}\n onChange={value => setSelectedKind(String(value))}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\n\n/**\n * Fetch and return all available kinds.\n */\nexport function useAllKinds(): {\n loading: boolean;\n error?: Error;\n allKinds: Map<string, string>;\n} {\n const catalogApi = useApi(catalogApiRef);\n\n const {\n error,\n loading,\n value: allKinds,\n } = useAsync(async () => {\n const { facets } = await catalogApi.getEntityFacets({ facets: ['kind'] });\n const kindFacets = (facets.kind ?? []).map(f => f.value);\n return new Map(\n kindFacets.map(kind => [kind.toLocaleLowerCase('en-US'), kind]),\n );\n }, [catalogApi]);\n\n return { loading, error, allKinds: allKinds ?? new Map() };\n}\n\n/**\n * Filter and capitalize accessible kinds.\n */\nexport function filterKinds(\n allKinds: Map<string, string>,\n allowedKinds?: string[],\n forcedKinds?: string,\n): Map<string, string> {\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n let availableKinds = Array.from(allKinds.keys());\n if (allowedKinds) {\n availableKinds = allowedKinds\n .map(k => k.toLocaleLowerCase('en-US'))\n .filter(k => allKinds.has(k));\n }\n\n const kindsMap = new Map(\n availableKinds.map(kind => [kind, allKinds.get(kind) || kind]),\n );\n\n if (forcedKinds && !kindsMap.has(forcedKinds)) {\n // this is the only time we set a label for a kind which is not properly capitalized\n kindsMap.set(forcedKinds.toLocaleLowerCase('en-US'), forcedKinds);\n }\n\n return kindsMap;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport { EntityLifecycleFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityLifecyclePickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n { name: 'CatalogReactEntityLifecyclePicker' },\n);\n\n/** @public */\nexport const EntityLifecyclePicker = (props: { initialFilter?: string[] }) => {\n const { initialFilter = [] } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityLifecyclePicker.title')}\n name=\"lifecycles\"\n path=\"spec.lifecycle\"\n Filter={EntityLifecycleFilter}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={initialFilter}\n />\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { EntityNamespaceFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityNamespacePickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n {\n name: 'CatalogReactEntityNamespacePicker',\n },\n);\n\n/**\n * Props for {@link EntityNamespacePicker}.\n *\n * @public\n */\nexport interface EntityNamespacePickerProps {\n initiallySelectedNamespaces?: string[];\n}\n\n/** @public */\nexport const EntityNamespacePicker = (props: EntityNamespacePickerProps) => {\n const { initiallySelectedNamespaces } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityNamespacePicker.title')}\n name=\"namespace\"\n path=\"metadata.namespace\"\n Filter={EntityNamespaceFilter}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={initiallySelectedNamespaces}\n />\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Typography from '@material-ui/core/Typography';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { MouseEvent, useEffect, useMemo, useState } from 'react';\nimport { useEntityList } from '../../hooks/useEntityListProvider';\nimport { EntityOwnerFilter } from '../../filters';\nimport { useDebouncedEffect } from '@react-hookz/web';\nimport PersonIcon from '@material-ui/icons/Person';\nimport GroupIcon from '@material-ui/icons/Group';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n} from '../../apis';\nimport { useFetchEntities } from './useFetchEntities';\nimport { withStyles } from '@material-ui/core/styles';\nimport { useEntityPresentation } from '../../apis';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\n\n/** @public */\nexport type CatalogReactEntityOwnerPickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {},\n input: {},\n fullWidth: { width: '100%' },\n boxLabel: {\n width: '100%',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n },\n },\n { name: 'CatalogReactEntityOwnerPicker' },\n);\n\n/** @public */\nexport type FixedWidthFormControlLabelClassKey = 'label' | 'root';\n\nconst FixedWidthFormControlLabel = withStyles(\n _theme => ({\n label: {\n width: '100%',\n },\n root: {\n width: '90%',\n },\n }),\n { name: 'FixedWidthFormControlLabel' },\n)(FormControlLabel);\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\n/**\n * @public\n */\nexport type EntityOwnerPickerProps = {\n mode?: 'owners-only' | 'all';\n};\n\nfunction RenderOptionLabel(props: { entity: Entity; isSelected: boolean }) {\n const classes = useStyles();\n const isGroup = props.entity.kind.toLocaleLowerCase('en-US') === 'group';\n const { primaryTitle: title } = useEntityPresentation(props.entity);\n return (\n <Box className={classes.fullWidth}>\n <FixedWidthFormControlLabel\n className={classes.fullWidth}\n control={\n <Checkbox\n icon={icon}\n checkedIcon={checkedIcon}\n checked={props.isSelected}\n />\n }\n onClick={event => event.preventDefault()}\n label={\n <Tooltip title={title}>\n <Box display=\"flex\" alignItems=\"center\">\n {isGroup ? (\n <GroupIcon fontSize=\"small\" />\n ) : (\n <PersonIcon fontSize=\"small\" />\n )}\n &nbsp;\n <Box className={classes.boxLabel}>\n <Typography noWrap>{title}</Typography>\n </Box>\n </Box>\n </Tooltip>\n }\n />\n </Box>\n );\n}\n\n/** @public */\nexport const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => {\n const classes = useStyles();\n const { mode = 'owners-only' } = props || {};\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const {\n updateFilters,\n filters,\n queryParameters: { owners: ownersParameter },\n } = useEntityList();\n\n const [text, setText] = useState('');\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const queryParamOwners = useMemo(\n () => [ownersParameter].flat().filter(Boolean) as string[],\n [ownersParameter],\n );\n\n const [selectedOwners, setSelectedOwners] = useState<string[]>(\n queryParamOwners.length ? queryParamOwners : filters.owners?.values ?? [],\n );\n\n const [{ value, loading }, handleFetch, cache] = useFetchEntities({\n mode,\n initialSelectedOwnersRefs: selectedOwners,\n });\n useDebouncedEffect(\n () => handleFetch({ text: text.toLocaleLowerCase('en-US') }),\n [text, handleFetch],\n 250,\n );\n\n const availableOwners = value?.items || [];\n\n // Set selected owners on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamOwners.length) {\n const filter = new EntityOwnerFilter(queryParamOwners);\n setSelectedOwners(filter.values);\n }\n }, [queryParamOwners]);\n\n useEffect(() => {\n updateFilters({\n owners: selectedOwners.length\n ? new EntityOwnerFilter(selectedOwners)\n : undefined,\n });\n }, [selectedOwners, updateFilters]);\n\n if (\n ['user', 'group'].includes(\n filters.kind?.value.toLocaleLowerCase('en-US') || '',\n )\n ) {\n return null;\n }\n\n return (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<Entity, true>\n label={t('entityOwnerPicker.title')}\n multiple\n disableCloseOnSelect\n loading={loading}\n options={availableOwners}\n value={selectedOwners as unknown as Entity[]}\n getOptionSelected={(o, v) => {\n if (typeof v === 'string') {\n return stringifyEntityRef(o) === v;\n }\n return o === v;\n }}\n getOptionLabel={o => {\n const entity =\n typeof o === 'string'\n ? cache.getEntity(o) ||\n parseEntityRef(o, {\n defaultKind: 'group',\n defaultNamespace: 'default',\n })\n : o;\n return entityPresentationSnapshot(\n entity,\n undefined,\n entityPresentationApi,\n ).primaryTitle;\n }}\n onChange={(_: object, owners) => {\n setText('');\n setSelectedOwners(\n owners.map(e => {\n const entityRef =\n typeof e === 'string' ? e : stringifyEntityRef(e);\n\n if (typeof e !== 'string') {\n cache.setEntity(e);\n }\n return entityRef;\n }),\n );\n }}\n filterOptions={x => x}\n renderOption={(entity, { selected }) => {\n return <RenderOptionLabel entity={entity} isSelected={selected} />;\n }}\n name=\"owner-picker\"\n onInputChange={(_e, inputValue) => {\n setText(inputValue);\n }}\n ListboxProps={{\n onScroll: (e: MouseEvent) => {\n const element = e.currentTarget;\n const hasReachedEnd =\n Math.abs(\n element.scrollHeight - element.clientHeight - element.scrollTop,\n ) < 1;\n\n if (hasReachedEnd && value?.cursor) {\n handleFetch({ items: value.items, cursor: value.cursor });\n }\n },\n 'data-testid': 'owner-picker-listbox',\n }}\n LabelProps={{ className: classes.label }}\n TextFieldProps={{ className: classes.input }}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useRef } from 'react';\nimport { useFacetsEntities } from './useFacetsEntities';\nimport { useQueryEntities } from './useQueryEntities';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../../api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { useMountEffect } from '@react-hookz/web';\n\nexport function useFetchEntities({\n mode,\n initialSelectedOwnersRefs,\n}: {\n mode: 'owners-only' | 'all';\n initialSelectedOwnersRefs: string[];\n}) {\n const isOwnersOnlyMode = mode === 'owners-only';\n const queryEntitiesResponse = useQueryEntities();\n const facetsEntitiesResponse = useFacetsEntities({\n enabled: isOwnersOnlyMode,\n });\n\n const [state, handleFetch] = isOwnersOnlyMode\n ? facetsEntitiesResponse\n : queryEntitiesResponse;\n\n return [\n state,\n handleFetch,\n useSelectedOwners({\n enabled: !isOwnersOnlyMode,\n initialSelectedOwnersRefs,\n }),\n ] as const;\n}\n\n/**\n * Hook used for storing the full entity of the specified owners\n * in order to display users and group using the information contained on each entity.\n * When a component is rendered for the first time, it loads the content of the entities\n * specified by `initialSelectedOwnersRefs` and export the `getEntity` and `setEntity`\n * utilities, used to retrieve and modify the owners.\n */\nfunction useSelectedOwners({\n enabled,\n initialSelectedOwnersRefs,\n}: {\n enabled: boolean;\n initialSelectedOwnersRefs: string[];\n}) {\n const allEntities = useRef<Record<string, Entity>>({});\n const catalogApi = useApi(catalogApiRef);\n\n const [, handleFetch] = useAsyncFn(async () => {\n const initialSelectedEntities = await catalogApi.getEntitiesByRefs({\n entityRefs: initialSelectedOwnersRefs,\n });\n initialSelectedEntities.items.forEach(e => {\n if (e) {\n allEntities.current[stringifyEntityRef(e)] = e;\n }\n });\n }, []);\n\n useMountEffect(() => {\n if (enabled && initialSelectedOwnersRefs.length > 0) {\n handleFetch();\n }\n });\n\n return {\n getEntity: (entityRef: string) => allEntities.current[entityRef],\n setEntity: (entity: Entity) => {\n allEntities.current[stringifyEntityRef(entity)] = entity;\n },\n };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../../api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { Entity } from '@backstage/catalog-model';\n\ntype QueryEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\nexport function useQueryEntities() {\n const catalogApi = useApi(catalogApiRef);\n return useAsyncFn(\n async (\n request: { text: string } | QueryEntitiesResponse,\n options?: { limit: number },\n ): Promise<QueryEntitiesResponse> => {\n const initialRequest = request as { text: string };\n const cursorRequest = request as QueryEntitiesResponse;\n const limit = options?.limit ?? 20;\n\n if (cursorRequest.cursor) {\n const response = await catalogApi.queryEntities({\n cursor: cursorRequest.cursor,\n limit,\n });\n return {\n cursor: response.pageInfo.nextCursor,\n items: [...cursorRequest.items, ...response.items],\n };\n }\n\n const response = await catalogApi.queryEntities({\n fullTextFilter: {\n term: initialRequest.text || '',\n fields: [\n 'metadata.name',\n 'kind',\n 'spec.profile.displayname',\n 'metadata.title',\n ],\n },\n filter: { kind: ['User', 'Group'] },\n orderFields: [{ field: 'metadata.name', order: 'asc' }],\n limit,\n });\n\n return {\n cursor: response.pageInfo.nextCursor,\n items: response.items,\n };\n },\n [],\n { loading: true },\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { catalogApiRef } from '../../api';\nimport { useState } from 'react';\nimport { Entity, parseEntityRef } from '@backstage/catalog-model';\n\ntype FacetsCursor = {\n start: number;\n text: string;\n};\n\ntype FacetsEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\ntype FacetsInitialRequest = {\n text: string;\n};\n\n/**\n * This hook asynchronously loads the entity owners using the facets endpoint.\n * EntityOwnerPicker uses this hook when mode=\"owners-only\" is passed as prop.\n * All the owners are kept internally in memory and rendered in batches once requested\n * by the frontend. The values returned by this hook are compatible with `useQueryEntities`\n * hook, which is also used by EntityOwnerPicker.\n * In this mode, the EntityOwnerPicker won't show detailed information of the owners.\n */\nexport function useFacetsEntities({ enabled }: { enabled: boolean }) {\n const catalogApi = useApi(catalogApiRef);\n\n const [facetsPromise] = useState(async () => {\n if (!enabled) {\n return [];\n }\n const facet = 'relations.ownedBy';\n\n return catalogApi\n .getEntityFacets({ facets: [facet] })\n .then(response =>\n response.facets[facet]\n .map(e => e.value)\n .map(ref => {\n const { kind, name, namespace } = parseEntityRef(ref);\n return {\n apiVersion: 'backstage.io/v1beta1',\n kind,\n metadata: { name, namespace },\n };\n })\n .sort(\n (a, b) =>\n a.kind.localeCompare(b.kind, 'en-US') ||\n a.metadata.namespace.localeCompare(\n b.metadata.namespace,\n 'en-US',\n ) ||\n a.metadata.name.localeCompare(b.metadata.name, 'en-US'),\n ),\n )\n .catch(() => []);\n });\n\n return useAsyncFn<\n (\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n options?: { limit?: number },\n ) => Promise<FacetsEntitiesResponse>\n >(\n async (request, options) => {\n const facets = await facetsPromise;\n\n if (!facets) {\n return {\n items: [],\n };\n }\n\n const limit = options?.limit ?? 20;\n\n const { text, start } = decodeCursor(request);\n const filteredRefs = facets.filter(e => filterEntity(text, e));\n const end = start + limit;\n return {\n items: filteredRefs.slice(0, end),\n ...encodeCursor({\n entities: filteredRefs,\n limit: end,\n payload: {\n text,\n start: end,\n },\n }),\n };\n },\n [facetsPromise],\n { loading: true, value: { items: [] } },\n );\n}\n\nfunction decodeCursor(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): FacetsCursor {\n if (isFacetsResponse(request) && request.cursor) {\n return JSON.parse(atob(request.cursor));\n }\n return {\n text: (request as FacetsInitialRequest).text || '',\n start: 0,\n };\n}\n\nfunction isFacetsResponse(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): request is FacetsEntitiesResponse {\n return !!(request as FacetsEntitiesResponse).cursor;\n}\n\nfunction encodeCursor({\n entities,\n limit,\n payload,\n}: {\n entities: Entity[];\n limit: number;\n payload: { text: string; start: number };\n}) {\n if (entities.length > limit) {\n return { cursor: btoa(JSON.stringify(payload)) };\n }\n return {};\n}\n\nfunction filterEntity(text: string, entity: Entity) {\n const normalizedText = text.trim();\n return (\n entity.kind.includes(normalizedText) ||\n entity.metadata.namespace?.includes(normalizedText) ||\n entity.metadata.name.includes(normalizedText)\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EntityErrorFilter, EntityOrphanFilter } from '../../filters';\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { useState } from 'react';\nimport { useEntityList } from '../../hooks';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\n\n/** @public */\nexport type CatalogReactEntityProcessingStatusPickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n root: {},\n input: {},\n label: {},\n },\n { name: 'CatalogReactEntityProcessingStatusPickerPicker' },\n);\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\n/** @public */\nexport const EntityProcessingStatusPicker = () => {\n const classes = useStyles();\n const { updateFilters } = useEntityList();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const [selectedAdvancedItems, setSelectedAdvancedItems] = useState<string[]>(\n [],\n );\n\n function orphanChange(value: boolean) {\n updateFilters({\n orphan: value ? new EntityOrphanFilter(value) : undefined,\n });\n }\n\n function errorChange(value: boolean) {\n updateFilters({\n error: value ? new EntityErrorFilter(value) : undefined,\n });\n }\n\n const availableAdvancedItems = ['Is Orphan', 'Has Error'];\n\n return (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<string, true>\n label={t('entityProcessingStatusPicker.title')}\n multiple\n disableCloseOnSelect\n options={availableAdvancedItems}\n value={selectedAdvancedItems}\n onChange={(_: object, value: string[]) => {\n setSelectedAdvancedItems(value);\n orphanChange(value.includes('Is Orphan'));\n errorChange(value.includes('Has Error'));\n }}\n renderOption={(option, { selected }) => (\n <FormControlLabel\n control={\n <Checkbox\n icon={icon}\n checkedIcon={checkedIcon}\n checked={selected}\n />\n }\n onClick={event => event.preventDefault()}\n label={option}\n />\n )}\n name=\"processing-status-picker\"\n LabelProps={{ className: classes.label }}\n TextFieldProps={{ className: classes.input }}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/**\n * @alpha\n */\nexport type EntityTableColumnTitleProps = {\n translationKey:\n | 'name'\n | 'system'\n | 'owner'\n | 'type'\n | 'lifecycle'\n | 'namespace'\n | 'description'\n | 'tags'\n | 'targets'\n | 'title'\n | 'label'\n | 'domain';\n};\n\n/**\n * @alpha\n */\nexport const EntityTableColumnTitle = ({\n translationKey,\n}: EntityTableColumnTitleProps) => {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return t(`entityTableColumnTitle.${translationKey}`);\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport { EntityTagFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker/EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityTagPickerClassKey = 'input';\n\n/** @public */\nexport type EntityTagPickerProps = {\n showCounts?: boolean;\n initialFilter?: string[];\n hidden?: boolean;\n};\n\nconst useStyles = makeStyles(\n { input: {} },\n { name: 'CatalogReactEntityTagPicker' },\n);\n\n/** @public */\nexport const EntityTagPicker = (props: EntityTagPickerProps) => {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityTagPicker.title')}\n name=\"tags\"\n path=\"metadata.tags\"\n Filter={EntityTagFilter}\n showCounts={props.showCounts}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={props.initialFilter ? props.initialFilter : []}\n hidden={props.hidden}\n />\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect } from 'react';\nimport Box from '@material-ui/core/Box';\nimport { useEntityTypeFilter } from '../../hooks/useEntityTypeFilter';\n\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Select } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Props for {@link EntityTypePicker}.\n *\n * @public\n */\nexport interface EntityTypePickerProps {\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityTypePicker = (props: EntityTypePickerProps) => {\n const { hidden, initialFilter } = props;\n const alertApi = useApi(alertApiRef);\n const { error, availableTypes, selectedTypes, setSelectedTypes } =\n useEntityTypeFilter();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: t('entityTypePicker.errorMessage'),\n severity: 'error',\n });\n }\n if (initialFilter) {\n setSelectedTypes([initialFilter]);\n }\n }, [error, alertApi, initialFilter, setSelectedTypes, t]);\n\n if (availableTypes.length === 0 || error) return null;\n\n availableTypes.sort((a, b) =>\n a.toLocaleLowerCase('en-US').localeCompare(b.toLocaleLowerCase('en-US')),\n );\n\n const items = [\n { value: 'all', label: t('entityTypePicker.optionAllTitle') },\n ...availableTypes.map((type: string) => ({\n value: type,\n label: type,\n })),\n ];\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label={t('entityTypePicker.title')}\n items={items}\n selected={(items.length > 1 ? selectedTypes[0] : undefined) ?? 'all'}\n onChange={value =>\n setSelectedTypes(value === 'all' ? [] : [String(value)])\n }\n />\n </Box>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport isEqual from 'lodash/isEqual';\nimport sortBy from 'lodash/sortBy';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../api';\nimport { useEntityList } from './useEntityListProvider';\nimport { EntityTypeFilter } from '../filters';\n\n/**\n * A hook built on top of `useEntityList` for enabling selection of valid `spec.type` values\n * based on the selected EntityKindFilter.\n * @public\n */\nexport function useEntityTypeFilter(): {\n loading: boolean;\n error?: Error;\n availableTypes: string[];\n selectedTypes: string[];\n setSelectedTypes: (types: string[]) => void;\n} {\n const catalogApi = useApi(catalogApiRef);\n const {\n filters: { kind: kindFilter, type: typeFilter },\n queryParameters: { type: typeParameter },\n updateFilters,\n } = useEntityList();\n\n const flattenedQueryTypes = useMemo(\n () => [typeParameter].flat().filter(Boolean) as string[],\n [typeParameter],\n );\n\n const [selectedTypes, setSelectedTypes] = useState(\n flattenedQueryTypes.length\n ? flattenedQueryTypes\n : typeFilter?.getTypes() ?? [],\n );\n\n // Set selected types on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (flattenedQueryTypes.length) {\n setSelectedTypes(flattenedQueryTypes);\n }\n }, [flattenedQueryTypes]);\n\n const [availableTypes, setAvailableTypes] = useState<string[]>([]);\n const kind = useMemo(() => kindFilter?.value, [kindFilter]);\n\n // Load all valid spec.type values straight from the catalogApi, paying attention to only the\n // kind filter for a complete list.\n const {\n error,\n loading,\n value: facets,\n } = useAsync(async () => {\n if (kind) {\n const items = await catalogApi\n .getEntityFacets({\n filter: { kind },\n facets: ['spec.type'],\n })\n .then(response => response.facets['spec.type'] || []);\n return items;\n }\n return [];\n }, [kind, catalogApi]);\n\n const facetsRef = useRef(facets);\n useEffect(() => {\n const oldFacets = facetsRef.current;\n facetsRef.current = facets;\n // Delay processing hook until kind and facets load updates have settled to generate list of types;\n // This prevents resetting the type filter due to saved type value from query params not matching the\n // empty set of type values while values are still being loaded; also only run this hook on changes\n // to facets\n if (loading || !kind || oldFacets === facets || !facets) {\n return;\n }\n\n // Sort by facet count descending, so the most common types appear on top\n const newTypes = [\n ...new Set(\n sortBy(facets, f => -f.count).map(f =>\n f.value.toLocaleLowerCase('en-US'),\n ),\n ),\n ];\n setAvailableTypes(newTypes);\n\n // Update type filter to only valid values when the list of available types has changed\n const stillValidTypes = selectedTypes.filter(value =>\n newTypes.includes(value),\n );\n if (!isEqual(selectedTypes, stillValidTypes)) {\n setSelectedTypes(stillValidTypes);\n }\n }, [loading, kind, selectedTypes, setSelectedTypes, facets]);\n\n useEffect(() => {\n updateFilters({\n type: selectedTypes.length\n ? new EntityTypeFilter(selectedTypes)\n : undefined,\n });\n }, [selectedTypes, updateFilters]);\n\n return {\n loading,\n error,\n availableTypes,\n selectedTypes,\n setSelectedTypes,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n configApiRef,\n IconComponent,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Card from '@material-ui/core/Card';\nimport List from '@material-ui/core/List';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport { StarIcon } from '@backstage/core-components';\nimport { Fragment, useEffect, useMemo, useState } from 'react';\nimport { EntityUserFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { UserListFilterKind } from '../../types';\nimport { useOwnedEntitiesCount } from './useOwnedEntitiesCount';\nimport { useAllEntitiesCount } from './useAllEntitiesCount';\nimport { useStarredEntitiesCount } from './useStarredEntitiesCount';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/** @public */\nexport type CatalogReactUserListPickerClassKey =\n | 'root'\n | 'title'\n | 'listIcon'\n | 'menuItem'\n | 'groupWrapper';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n backgroundColor: 'rgba(0, 0, 0, .11)',\n boxShadow: 'none',\n margin: theme.spacing(1, 0, 1, 0),\n },\n title: {\n margin: theme.spacing(1, 0, 0, 1),\n textTransform: 'uppercase',\n fontSize: 12,\n fontWeight: 'bold',\n },\n listIcon: {\n minWidth: 30,\n color: theme.palette.text.primary,\n },\n menuItem: {\n minHeight: theme.spacing(6),\n },\n groupWrapper: {\n margin: theme.spacing(1, 1, 2, 1),\n },\n }),\n { name: 'CatalogReactUserListPicker' },\n);\n\nexport type ButtonGroup = {\n name: string;\n items: {\n id: 'owned' | 'starred' | 'all';\n label: string;\n icon?: IconComponent;\n }[];\n};\n\nfunction getFilterGroups(\n orgName: string,\n t: TranslationFunction<typeof catalogReactTranslationRef.T>,\n): ButtonGroup[] {\n return [\n {\n name: t('userListPicker.personalFilter.title'),\n items: [\n {\n id: 'owned',\n label: t('userListPicker.personalFilter.ownedLabel'),\n icon: SettingsIcon,\n },\n {\n id: 'starred',\n label: t('userListPicker.personalFilter.starredLabel'),\n icon: StarIcon,\n },\n ],\n },\n {\n name: orgName,\n items: [\n {\n id: 'all',\n label: t('userListPicker.orgFilterAllLabel'),\n },\n ],\n },\n ];\n}\n\n/** @public */\nexport type UserListPickerProps = {\n initialFilter?: UserListFilterKind;\n availableFilters?: UserListFilterKind[];\n hidden?: boolean;\n alwaysKeepFilters?: boolean;\n};\n\n/** @public */\nexport const UserListPicker = (props: UserListPickerProps) => {\n const { initialFilter, availableFilters, hidden, alwaysKeepFilters } = props;\n const classes = useStyles();\n const configApi = useApi(configApiRef);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n const orgName =\n configApi.getOptionalString('organization.name') ??\n t('userListPicker.defaultOrgName');\n const {\n filters,\n updateFilters,\n queryParameters: { user: userParameter },\n } = useEntityList();\n const kindParameter = filters.kind?.value?.toLowerCase();\n\n // Remove group items that aren't in availableFilters and exclude\n // any now-empty groups.\n const userAndGroupFilterIds = ['starred', 'all'];\n const filterGroups = getFilterGroups(orgName, t)\n .map(filterGroup => ({\n ...filterGroup,\n items: filterGroup.items.filter(({ id }) =>\n // TODO: avoid hardcoding kinds here\n ['group', 'user'].some(kind => kind === kindParameter)\n ? userAndGroupFilterIds.includes(id)\n : !availableFilters || availableFilters.includes(id),\n ),\n }))\n .filter(({ items }) => !!items.length);\n\n const {\n count: ownedEntitiesCount,\n loading: loadingOwnedEntities,\n filter: ownedEntitiesFilter,\n } = useOwnedEntitiesCount();\n const { count: allCount } = useAllEntitiesCount();\n const {\n count: starredEntitiesCount,\n filter: starredEntitiesFilter,\n loading: loadingStarredEntities,\n } = useStarredEntitiesCount();\n\n const queryParamUserFilter = useMemo(\n () => [userParameter].flat()[0],\n [userParameter],\n );\n\n const [selectedUserFilter, setSelectedUserFilter] = useState(\n (queryParamUserFilter as UserListFilterKind) ?? initialFilter,\n );\n\n const filterCounts = useMemo(() => {\n return {\n all: allCount,\n starred: starredEntitiesCount,\n owned: ownedEntitiesCount,\n };\n }, [starredEntitiesCount, ownedEntitiesCount, allCount]);\n\n // Set selected user filter on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamUserFilter) {\n setSelectedUserFilter(queryParamUserFilter as UserListFilterKind);\n }\n }, [queryParamUserFilter]);\n\n const loading = loadingOwnedEntities || loadingStarredEntities;\n\n useEffect(() => {\n if (\n !loading &&\n !!selectedUserFilter &&\n selectedUserFilter !== 'all' &&\n filterCounts[selectedUserFilter] === 0 &&\n !alwaysKeepFilters\n ) {\n setSelectedUserFilter('all');\n }\n }, [\n loading,\n filterCounts,\n selectedUserFilter,\n setSelectedUserFilter,\n alwaysKeepFilters,\n ]);\n\n useEffect(() => {\n if (!selectedUserFilter) {\n return;\n }\n if (loading) {\n return;\n }\n\n const getFilter = () => {\n if (selectedUserFilter === 'owned') {\n return ownedEntitiesFilter;\n }\n if (selectedUserFilter === 'starred') {\n return starredEntitiesFilter;\n }\n return EntityUserFilter.all();\n };\n\n updateFilters({ user: getFilter() });\n }, [\n selectedUserFilter,\n starredEntitiesFilter,\n ownedEntitiesFilter,\n updateFilters,\n\n loading,\n ]);\n\n return hidden ? null : (\n <Card className={classes.root}>\n {filterGroups.map(group => (\n <Fragment key={group.name}>\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n className={classes.title}\n >\n {group.name}\n </Typography>\n <Card className={classes.groupWrapper}>\n <List disablePadding dense role=\"menu\" aria-label={group.name}>\n {group.items.map((item, index) => (\n <MenuItem\n role=\"none presentation\"\n key={item.id}\n divider={index !== group.items.length - 1}\n onClick={() => setSelectedUserFilter(item.id)}\n selected={item.id === filters.user?.value}\n className={classes.menuItem}\n disabled={filterCounts[item.id] === 0}\n data-testid={`user-picker-${item.id}`}\n tabIndex={0}\n ContainerProps={{ role: 'menuitem' }}\n >\n {item.icon && (\n <ListItemIcon className={classes.listIcon}>\n <item.icon fontSize=\"small\" />\n </ListItemIcon>\n )}\n <ListItemText>\n <Typography variant=\"body1\">{item.label} </Typography>\n </ListItemText>\n <ListItemSecondaryAction>\n {filterCounts[item.id] ?? '-'}\n </ListItemSecondaryAction>\n </MenuItem>\n ))}\n </List>\n </Card>\n </Fragment>\n ))}\n </Card>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\nimport { compact, intersection } from 'lodash';\nimport { useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityOwnerFilter, EntityUserFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { CatalogFilters, reduceCatalogFilters } from '../../utils/filters';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDeepCompareEffect from 'react-use/esm/useDeepCompareEffect';\n\nexport function useOwnedEntitiesCount() {\n const identityApi = useApi(identityApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n const { filters } = useEntityList();\n\n const { value: ownershipEntityRefs, loading: loadingEntityRefs } = useAsync(\n async () => (await identityApi.getBackstageIdentity()).ownershipEntityRefs,\n // load only on mount\n [],\n );\n\n const { user, owners, ...allFilters } = filters;\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(\n compact(Object.values(allFilters)),\n );\n\n const [{ value: count, loading: loadingEntityOwnership }, fetchEntities] =\n useAsyncFn(\n async (req: {\n ownershipEntityRefs: string[];\n owners: EntityOwnerFilter | undefined;\n filter: CatalogFilters;\n }) => {\n const ownedClaims = getOwnedCountClaims(\n req.owners,\n req.ownershipEntityRefs,\n );\n if (ownedClaims === undefined) {\n // this implicitly means that there aren't claims in common with\n // the logged in users, so avoid invoking the queryEntities endpoint\n // which will implicitly returns 0\n return 0;\n }\n\n const { ['metadata.name']: metadata, ...filter } = req.filter.filter;\n\n const { totalItems } = await catalogApi.queryEntities({\n ...req.filter,\n filter: {\n ...filter,\n 'relations.ownedBy': ownedClaims,\n },\n limit: 0,\n });\n return totalItems;\n },\n [],\n { loading: true },\n );\n\n useDeepCompareEffect(() => {\n // context contains no filter, wait\n if (Object.keys(catalogFilters.filter).length === 0) {\n return;\n }\n // ownershipEntityRefs is loading, wait\n if (ownershipEntityRefs === undefined) {\n return;\n }\n fetchEntities({\n ownershipEntityRefs,\n owners,\n filter: catalogFilters,\n });\n }, [ownershipEntityRefs, owners, catalogFilters]);\n\n const loading = loadingEntityRefs || loadingEntityOwnership;\n\n return {\n count,\n loading,\n filter: useMemo(\n () => EntityUserFilter.owned(ownershipEntityRefs ?? []),\n [ownershipEntityRefs],\n ),\n ownershipEntityRefs,\n };\n}\n\nfunction getOwnedCountClaims(\n owners: EntityOwnerFilter | undefined,\n ownershipEntityRefs: string[] | undefined,\n) {\n if (ownershipEntityRefs === undefined) {\n return undefined;\n }\n const ownersRefs = owners?.values ?? [];\n if (ownersRefs.length) {\n const commonOwnedBy = intersection(ownersRefs, ownershipEntityRefs);\n if (commonOwnedBy.length === 0) {\n return undefined;\n }\n return commonOwnedBy;\n }\n return ownershipEntityRefs;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { QueryEntitiesInitialRequest } from '@backstage/catalog-client';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport { useMemo, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { useEntityList } from '../../hooks';\nimport { reduceCatalogFilters } from '../../utils/filters';\n\nexport function useAllEntitiesCount() {\n const catalogApi = useApi(catalogApiRef);\n const { filters } = useEntityList();\n\n const prevRequest = useRef<QueryEntitiesInitialRequest>();\n const request = useMemo(() => {\n const { user, ...allFilters } = filters;\n const compacted = compact(Object.values(allFilters));\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(compacted);\n const newRequest: QueryEntitiesInitialRequest = {\n ...catalogFilters,\n limit: 0,\n };\n\n if (Object.keys(catalogFilters.filter).length === 0) {\n prevRequest.current = undefined;\n return prevRequest.current;\n }\n\n if (isEqual(newRequest, prevRequest.current)) {\n return prevRequest.current;\n }\n prevRequest.current = newRequest;\n return newRequest;\n }, [filters]);\n\n const { value: count, loading } = useAsync(async () => {\n if (request === undefined) {\n return 0;\n }\n const { totalItems } = await catalogApi.queryEntities(request);\n\n return totalItems;\n }, [request]);\n\n return { count, loading };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { QueryEntitiesInitialRequest } from '@backstage/catalog-client';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport { useMemo, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityUserFilter } from '../../filters';\nimport { useEntityList, useStarredEntities } from '../../hooks';\nimport { reduceCatalogFilters } from '../../utils/filters';\n\nexport function useStarredEntitiesCount() {\n const catalogApi = useApi(catalogApiRef);\n const { filters } = useEntityList();\n const { starredEntities } = useStarredEntities();\n\n const prevRequest = useRef<QueryEntitiesInitialRequest>();\n const request = useMemo(() => {\n const { user, ...allFilters } = filters;\n const compacted = compact(Object.values(allFilters));\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(compacted);\n\n const facet = 'metadata.name';\n\n const newRequest: QueryEntitiesInitialRequest = {\n ...catalogFilters,\n filter: {\n ...catalogFilters.filter,\n /**\n * here we are filtering entities by `name`. Given this filter,\n * the response might contain more entities than expected, in case multiple entities\n * of different kind or namespace share the same name. Those extra entities are filtered out\n * client side by `EntityUserFilter`, so they won't be visible to the user.\n */\n [facet]: Array.from(starredEntities).map(e => parseEntityRef(e).name),\n },\n /**\n * limit is set to a high value as we are not expecting many starred entities\n */\n limit: 1000,\n };\n if (isEqual(newRequest, prevRequest.current)) {\n return prevRequest.current;\n }\n prevRequest.current = newRequest;\n\n return newRequest;\n }, [filters, starredEntities]);\n\n const { value: count, loading } = useAsync(async () => {\n if (!starredEntities.size) {\n return 0;\n }\n\n /**\n * given a list of starred entity refs and some filters coming from CatalogPage,\n * it reduces the list of starred entities, to a list of entities that matches the\n * provided filters. It won't be possible to getEntitiesByRefs\n * as the method doesn't accept any filter.\n */\n const response = await catalogApi.queryEntities(request);\n\n return response.items\n .map(e =>\n stringifyEntityRef({\n kind: e.kind,\n namespace: e.metadata.namespace,\n name: e.metadata.name,\n }),\n )\n .filter(e => starredEntities.has(e)).length;\n }, [request, starredEntities]);\n\n const filter = useMemo(\n () => EntityUserFilter.starred(Array.from(starredEntities)),\n [starredEntities],\n );\n\n return { count, loading, filter };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n parseEntityRef,\n RELATION_OWNED_BY,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport { EntityFilter, UserListFilterKind } from './types';\nimport { getEntityRelations } from './utils/getEntityRelations';\nimport { EntityOrderQuery } from '@backstage/catalog-client';\n\n/**\n * Filter entities based on Kind.\n * @public\n */\nexport class EntityKindFilter implements EntityFilter {\n readonly value: string;\n readonly label: string;\n\n constructor(value: string, label: string) {\n this.value = value;\n this.label = label;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { kind: this.value };\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based on type\n * @public\n */\nexport class EntityTypeFilter implements EntityFilter {\n readonly value: string | string[];\n\n constructor(value: string | string[]) {\n this.value = value;\n }\n\n // Simplify `string | string[]` for consumers, always returns an array\n getTypes(): string[] {\n return Array.isArray(this.value) ? this.value : [this.value];\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'spec.type': this.getTypes() };\n }\n\n toQueryValue(): string[] {\n return this.getTypes();\n }\n}\n\n/**\n * Filters entities based on tag.\n * @public\n */\nexport class EntityTagFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.every(v => (entity.metadata.tags ?? []).includes(v));\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'metadata.tags': this.values };\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities where the text matches spec, title or tags.\n * @public\n */\nexport class EntityTextFilter implements EntityFilter {\n readonly value: string;\n\n constructor(value: string) {\n this.value = value;\n }\n\n filterEntity(entity: Entity): boolean {\n const words = this.toUpperArray(this.value.split(/\\s/));\n const exactMatch = this.toUpperArray([entity.metadata.tags]);\n const partialMatch = this.toUpperArray([\n entity.metadata.name,\n entity.metadata.title,\n (entity.spec?.profile as { displayName?: string })?.displayName,\n ]);\n\n for (const word of words) {\n if (\n exactMatch.every(m => m !== word) &&\n partialMatch.every(m => !m.includes(word))\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n getFullTextFilters() {\n return {\n term: this.value,\n // Update this to be more dynamic based on table columns.\n fields: ['metadata.name', 'metadata.title', 'spec.profile.displayName'],\n };\n }\n\n toQueryValue() {\n return this.value;\n }\n\n private toUpperArray(\n value: Array<string | string[] | undefined>,\n ): Array<string> {\n return value\n .flat()\n .filter((m): m is string => Boolean(m))\n .map(m => m.toLocaleUpperCase('en-US'));\n }\n}\n\n/**\n * Filter matching entities that are owned by group.\n * @public\n *\n * CAUTION: This class may contain both full and partial entity refs.\n */\nexport class EntityOwnerFilter implements EntityFilter {\n readonly values: string[];\n constructor(values: string[]) {\n this.values = values.reduce((fullRefs, ref) => {\n // Attempt to remove bad entity references here.\n try {\n fullRefs.push(\n stringifyEntityRef(parseEntityRef(ref, { defaultKind: 'Group' })),\n );\n return fullRefs;\n } catch (err) {\n return fullRefs;\n }\n }, [] as string[]);\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'relations.ownedBy': this.values };\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.some(v =>\n getEntityRelations(entity, RELATION_OWNED_BY).some(\n o => stringifyEntityRef(o) === v,\n ),\n );\n }\n\n /**\n * Get the URL query parameter value. May be a mix of full and humanized entity refs.\n * @returns list of entity refs.\n */\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities on lifecycle.\n * @public\n */\nexport class EntityLifecycleFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'spec.lifecycle': this.values };\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.some(v => entity.spec?.lifecycle === v);\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities to those within the given namespace(s).\n * @public\n */\nexport class EntityNamespaceFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'metadata.namespace': this.values };\n }\n filterEntity(entity: Entity): boolean {\n return this.values.some(v => entity.metadata.namespace === v);\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * @public\n */\nexport class EntityUserFilter implements EntityFilter {\n readonly value: UserListFilterKind;\n readonly refs?: string[];\n\n private constructor(value: UserListFilterKind, refs?: string[]) {\n this.value = value;\n this.refs = refs;\n }\n\n static owned(ownershipEntityRefs: string[]) {\n return new EntityUserFilter('owned', ownershipEntityRefs);\n }\n\n static all() {\n return new EntityUserFilter('all');\n }\n\n static starred(starredEntityRefs: string[]) {\n return new EntityUserFilter('starred', starredEntityRefs);\n }\n\n getCatalogFilters(): Record<string, string[]> {\n if (this.value === 'owned') {\n return { 'relations.ownedBy': this.refs ?? [] };\n }\n if (this.value === 'starred') {\n return {\n 'metadata.name': this.refs?.map(e => parseEntityRef(e).name) ?? [],\n };\n }\n return {};\n }\n\n filterEntity(entity: Entity) {\n if (this.value === 'starred') {\n return this.refs?.includes(stringifyEntityRef(entity)) ?? true;\n }\n // used only for retro-compatibility with non paginated data.\n // This is supposed to return always true for paginated\n // owned entities, since the filters are applied server side.\n if (this.value === 'owned') {\n const relations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return (\n this.refs?.some(v =>\n relations.some(o => stringifyEntityRef(o) === v),\n ) ?? false\n );\n }\n return true;\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based on whatever the user has starred or owns them.\n * @deprecated use EntityUserFilter\n * @public\n */\nexport class UserListFilter implements EntityFilter {\n readonly value: UserListFilterKind;\n readonly isOwnedEntity: (entity: Entity) => boolean;\n readonly isStarredEntity: (entity: Entity) => boolean;\n\n constructor(\n value: UserListFilterKind,\n isOwnedEntity: (entity: Entity) => boolean,\n isStarredEntity: (entity: Entity) => boolean,\n ) {\n this.value = value;\n this.isOwnedEntity = isOwnedEntity;\n this.isStarredEntity = isStarredEntity;\n }\n\n filterEntity(entity: Entity): boolean {\n switch (this.value) {\n case 'owned':\n return this.isOwnedEntity(entity);\n case 'starred':\n return this.isStarredEntity(entity);\n default:\n return true;\n }\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based if it is an orphan or not.\n * @public\n */\nexport class EntityOrphanFilter implements EntityFilter {\n readonly value: boolean;\n\n constructor(value: boolean) {\n this.value = value;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n if (this.value) {\n return { 'metadata.annotations.backstage.io/orphan': String(this.value) };\n }\n return {};\n }\n\n filterEntity(entity: Entity): boolean {\n const orphan = entity.metadata.annotations?.['backstage.io/orphan'];\n return orphan !== undefined && this.value.toString() === orphan;\n }\n}\n\n/**\n * Filters entities based on if it has errors or not.\n * @public\n */\nexport class EntityErrorFilter implements EntityFilter {\n readonly value: boolean;\n\n constructor(value: boolean) {\n this.value = value;\n }\n\n filterEntity(entity: Entity): boolean {\n const error =\n ((entity as AlphaEntity)?.status?.items?.length as number) > 0;\n return error !== undefined && this.value === error;\n }\n}\n\n/**\n * Sort entities by a given field/column.\n * @public\n */\nexport class EntityOrderFilter implements EntityFilter {\n readonly values: [string, 'asc' | 'desc'][];\n\n constructor(values: [string, 'asc' | 'desc'][]) {\n this.values = values;\n }\n\n getOrderFilters(): EntityOrderQuery {\n return this.values.map(([field, order]) => ({ field, order }));\n }\n\n toQueryValue(): string[] {\n return this.values.flat();\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { QueryEntitiesResponse } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n useVersionedContext,\n} from '@backstage/version-bridge';\nimport { compact, isEqual } from 'lodash';\nimport qs from 'qs';\nimport {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { useLocation } from 'react-router-dom';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport useMountedState from 'react-use/esm/useMountedState';\nimport { catalogApiRef } from '../api';\nimport {\n EntityErrorFilter,\n EntityKindFilter,\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityTypeFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityFilter, EntityListPagination } from '../types';\nimport {\n reduceBackendCatalogFilters,\n reduceCatalogFilters,\n reduceEntityFilters,\n} from '../utils/filters';\n\n/** @public */\nexport type DefaultEntityFilters = {\n kind?: EntityKindFilter;\n type?: EntityTypeFilter;\n user?: UserListFilter | EntityUserFilter;\n owners?: EntityOwnerFilter;\n lifecycles?: EntityLifecycleFilter;\n tags?: EntityTagFilter;\n text?: EntityTextFilter;\n orphan?: EntityOrphanFilter;\n error?: EntityErrorFilter;\n namespace?: EntityNamespaceFilter;\n order?: EntityOrderFilter;\n};\n\n/** @public */\nexport type PaginationMode = 'cursor' | 'offset' | 'none';\n\n/** @public */\nexport type EntityListContextProps<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n> = {\n /**\n * The currently registered filters, adhering to the shape of DefaultEntityFilters or an extension\n * of that default (to add custom filter types).\n */\n filters: EntityFilters;\n\n /**\n * The resolved list of catalog entities, after all filters are applied.\n */\n entities: Entity[];\n\n /**\n * The resolved list of catalog entities, after _only catalog-backend_ filters are applied.\n */\n backendEntities: Entity[];\n\n /**\n * Update one or more of the registered filters. Optional filters can be set to `undefined` to\n * reset the filter.\n */\n updateFilters: (\n filters:\n | Partial<EntityFilters>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => void;\n\n /**\n * Filter values from query parameters.\n */\n queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;\n\n loading: boolean;\n error?: Error;\n\n pageInfo?: {\n next?: () => void;\n prev?: () => void;\n };\n totalItems?: number;\n limit: number;\n offset?: number;\n setLimit: (limit: number) => void;\n setOffset?: (offset: number) => void;\n paginationMode: PaginationMode;\n};\n\n// This context has support for multiple concurrent versions of this package.\n// It is currently used in parallel with the old context in order to provide\n// a smooth transition, but will eventually be the only context we use.\nexport const NewEntityListContext = createVersionedContext<{\n 1: EntityListContextProps<any>;\n}>('entity-list-context');\n\n/**\n * Creates new context for entity listing and filtering.\n */\nexport const OldEntityListContext = createContext<\n EntityListContextProps<any> | undefined\n>(undefined);\n\ntype OutputState<EntityFilters extends DefaultEntityFilters> = {\n appliedFilters: EntityFilters;\n appliedCursor?: string;\n entities: Entity[];\n backendEntities: Entity[];\n pageInfo?: QueryEntitiesResponse['pageInfo'];\n totalItems?: number;\n offset?: number;\n limit?: number;\n};\n\n/**\n * @public\n */\nexport type EntityListProviderProps = PropsWithChildren<{\n pagination?: EntityListPagination;\n}>;\n\n/**\n * Provides entities and filters for a catalog listing.\n * @public\n */\nexport const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(\n props: EntityListProviderProps,\n) => {\n const isMounted = useMountedState();\n const catalogApi = useApi(catalogApiRef);\n const [requestedFilters, setRequestedFilters] = useState<EntityFilters>(\n {} as EntityFilters,\n );\n\n // We use react-router's useLocation hook so updates from external sources trigger an update to\n // the queryParameters in outputState. Updates from this hook use replaceState below and won't\n // trigger a useLocation change; this would instead come from an external source, such as a manual\n // update of the URL or two catalog sidebar links with different catalog filters.\n const location = useLocation();\n\n const getPaginationMode = (): PaginationMode => {\n if (props.pagination === true) {\n return 'cursor';\n }\n return typeof props.pagination === 'object'\n ? props.pagination.mode ?? 'cursor'\n : 'none';\n };\n\n const paginationMode = getPaginationMode();\n const paginationLimit =\n typeof props.pagination === 'object' ? props.pagination.limit ?? 20 : 20;\n\n const {\n queryParameters,\n cursor: initialCursor,\n offset: initialOffset,\n limit: initialLimit,\n } = useMemo(() => {\n const parsed = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n arrayLimit: 10000,\n });\n\n let limit = paginationLimit;\n if (typeof parsed.limit === 'string') {\n const queryLimit = Number.parseInt(parsed.limit, 10);\n if (!isNaN(queryLimit)) {\n limit = queryLimit;\n }\n }\n\n const offset =\n typeof parsed.offset === 'string' && paginationMode === 'offset'\n ? Number.parseInt(parsed.offset, 10)\n : undefined;\n\n return {\n queryParameters: (parsed.filters ?? {}) as Record<\n string,\n string | string[]\n >,\n cursor:\n typeof parsed.cursor === 'string' && paginationMode === 'cursor'\n ? parsed.cursor\n : undefined,\n offset:\n paginationMode === 'offset' && offset && !isNaN(offset)\n ? offset\n : undefined,\n limit,\n };\n }, [paginationMode, location.search, paginationLimit]);\n\n const [cursor, setCursor] = useState(initialCursor);\n const [offset, setOffset] = useState<number | undefined>(initialOffset);\n const [limit, setLimit] = useState(initialLimit);\n\n const [outputState, setOutputState] = useState<OutputState<EntityFilters>>(\n () => {\n return {\n appliedFilters: {} as EntityFilters,\n entities: [],\n backendEntities: [],\n pageInfo: {},\n offset,\n limit,\n };\n },\n );\n\n // The main async filter worker. Note that while it has a lot of dependencies\n // in terms of its implementation, the triggering only happens (debounced)\n // based on the requested filters changing.\n const [{ value: resolvedValue, loading, error }, refresh] = useAsyncFn(\n async () => {\n const kindValue =\n requestedFilters.kind?.value?.toLocaleLowerCase('en-US');\n const adjustedFilters =\n kindValue === 'user' || kindValue === 'group'\n ? { ...requestedFilters, owners: undefined }\n : requestedFilters;\n const compacted = compact(Object.values(adjustedFilters));\n const entityFilter = reduceEntityFilters(compacted);\n\n if (paginationMode !== 'none') {\n if (cursor) {\n if (cursor !== outputState.appliedCursor) {\n const response = await catalogApi.queryEntities({\n cursor,\n limit,\n });\n return {\n appliedFilters: requestedFilters,\n appliedCursor: cursor,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n appliedCursor: outputState.appliedCursor,\n backendEntities: outputState.backendEntities,\n entities,\n pageInfo: outputState.pageInfo,\n totalItems: outputState.totalItems,\n limit: outputState.limit,\n offset: outputState.offset,\n };\n }\n\n const backendFilter = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n if (\n (paginationMode === 'offset' &&\n (outputState.limit !== limit || outputState.offset !== offset)) ||\n !isEqual(previousBackendFilter, backendFilter)\n ) {\n const response = await catalogApi.queryEntities({\n ...backendFilter,\n limit,\n offset,\n });\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n limit,\n offset,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n pageInfo: outputState.pageInfo,\n totalItems: outputState.totalItems,\n limit: outputState.limit,\n offset: outputState.offset,\n };\n }\n\n const backendFilter = reduceBackendCatalogFilters(compacted);\n const { orderFields } = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceBackendCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n // TODO(mtlewis): currently entities will never be requested unless\n // there's at least one filter, we should allow an initial request\n // to happen with no filters.\n if (!isEqual(previousBackendFilter, backendFilter)) {\n // TODO(timbonicus): should limit fields here, but would need filter\n // fields + table columns\n const response = await catalogApi.getEntities({\n filter: backendFilter,\n order: orderFields,\n });\n const entities = response.items.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities,\n totalItems: entities.length,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n totalItems: entities.length,\n };\n },\n [\n catalogApi,\n queryParameters,\n requestedFilters,\n outputState,\n cursor,\n paginationMode,\n limit,\n offset,\n ],\n { loading: true },\n );\n\n // Slight debounce on the refresh, since (especially on page load) several\n // filters will be calling this in rapid succession.\n useDebounce(refresh, 10, [requestedFilters, cursor, limit, offset]);\n\n useEffect(() => {\n if (resolvedValue === undefined) {\n return;\n }\n setOutputState(resolvedValue);\n if (isMounted()) {\n const queryParams = Object.keys(requestedFilters).reduce(\n (params, key) => {\n const filter = requestedFilters[key as keyof EntityFilters] as\n | EntityFilter\n | undefined;\n if (filter?.toQueryValue) {\n params[key] = filter.toQueryValue();\n }\n return params;\n },\n {} as Record<string, string | string[]>,\n );\n\n const oldParams = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n arrayLimit: 10000,\n });\n const newParams = qs.stringify(\n {\n ...oldParams,\n filters: queryParams,\n ...(paginationMode === 'none' ? {} : { cursor, limit, offset }),\n },\n { addQueryPrefix: true, arrayFormat: 'repeat' },\n );\n const newUrl = `${window.location.pathname}${newParams}`;\n // We use direct history manipulation since useSearchParams and\n // useNavigate in react-router-dom cause unnecessary extra rerenders.\n // Also make sure to replace the state rather than pushing, since we\n // don't want there to be back/forward slots for every single filter\n // change.\n window.history?.replaceState(null, document.title, newUrl);\n }\n }, [\n cursor,\n isMounted,\n limit,\n location.search,\n offset,\n requestedFilters,\n resolvedValue,\n paginationMode,\n ]);\n\n const updateFilters = useCallback(\n (\n update:\n | Partial<EntityFilter>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => {\n // changing filters will affect pagination, so we need to reset\n // the cursor and start from the first page.\n // TODO(vinzscam): this is currently causing issues at page reload\n // where the state is not kept. Unfortunately we need to rethink\n // the way filters work in order to fix this.\n if (paginationMode === 'cursor') {\n setCursor(undefined);\n } else if (paginationMode === 'offset') {\n // Same thing with offset\n setOffset(0);\n }\n setRequestedFilters(prevFilters => {\n const newFilters =\n typeof update === 'function' ? update(prevFilters) : update;\n return { ...prevFilters, ...newFilters };\n });\n },\n [paginationMode],\n );\n\n // Use resolvedValue directly when available to avoid an extra render cycle.\n // Without this, there's a render where loading has flipped back to false but\n // outputState hasn't been updated yet (it syncs via useEffect), causing a\n // flash of stale data between the loading state and the new results.\n const latestOutput = resolvedValue ?? outputState;\n\n const pageInfo = useMemo(() => {\n if (paginationMode !== 'cursor') {\n return undefined;\n }\n\n const prevCursor = latestOutput.pageInfo?.prevCursor;\n const nextCursor = latestOutput.pageInfo?.nextCursor;\n return {\n prev: prevCursor ? () => setCursor(prevCursor) : undefined,\n next: nextCursor ? () => setCursor(nextCursor) : undefined,\n };\n }, [paginationMode, latestOutput.pageInfo]);\n\n const value = useMemo(\n () => ({\n filters: latestOutput.appliedFilters,\n entities: latestOutput.entities,\n backendEntities: latestOutput.backendEntities,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n totalItems: latestOutput.totalItems,\n limit,\n offset,\n setLimit,\n setOffset,\n paginationMode,\n }),\n [\n latestOutput,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n limit,\n offset,\n paginationMode,\n setLimit,\n setOffset,\n ],\n );\n\n return (\n <OldEntityListContext.Provider value={value}>\n <NewEntityListContext.Provider\n value={createVersionedValueMap({ 1: value })}\n >\n {props.children}\n </NewEntityListContext.Provider>\n </OldEntityListContext.Provider>\n );\n};\n\n/**\n * Hook for interacting with the entity list context provided by the {@link EntityListProvider}.\n * @public\n */\nexport function useEntityList<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n>(): EntityListContextProps<EntityFilters> {\n const versionedHolder = useVersionedContext<{\n 1: EntityListContextProps<any>;\n }>('entity-list-context');\n const oldContext = useContext(OldEntityListContext);\n\n if (versionedHolder) {\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityListContext v1 not available');\n }\n return value;\n }\n\n if (oldContext) {\n return oldContext;\n }\n\n throw new Error('useEntityList must be used within EntityListProvider');\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useMemo } from 'react';\nimport useObservable from 'react-use/esm/useObservable';\nimport { starredEntitiesApiRef } from '../apis';\n\nfunction getEntityRef(\n entityOrRef: Entity | CompoundEntityRef | string,\n): string {\n return typeof entityOrRef === 'string'\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n}\n\n/** @public */\nexport function useStarredEntities(): {\n starredEntities: Set<string>;\n toggleStarredEntity: (\n entityOrRef: Entity | CompoundEntityRef | string,\n ) => void;\n isStarredEntity: (\n entityOrRef: Entity | CompoundEntityRef | string,\n ) => boolean;\n} {\n const starredEntitiesApi = useApi(starredEntitiesApiRef);\n\n const starredEntities = useObservable(\n useMemo(() => starredEntitiesApi.starredEntitie$(), [starredEntitiesApi]),\n new Set<string>(),\n );\n\n const isStarredEntity = useCallback(\n (entityOrRef: Entity | CompoundEntityRef | string) =>\n starredEntities.has(getEntityRef(entityOrRef)),\n [starredEntities],\n );\n\n const toggleStarredEntity = useCallback(\n (entityOrRef: Entity | CompoundEntityRef | string) =>\n starredEntitiesApi.toggleStarred(getEntityRef(entityOrRef)).then(),\n [starredEntitiesApi],\n );\n\n return {\n starredEntities,\n toggleStarredEntity,\n isStarredEntity,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { EntityFilter } from '../types';\nimport {\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityOrderQuery } from '@backstage/catalog-client';\n\nexport interface CatalogFilters {\n filter: Record<string, string | symbol | (string | symbol)[]>;\n fullTextFilter?: {\n term: string;\n };\n orderFields?: EntityOrderQuery;\n}\n\nfunction isEntityTextFilter(t: EntityFilter): t is EntityTextFilter {\n return !!(t as EntityTextFilter).getFullTextFilters;\n}\n\nfunction isEntityOrderFilter(t: EntityFilter): t is EntityOrderFilter {\n return !!(t as EntityOrderFilter).getOrderFilters;\n}\n\nexport function reduceCatalogFilters(filters: EntityFilter[]): CatalogFilters {\n const condensedFilters = filters.reduce<CatalogFilters['filter']>(\n (compoundFilter, filter) => {\n return {\n ...compoundFilter,\n ...(filter.getCatalogFilters ? filter.getCatalogFilters() : {}),\n };\n },\n {},\n );\n\n const fullTextFilter = filters.find(isEntityTextFilter)?.getFullTextFilters();\n\n const orderFields = filters.find(isEntityOrderFilter)?.getOrderFilters() || [\n {\n field: 'metadata.name',\n order: 'asc',\n },\n ];\n return { filter: condensedFilters, fullTextFilter, orderFields };\n}\n\n/**\n * This function computes and returns an object containing the filters to be sent\n * to the backend. Any filter coming from `EntityKindFilter` and `EntityTypeFilter`, together\n * with custom filter set by the adopters is allowed. This function is used by `EntityListProvider`\n * and it won't be needed anymore in the future once pagination is implemented, as all the filters\n * will be applied backend-side.\n */\nexport function reduceBackendCatalogFilters(filters: EntityFilter[]) {\n const backendCatalogFilters: Record<\n string,\n string | symbol | (string | symbol)[]\n > = {};\n\n filters.forEach(filter => {\n if (\n filter instanceof EntityTagFilter ||\n filter instanceof EntityOwnerFilter ||\n filter instanceof EntityLifecycleFilter ||\n filter instanceof EntityNamespaceFilter ||\n filter instanceof EntityUserFilter ||\n filter instanceof EntityOrphanFilter ||\n filter instanceof EntityTextFilter ||\n filter instanceof UserListFilter\n ) {\n return;\n }\n Object.assign(backendCatalogFilters, filter.getCatalogFilters?.() || {});\n });\n\n return backendCatalogFilters;\n}\n\nexport function reduceEntityFilters(\n filters: EntityFilter[],\n): (entity: Entity) => boolean {\n return (entity: Entity) =>\n filters.every(\n filter => !filter.filterEntity || filter.filterEntity(entity),\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Button from '@material-ui/core/Button';\nimport IconButton from '@material-ui/core/IconButton';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Link as RouterLink, LinkProps } from 'react-router-dom';\nimport AddCircleOutline from '@material-ui/icons/AddCircleOutline';\nimport { Theme } from '@material-ui/core/styles';\n\n/**\n * Properties for {@link CreateButton}\n *\n * @public\n */\nexport type CreateButtonProps = {\n title: string;\n} & Partial<Pick<LinkProps, 'to'>>;\n\n/**\n * Responsive Button giving consistent UX for creation of different things\n *\n * @public\n */\nexport function CreateButton(props: CreateButtonProps) {\n const { title, to } = props;\n const isXSScreen = useMediaQuery<Theme>(theme =>\n theme.breakpoints.down('xs'),\n );\n\n if (!to) {\n return null;\n }\n\n return isXSScreen ? (\n <IconButton\n component={RouterLink}\n color=\"primary\"\n title={title}\n size=\"small\"\n to={to}\n >\n <AddCircleOutline />\n </IconButton>\n ) : (\n <Button component={RouterLink} variant=\"contained\" color=\"primary\" to={to}>\n {title}\n </Button>\n );\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { UserListFilterKind } from '../../types';\nimport { EntityKindPicker } from '../EntityKindPicker';\nimport { EntityLifecyclePicker } from '../EntityLifecyclePicker';\nimport { EntityNamespacePicker } from '../EntityNamespacePicker';\nimport {\n EntityOwnerPickerProps,\n EntityOwnerPicker,\n} from '../EntityOwnerPicker';\nimport { EntityProcessingStatusPicker } from '../EntityProcessingStatusPicker';\nimport { EntityTagPicker } from '../EntityTagPicker';\nimport { EntityTypePicker } from '../EntityTypePicker';\nimport { UserListPicker } from '../UserListPicker';\n\n/**\n * Props for default filters.\n *\n * @public\n */\nexport type DefaultFiltersProps = {\n initialKind?: string;\n initiallySelectedFilter?: UserListFilterKind;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n initiallySelectedNamespaces?: string[];\n};\n\n/** @public */\nexport const DefaultFilters = (props: DefaultFiltersProps) => {\n const {\n initialKind,\n initiallySelectedFilter,\n ownerPickerMode,\n initiallySelectedNamespaces,\n } = props;\n return (\n <>\n <EntityKindPicker initialFilter={initialKind} />\n <EntityTypePicker />\n <UserListPicker initialFilter={initiallySelectedFilter} />\n <EntityOwnerPicker mode={ownerPickerMode} />\n <EntityLifecyclePicker />\n <EntityTagPicker />\n <EntityProcessingStatusPicker />\n <EntityNamespacePicker\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n </>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n defaultEntityPresentation,\n EntityRefLink,\n EntityRefLinks,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport Chip from '@material-ui/core/Chip';\nimport { CatalogTableRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport { JsonArray } from '@backstage/types';\nimport { EntityTableColumnTitle } from '@backstage/plugin-catalog-react/alpha';\n\n// The columnFactories symbol is not directly exported, but through the\n// CatalogTable.columns field.\n/** @public */\nexport const columnFactories = Object.freeze({\n createNameColumn(options?: {\n defaultKind?: string;\n entityPresentationApi?: EntityPresentationApi;\n }): TableColumn<CatalogTableRow> {\n function formatContent(entity: Entity): string {\n if (options?.entityPresentationApi) {\n return options.entityPresentationApi.forEntity(entity, {\n defaultKind: options?.defaultKind,\n }).snapshot.primaryTitle;\n }\n return defaultEntityPresentation(entity, {\n defaultKind: options?.defaultKind,\n }).primaryTitle;\n }\n\n return {\n title: <EntityTableColumnTitle translationKey=\"name\" />,\n field: 'resolved.entityRef',\n highlight: true,\n customSort({ entity: entity1 }, { entity: entity2 }) {\n // TODO: We could implement this more efficiently by comparing field by field.\n // This has similar issues as above.\n return formatContent(entity1).localeCompare(formatContent(entity2));\n },\n render: ({ entity }) => (\n <EntityRefLink\n entityRef={entity}\n defaultKind={options?.defaultKind || 'Component'}\n />\n ),\n };\n },\n createSystemColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"system\" />,\n field: 'resolved.partOfSystemRelationTitle',\n customFilterAndSearch: (query, row) => {\n if (!row.resolved.partOfSystemRelations) {\n return false;\n }\n\n const systemNames = row.resolved.partOfSystemRelations.map(\n ref => ref.name,\n ); // Extract system names from entityRefs\n\n const searchText = systemNames.join(', ').toLocaleUpperCase('en-US');\n return searchText.includes(query.toLocaleUpperCase('en-US'));\n },\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.partOfSystemRelations}\n defaultKind=\"system\"\n />\n ),\n };\n },\n createOwnerColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"owner\" />,\n field: 'resolved.ownedByRelationsTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.ownedByRelations}\n defaultKind=\"group\"\n />\n ),\n };\n },\n createSpecTargetsColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"targets\" />,\n field: 'entity.spec.targets',\n customFilterAndSearch: (query, row) => {\n let targets: JsonArray = [];\n if (\n row.entity?.spec?.targets &&\n Array.isArray(row.entity?.spec?.targets)\n ) {\n targets = row.entity?.spec?.targets;\n } else if (row.entity?.spec?.target) {\n targets = [row.entity?.spec?.target];\n }\n return targets\n .join(', ')\n .toLocaleUpperCase('en-US')\n .includes(query.toLocaleUpperCase('en-US'));\n },\n render: ({ entity }) => (\n <>\n {(entity?.spec?.targets || entity?.spec?.target) && (\n <OverflowTooltip\n text={(\n (entity!.spec!.targets as JsonArray) || [entity.spec.target]\n ).join(', ')}\n placement=\"bottom-start\"\n />\n )}\n </>\n ),\n };\n },\n createSpecTypeColumn(\n options: {\n hidden: boolean;\n } = { hidden: false },\n ): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"type\" />,\n field: 'entity.spec.type',\n hidden: options.hidden,\n width: 'auto',\n };\n },\n createSpecLifecycleColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"lifecycle\" />,\n field: 'entity.spec.lifecycle',\n };\n },\n createMetadataDescriptionColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"description\" />,\n field: 'entity.metadata.description',\n render: ({ entity }) => (\n <OverflowTooltip\n text={entity.metadata.description}\n placement=\"bottom-start\"\n />\n ),\n width: 'auto',\n };\n },\n createTagsColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"tags\" />,\n field: 'entity.metadata.tags',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n render: ({ entity }) => (\n <>\n {entity.metadata.tags &&\n entity.metadata.tags.map(t => (\n <Chip\n key={t}\n label={t}\n size=\"small\"\n variant=\"outlined\"\n style={{ margin: '2px' }}\n />\n ))}\n </>\n ),\n width: 'auto',\n };\n },\n createTitleColumn(options?: {\n hidden?: boolean;\n }): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"title\" />,\n field: 'entity.metadata.title',\n hidden: options?.hidden,\n searchable: true,\n };\n },\n createLabelColumn(\n key: string,\n options?: { title?: string; defaultValue?: string },\n ): TableColumn<CatalogTableRow> {\n function formatContent(keyLabel: string, entity: Entity): string {\n const labels: Record<string, string> | undefined =\n entity.metadata?.labels;\n return (labels && labels[keyLabel]) || '';\n }\n\n return {\n title: options?.title || (\n <EntityTableColumnTitle translationKey=\"label\" />\n ),\n field: 'entity.metadata.labels',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n customSort({ entity: entity1 }, { entity: entity2 }) {\n return formatContent(key, entity1).localeCompare(\n formatContent(key, entity2),\n );\n },\n render: ({ entity }: { entity: Entity }) => {\n const labels: Record<string, string> | undefined =\n entity.metadata?.labels;\n const specifiedLabelValue =\n (labels && labels[key]) || options?.defaultValue;\n return (\n <>\n {specifiedLabelValue && (\n <Chip\n key={specifiedLabelValue}\n label={specifiedLabelValue}\n size=\"small\"\n variant=\"outlined\"\n />\n )}\n </>\n );\n },\n width: 'auto',\n };\n },\n createNamespaceColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"namespace\" />,\n field: 'entity.metadata.namespace',\n width: 'auto',\n };\n },\n});\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport FormControl from '@material-ui/core/FormControl';\nimport IconButton from '@material-ui/core/IconButton';\nimport Input from '@material-ui/core/Input';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Clear from '@material-ui/icons/Clear';\nimport Search from '@material-ui/icons/Search';\nimport { useEffect, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { useEntityList } from '../../hooks/useEntityListProvider';\nimport { EntityTextFilter } from '../../filters';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntitySearchBarClassKey = 'searchToolbar' | 'input';\n\nconst useStyles = makeStyles(\n _theme => ({\n searchToolbar: {\n paddingLeft: 0,\n paddingRight: 0,\n },\n input: {},\n }),\n { name: 'CatalogReactEntitySearchBar' },\n);\n\n/**\n * Renders search bar for filtering the entity list.\n * @public\n */\nexport const EntitySearchBar = () => {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const {\n updateFilters,\n queryParameters: { text: textParameter },\n } = useEntityList();\n\n const queryParamTextFilter = useMemo(\n () => [textParameter].flat()[0],\n [textParameter],\n );\n\n const [search, setSearch] = useState(queryParamTextFilter ?? '');\n\n useDebounce(\n () => {\n updateFilters({\n text: search.length ? new EntityTextFilter(search) : undefined,\n });\n },\n 250,\n [search, updateFilters],\n );\n\n useEffect(() => {\n if (queryParamTextFilter) {\n setSearch(queryParamTextFilter);\n }\n }, [queryParamTextFilter]);\n\n return (\n <Toolbar className={classes.searchToolbar}>\n <FormControl>\n <Input\n aria-label=\"search\"\n id=\"input-with-icon-adornment\"\n className={classes.input}\n placeholder={t('entitySearchBar.placeholder')}\n autoComplete=\"off\"\n onChange={event => setSearch(event.target.value)}\n value={search}\n startAdornment={\n <InputAdornment position=\"start\">\n <Search />\n </InputAdornment>\n }\n endAdornment={\n <InputAdornment position=\"end\">\n <IconButton\n aria-label=\"clear search\"\n onClick={() => setSearch('')}\n edge=\"end\"\n disabled={search.length === 0}\n >\n <Clear />\n </IconButton>\n </InputAdornment>\n }\n />\n </FormControl>\n </Toolbar>\n );\n};\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ReactElement } from 'react';\nimport { EntitySearchBar } from '@backstage/plugin-catalog-react';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\n\n/** @public */\nexport type CatalogTableToolbarClassKey = 'root' | 'text';\n\nconst useToolbarStyles = makeStyles(\n theme => ({\n root: {\n paddingTop: theme.spacing(1.25),\n paddingLeft: theme.spacing(2.5),\n paddingBottom: theme.spacing(0.75),\n display: 'flex',\n justifyContent: 'space-between',\n },\n text: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n }),\n { name: 'PluginCatalogTableToolbar' },\n);\n\nexport function CatalogTableToolbar(props: {\n title?: string | ReactElement<any>;\n}) {\n const styles = useToolbarStyles();\n return (\n <Toolbar className={styles.root}>\n <Typography variant=\"h5\" className={styles.text}>\n {props.title}\n </Typography>\n <EntitySearchBar />\n </Toolbar>\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useEffect } from 'react';\n\nimport { Table, TableProps } from '@backstage/core-components';\nimport { CatalogTableRow } from './types';\nimport { useEntityList } from '@backstage/plugin-catalog-react';\nimport { CatalogTableToolbar } from './CatalogTableToolbar';\n\n/**\n * @internal\n */\nexport function OffsetPaginatedCatalogTable(\n props: TableProps<CatalogTableRow>,\n) {\n const { columns, data, options, ...restProps } = props;\n const { setLimit, setOffset, limit, totalItems, offset } = useEntityList();\n\n const [page, setPage] = useState(\n offset && limit ? Math.floor(offset / limit) : 0,\n );\n\n useEffect(() => {\n if (totalItems && page * limit >= totalItems) {\n setOffset!(Math.max(0, totalItems - limit));\n } else {\n setOffset!(Math.max(0, page * limit));\n }\n }, [setOffset, page, limit, totalItems]);\n\n return (\n <Table\n columns={columns}\n data={data}\n options={{\n pageSizeOptions: [5, 10, 20, 50, 100],\n pageSize: limit,\n emptyRowsWhenPaging: false,\n ...options,\n }}\n components={{\n Toolbar: CatalogTableToolbar,\n }}\n page={page}\n onPageChange={setPage}\n onRowsPerPageChange={setLimit}\n totalCount={totalItems}\n {...restProps}\n />\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Table, TableProps } from '@backstage/core-components';\nimport { CatalogTableRow } from './types';\nimport { CatalogTableToolbar } from './CatalogTableToolbar';\n\ntype PaginatedCatalogTableProps = {\n prev?(): void;\n next?(): void;\n} & TableProps<CatalogTableRow>;\n\n/**\n * @internal\n */\n\nexport function CursorPaginatedCatalogTable(props: PaginatedCatalogTableProps) {\n const { columns, data, next, prev, options, ...restProps } = props;\n\n return (\n <Table\n columns={columns}\n data={data}\n options={{\n ...options,\n // These settings are configured to force server side pagination\n pageSizeOptions: [],\n showFirstLastPageButtons: false,\n pageSize: Number.MAX_SAFE_INTEGER,\n emptyRowsWhenPaging: false,\n }}\n onPageChange={page => {\n if (page > 0) {\n next?.();\n } else {\n prev?.();\n }\n }}\n components={{\n Toolbar: CatalogTableToolbar,\n }}\n /* this will enable the prev button accordingly */\n page={prev ? 1 : 0}\n /* this will enable the next button accordingly */\n totalCount={next ? Number.MAX_VALUE : Number.MAX_SAFE_INTEGER}\n localization={{ pagination: { labelDisplayedRows: '' } }}\n {...restProps}\n />\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TableColumn } from '@backstage/core-components';\nimport { columnFactories } from './columns';\nimport { CatalogTableColumnsFunc, CatalogTableRow } from './types';\n\n// The defaultCatalogTableColumnsFunc symbol is not directly exported, but through the\n// CatalogTable.defaultColumnsFunc field.\n/** @public */\nexport const defaultCatalogTableColumnsFunc: CatalogTableColumnsFunc = ({\n filters,\n entities,\n}) => {\n const showTypeColumn = filters.type === undefined;\n\n return [\n columnFactories.createTitleColumn({ hidden: true }),\n columnFactories.createNameColumn({ defaultKind: filters.kind?.value }),\n ...createEntitySpecificColumns(),\n ];\n\n function createEntitySpecificColumns(): TableColumn<CatalogTableRow>[] {\n const descriptionTagColumns = [\n columnFactories.createMetadataDescriptionColumn(),\n columnFactories.createTagsColumn(),\n ];\n const baseColumns = [\n columnFactories.createSystemColumn(),\n columnFactories.createOwnerColumn(),\n columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }),\n columnFactories.createSpecLifecycleColumn(),\n ];\n switch (filters.kind?.value) {\n case 'user':\n return [...descriptionTagColumns];\n case 'domain':\n case 'system':\n return [columnFactories.createOwnerColumn(), ...descriptionTagColumns];\n case 'group':\n case 'template':\n return [\n columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }),\n ...descriptionTagColumns,\n ];\n case 'location':\n return [\n columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }),\n columnFactories.createSpecTargetsColumn(),\n ];\n default:\n return entities.every(entity => entity.metadata.namespace === 'default')\n ? [...baseColumns, ...descriptionTagColumns]\n : [\n ...baseColumns,\n columnFactories.createNamespaceColumn(),\n ...descriptionTagColumns,\n ];\n }\n }\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport { default } from './plugin';\n\nexport { NfsDefaultCatalogPage as CatalogIndexPage } from '../components/CatalogPage';\nexport type { DefaultCatalogPageProps as CatalogIndexPageProps } from '../components/CatalogPage';\nexport type {\n CatalogTableRow,\n CatalogTableColumnsFunc,\n} from '../components/CatalogTable';\n\nimport { catalogTranslationRef as _catalogTranslationRef } from './translation';\n\n/**\n * @alpha\n * @deprecated Import from `@backstage/plugin-catalog` instead.\n */\nexport const catalogTranslationRef = _catalogTranslationRef;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ANNOTATION_EDIT_URL,\n ANNOTATION_VIEW_URL,\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n getEntityRelations,\n useEntityList,\n useStarredEntities,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport Typography from '@material-ui/core/Typography';\nimport { visuallyHidden } from '@mui/utils';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport { capitalize, sortBy } from 'lodash';\nimport pluralize from 'pluralize';\nimport { ReactNode, useMemo } from 'react';\nimport { columnFactories } from './columns';\nimport { CatalogTableColumnsFunc, CatalogTableRow } from './types';\nimport { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable';\nimport { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable';\nimport { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../alpha';\nimport { FavoriteToggleIcon } from '@backstage/core-components';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n /**\n * A static title to use for the table. If not provided, a title will be\n * generated based on the current Kind and Type filters and total number of items.\n */\n title?: string;\n subtitle?: string;\n}\n\nconst sortEntities = (entities: Entity[], api?: EntityPresentationApi) => {\n return sortBy(\n entities,\n e =>\n entityPresentationSnapshot(e, { defaultKind: 'Component' }, api)\n .primaryTitle,\n );\n};\n\n/**\n * CatalogTable is a wrapper around the Table component that is pre-configured\n * to display catalog entities.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/features/software-catalog/catalog-customization}\n *\n * @public\n */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const {\n columns = defaultCatalogTableColumnsFunc,\n tableOptions,\n subtitle,\n emptyContent,\n } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const entityListContext = useEntityList();\n\n const {\n loading,\n error,\n entities,\n filters,\n pageInfo,\n totalItems,\n paginationMode,\n } = entityListContext;\n\n // For non-paginated tables, only show the full loading indicator when\n // there's no data yet (initial load). During filter changes we keep stale\n // data visible and let the new results swap in seamlessly. For paginated\n // tables we always show loading, since stale data from a different page\n // would be misleading.\n const isLoading =\n paginationMode === 'none' ? loading && entities.length === 0 : loading;\n\n const tableColumns = useMemo(\n () =>\n typeof columns === 'function' ? columns(entityListContext) : columns,\n [columns, entityListContext],\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title={t('catalogTable.warningPanelTitle')}\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<CatalogTableRow>['actions'] = [\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_VIEW_URL];\n const title = t('catalogTable.viewActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <OpenInNew fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n const title = t('catalogTable.editActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <Edit fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n const title = isStarred\n ? t('catalogTable.unStarActionTitle')\n : t('catalogTable.starActionTitle');\n\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => <FavoriteToggleIcon isFavorite={isStarred} />,\n tooltip: title,\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n const currentKind = filters.kind?.label || '';\n const currentType = filters.type?.value || '';\n const currentCount = typeof totalItems === 'number' ? `(${totalItems})` : '';\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(\n filters.user?.value ?? t('catalogTable.allFilters'),\n );\n const titleText =\n props.title ||\n [titlePreamble, currentType, pluralize(currentKind), currentCount]\n .filter(s => s)\n .join(' ');\n const title =\n loading && !isLoading ? (\n <span\n style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5em' }}\n >\n {titleText}\n <CircularProgress size=\"0.8em\" data-testid=\"loading-indicator\" />\n </span>\n ) : (\n titleText\n );\n\n const actions = props.actions || defaultActions;\n const options: TableProps['options'] = {\n actionsColumnIndex: -1,\n loadingType: 'linear' as const,\n showEmptyDataSourceMessage: !isLoading,\n padding: 'dense' as const,\n ...tableOptions,\n };\n\n if (paginationMode === 'cursor') {\n return (\n <CursorPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n next={pageInfo?.next}\n prev={pageInfo?.prev}\n />\n );\n } else if (paginationMode === 'offset') {\n return (\n <OffsetPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n />\n );\n }\n\n const rows = sortEntities(entities, entityPresentationApi).map(e =>\n toEntityRow(e, entityPresentationApi),\n );\n const pageSize = 20;\n const showPagination = rows.length > pageSize;\n\n return (\n <Table<CatalogTableRow>\n isLoading={isLoading}\n columns={tableColumns}\n options={{\n paging: showPagination,\n pageSize: pageSize,\n pageSizeOptions: [20, 50, 100],\n ...options,\n }}\n title={title}\n data={rows}\n actions={actions}\n subtitle={subtitle}\n emptyContent={emptyContent}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\nCatalogTable.defaultColumnsFunc = defaultCatalogTableColumnsFunc;\n\nfunction toEntityRow(entity: Entity, api?: EntityPresentationApi) {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n // This name is here for backwards compatibility mostly; the\n // presentation of refs in the table should in general be handled with\n // EntityRefLink / EntityName components\n name: entityPresentationSnapshot(\n entity,\n { defaultKind: 'Component' },\n api,\n ).primaryTitle,\n entityRef: stringifyEntityRef(entity),\n ownedByRelationsTitle: ownedByRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'group' }, api)\n .primaryTitle,\n )\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'system' }, api)\n .primaryTitle,\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { HeaderPage } from '@backstage/ui';\nimport {\n CatalogFilterLayout,\n DefaultFilters,\n EntityListPagination,\n EntityListProvider,\n EntityOwnerPickerProps,\n UserListFilterKind,\n} from '@backstage/plugin-catalog-react';\nimport { ReactNode } from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable, CatalogTableRow } from '../CatalogTable';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogTableColumnsFunc } from '../CatalogTable/types';\nimport { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';\nimport { usePermission } from '@backstage/plugin-permission-react';\n\n/** @internal */\nexport type BaseCatalogPageProps = {\n filters: ReactNode;\n content?: ReactNode;\n pagination?: EntityListPagination;\n};\n\nfunction CatalogPageContent(props: BaseCatalogPageProps) {\n const { filters, content = <CatalogTable />, pagination } = props;\n\n return (\n <EntityListProvider pagination={pagination}>\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>{filters}</CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>{content}</CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </EntityListProvider>\n );\n}\n\n/** @internal */\nexport function BaseCatalogPage(props: BaseCatalogPageProps) {\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n const headerActions = (\n <>\n {allowed && (\n <CreateButton\n title={t('indexPage.createButtonTitle')}\n to={createComponentLink && createComponentLink()}\n />\n )}\n <SupportButton>{t('indexPage.supportButtonContent')}</SupportButton>\n </>\n );\n\n return (\n <PageWithHeader title={t('indexPage.title', { orgName })} themeId=\"home\">\n <Content>\n <ContentHeader title=\"\">{headerActions}</ContentHeader>\n <CatalogPageContent {...props} />\n </Content>\n </PageWithHeader>\n );\n}\n\nfunction NfsBaseCatalogPage(props: BaseCatalogPageProps) {\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n\n return (\n <>\n <HeaderPage\n title={t('indexPage.title', { orgName })}\n customActions={\n <>\n {allowed && (\n <CreateButton\n title={t('indexPage.createButtonTitle')}\n to={createComponentLink && createComponentLink()}\n />\n )}\n <SupportButton>{t('indexPage.supportButtonContent')}</SupportButton>\n </>\n }\n />\n <Content>\n <CatalogPageContent {...props} />\n </Content>\n </>\n );\n}\n\n/**\n * Props for root catalog pages.\n *\n * @public\n */\nexport interface DefaultCatalogPageProps {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n initialKind?: string;\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n filters?: ReactNode;\n initiallySelectedNamespaces?: string[];\n pagination?: EntityListPagination;\n}\n\nexport function DefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n } = props;\n\n return (\n <BaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n />\n );\n}\n\n/** @public */\nexport function NfsDefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n } = props;\n\n return (\n <NfsBaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n />\n );\n}\n"],"names":["useStyles","makeStyles","FavoriteToggleIcon","props","isFavorite","classes","Typography","StarIcon","UnstarredIcon","FavoriteToggle","id","title","value","onChange","iconButtonProps","Tooltip","IconButton","line","OverflowTooltip","theme","createStyles","SvgIcon","BootstrapInput","withStyles","InputBase","SelectComponent","multiple","items","label","placeholder","selected","triggerReset","native","disabled","margin","dataTestId","setValue","useState","isOpen","setOpen","useEffect","Box","FormControl","InputLabel","Select","event","previous","HTMLElement","s","selectedValue","item","el","Chip","CancelIcon","newValue","chip","OpenedDropdown","ClosedDropdown","MenuItem","Checkbox","useFilterStyles","Filters","onChangeFilters","t","useTranslationRef","coreComponentsTranslationRef","selectedFilters","setSelectedFilters","reset","Button","filter","TableLoadingBody","CircularProgress","tableIcons","forwardRef","ref","AddBox","Check","Clear","DeleteOutline","ChevronRight","Edit","SaveAlt","FilterList","FirstPage","LastPage","ChevronLeft","Search","ArrowUpward","Remove","ViewColumn","extractValueByField","data","field","path","i","undefined","StyledMTableHeader","MTableHeader","StyledMTableToolbar","MTableToolbar","useTableStyles","defaultInitialState","TableToolbar","toolbarProps","toolbarRef","setSearch","hasFilters","selectedFiltersLength","toggleFilters","filtersClasses","onSearchChanged","useCallback","searchText","Table","filterConfig","dataValue","columns","emptyContent","options","subtitle","localization","filters","initialState","onStateChange","components","loading","style","restProps","tableClasses","useTheme","calculatedInitialState","filtersOpen","setFiltersOpen","v","search","state","transform","result","key","isEqual","defaultState","getFieldByTitle","titleValue","tableData","useMemo","selectedFiltersArray","Object","filterValue","fieldValue","Array","Toolbar","hasNoRows","columnCount","Body","makeBody","bodyProps","MTableBody","distinctValues","addValue","Set","c","MTable","column","headerStyle","cellStyle","cellStyleFn","rowData","rowColumn","entityPresentationSnapshot","entityOrRef","context","entityPresentationApi","stringifyEntityRef","defaultEntityPresentation","BootstrapAutocomplete","Autocomplete","PopperComponent","Popper","TransitionProps","Grow","PaperComponent","Paper","CatalogAutocomplete","name","LabelProps","TextFieldProps","rest","renderInput","params","TextField","merge","autocomplete","ExpandMoreIcon","classNames","CatalogFilterLayout","Grid","isScreenSmallerThanBreakpoint","useMediaQuery","filterDrawerOpen","setFilterDrawerOpen","catalogReactTranslationRef","FilterListIcon","Drawer","icon","CheckBoxOutlineBlankIcon","checkedIcon","CheckBoxIcon","OptionCheckbox","EntityAutocompletePickerOption","memo","availableOptions","showCounts","FormControlLabel","EntityAutocompletePicker","Filter","InputProps","initialSelectedOptions","filtersForAvailableValues","hidden","updateFilters","queryParameter","useEntityList","catalogApi","useApi","catalogApiRef","availableValuesFilters","f","availableValues","useAsync","facets","reduceBackendCatalogFilters","Boolean","count","queryParameters","filteredOptions","selectedOptions","setSelectedOptions","shouldAddFilter","newSelectedOptions","String","_event","option","EntityKindPicker","availableKinds","kindsMap","allowedKinds","initialFilter","alertApi","alertApiRef","error","allKinds","selectedKind","setSelectedKind","useEntityKindFilter","opts","kindParameter","queryParamKind","useAllKinds","Map","kindFacets","kind","selectedKindLabel","EntityKindFilter","k","forcedKinds","EntityLifecyclePicker","EntityLifecycleFilter","EntityNamespacePicker","initiallySelectedNamespaces","EntityNamespaceFilter","FixedWidthFormControlLabel","_theme","RenderOptionLabel","isGroup","useEntityPresentation","GroupIcon","PersonIcon","EntityOwnerPicker","mode","apis","useApiHolder","entityPresentationApiRef","ownersParameter","text","setText","queryParamOwners","selectedOwners","setSelectedOwners","handleFetch","cache","useFetchEntities","initialSelectedOwnersRefs","isOwnersOnlyMode","queryEntitiesResponse","useAsyncFn","request","limit","cursorRequest","response","initialRequest","facetsEntitiesResponse","useFacetsEntities","enabled","facetsPromise","facet","e","namespace","parseEntityRef","a","b","start","isFacetsResponse","JSON","atob","filteredRefs","entity","normalizedText","end","encodeCursor","entities","payload","btoa","useSelectedOwners","allEntities","useRef","initialSelectedEntities","useMountEffect","entityRef","useDebouncedEffect","availableOwners","EntityOwnerFilter","o","_","owners","x","_e","inputValue","element","hasReachedEnd","Math","EntityProcessingStatusPicker","selectedAdvancedItems","setSelectedAdvancedItems","EntityOrphanFilter","EntityErrorFilter","EntityTableColumnTitle","translationKey","EntityTagPicker","EntityTagFilter","EntityTypePicker","availableTypes","selectedTypes","setSelectedTypes","useEntityTypeFilter","kindFilter","typeFilter","typeParameter","flattenedQueryTypes","setAvailableTypes","facetsRef","oldFacets","newTypes","sortBy","stillValidTypes","EntityTypeFilter","type","UserListPicker","availableFilters","alwaysKeepFilters","configApi","configApiRef","orgName","userParameter","userAndGroupFilterIds","filterGroups","getFilterGroups","SettingsIcon","filterGroup","ownedEntitiesCount","loadingOwnedEntities","ownedEntitiesFilter","useOwnedEntitiesCount","identityApi","identityApiRef","ownershipEntityRefs","loadingEntityRefs","user","allFilters","orderFields","catalogFilters","reduceCatalogFilters","compact","loadingEntityOwnership","fetchEntities","req","ownedClaims","getOwnedCountClaims","ownersRefs","commonOwnedBy","intersection","metadata","totalItems","useDeepCompareEffect","EntityUserFilter","allCount","useAllEntitiesCount","prevRequest","compacted","newRequest","starredEntitiesCount","starredEntitiesFilter","loadingStarredEntities","useStarredEntitiesCount","starredEntities","useStarredEntities","queryParamUserFilter","selectedUserFilter","setSelectedUserFilter","filterCounts","Card","group","Fragment","List","index","ListItemIcon","ListItemText","ListItemSecondaryAction","values","EntityTextFilter","words","exactMatch","partialMatch","word","m","fullRefs","err","getEntityRelations","RELATION_OWNED_BY","refs","starredEntityRefs","relations","UserListFilter","isOwnedEntity","isStarredEntity","orphan","NewEntityListContext","createVersionedContext","OldEntityListContext","createContext","EntityListProvider","isMounted","useMountedState","requestedFilters","setRequestedFilters","location","useLocation","paginationMode","paginationLimit","initialCursor","initialOffset","initialLimit","parsed","qs","queryLimit","Number","isNaN","offset","cursor","setCursor","setOffset","setLimit","outputState","setOutputState","resolvedValue","refresh","kindValue","adjustedFilters","entityFilter","reduceEntityFilters","backendFilter","previousBackendFilter","useDebounce","queryParams","oldParams","newParams","newUrl","window","document","update","prevFilters","newFilters","latestOutput","pageInfo","prevCursor","nextCursor","createVersionedValueMap","versionedHolder","useVersionedContext","oldContext","useContext","Error","getEntityRef","starredEntitiesApi","starredEntitiesApiRef","useObservable","toggleStarredEntity","isEntityTextFilter","isEntityOrderFilter","condensedFilters","compoundFilter","fullTextFilter","backendCatalogFilters","CreateButton","to","isXSScreen","RouterLink","AddCircleOutline","DefaultFilters","initialKind","initiallySelectedFilter","ownerPickerMode","columnFactories","formatContent","entity1","entity2","EntityRefLink","query","row","systemNames","resolved","EntityRefLinks","targets","keyLabel","labels","specifiedLabelValue","EntitySearchBar","textParameter","queryParamTextFilter","Input","InputAdornment","useToolbarStyles","CatalogTableToolbar","styles","OffsetPaginatedCatalogTable","page","setPage","CursorPaginatedCatalogTable","next","prev","defaultCatalogTableColumnsFunc","showTypeColumn","createEntitySpecificColumns","descriptionTagColumns","baseColumns","catalogTranslationRef","_catalogTranslationRef","CatalogTable","tableOptions","entityListContext","isLoading","tableColumns","WarningPanel","CodeSnippet","defaultActions","url","ANNOTATION_VIEW_URL","visuallyHidden","OpenInNew","ANNOTATION_EDIT_URL","isStarred","currentKind","currentType","currentCount","titlePreamble","capitalize","titleText","pluralize","actions","toEntityRow","rows","sortEntities","showPagination","api","partOfSystemRelations","RELATION_PART_OF","ownedByRelations","r","CatalogPageContent","content","pagination","NfsBaseCatalogPage","createComponentLink","useRouteRef","createComponentRouteRef","allowed","usePermission","catalogEntityCreatePermission","HeaderPage","SupportButton","Content","NfsDefaultCatalogPage"],"mappings":"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"}
1
+ {"version":3,"file":"static/4384.dc692f4f.chunk.js","sources":["webpack://techdocs-cli-embedded-app/../core-components/src/components/FavoriteToggle/FavoriteToggle.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/OverflowTooltip/OverflowTooltip.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/static/ClosedDropdown.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/static/OpenedDropdown.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/Select.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/Filters.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/TableLoadingBody.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/Table.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/apis/EntityPresentationApi/entityPresentationSnapshot.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/CatalogAutocomplete/CatalogAutocomplete.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityKindPicker/kindFilterUtils.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useFetchEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useQueryEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTable/TitleColumn.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useOwnedEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useAllEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useStarredEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/filters.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useEntityListProvider.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useStarredEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/utils/filters.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/CreateButton/CreateButton.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/DefaultFilters/DefaultFilters.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/columns.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CatalogTableToolbar.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CursorPaginatedCatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/index.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ComponentProps } from 'react';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport { StarIcon, UnstarredIcon } from '../../icons';\n\nconst useStyles = makeStyles<Theme>(\n () => ({\n icon: {\n color: '#f3ba37',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n iconBorder: {\n color: 'inherit',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n }),\n { name: 'BackstageFavoriteToggleIcon' },\n);\n\n/**\n * @public\n */\nexport type FavoriteToggleIconClassKey = 'icon' | 'iconBorder';\n\n/**\n * Icon used in FavoriteToggle component.\n *\n * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable}\n *\n * @public\n */\nexport function FavoriteToggleIcon(props: { isFavorite: boolean }) {\n const { isFavorite } = props;\n const classes = useStyles();\n\n return (\n <Typography\n component=\"span\"\n className={isFavorite ? classes.icon : classes.iconBorder}\n >\n {isFavorite ? <StarIcon /> : <UnstarredIcon />}\n </Typography>\n );\n}\n\n/**\n * Props for the {@link FavoriteToggle} component.\n *\n * @public\n */\nexport type FavoriteToggleProps = ComponentProps<typeof IconButton> & {\n id: string;\n title: string;\n isFavorite: boolean;\n onToggle: (value: boolean) => void;\n};\n\n/**\n * Toggle encapsulating logic for marking something as favorite,\n * primarily used in various instances of entity lists and cards but can be used elsewhere.\n *\n * This component can only be used in as a controlled toggle and does not keep internal state.\n *\n * @public\n */\nexport function FavoriteToggle(props: FavoriteToggleProps) {\n const {\n id,\n title,\n isFavorite: value,\n onToggle: onChange,\n ...iconButtonProps\n } = props;\n return (\n <Tooltip id={id} title={title}>\n <IconButton\n aria-label={title}\n id={id}\n onClick={() => onChange(!value)}\n color=\"inherit\"\n {...iconButtonProps}\n >\n <FavoriteToggleIcon isFavorite={value} />\n </IconButton>\n </Tooltip>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tooltip, { TooltipProps } from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\n\ntype Props = {\n text?: string | undefined;\n title?: TooltipProps['title'];\n line?: number | undefined;\n placement?: TooltipProps['placement'];\n tooltipClasses?: TooltipProps['classes'];\n};\n\nexport type OverflowTooltipClassKey = 'container';\n\nconst useStyles = makeStyles(\n {\n container: {\n overflow: 'visible !important',\n },\n typo: {\n fontSize: 'inherit',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: '-webkit-box',\n '-webkit-line-clamp': ({ line }: Props) => line || 1,\n '-webkit-box-orient': 'vertical',\n },\n },\n { name: 'BackstageOverflowTooltip' },\n);\n\nexport function OverflowTooltip(props: Props) {\n const classes = useStyles(props);\n\n return (\n <Tooltip\n title={props.title ?? (props.text || '')}\n placement={props.placement}\n classes={props.tooltipClasses}\n >\n <Typography className={classes.typo} variant=\"inherit\">\n {props.text}\n </Typography>\n </Tooltip>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\n/** @public */\nexport type ClosedDropdownClassKey = 'icon';\n\nconst useStyles = makeStyles(\n theme =>\n createStyles({\n icon: {\n position: 'absolute',\n right: theme.spacing(0.5),\n pointerEvents: 'none',\n color: '#616161',\n },\n }),\n { name: 'BackstageClosedDropdown' },\n);\n\nconst ClosedDropdown = () => {\n const classes = useStyles();\n return (\n <SvgIcon\n className={classes.icon}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7.5 8L6 9.5L12.0703 15.5703L18.1406 9.5L16.6406 8L12.0703 12.5703L7.5 8Z\"\n fill=\"currentColor\"\n />\n </SvgIcon>\n );\n};\n\nexport default ClosedDropdown;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\nexport type OpenedDropdownClassKey = 'icon';\n\nconst useStyles = makeStyles(\n theme =>\n createStyles({\n icon: {\n position: 'absolute',\n right: theme.spacing(0.5),\n pointerEvents: 'none',\n color: '#616161',\n },\n }),\n { name: 'BackstageOpenedDropdown' },\n);\n\nconst OpenedDropdown = () => {\n const classes = useStyles();\n return (\n <SvgIcon\n className={classes.icon}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M16.5 16L18 14.5L11.9297 8.42969L5.85938 14.5L7.35938 16L11.9297 11.4297L16.5 16Z\"\n fill=\"currentColor\"\n />\n </SvgIcon>\n );\n};\n\nexport default OpenedDropdown;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Chip from '@material-ui/core/Chip';\nimport FormControl from '@material-ui/core/FormControl';\nimport InputBase from '@material-ui/core/InputBase';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Select from '@material-ui/core/Select';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { ChangeEvent, useEffect, useState } from 'react';\n\nimport ClosedDropdown from './static/ClosedDropdown';\nimport OpenedDropdown from './static/OpenedDropdown';\n\n/** @public */\nexport type SelectInputBaseClassKey = 'root' | 'input';\n\nconst BootstrapInput = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {\n 'label + &': {\n marginTop: theme.spacing(3),\n },\n '&.Mui-focused > div[role=button]': {\n borderColor: theme.palette.primary.main,\n },\n },\n input: {\n borderRadius: theme.shape.borderRadius,\n position: 'relative',\n backgroundColor: theme.palette.background.paper,\n border: '1px solid #ced4da',\n fontSize: theme.typography.body1.fontSize,\n padding: theme.spacing(1.25, 3.25, 1.25, 1.5),\n transition: theme.transitions.create(['border-color', 'box-shadow']),\n '&:focus': {\n background: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n },\n },\n }),\n { name: 'BackstageSelectInputBase' },\n)(InputBase);\n\n/** @public */\nexport type SelectClassKey =\n | 'formControl'\n | 'label'\n | 'chips'\n | 'chip'\n | 'checkbox'\n | 'root';\n\nconst useStyles = makeStyles(\n (theme: Theme) =>\n createStyles({\n formControl: {\n margin: theme.spacing(1, 0),\n },\n label: {\n transform: 'initial',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '&.Mui-focused': {\n color: theme.palette.text.primary,\n },\n },\n formLabel: {\n transform: 'initial',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '&.Mui-focused': {\n color: theme.palette.text.primary,\n },\n },\n chips: {\n display: 'flex',\n flexWrap: 'wrap',\n },\n chip: {\n margin: 2,\n },\n checkbox: {},\n\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n }),\n { name: 'BackstageSelect' },\n);\n\n/** @public */\nexport type SelectItem = {\n label: string;\n value: string | number;\n};\n\n/** @public */\nexport type SelectedItems = string | string[] | number | number[];\n\nexport type SelectProps = {\n multiple?: boolean;\n items: SelectItem[];\n label: string;\n placeholder?: string;\n selected?: SelectedItems;\n onChange: (arg: SelectedItems) => void;\n triggerReset?: boolean;\n native?: boolean;\n disabled?: boolean;\n margin?: 'dense' | 'none';\n 'data-testid'?: string;\n};\n\n/** @public */\nexport function SelectComponent(props: SelectProps) {\n const {\n multiple,\n items,\n label,\n placeholder,\n selected,\n onChange,\n triggerReset,\n native = false,\n disabled = false,\n margin,\n 'data-testid': dataTestId = 'select',\n } = props;\n const classes = useStyles();\n const [value, setValue] = useState<SelectedItems>(\n selected || (multiple ? [] : ''),\n );\n const [isOpen, setOpen] = useState(false);\n\n useEffect(() => {\n setValue(multiple ? [] : '');\n }, [triggerReset, multiple]);\n\n useEffect(() => {\n setValue(selected || (multiple ? [] : ''));\n }, [selected, multiple]);\n\n const handleChange = (event: ChangeEvent<{ value: unknown }>) => {\n setValue(event.target.value as SelectedItems);\n onChange(event.target.value as SelectedItems);\n };\n\n const handleOpen = (event: ChangeEvent<any>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n setOpen(previous => {\n if (multiple && !(event.target instanceof HTMLElement)) {\n return true;\n }\n return !previous;\n });\n };\n\n const handleClose = () => {\n setOpen(false);\n };\n\n const handleDelete = (selectedValue: string | number) => () => {\n const newValue = (value as any[]).filter(chip => chip !== selectedValue);\n setValue(newValue);\n onChange(newValue);\n };\n\n return (\n <Box className={classes.root}>\n <FormControl className={classes.formControl}>\n <InputLabel className={classes.formLabel}>{label}</InputLabel>\n <Select\n aria-label={label}\n value={value}\n native={native}\n disabled={disabled}\n data-testid={dataTestId}\n displayEmpty\n multiple={multiple}\n margin={margin}\n onChange={handleChange}\n open={isOpen}\n onOpen={handleOpen}\n onClose={handleClose}\n input={<BootstrapInput />}\n label={label}\n renderValue={s =>\n multiple && (value as any[]).length !== 0 ? (\n <Box className={classes.chips}>\n {(s as string[]).map(selectedValue => {\n const item = items.find(el => el.value === selectedValue);\n return item ? (\n <Chip\n data-testid=\"chip\"\n key={item?.value}\n label={item?.label}\n clickable\n deleteIcon={\n <CancelIcon\n data-testid=\"cancel-icon\"\n onMouseDown={event => event.stopPropagation()}\n />\n }\n onDelete={handleDelete(selectedValue)}\n className={classes.chip}\n />\n ) : (\n false\n );\n })}\n </Box>\n ) : (\n <Typography>\n {(value as any[]).length === 0\n ? placeholder || ''\n : items.find(el => el.value === s)?.label}\n </Typography>\n )\n }\n IconComponent={() =>\n !isOpen ? <ClosedDropdown /> : <OpenedDropdown />\n }\n MenuProps={{\n anchorOrigin: {\n vertical: 'bottom',\n horizontal: 'left',\n },\n transformOrigin: {\n vertical: 'top',\n horizontal: 'left',\n },\n getContentAnchorEl: null,\n }}\n >\n {!!placeholder && !multiple && (\n <MenuItem value={[]}>{placeholder}</MenuItem>\n )}\n {native\n ? items &&\n items.map(item => (\n <option value={item.value} key={item.value}>\n {item.label}\n </option>\n ))\n : items &&\n items.map(item => (\n <MenuItem key={item.value} value={item.value}>\n {multiple && (\n <Checkbox\n color=\"primary\"\n checked={(value as any[]).includes(item.value) || false}\n className={classes.checkbox}\n />\n )}\n {item.label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useEffect, useState } from 'react';\n\nimport { Select } from '../Select';\nimport { SelectProps } from '../Select/Select';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport type TableFiltersClassKey = 'root' | 'value' | 'heder' | 'filters';\n\nconst useFilterStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n width: '315px',\n display: 'flex',\n flexDirection: 'column',\n marginRight: theme.spacing(3),\n },\n value: {\n fontWeight: 'bold',\n fontSize: 18,\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n height: theme.spacing(7.5),\n justifyContent: 'space-between',\n borderBottom: `1px solid ${theme.palette.grey[500]}`,\n },\n filters: {\n display: 'flex',\n flexDirection: 'column',\n '& > *': {\n marginTop: theme.spacing(2),\n },\n },\n }),\n { name: 'BackstageTableFilters' },\n);\n\nexport type Without<T, K> = Pick<T, Exclude<keyof T, K>>;\n\nexport type Filter = {\n type: 'select' | 'multiple-select';\n element: Without<SelectProps, 'onChange'>;\n};\n\nexport type SelectedFilters = {\n [key: string]: string | string[];\n};\n\ntype Props = {\n filters: Filter[];\n selectedFilters?: SelectedFilters;\n onChangeFilters: (arg: any) => any;\n};\n\nexport const Filters = (props: Props) => {\n const classes = useFilterStyles();\n\n const { onChangeFilters } = props;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const [selectedFilters, setSelectedFilters] = useState<SelectedFilters>({\n ...props.selectedFilters,\n });\n const [reset, triggerReset] = useState(false);\n\n // Trigger re-rendering\n const handleClick = () => {\n setSelectedFilters({});\n triggerReset(el => !el);\n };\n\n useEffect(() => {\n onChangeFilters(selectedFilters);\n }, [selectedFilters, onChangeFilters]);\n\n // As material table doesn't provide a way to add a column filter tab we will make our own filter logic\n return (\n <Box className={classes.root}>\n <Box className={classes.header}>\n <Box className={classes.value}>{t('table.filter.title')}</Box>\n <Button color=\"primary\" onClick={handleClick}>\n {t('table.filter.clearAll')}\n </Button>\n </Box>\n <Box className={classes.filters}>\n {props.filters?.length &&\n props.filters.map(filter => (\n <Select\n triggerReset={reset}\n key={filter.element.label}\n {...(filter.element as SelectProps)}\n selected={selectedFilters[filter.element.label]}\n onChange={el =>\n setSelectedFilters({\n ...selectedFilters,\n [filter.element.label]: el as any,\n })\n }\n />\n ))}\n </Box>\n </Box>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport CircularProgress from '@material-ui/core/CircularProgress';\n\n/**\n * @internal\n */\nexport function TableLoadingBody(props: { colSpan?: number }) {\n return (\n <tbody data-testid=\"loading-indicator\">\n <tr>\n <td colSpan={props.colSpan}>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n minHeight: '15rem',\n }}\n >\n <CircularProgress size=\"5rem\" />\n </Box>\n </td>\n </tr>\n </tbody>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport MTable, {\n Column,\n Icons,\n MaterialTableProps,\n MTableBody,\n MTableHeader,\n MTableToolbar,\n Options,\n} from '@material-table/core';\nimport Box from '@material-ui/core/Box';\nimport IconButton from '@material-ui/core/IconButton';\nimport {\n makeStyles,\n Theme,\n useTheme,\n withStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport AddBox from '@material-ui/icons/AddBox';\nimport ArrowUpward from '@material-ui/icons/ArrowUpward';\nimport Check from '@material-ui/icons/Check';\nimport ChevronLeft from '@material-ui/icons/ChevronLeft';\nimport ChevronRight from '@material-ui/icons/ChevronRight';\nimport Clear from '@material-ui/icons/Clear';\nimport DeleteOutline from '@material-ui/icons/DeleteOutline';\nimport Edit from '@material-ui/icons/Edit';\nimport FilterList from '@material-ui/icons/FilterList';\nimport Search from '@material-ui/icons/Search';\nimport FirstPage from '@material-ui/icons/FirstPage';\nimport LastPage from '@material-ui/icons/LastPage';\nimport Remove from '@material-ui/icons/Remove';\nimport SaveAlt from '@material-ui/icons/SaveAlt';\nimport ViewColumn from '@material-ui/icons/ViewColumn';\nimport { isEqual, transform } from 'lodash';\nimport {\n CSSProperties,\n forwardRef,\n MutableRefObject,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { SelectProps } from '../Select/Select';\nimport { Filter, Filters, SelectedFilters, Without } from './Filters';\nimport { TableLoadingBody } from './TableLoadingBody';\n\n// Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51\nconst tableIcons: Icons = {\n Add: forwardRef<SVGSVGElement>((props, ref) => (\n <AddBox {...props} ref={ref} />\n )),\n Check: forwardRef<SVGSVGElement>((props, ref) => (\n <Check {...props} ref={ref} />\n )),\n Clear: forwardRef<SVGSVGElement>((props, ref) => (\n <Clear {...props} ref={ref} />\n )),\n Delete: forwardRef<SVGSVGElement>((props, ref) => (\n <DeleteOutline {...props} ref={ref} />\n )),\n DetailPanel: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronRight {...props} ref={ref} />\n )),\n Edit: forwardRef<SVGSVGElement>((props, ref) => (\n <Edit {...props} ref={ref} />\n )),\n Export: forwardRef<SVGSVGElement>((props, ref) => (\n <SaveAlt {...props} ref={ref} />\n )),\n Filter: forwardRef<SVGSVGElement>((props, ref) => (\n <FilterList {...props} ref={ref} />\n )),\n FirstPage: forwardRef<SVGSVGElement>((props, ref) => (\n <FirstPage {...props} ref={ref} />\n )),\n LastPage: forwardRef<SVGSVGElement>((props, ref) => (\n <LastPage {...props} ref={ref} />\n )),\n NextPage: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronRight {...props} ref={ref} />\n )),\n PreviousPage: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronLeft {...props} ref={ref} />\n )),\n ResetSearch: forwardRef<SVGSVGElement>((props, ref) => (\n <Clear {...props} ref={ref} />\n )),\n Search: forwardRef<SVGSVGElement>((props, ref) => (\n <Search {...props} ref={ref} />\n )),\n SortArrow: forwardRef<SVGSVGElement>((props, ref) => (\n <ArrowUpward {...props} ref={ref} />\n )),\n ThirdStateCheck: forwardRef<SVGSVGElement>((props, ref) => (\n <Remove {...props} ref={ref} />\n )),\n ViewColumn: forwardRef<SVGSVGElement>((props, ref) => (\n <ViewColumn {...props} ref={ref} />\n )),\n};\n\n// TODO: Material table might already have such a function internally that we can use?\nfunction extractValueByField(data: any, field: string): any | undefined {\n const path = field.split('.');\n let value = data[path[0]];\n\n for (let i = 1; i < path.length; ++i) {\n if (value === undefined) {\n return value;\n }\n\n const f = path[i];\n value = value[f];\n }\n\n return value;\n}\n\nexport type TableHeaderClassKey = 'header';\n\nconst StyledMTableHeader = withStyles(\n theme => ({\n header: {\n padding: theme.spacing(1, 2, 1, 2.5),\n borderTop: `1px solid ${theme.palette.grey.A100}`,\n borderBottom: `1px solid ${theme.palette.grey.A100}`,\n // withStyles hasn't a generic overload for theme\n fontWeight: theme.typography.fontWeightBold,\n position: 'static',\n wordBreak: 'normal',\n textTransform: 'uppercase',\n },\n }),\n { name: 'BackstageTableHeader' },\n)(MTableHeader);\n\nexport type TableToolbarClassKey = 'root' | 'title' | 'searchField';\n\nconst StyledMTableToolbar = withStyles(\n theme => ({\n root: {\n padding: theme.spacing(3, 0, 2.5, 2.5),\n },\n title: {\n '& > h6': {\n fontWeight: theme.typography.fontWeightBold,\n },\n },\n searchField: {\n paddingRight: theme.spacing(2),\n },\n }),\n { name: 'BackstageTableToolbar' },\n)(MTableToolbar);\n\n/** @public */\nexport type FiltersContainerClassKey = 'root' | 'filterControls' | 'title';\n\nconst useFilterStyles = makeStyles(\n theme => ({\n root: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n },\n filterControls: {\n display: 'flex',\n alignItems: 'center',\n },\n title: {\n fontWeight: theme.typography.fontWeightBold,\n fontSize: 18,\n whiteSpace: 'nowrap',\n },\n }),\n { name: 'BackstageTableFiltersContainer' },\n);\n\nexport type TableClassKey = 'root';\n\nconst useTableStyles = makeStyles(\n () => ({\n root: {\n display: 'flex',\n alignItems: 'start',\n },\n }),\n { name: 'BackstageTable' },\n);\n\nfunction convertColumns<T extends object>(\n columns: TableColumn<T>[],\n theme: Theme,\n): TableColumn<T>[] {\n return columns.map(column => {\n const headerStyle: CSSProperties = column.headerStyle ?? {};\n\n let cellStyle = column.cellStyle || {};\n\n if (column.highlight) {\n headerStyle.color = theme.palette.textContrast;\n\n if (typeof cellStyle === 'object') {\n (cellStyle as CSSProperties).fontWeight =\n theme.typography.fontWeightBold;\n } else {\n const cellStyleFn = cellStyle as (\n data: any,\n rowData: T,\n column?: Column<T>,\n ) => CSSProperties;\n cellStyle = (data, rowData, rowColumn) => {\n const style = cellStyleFn(data, rowData, rowColumn);\n return { ...style, fontWeight: theme.typography.fontWeightBold };\n };\n }\n }\n\n return {\n ...column,\n headerStyle,\n cellStyle,\n };\n });\n}\n\nfunction removeDefaultValues(state: any, defaultState: any): any {\n return transform(state, (result, value, key) => {\n if (!isEqual(value, defaultState[key])) {\n result[key] = value;\n }\n });\n}\n\nconst defaultInitialState = {\n search: '',\n filtersOpen: false,\n filters: {},\n};\n\nexport interface TableColumn<T extends object = {}> extends Column<T> {\n highlight?: boolean;\n width?: string;\n}\n\nexport type TableFilter = {\n column: string;\n type: 'select' | 'multiple-select';\n};\n\nexport type TableState = {\n search?: string;\n filtersOpen?: boolean;\n filters?: SelectedFilters;\n};\n\nexport interface TableProps<T extends object = {}>\n extends MaterialTableProps<T> {\n columns: TableColumn<T>[];\n subtitle?: string;\n filters?: TableFilter[];\n initialState?: TableState;\n emptyContent?: ReactNode;\n isLoading?: boolean;\n onStateChange?: (state: TableState) => any;\n}\n\nexport interface TableOptions<T extends object = {}> extends Options<T> {}\n\nexport function TableToolbar(toolbarProps: {\n toolbarRef: MutableRefObject<any>;\n setSearch: (value: string) => void;\n onSearchChanged: (value: string) => void;\n toggleFilters: () => void;\n hasFilters: boolean;\n selectedFiltersLength: number;\n}) {\n const {\n toolbarRef,\n setSearch,\n hasFilters,\n selectedFiltersLength,\n toggleFilters,\n } = toolbarProps;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const filtersClasses = useFilterStyles();\n const onSearchChanged = useCallback(\n (searchText: string) => {\n toolbarProps.onSearchChanged(searchText);\n setSearch(searchText);\n },\n [toolbarProps, setSearch],\n );\n\n if (hasFilters) {\n return (\n <Box className={filtersClasses.root}>\n <Box className={filtersClasses.filterControls}>\n <IconButton onClick={toggleFilters} aria-label=\"filter list\">\n <FilterList />\n </IconButton>\n <Typography className={filtersClasses.title}>\n {t('table.filter.title')} ({selectedFiltersLength})\n </Typography>\n </Box>\n <StyledMTableToolbar\n {...toolbarProps}\n ref={toolbarRef}\n onSearchChanged={onSearchChanged}\n />\n </Box>\n );\n }\n\n return (\n <StyledMTableToolbar\n {...toolbarProps}\n ref={toolbarRef}\n onSearchChanged={onSearchChanged}\n />\n );\n}\n\n/**\n * @public\n */\nexport function Table<T extends object = {}>(props: TableProps<T>) {\n const {\n data,\n columns,\n emptyContent,\n options,\n title,\n subtitle,\n localization,\n filters,\n initialState,\n onStateChange,\n components,\n isLoading: loading,\n style,\n ...restProps\n } = props;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const tableClasses = useTableStyles();\n\n const theme = useTheme();\n\n const calculatedInitialState = { ...defaultInitialState, ...initialState };\n\n const [filtersOpen, setFiltersOpen] = useState(\n calculatedInitialState.filtersOpen,\n );\n const toggleFilters = useCallback(\n () => setFiltersOpen(v => !v),\n [setFiltersOpen],\n );\n\n const [selectedFilters, setSelectedFilters] = useState(\n calculatedInitialState.filters,\n );\n\n const [search, setSearch] = useState(calculatedInitialState.search);\n\n useEffect(() => {\n if (onStateChange) {\n const state = removeDefaultValues(\n {\n search,\n filtersOpen,\n filters: selectedFilters,\n },\n defaultInitialState,\n );\n\n onStateChange(state);\n }\n }, [search, filtersOpen, selectedFilters, onStateChange]);\n\n const getFieldByTitle = useCallback(\n (titleValue: string | keyof T) =>\n columns.find(el => el.title === titleValue)?.field,\n [columns],\n );\n\n const tableData = useMemo(() => {\n if (typeof data === 'function' || !selectedFilters) {\n return data;\n }\n\n const selectedFiltersArray = Object.values(selectedFilters);\n if (data && selectedFiltersArray.flat().length) {\n const newData = (data as any[]).filter(\n el =>\n !!Object.entries(selectedFilters)\n .filter(([, value]) => !!(value as { length?: number }).length)\n .every(([key, filterValue]) => {\n const fieldValue = extractValueByField(\n el,\n getFieldByTitle(key) as string,\n );\n\n if (Array.isArray(fieldValue) && Array.isArray(filterValue)) {\n return fieldValue.some(v => filterValue.includes(v));\n } else if (Array.isArray(fieldValue)) {\n return fieldValue.includes(filterValue);\n } else if (Array.isArray(filterValue)) {\n return filterValue.includes(fieldValue);\n }\n\n return fieldValue === filterValue;\n }),\n );\n return newData;\n }\n return data;\n }, [data, selectedFilters, getFieldByTitle]);\n\n const selectedFiltersLength = Object.values(selectedFilters).flat().length;\n\n const hasFilters = !!filters?.length;\n const Toolbar = useCallback(\n (toolbarProps: any /* no type for this in material-table */) => {\n return (\n <TableToolbar\n setSearch={setSearch}\n hasFilters={hasFilters}\n selectedFiltersLength={selectedFiltersLength}\n toggleFilters={toggleFilters}\n {...toolbarProps}\n />\n );\n },\n [toggleFilters, hasFilters, selectedFiltersLength, setSearch],\n );\n\n const hasNoRows = typeof data !== 'function' && data.length === 0;\n const columnCount = columns.length;\n const Body = useMemo(\n () => makeBody({ hasNoRows, emptyContent, columnCount, loading }),\n [hasNoRows, emptyContent, columnCount, loading],\n );\n\n return (\n <Box className={tableClasses.root}>\n {filtersOpen && data && typeof data !== 'function' && filters?.length && (\n <Filters\n filters={constructFilters(filters, data as any[], columns, t)}\n selectedFilters={selectedFilters}\n onChangeFilters={setSelectedFilters}\n />\n )}\n <MTable<T>\n components={{\n Header: StyledMTableHeader,\n Body,\n Toolbar,\n ...components,\n }}\n options={options}\n columns={convertColumns(columns, theme)}\n icons={tableIcons}\n title={\n <>\n <Typography variant=\"h5\" component=\"h2\">\n {title}\n </Typography>\n {subtitle && (\n <Typography color=\"textSecondary\" variant=\"body1\">\n {subtitle}\n </Typography>\n )}\n </>\n }\n data={tableData}\n style={{ width: '100%', ...style }}\n localization={{\n ...localization,\n body: {\n emptyDataSourceMessage: t('table.body.emptyDataSourceMessage'),\n ...localization?.body,\n },\n pagination: {\n firstTooltip: t('table.pagination.firstTooltip'),\n labelDisplayedRows: t('table.pagination.labelDisplayedRows'),\n labelRowsSelect: t('table.pagination.labelRowsSelect'),\n lastTooltip: t('table.pagination.lastTooltip'),\n nextTooltip: t('table.pagination.nextTooltip'),\n previousTooltip: t('table.pagination.previousTooltip'),\n ...localization?.pagination,\n },\n header: {\n actions: t('table.header.actions'),\n ...localization?.header,\n },\n toolbar: {\n searchPlaceholder: t('table.toolbar.search'),\n searchTooltip: t('table.toolbar.search'),\n ...localization?.toolbar,\n },\n }}\n {...restProps}\n />\n </Box>\n );\n}\n\nTable.icons = Object.freeze(tableIcons);\n\nfunction makeBody({\n columnCount,\n emptyContent,\n hasNoRows,\n loading,\n}: {\n hasNoRows: boolean;\n emptyContent: ReactNode;\n columnCount: number;\n loading?: boolean;\n}) {\n return (bodyProps: any /* no type for this in material-table */) => {\n if (loading) {\n return <TableLoadingBody colSpan={columnCount} />;\n }\n\n if (emptyContent && hasNoRows) {\n return (\n <tbody>\n <tr>\n <td colSpan={columnCount}>{emptyContent}</td>\n </tr>\n </tbody>\n );\n }\n\n return <MTableBody {...bodyProps} />;\n };\n}\n\nfunction constructFilters<T extends object>(\n filterConfig: TableFilter[],\n dataValue: any[] | undefined,\n columns: TableColumn<T>[],\n t: TranslationFunction<typeof coreComponentsTranslationRef.T>,\n): Filter[] {\n const extractDistinctValues = (field: string | keyof T): Set<any> => {\n const distinctValues = new Set<any>();\n const addValue = (value: any) => {\n if (value !== undefined && value !== null) {\n distinctValues.add(value);\n }\n };\n\n if (dataValue) {\n dataValue.forEach(el => {\n const value = extractValueByField(\n el,\n columns.find(c => c.title === field)?.field as string,\n );\n\n if (Array.isArray(value)) {\n (value as []).forEach(addValue);\n } else {\n addValue(value);\n }\n });\n }\n\n return distinctValues;\n };\n\n const constructSelect = (\n filter: TableFilter,\n ): Without<SelectProps, 'onChange'> => {\n return {\n placeholder: t('table.filter.placeholder'),\n label: filter.column,\n multiple: filter.type === 'multiple-select',\n items: [...extractDistinctValues(filter.column)].sort().map(value => ({\n label: value,\n value,\n })),\n };\n };\n\n return filterConfig.map(filter => ({\n type: filter.type,\n element: constructSelect(filter),\n }));\n}\n","/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CompoundEntityRef,\n Entity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n EntityPresentationApi,\n EntityRefPresentationSnapshot,\n} from './EntityPresentationApi';\nimport { defaultEntityPresentation } from './defaultEntityPresentation';\n\n/**\n * Returns a synchronous presentation snapshot for an entity in non-React\n * contexts.\n *\n * @remarks\n *\n * This is the synchronous, non-React counterpart to\n * {@link useEntityPresentation}. It handles `Entity`, `CompoundEntityRef`,\n * and string ref inputs uniformly, using the provided\n * {@link EntityPresentationApi} when available and falling back to\n * {@link defaultEntityPresentation} otherwise.\n *\n * Because this function is synchronous, it uses cached data from the\n * presentation API (via `.snapshot`). If the entity has been seen before,\n * the snapshot will contain the full resolved title; otherwise it falls\n * back to what can be extracted from the ref alone. This is the correct\n * trade-off for sort comparators, column factories, filter callbacks, and\n * data mappers where a synchronous return value is required.\n *\n * In async contexts such as data loaders where you can `await`, prefer\n * using the {@link EntityPresentationApi} directly via\n * `forEntity().promise` for the richest possible presentation.\n *\n * @public\n * @param entityOrRef - An entity, a compound entity ref, or a string entity ref.\n * @param context - Optional context that may affect the presentation.\n * @param entityPresentationApi - Optional presentation API instance. When not\n * provided, falls back to {@link defaultEntityPresentation}.\n */\nexport function entityPresentationSnapshot(\n entityOrRef: Entity | CompoundEntityRef | string,\n context?: { defaultKind?: string; defaultNamespace?: string },\n entityPresentationApi?: EntityPresentationApi,\n): EntityRefPresentationSnapshot {\n if (entityPresentationApi) {\n const ref =\n typeof entityOrRef === 'string' || 'metadata' in entityOrRef\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n return entityPresentationApi.forEntity(ref, context).snapshot;\n }\n return defaultEntityPresentation(entityOrRef, context);\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\n/**\n * Props for {@link CatalogAutocomplete}\n *\n * @public\n */\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\n/** @public */\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactNode, useState } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Theme, useTheme } from '@material-ui/core/styles';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport const Filters = (props: {\n children: ReactNode;\n options?: {\n drawerBreakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;\n drawerAnchor?: 'left' | 'right' | 'top' | 'bottom';\n };\n}) => {\n const isScreenSmallerThanBreakpoint = useMediaQuery(\n (theme: Theme) =>\n theme.breakpoints.down(props.options?.drawerBreakpoint ?? 'md'),\n { noSsr: true },\n );\n const theme = useTheme();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return isScreenSmallerThanBreakpoint ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n {t('catalogFilter.buttonTitle')}\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor={props.options?.drawerAnchor ?? 'left'}\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n {t('catalogFilter.title')}\n </Typography>\n {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const Content = (props: { children: ReactNode }) => {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const CatalogFilterLayout = (props: { children: ReactNode }) => {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.children}\n </Grid>\n );\n};\n\nCatalogFilterLayout.Filters = Filters;\nCatalogFilterLayout.Content = Content;\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { memo } from 'react';\n\ninterface Props {\n selected: boolean;\n value: string;\n availableOptions?: Record<string, number>;\n showCounts: boolean;\n}\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\nfunction OptionCheckbox({ selected }: { selected: boolean }) {\n return <Checkbox icon={icon} checkedIcon={checkedIcon} checked={selected} />;\n}\n\nexport const EntityAutocompletePickerOption = memo((props: Props) => {\n const { selected, value, availableOptions, showCounts } = props;\n const label = showCounts ? `${value} (${availableOptions?.[value]})` : value;\n\n return (\n <FormControlLabel\n control={<OptionCheckbox selected={selected} />}\n label={label}\n onClick={event => event.preventDefault()}\n />\n );\n});\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport { TextFieldProps } from '@material-ui/core/TextField';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils/filters';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\nimport { isEqual } from 'lodash';\n\n/** @public */\nexport type AllowedEntityFilters<T extends DefaultEntityFilters> = {\n [K in keyof T]-?: NonNullable<T[K]> extends EntityFilter & {\n values: string[];\n }\n ? K\n : never;\n}[keyof T];\n\n/** @public */\nexport type EntityAutocompletePickerProps<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n> = {\n label: string;\n name: Name;\n path: string;\n showCounts?: boolean;\n Filter: { new (values: string[]): NonNullable<T[Name]> };\n InputProps?: TextFieldProps;\n initialSelectedOptions?: string[];\n filtersForAvailableValues?: Array<keyof T>;\n hidden?: boolean;\n};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {\n textTransform: 'none',\n fontWeight: 'bold',\n },\n },\n { name: 'CatalogReactEntityAutocompletePicker' },\n);\n\n/** @public */\nexport function EntityAutocompletePicker<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n>(props: EntityAutocompletePickerProps<T, Name>) {\n const {\n label,\n name,\n path,\n showCounts,\n Filter,\n InputProps,\n initialSelectedOptions = [],\n filtersForAvailableValues = ['kind'],\n hidden,\n } = props;\n const classes = useStyles();\n\n const {\n updateFilters,\n filters,\n queryParameters: { [name]: queryParameter },\n } = useEntityList<T>();\n\n const catalogApi = useApi(catalogApiRef);\n const availableValuesFilters = filtersForAvailableValues.map(\n f => filters[f] as EntityFilter | undefined,\n );\n const { value: availableValues } = useAsync(async () => {\n const facet = path;\n const { facets } = await catalogApi.getEntityFacets({\n facets: [facet],\n filter: reduceBackendCatalogFilters(\n availableValuesFilters.filter(Boolean) as EntityFilter[],\n ),\n });\n\n return Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n }, [...availableValuesFilters]);\n\n const queryParameters = useMemo(\n () => [queryParameter].flat().filter(Boolean) as string[],\n [queryParameter],\n );\n\n const filteredOptions = (filters[name] as unknown as { values: string[] })\n ?.values;\n\n const [selectedOptions, setSelectedOptions] = useState(\n queryParameters.length\n ? queryParameters\n : filteredOptions ?? initialSelectedOptions,\n );\n\n // Set selected options on query parameter updates; this happens at initial page load and from\n // external updates to the page location\n useEffect(() => {\n if (queryParameters.length) {\n setSelectedOptions(queryParameters);\n }\n }, [queryParameters]);\n\n const availableOptions = Object.keys(availableValues ?? {});\n const shouldAddFilter = selectedOptions.length && availableOptions.length;\n\n // Update filter value when selectedOptions change\n useEffect(() => {\n updateFilters({\n [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined,\n } as Partial<T>);\n }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);\n\n // Update selected options when filter value changes\n useEffect(() => {\n if (!shouldAddFilter) return;\n\n const newSelectedOptions = filteredOptions ?? [];\n\n // Check value is actually different (not just a different reference) to prevent selectedOptions <> filters loop\n if (!isEqual(newSelectedOptions, selectedOptions)) {\n setSelectedOptions(newSelectedOptions);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Don't re-set filter value when selectedOptions changes\n }, [filteredOptions]);\n\n const filter = filters[name];\n if (\n (filter && typeof filter === 'object' && !('values' in filter)) ||\n !availableOptions.length\n ) {\n return null;\n }\n\n return hidden ? null : (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<string, true>\n multiple\n disableCloseOnSelect\n label={label}\n name={`${String(name)}-picker`}\n options={availableOptions}\n value={selectedOptions}\n TextFieldProps={InputProps}\n onChange={(_event: object, options: string[]) =>\n setSelectedOptions(options)\n }\n renderOption={(option, { selected }) => (\n <EntityAutocompletePickerOption\n selected={selected}\n value={option}\n availableOptions={availableValues}\n showCounts={!!showCounts}\n />\n )}\n />\n </Box>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Select } from '@backstage/core-components';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport { useEffect, useMemo, useState } from 'react';\nimport { EntityKindFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { filterKinds, useAllKinds } from './kindFilterUtils';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nfunction useEntityKindFilter(opts: { initialFilter: string }): {\n loading: boolean;\n error?: Error;\n allKinds: Map<string, string>;\n selectedKind: string;\n setSelectedKind: (kind: string) => void;\n} {\n const {\n filters,\n queryParameters: { kind: kindParameter },\n updateFilters,\n } = useEntityList();\n\n const queryParamKind = useMemo(\n () => [kindParameter].flat()[0],\n [kindParameter],\n );\n\n const [selectedKind, setSelectedKind] = useState(\n queryParamKind ?? filters.kind?.value ?? opts.initialFilter,\n );\n\n // Set selected kinds on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamKind) {\n setSelectedKind(queryParamKind);\n }\n }, [queryParamKind]);\n\n // Set selected kind from filters; this happens when the kind filter is\n // updated from another component\n useEffect(() => {\n if (filters.kind?.value) {\n setSelectedKind(filters.kind?.value);\n }\n }, [filters.kind]);\n\n const { allKinds, loading, error } = useAllKinds();\n const selectedKindLabel = allKinds.get(selectedKind) || selectedKind;\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind\n ? new EntityKindFilter(selectedKind, selectedKindLabel)\n : undefined,\n });\n }, [selectedKind, selectedKindLabel, updateFilters]);\n\n return {\n loading,\n error,\n allKinds,\n selectedKind,\n setSelectedKind,\n };\n}\n\n/**\n * Props for {@link EntityKindPicker}.\n *\n * @public\n */\nexport interface EntityKindPickerProps {\n /**\n * Entity kinds to show in the dropdown; by default all kinds are fetched from the catalog and\n * displayed.\n */\n allowedKinds?: string[];\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityKindPicker = (props: EntityKindPickerProps) => {\n const { allowedKinds, hidden, initialFilter = 'component' } = props;\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const alertApi = useApi(alertApiRef);\n\n const { error, allKinds, selectedKind, setSelectedKind } =\n useEntityKindFilter({\n initialFilter: initialFilter,\n });\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: t('entityKindPicker.errorMessage'),\n severity: 'error',\n });\n }\n }, [error, alertApi, t]);\n\n if (error) return null;\n\n const options = filterKinds(allKinds, allowedKinds, selectedKind);\n\n const items = [...options.entries()].map(([key, value]) => ({\n label: value,\n value: key,\n }));\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label={t('entityKindPicker.title')}\n items={items}\n selected={selectedKind.toLocaleLowerCase('en-US')}\n onChange={value => setSelectedKind(String(value))}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\n\n/**\n * Fetch and return all available kinds.\n */\nexport function useAllKinds(): {\n loading: boolean;\n error?: Error;\n allKinds: Map<string, string>;\n} {\n const catalogApi = useApi(catalogApiRef);\n\n const {\n error,\n loading,\n value: allKinds,\n } = useAsync(async () => {\n const { facets } = await catalogApi.getEntityFacets({ facets: ['kind'] });\n const kindFacets = (facets.kind ?? []).map(f => f.value);\n return new Map(\n kindFacets.map(kind => [kind.toLocaleLowerCase('en-US'), kind]),\n );\n }, [catalogApi]);\n\n return { loading, error, allKinds: allKinds ?? new Map() };\n}\n\n/**\n * Filter and capitalize accessible kinds.\n */\nexport function filterKinds(\n allKinds: Map<string, string>,\n allowedKinds?: string[],\n forcedKinds?: string,\n): Map<string, string> {\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n let availableKinds = Array.from(allKinds.keys());\n if (allowedKinds) {\n availableKinds = allowedKinds\n .map(k => k.toLocaleLowerCase('en-US'))\n .filter(k => allKinds.has(k));\n }\n\n const kindsMap = new Map(\n availableKinds.map(kind => [kind, allKinds.get(kind) || kind]),\n );\n\n if (forcedKinds && !kindsMap.has(forcedKinds)) {\n // this is the only time we set a label for a kind which is not properly capitalized\n kindsMap.set(forcedKinds.toLocaleLowerCase('en-US'), forcedKinds);\n }\n\n return kindsMap;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport { EntityLifecycleFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityLifecyclePickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n { name: 'CatalogReactEntityLifecyclePicker' },\n);\n\n/** @public */\nexport const EntityLifecyclePicker = (props: { initialFilter?: string[] }) => {\n const { initialFilter = [] } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityLifecyclePicker.title')}\n name=\"lifecycles\"\n path=\"spec.lifecycle\"\n Filter={EntityLifecycleFilter}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={initialFilter}\n />\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { EntityNamespaceFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityNamespacePickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n {\n name: 'CatalogReactEntityNamespacePicker',\n },\n);\n\n/**\n * Props for {@link EntityNamespacePicker}.\n *\n * @public\n */\nexport interface EntityNamespacePickerProps {\n initiallySelectedNamespaces?: string[];\n}\n\n/** @public */\nexport const EntityNamespacePicker = (props: EntityNamespacePickerProps) => {\n const { initiallySelectedNamespaces } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityNamespacePicker.title')}\n name=\"namespace\"\n path=\"metadata.namespace\"\n Filter={EntityNamespaceFilter}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={initiallySelectedNamespaces}\n />\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Typography from '@material-ui/core/Typography';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { MouseEvent, useEffect, useMemo, useState } from 'react';\nimport { useEntityList } from '../../hooks/useEntityListProvider';\nimport { EntityOwnerFilter } from '../../filters';\nimport { useDebouncedEffect } from '@react-hookz/web';\nimport PersonIcon from '@material-ui/icons/Person';\nimport GroupIcon from '@material-ui/icons/Group';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n} from '../../apis';\nimport { useFetchEntities } from './useFetchEntities';\nimport { withStyles } from '@material-ui/core/styles';\nimport { useEntityPresentation } from '../../apis';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\n\n/** @public */\nexport type CatalogReactEntityOwnerPickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {},\n input: {},\n fullWidth: { width: '100%' },\n boxLabel: {\n width: '100%',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n },\n },\n { name: 'CatalogReactEntityOwnerPicker' },\n);\n\n/** @public */\nexport type FixedWidthFormControlLabelClassKey = 'label' | 'root';\n\nconst FixedWidthFormControlLabel = withStyles(\n _theme => ({\n label: {\n width: '100%',\n },\n root: {\n width: '90%',\n },\n }),\n { name: 'FixedWidthFormControlLabel' },\n)(FormControlLabel);\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\n/**\n * @public\n */\nexport type EntityOwnerPickerProps = {\n mode?: 'owners-only' | 'all';\n};\n\nfunction RenderOptionLabel(props: { entity: Entity; isSelected: boolean }) {\n const classes = useStyles();\n const isGroup = props.entity.kind.toLocaleLowerCase('en-US') === 'group';\n const { primaryTitle: title } = useEntityPresentation(props.entity);\n return (\n <Box className={classes.fullWidth}>\n <FixedWidthFormControlLabel\n className={classes.fullWidth}\n control={\n <Checkbox\n icon={icon}\n checkedIcon={checkedIcon}\n checked={props.isSelected}\n />\n }\n onClick={event => event.preventDefault()}\n label={\n <Tooltip title={title}>\n <Box display=\"flex\" alignItems=\"center\">\n {isGroup ? (\n <GroupIcon fontSize=\"small\" />\n ) : (\n <PersonIcon fontSize=\"small\" />\n )}\n &nbsp;\n <Box className={classes.boxLabel}>\n <Typography noWrap>{title}</Typography>\n </Box>\n </Box>\n </Tooltip>\n }\n />\n </Box>\n );\n}\n\n/** @public */\nexport const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => {\n const classes = useStyles();\n const { mode = 'owners-only' } = props || {};\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const {\n updateFilters,\n filters,\n queryParameters: { owners: ownersParameter },\n } = useEntityList();\n\n const [text, setText] = useState('');\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const queryParamOwners = useMemo(\n () => [ownersParameter].flat().filter(Boolean) as string[],\n [ownersParameter],\n );\n\n const [selectedOwners, setSelectedOwners] = useState<string[]>(\n queryParamOwners.length ? queryParamOwners : filters.owners?.values ?? [],\n );\n\n const [{ value, loading }, handleFetch, cache] = useFetchEntities({\n mode,\n initialSelectedOwnersRefs: selectedOwners,\n });\n useDebouncedEffect(\n () => handleFetch({ text: text.toLocaleLowerCase('en-US') }),\n [text, handleFetch],\n 250,\n );\n\n const availableOwners = value?.items || [];\n\n // Set selected owners on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamOwners.length) {\n const filter = new EntityOwnerFilter(queryParamOwners);\n setSelectedOwners(filter.values);\n }\n }, [queryParamOwners]);\n\n useEffect(() => {\n updateFilters({\n owners: selectedOwners.length\n ? new EntityOwnerFilter(selectedOwners)\n : undefined,\n });\n }, [selectedOwners, updateFilters]);\n\n if (\n ['user', 'group'].includes(\n filters.kind?.value.toLocaleLowerCase('en-US') || '',\n )\n ) {\n return null;\n }\n\n return (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<Entity, true>\n label={t('entityOwnerPicker.title')}\n multiple\n disableCloseOnSelect\n loading={loading}\n options={availableOwners}\n value={selectedOwners as unknown as Entity[]}\n getOptionSelected={(o, v) => {\n if (typeof v === 'string') {\n return stringifyEntityRef(o) === v;\n }\n return o === v;\n }}\n getOptionLabel={o => {\n const entity =\n typeof o === 'string'\n ? cache.getEntity(o) ||\n parseEntityRef(o, {\n defaultKind: 'group',\n defaultNamespace: 'default',\n })\n : o;\n return entityPresentationSnapshot(\n entity,\n undefined,\n entityPresentationApi,\n ).primaryTitle;\n }}\n onChange={(_: object, owners) => {\n setText('');\n setSelectedOwners(\n owners.map(e => {\n const entityRef =\n typeof e === 'string' ? e : stringifyEntityRef(e);\n\n if (typeof e !== 'string') {\n cache.setEntity(e);\n }\n return entityRef;\n }),\n );\n }}\n filterOptions={x => x}\n renderOption={(entity, { selected }) => {\n return <RenderOptionLabel entity={entity} isSelected={selected} />;\n }}\n name=\"owner-picker\"\n onInputChange={(_e, inputValue) => {\n setText(inputValue);\n }}\n ListboxProps={{\n onScroll: (e: MouseEvent) => {\n const element = e.currentTarget;\n const hasReachedEnd =\n Math.abs(\n element.scrollHeight - element.clientHeight - element.scrollTop,\n ) < 1;\n\n if (hasReachedEnd && value?.cursor) {\n handleFetch({ items: value.items, cursor: value.cursor });\n }\n },\n 'data-testid': 'owner-picker-listbox',\n }}\n LabelProps={{ className: classes.label }}\n TextFieldProps={{ className: classes.input }}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useRef } from 'react';\nimport { useFacetsEntities } from './useFacetsEntities';\nimport { useQueryEntities } from './useQueryEntities';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../../api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { useMountEffect } from '@react-hookz/web';\n\nexport function useFetchEntities({\n mode,\n initialSelectedOwnersRefs,\n}: {\n mode: 'owners-only' | 'all';\n initialSelectedOwnersRefs: string[];\n}) {\n const isOwnersOnlyMode = mode === 'owners-only';\n const queryEntitiesResponse = useQueryEntities();\n const facetsEntitiesResponse = useFacetsEntities({\n enabled: isOwnersOnlyMode,\n });\n\n const [state, handleFetch] = isOwnersOnlyMode\n ? facetsEntitiesResponse\n : queryEntitiesResponse;\n\n return [\n state,\n handleFetch,\n useSelectedOwners({\n enabled: !isOwnersOnlyMode,\n initialSelectedOwnersRefs,\n }),\n ] as const;\n}\n\n/**\n * Hook used for storing the full entity of the specified owners\n * in order to display users and group using the information contained on each entity.\n * When a component is rendered for the first time, it loads the content of the entities\n * specified by `initialSelectedOwnersRefs` and export the `getEntity` and `setEntity`\n * utilities, used to retrieve and modify the owners.\n */\nfunction useSelectedOwners({\n enabled,\n initialSelectedOwnersRefs,\n}: {\n enabled: boolean;\n initialSelectedOwnersRefs: string[];\n}) {\n const allEntities = useRef<Record<string, Entity>>({});\n const catalogApi = useApi(catalogApiRef);\n\n const [, handleFetch] = useAsyncFn(async () => {\n const initialSelectedEntities = await catalogApi.getEntitiesByRefs({\n entityRefs: initialSelectedOwnersRefs,\n });\n initialSelectedEntities.items.forEach(e => {\n if (e) {\n allEntities.current[stringifyEntityRef(e)] = e;\n }\n });\n }, []);\n\n useMountEffect(() => {\n if (enabled && initialSelectedOwnersRefs.length > 0) {\n handleFetch();\n }\n });\n\n return {\n getEntity: (entityRef: string) => allEntities.current[entityRef],\n setEntity: (entity: Entity) => {\n allEntities.current[stringifyEntityRef(entity)] = entity;\n },\n };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../../api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { Entity } from '@backstage/catalog-model';\n\ntype QueryEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\nexport function useQueryEntities() {\n const catalogApi = useApi(catalogApiRef);\n return useAsyncFn(\n async (\n request: { text: string } | QueryEntitiesResponse,\n options?: { limit: number },\n ): Promise<QueryEntitiesResponse> => {\n const initialRequest = request as { text: string };\n const cursorRequest = request as QueryEntitiesResponse;\n const limit = options?.limit ?? 20;\n\n if (cursorRequest.cursor) {\n const response = await catalogApi.queryEntities({\n cursor: cursorRequest.cursor,\n limit,\n });\n return {\n cursor: response.pageInfo.nextCursor,\n items: [...cursorRequest.items, ...response.items],\n };\n }\n\n const response = await catalogApi.queryEntities({\n fullTextFilter: {\n term: initialRequest.text || '',\n fields: [\n 'metadata.name',\n 'kind',\n 'spec.profile.displayname',\n 'metadata.title',\n ],\n },\n filter: { kind: ['User', 'Group'] },\n orderFields: [{ field: 'metadata.name', order: 'asc' }],\n limit,\n });\n\n return {\n cursor: response.pageInfo.nextCursor,\n items: response.items,\n };\n },\n [],\n { loading: true },\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { catalogApiRef } from '../../api';\nimport { useState } from 'react';\nimport { Entity, parseEntityRef } from '@backstage/catalog-model';\n\ntype FacetsCursor = {\n start: number;\n text: string;\n};\n\ntype FacetsEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\ntype FacetsInitialRequest = {\n text: string;\n};\n\n/**\n * This hook asynchronously loads the entity owners using the facets endpoint.\n * EntityOwnerPicker uses this hook when mode=\"owners-only\" is passed as prop.\n * All the owners are kept internally in memory and rendered in batches once requested\n * by the frontend. The values returned by this hook are compatible with `useQueryEntities`\n * hook, which is also used by EntityOwnerPicker.\n * In this mode, the EntityOwnerPicker won't show detailed information of the owners.\n */\nexport function useFacetsEntities({ enabled }: { enabled: boolean }) {\n const catalogApi = useApi(catalogApiRef);\n\n const [facetsPromise] = useState(async () => {\n if (!enabled) {\n return [];\n }\n const facet = 'relations.ownedBy';\n\n return catalogApi\n .getEntityFacets({ facets: [facet] })\n .then(response =>\n response.facets[facet]\n .map(e => e.value)\n .map(ref => {\n const { kind, name, namespace } = parseEntityRef(ref);\n return {\n apiVersion: 'backstage.io/v1beta1',\n kind,\n metadata: { name, namespace },\n };\n })\n .sort(\n (a, b) =>\n a.kind.localeCompare(b.kind, 'en-US') ||\n a.metadata.namespace.localeCompare(\n b.metadata.namespace,\n 'en-US',\n ) ||\n a.metadata.name.localeCompare(b.metadata.name, 'en-US'),\n ),\n )\n .catch(() => []);\n });\n\n return useAsyncFn<\n (\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n options?: { limit?: number },\n ) => Promise<FacetsEntitiesResponse>\n >(\n async (request, options) => {\n const facets = await facetsPromise;\n\n if (!facets) {\n return {\n items: [],\n };\n }\n\n const limit = options?.limit ?? 20;\n\n const { text, start } = decodeCursor(request);\n const filteredRefs = facets.filter(e => filterEntity(text, e));\n const end = start + limit;\n return {\n items: filteredRefs.slice(0, end),\n ...encodeCursor({\n entities: filteredRefs,\n limit: end,\n payload: {\n text,\n start: end,\n },\n }),\n };\n },\n [facetsPromise],\n { loading: true, value: { items: [] } },\n );\n}\n\nfunction decodeCursor(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): FacetsCursor {\n if (isFacetsResponse(request) && request.cursor) {\n return JSON.parse(atob(request.cursor));\n }\n return {\n text: (request as FacetsInitialRequest).text || '',\n start: 0,\n };\n}\n\nfunction isFacetsResponse(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): request is FacetsEntitiesResponse {\n return !!(request as FacetsEntitiesResponse).cursor;\n}\n\nfunction encodeCursor({\n entities,\n limit,\n payload,\n}: {\n entities: Entity[];\n limit: number;\n payload: { text: string; start: number };\n}) {\n if (entities.length > limit) {\n return { cursor: btoa(JSON.stringify(payload)) };\n }\n return {};\n}\n\nfunction filterEntity(text: string, entity: Entity) {\n const normalizedText = text.trim();\n return (\n entity.kind.includes(normalizedText) ||\n entity.metadata.namespace?.includes(normalizedText) ||\n entity.metadata.name.includes(normalizedText)\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EntityErrorFilter, EntityOrphanFilter } from '../../filters';\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { useState } from 'react';\nimport { useEntityList } from '../../hooks';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\n\n/** @public */\nexport type CatalogReactEntityProcessingStatusPickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n root: {},\n input: {},\n label: {},\n },\n { name: 'CatalogReactEntityProcessingStatusPickerPicker' },\n);\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\n/** @public */\nexport const EntityProcessingStatusPicker = () => {\n const classes = useStyles();\n const { updateFilters } = useEntityList();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const [selectedAdvancedItems, setSelectedAdvancedItems] = useState<string[]>(\n [],\n );\n\n function orphanChange(value: boolean) {\n updateFilters({\n orphan: value ? new EntityOrphanFilter(value) : undefined,\n });\n }\n\n function errorChange(value: boolean) {\n updateFilters({\n error: value ? new EntityErrorFilter(value) : undefined,\n });\n }\n\n const availableAdvancedItems = ['Is Orphan', 'Has Error'];\n\n return (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<string, true>\n label={t('entityProcessingStatusPicker.title')}\n multiple\n disableCloseOnSelect\n options={availableAdvancedItems}\n value={selectedAdvancedItems}\n onChange={(_: object, value: string[]) => {\n setSelectedAdvancedItems(value);\n orphanChange(value.includes('Is Orphan'));\n errorChange(value.includes('Has Error'));\n }}\n renderOption={(option, { selected }) => (\n <FormControlLabel\n control={\n <Checkbox\n icon={icon}\n checkedIcon={checkedIcon}\n checked={selected}\n />\n }\n onClick={event => event.preventDefault()}\n label={option}\n />\n )}\n name=\"processing-status-picker\"\n LabelProps={{ className: classes.label }}\n TextFieldProps={{ className: classes.input }}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/**\n * @alpha\n */\nexport type EntityTableColumnTitleProps = {\n translationKey:\n | 'name'\n | 'system'\n | 'owner'\n | 'type'\n | 'lifecycle'\n | 'namespace'\n | 'description'\n | 'tags'\n | 'targets'\n | 'title'\n | 'label'\n | 'domain';\n};\n\n/**\n * @alpha\n */\nexport const EntityTableColumnTitle = ({\n translationKey,\n}: EntityTableColumnTitleProps) => {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return t(`entityTableColumnTitle.${translationKey}`);\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport { EntityTagFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker/EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityTagPickerClassKey = 'input';\n\n/** @public */\nexport type EntityTagPickerProps = {\n showCounts?: boolean;\n initialFilter?: string[];\n hidden?: boolean;\n};\n\nconst useStyles = makeStyles(\n { input: {} },\n { name: 'CatalogReactEntityTagPicker' },\n);\n\n/** @public */\nexport const EntityTagPicker = (props: EntityTagPickerProps) => {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityTagPicker.title')}\n name=\"tags\"\n path=\"metadata.tags\"\n Filter={EntityTagFilter}\n showCounts={props.showCounts}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={props.initialFilter ? props.initialFilter : []}\n hidden={props.hidden}\n />\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect } from 'react';\nimport Box from '@material-ui/core/Box';\nimport { useEntityTypeFilter } from '../../hooks/useEntityTypeFilter';\n\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Select } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Props for {@link EntityTypePicker}.\n *\n * @public\n */\nexport interface EntityTypePickerProps {\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityTypePicker = (props: EntityTypePickerProps) => {\n const { hidden, initialFilter } = props;\n const alertApi = useApi(alertApiRef);\n const { error, availableTypes, selectedTypes, setSelectedTypes } =\n useEntityTypeFilter();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: t('entityTypePicker.errorMessage'),\n severity: 'error',\n });\n }\n if (initialFilter) {\n setSelectedTypes([initialFilter]);\n }\n }, [error, alertApi, initialFilter, setSelectedTypes, t]);\n\n if (availableTypes.length === 0 || error) return null;\n\n availableTypes.sort((a, b) =>\n a.toLocaleLowerCase('en-US').localeCompare(b.toLocaleLowerCase('en-US')),\n );\n\n const items = [\n { value: 'all', label: t('entityTypePicker.optionAllTitle') },\n ...availableTypes.map((type: string) => ({\n value: type,\n label: type,\n })),\n ];\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label={t('entityTypePicker.title')}\n items={items}\n selected={(items.length > 1 ? selectedTypes[0] : undefined) ?? 'all'}\n onChange={value =>\n setSelectedTypes(value === 'all' ? [] : [String(value)])\n }\n />\n </Box>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport isEqual from 'lodash/isEqual';\nimport sortBy from 'lodash/sortBy';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../api';\nimport { useEntityList } from './useEntityListProvider';\nimport { EntityTypeFilter } from '../filters';\n\n/**\n * A hook built on top of `useEntityList` for enabling selection of valid `spec.type` values\n * based on the selected EntityKindFilter.\n * @public\n */\nexport function useEntityTypeFilter(): {\n loading: boolean;\n error?: Error;\n availableTypes: string[];\n selectedTypes: string[];\n setSelectedTypes: (types: string[]) => void;\n} {\n const catalogApi = useApi(catalogApiRef);\n const {\n filters: { kind: kindFilter, type: typeFilter },\n queryParameters: { type: typeParameter },\n updateFilters,\n } = useEntityList();\n\n const flattenedQueryTypes = useMemo(\n () => [typeParameter].flat().filter(Boolean) as string[],\n [typeParameter],\n );\n\n const [selectedTypes, setSelectedTypes] = useState(\n flattenedQueryTypes.length\n ? flattenedQueryTypes\n : typeFilter?.getTypes() ?? [],\n );\n\n // Set selected types on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (flattenedQueryTypes.length) {\n setSelectedTypes(flattenedQueryTypes);\n }\n }, [flattenedQueryTypes]);\n\n const [availableTypes, setAvailableTypes] = useState<string[]>([]);\n const kind = useMemo(() => kindFilter?.value, [kindFilter]);\n\n // Load all valid spec.type values straight from the catalogApi, paying attention to only the\n // kind filter for a complete list.\n const {\n error,\n loading,\n value: facets,\n } = useAsync(async () => {\n if (kind) {\n const items = await catalogApi\n .getEntityFacets({\n filter: { kind },\n facets: ['spec.type'],\n })\n .then(response => response.facets['spec.type'] || []);\n return items;\n }\n return [];\n }, [kind, catalogApi]);\n\n const facetsRef = useRef(facets);\n useEffect(() => {\n const oldFacets = facetsRef.current;\n facetsRef.current = facets;\n // Delay processing hook until kind and facets load updates have settled to generate list of types;\n // This prevents resetting the type filter due to saved type value from query params not matching the\n // empty set of type values while values are still being loaded; also only run this hook on changes\n // to facets\n if (loading || !kind || oldFacets === facets || !facets) {\n return;\n }\n\n // Sort by facet count descending, so the most common types appear on top\n const newTypes = [\n ...new Set(\n sortBy(facets, f => -f.count).map(f =>\n f.value.toLocaleLowerCase('en-US'),\n ),\n ),\n ];\n setAvailableTypes(newTypes);\n\n // Update type filter to only valid values when the list of available types has changed\n const stillValidTypes = selectedTypes.filter(value =>\n newTypes.includes(value),\n );\n if (!isEqual(selectedTypes, stillValidTypes)) {\n setSelectedTypes(stillValidTypes);\n }\n }, [loading, kind, selectedTypes, setSelectedTypes, facets]);\n\n useEffect(() => {\n updateFilters({\n type: selectedTypes.length\n ? new EntityTypeFilter(selectedTypes)\n : undefined,\n });\n }, [selectedTypes, updateFilters]);\n\n return {\n loading,\n error,\n availableTypes,\n selectedTypes,\n setSelectedTypes,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n configApiRef,\n IconComponent,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Card from '@material-ui/core/Card';\nimport List from '@material-ui/core/List';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport { StarIcon } from '@backstage/core-components';\nimport { Fragment, useEffect, useMemo, useState } from 'react';\nimport { EntityUserFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { UserListFilterKind } from '../../types';\nimport { useOwnedEntitiesCount } from './useOwnedEntitiesCount';\nimport { useAllEntitiesCount } from './useAllEntitiesCount';\nimport { useStarredEntitiesCount } from './useStarredEntitiesCount';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/** @public */\nexport type CatalogReactUserListPickerClassKey =\n | 'root'\n | 'title'\n | 'listIcon'\n | 'menuItem'\n | 'groupWrapper';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n backgroundColor: 'rgba(0, 0, 0, .11)',\n boxShadow: 'none',\n margin: theme.spacing(1, 0, 1, 0),\n },\n title: {\n margin: theme.spacing(1, 0, 0, 1),\n textTransform: 'uppercase',\n fontSize: 12,\n fontWeight: 'bold',\n },\n listIcon: {\n minWidth: 30,\n color: theme.palette.text.primary,\n },\n menuItem: {\n minHeight: theme.spacing(6),\n },\n groupWrapper: {\n margin: theme.spacing(1, 1, 2, 1),\n },\n }),\n { name: 'CatalogReactUserListPicker' },\n);\n\nexport type ButtonGroup = {\n name: string;\n items: {\n id: 'owned' | 'starred' | 'all';\n label: string;\n icon?: IconComponent;\n }[];\n};\n\nfunction getFilterGroups(\n orgName: string,\n t: TranslationFunction<typeof catalogReactTranslationRef.T>,\n): ButtonGroup[] {\n return [\n {\n name: t('userListPicker.personalFilter.title'),\n items: [\n {\n id: 'owned',\n label: t('userListPicker.personalFilter.ownedLabel'),\n icon: SettingsIcon,\n },\n {\n id: 'starred',\n label: t('userListPicker.personalFilter.starredLabel'),\n icon: StarIcon,\n },\n ],\n },\n {\n name: orgName,\n items: [\n {\n id: 'all',\n label: t('userListPicker.orgFilterAllLabel'),\n },\n ],\n },\n ];\n}\n\n/** @public */\nexport type UserListPickerProps = {\n initialFilter?: UserListFilterKind;\n availableFilters?: UserListFilterKind[];\n hidden?: boolean;\n alwaysKeepFilters?: boolean;\n};\n\n/** @public */\nexport const UserListPicker = (props: UserListPickerProps) => {\n const { initialFilter, availableFilters, hidden, alwaysKeepFilters } = props;\n const classes = useStyles();\n const configApi = useApi(configApiRef);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n const orgName =\n configApi.getOptionalString('organization.name') ??\n t('userListPicker.defaultOrgName');\n const {\n filters,\n updateFilters,\n queryParameters: { user: userParameter },\n } = useEntityList();\n const kindParameter = filters.kind?.value?.toLowerCase();\n\n // Remove group items that aren't in availableFilters and exclude\n // any now-empty groups.\n const userAndGroupFilterIds = ['starred', 'all'];\n const filterGroups = getFilterGroups(orgName, t)\n .map(filterGroup => ({\n ...filterGroup,\n items: filterGroup.items.filter(({ id }) =>\n // TODO: avoid hardcoding kinds here\n ['group', 'user'].some(kind => kind === kindParameter)\n ? userAndGroupFilterIds.includes(id)\n : !availableFilters || availableFilters.includes(id),\n ),\n }))\n .filter(({ items }) => !!items.length);\n\n const {\n count: ownedEntitiesCount,\n loading: loadingOwnedEntities,\n filter: ownedEntitiesFilter,\n } = useOwnedEntitiesCount();\n const { count: allCount } = useAllEntitiesCount();\n const {\n count: starredEntitiesCount,\n filter: starredEntitiesFilter,\n loading: loadingStarredEntities,\n } = useStarredEntitiesCount();\n\n const queryParamUserFilter = useMemo(\n () => [userParameter].flat()[0],\n [userParameter],\n );\n\n const [selectedUserFilter, setSelectedUserFilter] = useState(\n (queryParamUserFilter as UserListFilterKind) ?? initialFilter,\n );\n\n const filterCounts = useMemo(() => {\n return {\n all: allCount,\n starred: starredEntitiesCount,\n owned: ownedEntitiesCount,\n };\n }, [starredEntitiesCount, ownedEntitiesCount, allCount]);\n\n // Set selected user filter on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamUserFilter) {\n setSelectedUserFilter(queryParamUserFilter as UserListFilterKind);\n }\n }, [queryParamUserFilter]);\n\n const loading = loadingOwnedEntities || loadingStarredEntities;\n\n useEffect(() => {\n if (\n !loading &&\n !!selectedUserFilter &&\n selectedUserFilter !== 'all' &&\n filterCounts[selectedUserFilter] === 0 &&\n !alwaysKeepFilters\n ) {\n setSelectedUserFilter('all');\n }\n }, [\n loading,\n filterCounts,\n selectedUserFilter,\n setSelectedUserFilter,\n alwaysKeepFilters,\n ]);\n\n useEffect(() => {\n if (!selectedUserFilter) {\n return;\n }\n if (loading) {\n return;\n }\n\n const getFilter = () => {\n if (selectedUserFilter === 'owned') {\n return ownedEntitiesFilter;\n }\n if (selectedUserFilter === 'starred') {\n return starredEntitiesFilter;\n }\n return EntityUserFilter.all();\n };\n\n updateFilters({ user: getFilter() });\n }, [\n selectedUserFilter,\n starredEntitiesFilter,\n ownedEntitiesFilter,\n updateFilters,\n\n loading,\n ]);\n\n return hidden ? null : (\n <Card className={classes.root}>\n {filterGroups.map(group => (\n <Fragment key={group.name}>\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n className={classes.title}\n >\n {group.name}\n </Typography>\n <Card className={classes.groupWrapper}>\n <List disablePadding dense role=\"menu\" aria-label={group.name}>\n {group.items.map((item, index) => (\n <MenuItem\n role=\"none presentation\"\n key={item.id}\n divider={index !== group.items.length - 1}\n onClick={() => setSelectedUserFilter(item.id)}\n selected={item.id === filters.user?.value}\n className={classes.menuItem}\n disabled={filterCounts[item.id] === 0}\n data-testid={`user-picker-${item.id}`}\n tabIndex={0}\n ContainerProps={{ role: 'menuitem' }}\n >\n {item.icon && (\n <ListItemIcon className={classes.listIcon}>\n <item.icon fontSize=\"small\" />\n </ListItemIcon>\n )}\n <ListItemText>\n <Typography variant=\"body1\">{item.label} </Typography>\n </ListItemText>\n <ListItemSecondaryAction>\n {filterCounts[item.id] ?? '-'}\n </ListItemSecondaryAction>\n </MenuItem>\n ))}\n </List>\n </Card>\n </Fragment>\n ))}\n </Card>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\nimport { compact, intersection } from 'lodash';\nimport { useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityOwnerFilter, EntityUserFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { CatalogFilters, reduceCatalogFilters } from '../../utils/filters';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDeepCompareEffect from 'react-use/esm/useDeepCompareEffect';\n\nexport function useOwnedEntitiesCount() {\n const identityApi = useApi(identityApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n const { filters } = useEntityList();\n\n const { value: ownershipEntityRefs, loading: loadingEntityRefs } = useAsync(\n async () => (await identityApi.getBackstageIdentity()).ownershipEntityRefs,\n // load only on mount\n [],\n );\n\n const { user, owners, ...allFilters } = filters;\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(\n compact(Object.values(allFilters)),\n );\n\n const [{ value: count, loading: loadingEntityOwnership }, fetchEntities] =\n useAsyncFn(\n async (req: {\n ownershipEntityRefs: string[];\n owners: EntityOwnerFilter | undefined;\n filter: CatalogFilters;\n }) => {\n const ownedClaims = getOwnedCountClaims(\n req.owners,\n req.ownershipEntityRefs,\n );\n if (ownedClaims === undefined) {\n // this implicitly means that there aren't claims in common with\n // the logged in users, so avoid invoking the queryEntities endpoint\n // which will implicitly returns 0\n return 0;\n }\n\n const { ['metadata.name']: metadata, ...filter } = req.filter.filter;\n\n const { totalItems } = await catalogApi.queryEntities({\n ...req.filter,\n filter: {\n ...filter,\n 'relations.ownedBy': ownedClaims,\n },\n limit: 0,\n });\n return totalItems;\n },\n [],\n { loading: true },\n );\n\n useDeepCompareEffect(() => {\n // context contains no filter, wait\n if (Object.keys(catalogFilters.filter).length === 0) {\n return;\n }\n // ownershipEntityRefs is loading, wait\n if (ownershipEntityRefs === undefined) {\n return;\n }\n fetchEntities({\n ownershipEntityRefs,\n owners,\n filter: catalogFilters,\n });\n }, [ownershipEntityRefs, owners, catalogFilters]);\n\n const loading = loadingEntityRefs || loadingEntityOwnership;\n\n return {\n count,\n loading,\n filter: useMemo(\n () => EntityUserFilter.owned(ownershipEntityRefs ?? []),\n [ownershipEntityRefs],\n ),\n ownershipEntityRefs,\n };\n}\n\nfunction getOwnedCountClaims(\n owners: EntityOwnerFilter | undefined,\n ownershipEntityRefs: string[] | undefined,\n) {\n if (ownershipEntityRefs === undefined) {\n return undefined;\n }\n const ownersRefs = owners?.values ?? [];\n if (ownersRefs.length) {\n const commonOwnedBy = intersection(ownersRefs, ownershipEntityRefs);\n if (commonOwnedBy.length === 0) {\n return undefined;\n }\n return commonOwnedBy;\n }\n return ownershipEntityRefs;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { QueryEntitiesInitialRequest } from '@backstage/catalog-client';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport { useMemo, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { useEntityList } from '../../hooks';\nimport { reduceCatalogFilters } from '../../utils/filters';\n\nexport function useAllEntitiesCount() {\n const catalogApi = useApi(catalogApiRef);\n const { filters } = useEntityList();\n\n const prevRequest = useRef<QueryEntitiesInitialRequest>();\n const request = useMemo(() => {\n const { user, ...allFilters } = filters;\n const compacted = compact(Object.values(allFilters));\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(compacted);\n const newRequest: QueryEntitiesInitialRequest = {\n ...catalogFilters,\n limit: 0,\n };\n\n if (Object.keys(catalogFilters.filter).length === 0) {\n prevRequest.current = undefined;\n return prevRequest.current;\n }\n\n if (isEqual(newRequest, prevRequest.current)) {\n return prevRequest.current;\n }\n prevRequest.current = newRequest;\n return newRequest;\n }, [filters]);\n\n const { value: count, loading } = useAsync(async () => {\n if (request === undefined) {\n return 0;\n }\n const { totalItems } = await catalogApi.queryEntities(request);\n\n return totalItems;\n }, [request]);\n\n return { count, loading };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { QueryEntitiesInitialRequest } from '@backstage/catalog-client';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport { useMemo, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityUserFilter } from '../../filters';\nimport { useEntityList, useStarredEntities } from '../../hooks';\nimport { reduceCatalogFilters } from '../../utils/filters';\n\nexport function useStarredEntitiesCount() {\n const catalogApi = useApi(catalogApiRef);\n const { filters } = useEntityList();\n const { starredEntities } = useStarredEntities();\n\n const prevRequest = useRef<QueryEntitiesInitialRequest>();\n const request = useMemo(() => {\n const { user, ...allFilters } = filters;\n const compacted = compact(Object.values(allFilters));\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(compacted);\n\n const facet = 'metadata.name';\n\n const newRequest: QueryEntitiesInitialRequest = {\n ...catalogFilters,\n filter: {\n ...catalogFilters.filter,\n /**\n * here we are filtering entities by `name`. Given this filter,\n * the response might contain more entities than expected, in case multiple entities\n * of different kind or namespace share the same name. Those extra entities are filtered out\n * client side by `EntityUserFilter`, so they won't be visible to the user.\n */\n [facet]: Array.from(starredEntities).map(e => parseEntityRef(e).name),\n },\n /**\n * limit is set to a high value as we are not expecting many starred entities\n */\n limit: 1000,\n };\n if (isEqual(newRequest, prevRequest.current)) {\n return prevRequest.current;\n }\n prevRequest.current = newRequest;\n\n return newRequest;\n }, [filters, starredEntities]);\n\n const { value: count, loading } = useAsync(async () => {\n if (!starredEntities.size) {\n return 0;\n }\n\n /**\n * given a list of starred entity refs and some filters coming from CatalogPage,\n * it reduces the list of starred entities, to a list of entities that matches the\n * provided filters. It won't be possible to getEntitiesByRefs\n * as the method doesn't accept any filter.\n */\n const response = await catalogApi.queryEntities(request);\n\n return response.items\n .map(e =>\n stringifyEntityRef({\n kind: e.kind,\n namespace: e.metadata.namespace,\n name: e.metadata.name,\n }),\n )\n .filter(e => starredEntities.has(e)).length;\n }, [request, starredEntities]);\n\n const filter = useMemo(\n () => EntityUserFilter.starred(Array.from(starredEntities)),\n [starredEntities],\n );\n\n return { count, loading, filter };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n parseEntityRef,\n RELATION_OWNED_BY,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport { EntityFilter, UserListFilterKind } from './types';\nimport { getEntityRelations } from './utils/getEntityRelations';\nimport { EntityOrderQuery } from '@backstage/catalog-client';\n\n/**\n * Filter entities based on Kind.\n * @public\n */\nexport class EntityKindFilter implements EntityFilter {\n readonly value: string;\n readonly label: string;\n\n constructor(value: string, label: string) {\n this.value = value;\n this.label = label;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { kind: this.value };\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based on type\n * @public\n */\nexport class EntityTypeFilter implements EntityFilter {\n readonly value: string | string[];\n\n constructor(value: string | string[]) {\n this.value = value;\n }\n\n // Simplify `string | string[]` for consumers, always returns an array\n getTypes(): string[] {\n return Array.isArray(this.value) ? this.value : [this.value];\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'spec.type': this.getTypes() };\n }\n\n toQueryValue(): string[] {\n return this.getTypes();\n }\n}\n\n/**\n * Filters entities based on tag.\n * @public\n */\nexport class EntityTagFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.every(v => (entity.metadata.tags ?? []).includes(v));\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'metadata.tags': this.values };\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities where the text matches spec, title or tags.\n * @public\n */\nexport class EntityTextFilter implements EntityFilter {\n readonly value: string;\n\n constructor(value: string) {\n this.value = value;\n }\n\n filterEntity(entity: Entity): boolean {\n const words = this.toUpperArray(this.value.split(/\\s/));\n const exactMatch = this.toUpperArray([entity.metadata.tags]);\n const partialMatch = this.toUpperArray([\n entity.metadata.name,\n entity.metadata.title,\n (entity.spec?.profile as { displayName?: string })?.displayName,\n ]);\n\n for (const word of words) {\n if (\n exactMatch.every(m => m !== word) &&\n partialMatch.every(m => !m.includes(word))\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n getFullTextFilters() {\n return {\n term: this.value,\n // Update this to be more dynamic based on table columns.\n fields: ['metadata.name', 'metadata.title', 'spec.profile.displayName'],\n };\n }\n\n toQueryValue() {\n return this.value;\n }\n\n private toUpperArray(\n value: Array<string | string[] | undefined>,\n ): Array<string> {\n return value\n .flat()\n .filter((m): m is string => Boolean(m))\n .map(m => m.toLocaleUpperCase('en-US'));\n }\n}\n\n/**\n * Filter matching entities that are owned by group.\n * @public\n *\n * CAUTION: This class may contain both full and partial entity refs.\n */\nexport class EntityOwnerFilter implements EntityFilter {\n readonly values: string[];\n constructor(values: string[]) {\n this.values = values.reduce((fullRefs, ref) => {\n // Attempt to remove bad entity references here.\n try {\n fullRefs.push(\n stringifyEntityRef(parseEntityRef(ref, { defaultKind: 'Group' })),\n );\n return fullRefs;\n } catch (err) {\n return fullRefs;\n }\n }, [] as string[]);\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'relations.ownedBy': this.values };\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.some(v =>\n getEntityRelations(entity, RELATION_OWNED_BY).some(\n o => stringifyEntityRef(o) === v,\n ),\n );\n }\n\n /**\n * Get the URL query parameter value. May be a mix of full and humanized entity refs.\n * @returns list of entity refs.\n */\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities on lifecycle.\n * @public\n */\nexport class EntityLifecycleFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'spec.lifecycle': this.values };\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.some(v => entity.spec?.lifecycle === v);\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities to those within the given namespace(s).\n * @public\n */\nexport class EntityNamespaceFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'metadata.namespace': this.values };\n }\n filterEntity(entity: Entity): boolean {\n return this.values.some(v => entity.metadata.namespace === v);\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * @public\n */\nexport class EntityUserFilter implements EntityFilter {\n readonly value: UserListFilterKind;\n readonly refs?: string[];\n\n private constructor(value: UserListFilterKind, refs?: string[]) {\n this.value = value;\n this.refs = refs;\n }\n\n static owned(ownershipEntityRefs: string[]) {\n return new EntityUserFilter('owned', ownershipEntityRefs);\n }\n\n static all() {\n return new EntityUserFilter('all');\n }\n\n static starred(starredEntityRefs: string[]) {\n return new EntityUserFilter('starred', starredEntityRefs);\n }\n\n getCatalogFilters(): Record<string, string[]> {\n if (this.value === 'owned') {\n return { 'relations.ownedBy': this.refs ?? [] };\n }\n if (this.value === 'starred') {\n return {\n 'metadata.name': this.refs?.map(e => parseEntityRef(e).name) ?? [],\n };\n }\n return {};\n }\n\n filterEntity(entity: Entity) {\n if (this.value === 'starred') {\n return this.refs?.includes(stringifyEntityRef(entity)) ?? true;\n }\n // used only for retro-compatibility with non paginated data.\n // This is supposed to return always true for paginated\n // owned entities, since the filters are applied server side.\n if (this.value === 'owned') {\n const relations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return (\n this.refs?.some(v =>\n relations.some(o => stringifyEntityRef(o) === v),\n ) ?? false\n );\n }\n return true;\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based on whatever the user has starred or owns them.\n * @deprecated use EntityUserFilter\n * @public\n */\nexport class UserListFilter implements EntityFilter {\n readonly value: UserListFilterKind;\n readonly isOwnedEntity: (entity: Entity) => boolean;\n readonly isStarredEntity: (entity: Entity) => boolean;\n\n constructor(\n value: UserListFilterKind,\n isOwnedEntity: (entity: Entity) => boolean,\n isStarredEntity: (entity: Entity) => boolean,\n ) {\n this.value = value;\n this.isOwnedEntity = isOwnedEntity;\n this.isStarredEntity = isStarredEntity;\n }\n\n filterEntity(entity: Entity): boolean {\n switch (this.value) {\n case 'owned':\n return this.isOwnedEntity(entity);\n case 'starred':\n return this.isStarredEntity(entity);\n default:\n return true;\n }\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based if it is an orphan or not.\n * @public\n */\nexport class EntityOrphanFilter implements EntityFilter {\n readonly value: boolean;\n\n constructor(value: boolean) {\n this.value = value;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n if (this.value) {\n return { 'metadata.annotations.backstage.io/orphan': String(this.value) };\n }\n return {};\n }\n\n filterEntity(entity: Entity): boolean {\n const orphan = entity.metadata.annotations?.['backstage.io/orphan'];\n return orphan !== undefined && this.value.toString() === orphan;\n }\n}\n\n/**\n * Filters entities based on if it has errors or not.\n * @public\n */\nexport class EntityErrorFilter implements EntityFilter {\n readonly value: boolean;\n\n constructor(value: boolean) {\n this.value = value;\n }\n\n filterEntity(entity: Entity): boolean {\n const error =\n ((entity as AlphaEntity)?.status?.items?.length as number) > 0;\n return error !== undefined && this.value === error;\n }\n}\n\n/**\n * Sort entities by a given field/column.\n * @public\n */\nexport class EntityOrderFilter implements EntityFilter {\n readonly values: [string, 'asc' | 'desc'][];\n\n constructor(values: [string, 'asc' | 'desc'][]) {\n this.values = values;\n }\n\n getOrderFilters(): EntityOrderQuery {\n return this.values.map(([field, order]) => ({ field, order }));\n }\n\n toQueryValue(): string[] {\n return this.values.flat();\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { QueryEntitiesResponse } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n useVersionedContext,\n} from '@backstage/version-bridge';\nimport { compact, isEqual } from 'lodash';\nimport qs from 'qs';\nimport {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { useLocation } from 'react-router-dom';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport useMountedState from 'react-use/esm/useMountedState';\nimport { catalogApiRef } from '../api';\nimport {\n EntityErrorFilter,\n EntityKindFilter,\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityTypeFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityFilter, EntityListPagination } from '../types';\nimport {\n reduceBackendCatalogFilters,\n reduceCatalogFilters,\n reduceEntityFilters,\n} from '../utils/filters';\n\n/** @public */\nexport type DefaultEntityFilters = {\n kind?: EntityKindFilter;\n type?: EntityTypeFilter;\n user?: UserListFilter | EntityUserFilter;\n owners?: EntityOwnerFilter;\n lifecycles?: EntityLifecycleFilter;\n tags?: EntityTagFilter;\n text?: EntityTextFilter;\n orphan?: EntityOrphanFilter;\n error?: EntityErrorFilter;\n namespace?: EntityNamespaceFilter;\n order?: EntityOrderFilter;\n};\n\n/** @public */\nexport type PaginationMode = 'cursor' | 'offset' | 'none';\n\n/** @public */\nexport type EntityListContextProps<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n> = {\n /**\n * The currently registered filters, adhering to the shape of DefaultEntityFilters or an extension\n * of that default (to add custom filter types).\n */\n filters: EntityFilters;\n\n /**\n * The resolved list of catalog entities, after all filters are applied.\n */\n entities: Entity[];\n\n /**\n * The resolved list of catalog entities, after _only catalog-backend_ filters are applied.\n */\n backendEntities: Entity[];\n\n /**\n * Update one or more of the registered filters. Optional filters can be set to `undefined` to\n * reset the filter.\n */\n updateFilters: (\n filters:\n | Partial<EntityFilters>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => void;\n\n /**\n * Filter values from query parameters.\n */\n queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;\n\n loading: boolean;\n error?: Error;\n\n pageInfo?: {\n next?: () => void;\n prev?: () => void;\n };\n totalItems?: number;\n limit: number;\n offset?: number;\n setLimit: (limit: number) => void;\n setOffset?: (offset: number) => void;\n paginationMode: PaginationMode;\n};\n\n// This context has support for multiple concurrent versions of this package.\n// It is currently used in parallel with the old context in order to provide\n// a smooth transition, but will eventually be the only context we use.\nexport const NewEntityListContext = createVersionedContext<{\n 1: EntityListContextProps<any>;\n}>('entity-list-context');\n\n/**\n * Creates new context for entity listing and filtering.\n */\nexport const OldEntityListContext = createContext<\n EntityListContextProps<any> | undefined\n>(undefined);\n\ntype OutputState<EntityFilters extends DefaultEntityFilters> = {\n appliedFilters: EntityFilters;\n appliedCursor?: string;\n entities: Entity[];\n backendEntities: Entity[];\n pageInfo?: QueryEntitiesResponse['pageInfo'];\n totalItems?: number;\n offset?: number;\n limit?: number;\n};\n\n/**\n * @public\n */\nexport type EntityListProviderProps = PropsWithChildren<{\n pagination?: EntityListPagination;\n}>;\n\n/**\n * Provides entities and filters for a catalog listing.\n * @public\n */\nexport const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(\n props: EntityListProviderProps,\n) => {\n const isMounted = useMountedState();\n const catalogApi = useApi(catalogApiRef);\n const [requestedFilters, setRequestedFilters] = useState<EntityFilters>(\n {} as EntityFilters,\n );\n\n // We use react-router's useLocation hook so updates from external sources trigger an update to\n // the queryParameters in outputState. Updates from this hook use replaceState below and won't\n // trigger a useLocation change; this would instead come from an external source, such as a manual\n // update of the URL or two catalog sidebar links with different catalog filters.\n const location = useLocation();\n\n const getPaginationMode = (): PaginationMode => {\n if (props.pagination === true) {\n return 'cursor';\n }\n return typeof props.pagination === 'object'\n ? props.pagination.mode ?? 'cursor'\n : 'none';\n };\n\n const paginationMode = getPaginationMode();\n const paginationLimit =\n typeof props.pagination === 'object' ? props.pagination.limit ?? 20 : 20;\n\n const {\n queryParameters,\n cursor: initialCursor,\n offset: initialOffset,\n limit: initialLimit,\n } = useMemo(() => {\n const parsed = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n arrayLimit: 10000,\n });\n\n let limit = paginationLimit;\n if (typeof parsed.limit === 'string') {\n const queryLimit = Number.parseInt(parsed.limit, 10);\n if (!isNaN(queryLimit)) {\n limit = queryLimit;\n }\n }\n\n const offset =\n typeof parsed.offset === 'string' && paginationMode === 'offset'\n ? Number.parseInt(parsed.offset, 10)\n : undefined;\n\n return {\n queryParameters: (parsed.filters ?? {}) as Record<\n string,\n string | string[]\n >,\n cursor:\n typeof parsed.cursor === 'string' && paginationMode === 'cursor'\n ? parsed.cursor\n : undefined,\n offset:\n paginationMode === 'offset' && offset && !isNaN(offset)\n ? offset\n : undefined,\n limit,\n };\n }, [paginationMode, location.search, paginationLimit]);\n\n const [cursor, setCursor] = useState(initialCursor);\n const [offset, setOffset] = useState<number | undefined>(initialOffset);\n const [limit, setLimit] = useState(initialLimit);\n\n const [outputState, setOutputState] = useState<OutputState<EntityFilters>>(\n () => {\n return {\n appliedFilters: {} as EntityFilters,\n entities: [],\n backendEntities: [],\n pageInfo: {},\n offset,\n limit,\n };\n },\n );\n\n // The main async filter worker. Note that while it has a lot of dependencies\n // in terms of its implementation, the triggering only happens (debounced)\n // based on the requested filters changing.\n const [{ value: resolvedValue, loading, error }, refresh] = useAsyncFn(\n async () => {\n const kindValue =\n requestedFilters.kind?.value?.toLocaleLowerCase('en-US');\n const adjustedFilters =\n kindValue === 'user' || kindValue === 'group'\n ? { ...requestedFilters, owners: undefined }\n : requestedFilters;\n const compacted = compact(Object.values(adjustedFilters));\n const entityFilter = reduceEntityFilters(compacted);\n\n if (paginationMode !== 'none') {\n if (cursor) {\n if (cursor !== outputState.appliedCursor) {\n const response = await catalogApi.queryEntities({\n cursor,\n limit,\n });\n return {\n appliedFilters: requestedFilters,\n appliedCursor: cursor,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n appliedCursor: outputState.appliedCursor,\n backendEntities: outputState.backendEntities,\n entities,\n pageInfo: outputState.pageInfo,\n totalItems: outputState.totalItems,\n limit: outputState.limit,\n offset: outputState.offset,\n };\n }\n\n const backendFilter = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n if (\n (paginationMode === 'offset' &&\n (outputState.limit !== limit || outputState.offset !== offset)) ||\n !isEqual(previousBackendFilter, backendFilter)\n ) {\n const response = await catalogApi.queryEntities({\n ...backendFilter,\n limit,\n offset,\n });\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n limit,\n offset,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n pageInfo: outputState.pageInfo,\n totalItems: outputState.totalItems,\n limit: outputState.limit,\n offset: outputState.offset,\n };\n }\n\n const backendFilter = reduceBackendCatalogFilters(compacted);\n const { orderFields } = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceBackendCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n // TODO(mtlewis): currently entities will never be requested unless\n // there's at least one filter, we should allow an initial request\n // to happen with no filters.\n if (!isEqual(previousBackendFilter, backendFilter)) {\n // TODO(timbonicus): should limit fields here, but would need filter\n // fields + table columns\n const response = await catalogApi.getEntities({\n filter: backendFilter,\n order: orderFields,\n });\n const entities = response.items.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities,\n totalItems: entities.length,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n totalItems: entities.length,\n };\n },\n [\n catalogApi,\n queryParameters,\n requestedFilters,\n outputState,\n cursor,\n paginationMode,\n limit,\n offset,\n ],\n { loading: true },\n );\n\n // Slight debounce on the refresh, since (especially on page load) several\n // filters will be calling this in rapid succession.\n useDebounce(refresh, 10, [requestedFilters, cursor, limit, offset]);\n\n useEffect(() => {\n if (resolvedValue === undefined) {\n return;\n }\n setOutputState(resolvedValue);\n if (isMounted()) {\n const queryParams = Object.keys(requestedFilters).reduce(\n (params, key) => {\n const filter = requestedFilters[key as keyof EntityFilters] as\n | EntityFilter\n | undefined;\n if (filter?.toQueryValue) {\n params[key] = filter.toQueryValue();\n }\n return params;\n },\n {} as Record<string, string | string[]>,\n );\n\n const oldParams = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n arrayLimit: 10000,\n });\n const newParams = qs.stringify(\n {\n ...oldParams,\n filters: queryParams,\n ...(paginationMode === 'none' ? {} : { cursor, limit, offset }),\n },\n { addQueryPrefix: true, arrayFormat: 'repeat' },\n );\n const newUrl = `${window.location.pathname}${newParams}`;\n // We use direct history manipulation since useSearchParams and\n // useNavigate in react-router-dom cause unnecessary extra rerenders.\n // Also make sure to replace the state rather than pushing, since we\n // don't want there to be back/forward slots for every single filter\n // change.\n window.history?.replaceState(null, document.title, newUrl);\n }\n }, [\n cursor,\n isMounted,\n limit,\n location.search,\n offset,\n requestedFilters,\n resolvedValue,\n paginationMode,\n ]);\n\n const updateFilters = useCallback(\n (\n update:\n | Partial<EntityFilter>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => {\n // changing filters will affect pagination, so we need to reset\n // the cursor and start from the first page.\n // TODO(vinzscam): this is currently causing issues at page reload\n // where the state is not kept. Unfortunately we need to rethink\n // the way filters work in order to fix this.\n if (paginationMode === 'cursor') {\n setCursor(undefined);\n } else if (paginationMode === 'offset') {\n // Same thing with offset\n setOffset(0);\n }\n setRequestedFilters(prevFilters => {\n const newFilters =\n typeof update === 'function' ? update(prevFilters) : update;\n return { ...prevFilters, ...newFilters };\n });\n },\n [paginationMode],\n );\n\n // Use resolvedValue directly when available to avoid an extra render cycle.\n // Without this, there's a render where loading has flipped back to false but\n // outputState hasn't been updated yet (it syncs via useEffect), causing a\n // flash of stale data between the loading state and the new results.\n const latestOutput = resolvedValue ?? outputState;\n\n const pageInfo = useMemo(() => {\n if (paginationMode !== 'cursor') {\n return undefined;\n }\n\n const prevCursor = latestOutput.pageInfo?.prevCursor;\n const nextCursor = latestOutput.pageInfo?.nextCursor;\n return {\n prev: prevCursor ? () => setCursor(prevCursor) : undefined,\n next: nextCursor ? () => setCursor(nextCursor) : undefined,\n };\n }, [paginationMode, latestOutput.pageInfo]);\n\n const value = useMemo(\n () => ({\n filters: latestOutput.appliedFilters,\n entities: latestOutput.entities,\n backendEntities: latestOutput.backendEntities,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n totalItems: latestOutput.totalItems,\n limit,\n offset,\n setLimit,\n setOffset,\n paginationMode,\n }),\n [\n latestOutput,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n limit,\n offset,\n paginationMode,\n setLimit,\n setOffset,\n ],\n );\n\n return (\n <OldEntityListContext.Provider value={value}>\n <NewEntityListContext.Provider\n value={createVersionedValueMap({ 1: value })}\n >\n {props.children}\n </NewEntityListContext.Provider>\n </OldEntityListContext.Provider>\n );\n};\n\n/**\n * Hook for interacting with the entity list context provided by the {@link EntityListProvider}.\n * @public\n */\nexport function useEntityList<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n>(): EntityListContextProps<EntityFilters> {\n const versionedHolder = useVersionedContext<{\n 1: EntityListContextProps<any>;\n }>('entity-list-context');\n const oldContext = useContext(OldEntityListContext);\n\n if (versionedHolder) {\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityListContext v1 not available');\n }\n return value;\n }\n\n if (oldContext) {\n return oldContext;\n }\n\n throw new Error('useEntityList must be used within EntityListProvider');\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useMemo } from 'react';\nimport useObservable from 'react-use/esm/useObservable';\nimport { starredEntitiesApiRef } from '../apis';\n\nfunction getEntityRef(\n entityOrRef: Entity | CompoundEntityRef | string,\n): string {\n return typeof entityOrRef === 'string'\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n}\n\n/** @public */\nexport function useStarredEntities(): {\n starredEntities: Set<string>;\n toggleStarredEntity: (\n entityOrRef: Entity | CompoundEntityRef | string,\n ) => void;\n isStarredEntity: (\n entityOrRef: Entity | CompoundEntityRef | string,\n ) => boolean;\n} {\n const starredEntitiesApi = useApi(starredEntitiesApiRef);\n\n const starredEntities = useObservable(\n useMemo(() => starredEntitiesApi.starredEntitie$(), [starredEntitiesApi]),\n new Set<string>(),\n );\n\n const isStarredEntity = useCallback(\n (entityOrRef: Entity | CompoundEntityRef | string) =>\n starredEntities.has(getEntityRef(entityOrRef)),\n [starredEntities],\n );\n\n const toggleStarredEntity = useCallback(\n (entityOrRef: Entity | CompoundEntityRef | string) =>\n starredEntitiesApi.toggleStarred(getEntityRef(entityOrRef)).then(),\n [starredEntitiesApi],\n );\n\n return {\n starredEntities,\n toggleStarredEntity,\n isStarredEntity,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { EntityFilter } from '../types';\nimport {\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityOrderQuery } from '@backstage/catalog-client';\n\nexport interface CatalogFilters {\n filter: Record<string, string | symbol | (string | symbol)[]>;\n fullTextFilter?: {\n term: string;\n };\n orderFields?: EntityOrderQuery;\n}\n\nfunction isEntityTextFilter(t: EntityFilter): t is EntityTextFilter {\n return !!(t as EntityTextFilter).getFullTextFilters;\n}\n\nfunction isEntityOrderFilter(t: EntityFilter): t is EntityOrderFilter {\n return !!(t as EntityOrderFilter).getOrderFilters;\n}\n\nexport function reduceCatalogFilters(filters: EntityFilter[]): CatalogFilters {\n const condensedFilters = filters.reduce<CatalogFilters['filter']>(\n (compoundFilter, filter) => {\n return {\n ...compoundFilter,\n ...(filter.getCatalogFilters ? filter.getCatalogFilters() : {}),\n };\n },\n {},\n );\n\n const fullTextFilter = filters.find(isEntityTextFilter)?.getFullTextFilters();\n\n const orderFields = filters.find(isEntityOrderFilter)?.getOrderFilters() || [\n {\n field: 'metadata.name',\n order: 'asc',\n },\n ];\n return { filter: condensedFilters, fullTextFilter, orderFields };\n}\n\n/**\n * This function computes and returns an object containing the filters to be sent\n * to the backend. Any filter coming from `EntityKindFilter` and `EntityTypeFilter`, together\n * with custom filter set by the adopters is allowed. This function is used by `EntityListProvider`\n * and it won't be needed anymore in the future once pagination is implemented, as all the filters\n * will be applied backend-side.\n */\nexport function reduceBackendCatalogFilters(filters: EntityFilter[]) {\n const backendCatalogFilters: Record<\n string,\n string | symbol | (string | symbol)[]\n > = {};\n\n filters.forEach(filter => {\n if (\n filter instanceof EntityTagFilter ||\n filter instanceof EntityOwnerFilter ||\n filter instanceof EntityLifecycleFilter ||\n filter instanceof EntityNamespaceFilter ||\n filter instanceof EntityUserFilter ||\n filter instanceof EntityOrphanFilter ||\n filter instanceof EntityTextFilter ||\n filter instanceof UserListFilter\n ) {\n return;\n }\n Object.assign(backendCatalogFilters, filter.getCatalogFilters?.() || {});\n });\n\n return backendCatalogFilters;\n}\n\nexport function reduceEntityFilters(\n filters: EntityFilter[],\n): (entity: Entity) => boolean {\n return (entity: Entity) =>\n filters.every(\n filter => !filter.filterEntity || filter.filterEntity(entity),\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Button from '@material-ui/core/Button';\nimport IconButton from '@material-ui/core/IconButton';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Link as RouterLink, LinkProps } from 'react-router-dom';\nimport AddCircleOutline from '@material-ui/icons/AddCircleOutline';\nimport { Theme } from '@material-ui/core/styles';\n\n/**\n * Properties for {@link CreateButton}\n *\n * @public\n */\nexport type CreateButtonProps = {\n title: string;\n} & Partial<Pick<LinkProps, 'to'>>;\n\n/**\n * Responsive Button giving consistent UX for creation of different things\n *\n * @public\n */\nexport function CreateButton(props: CreateButtonProps) {\n const { title, to } = props;\n const isXSScreen = useMediaQuery<Theme>(theme =>\n theme.breakpoints.down('xs'),\n );\n\n if (!to) {\n return null;\n }\n\n return isXSScreen ? (\n <IconButton\n component={RouterLink}\n color=\"primary\"\n title={title}\n size=\"small\"\n to={to}\n >\n <AddCircleOutline />\n </IconButton>\n ) : (\n <Button component={RouterLink} variant=\"contained\" color=\"primary\" to={to}>\n {title}\n </Button>\n );\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { UserListFilterKind } from '../../types';\nimport { EntityKindPicker } from '../EntityKindPicker';\nimport { EntityLifecyclePicker } from '../EntityLifecyclePicker';\nimport { EntityNamespacePicker } from '../EntityNamespacePicker';\nimport {\n EntityOwnerPickerProps,\n EntityOwnerPicker,\n} from '../EntityOwnerPicker';\nimport { EntityProcessingStatusPicker } from '../EntityProcessingStatusPicker';\nimport { EntityTagPicker } from '../EntityTagPicker';\nimport { EntityTypePicker } from '../EntityTypePicker';\nimport { UserListPicker } from '../UserListPicker';\n\n/**\n * Props for default filters.\n *\n * @public\n */\nexport type DefaultFiltersProps = {\n initialKind?: string;\n initiallySelectedFilter?: UserListFilterKind;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n initiallySelectedNamespaces?: string[];\n};\n\n/** @public */\nexport const DefaultFilters = (props: DefaultFiltersProps) => {\n const {\n initialKind,\n initiallySelectedFilter,\n ownerPickerMode,\n initiallySelectedNamespaces,\n } = props;\n return (\n <>\n <EntityKindPicker initialFilter={initialKind} />\n <EntityTypePicker />\n <UserListPicker initialFilter={initiallySelectedFilter} />\n <EntityOwnerPicker mode={ownerPickerMode} />\n <EntityLifecyclePicker />\n <EntityTagPicker />\n <EntityProcessingStatusPicker />\n <EntityNamespacePicker\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n </>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n defaultEntityPresentation,\n EntityRefLink,\n EntityRefLinks,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport Chip from '@material-ui/core/Chip';\nimport { CatalogTableRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport { JsonArray } from '@backstage/types';\nimport { EntityTableColumnTitle } from '@backstage/plugin-catalog-react/alpha';\n\n// The columnFactories symbol is not directly exported, but through the\n// CatalogTable.columns field.\n/** @public */\nexport const columnFactories = Object.freeze({\n createNameColumn(options?: {\n defaultKind?: string;\n entityPresentationApi?: EntityPresentationApi;\n }): TableColumn<CatalogTableRow> {\n function formatContent(entity: Entity): string {\n if (options?.entityPresentationApi) {\n return options.entityPresentationApi.forEntity(entity, {\n defaultKind: options?.defaultKind,\n }).snapshot.primaryTitle;\n }\n return defaultEntityPresentation(entity, {\n defaultKind: options?.defaultKind,\n }).primaryTitle;\n }\n\n return {\n title: <EntityTableColumnTitle translationKey=\"name\" />,\n field: 'resolved.entityRef',\n highlight: true,\n customSort({ entity: entity1 }, { entity: entity2 }) {\n // TODO: We could implement this more efficiently by comparing field by field.\n // This has similar issues as above.\n return formatContent(entity1).localeCompare(formatContent(entity2));\n },\n render: ({ entity }) => (\n <EntityRefLink\n entityRef={entity}\n defaultKind={options?.defaultKind || 'Component'}\n />\n ),\n };\n },\n createSystemColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"system\" />,\n field: 'resolved.partOfSystemRelationTitle',\n customFilterAndSearch: (query, row) => {\n if (!row.resolved.partOfSystemRelations) {\n return false;\n }\n\n const systemNames = row.resolved.partOfSystemRelations.map(\n ref => ref.name,\n ); // Extract system names from entityRefs\n\n const searchText = systemNames.join(', ').toLocaleUpperCase('en-US');\n return searchText.includes(query.toLocaleUpperCase('en-US'));\n },\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.partOfSystemRelations}\n defaultKind=\"system\"\n />\n ),\n };\n },\n createOwnerColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"owner\" />,\n field: 'resolved.ownedByRelationsTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.ownedByRelations}\n defaultKind=\"group\"\n />\n ),\n };\n },\n createSpecTargetsColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"targets\" />,\n field: 'entity.spec.targets',\n customFilterAndSearch: (query, row) => {\n let targets: JsonArray = [];\n if (\n row.entity?.spec?.targets &&\n Array.isArray(row.entity?.spec?.targets)\n ) {\n targets = row.entity?.spec?.targets;\n } else if (row.entity?.spec?.target) {\n targets = [row.entity?.spec?.target];\n }\n return targets\n .join(', ')\n .toLocaleUpperCase('en-US')\n .includes(query.toLocaleUpperCase('en-US'));\n },\n render: ({ entity }) => (\n <>\n {(entity?.spec?.targets || entity?.spec?.target) && (\n <OverflowTooltip\n text={(\n (entity!.spec!.targets as JsonArray) || [entity.spec.target]\n ).join(', ')}\n placement=\"bottom-start\"\n />\n )}\n </>\n ),\n };\n },\n createSpecTypeColumn(\n options: {\n hidden: boolean;\n } = { hidden: false },\n ): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"type\" />,\n field: 'entity.spec.type',\n hidden: options.hidden,\n width: 'auto',\n };\n },\n createSpecLifecycleColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"lifecycle\" />,\n field: 'entity.spec.lifecycle',\n };\n },\n createMetadataDescriptionColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"description\" />,\n field: 'entity.metadata.description',\n render: ({ entity }) => (\n <OverflowTooltip\n text={entity.metadata.description}\n placement=\"bottom-start\"\n />\n ),\n width: 'auto',\n };\n },\n createTagsColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"tags\" />,\n field: 'entity.metadata.tags',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n render: ({ entity }) => (\n <>\n {entity.metadata.tags &&\n entity.metadata.tags.map(t => (\n <Chip\n key={t}\n label={t}\n size=\"small\"\n variant=\"outlined\"\n style={{ margin: '2px' }}\n />\n ))}\n </>\n ),\n width: 'auto',\n };\n },\n createTitleColumn(options?: {\n hidden?: boolean;\n }): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"title\" />,\n field: 'entity.metadata.title',\n hidden: options?.hidden,\n searchable: true,\n };\n },\n createLabelColumn(\n key: string,\n options?: { title?: string; defaultValue?: string },\n ): TableColumn<CatalogTableRow> {\n function formatContent(keyLabel: string, entity: Entity): string {\n const labels: Record<string, string> | undefined =\n entity.metadata?.labels;\n return (labels && labels[keyLabel]) || '';\n }\n\n return {\n title: options?.title || (\n <EntityTableColumnTitle translationKey=\"label\" />\n ),\n field: 'entity.metadata.labels',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n customSort({ entity: entity1 }, { entity: entity2 }) {\n return formatContent(key, entity1).localeCompare(\n formatContent(key, entity2),\n );\n },\n render: ({ entity }: { entity: Entity }) => {\n const labels: Record<string, string> | undefined =\n entity.metadata?.labels;\n const specifiedLabelValue =\n (labels && labels[key]) || options?.defaultValue;\n return (\n <>\n {specifiedLabelValue && (\n <Chip\n key={specifiedLabelValue}\n label={specifiedLabelValue}\n size=\"small\"\n variant=\"outlined\"\n />\n )}\n </>\n );\n },\n width: 'auto',\n };\n },\n createNamespaceColumn(): TableColumn<CatalogTableRow> {\n return {\n title: <EntityTableColumnTitle translationKey=\"namespace\" />,\n field: 'entity.metadata.namespace',\n width: 'auto',\n };\n },\n});\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport FormControl from '@material-ui/core/FormControl';\nimport IconButton from '@material-ui/core/IconButton';\nimport Input from '@material-ui/core/Input';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Clear from '@material-ui/icons/Clear';\nimport Search from '@material-ui/icons/Search';\nimport { useEffect, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { useEntityList } from '../../hooks/useEntityListProvider';\nimport { EntityTextFilter } from '../../filters';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntitySearchBarClassKey = 'searchToolbar' | 'input';\n\nconst useStyles = makeStyles(\n _theme => ({\n searchToolbar: {\n paddingLeft: 0,\n paddingRight: 0,\n },\n input: {},\n }),\n { name: 'CatalogReactEntitySearchBar' },\n);\n\n/**\n * Renders search bar for filtering the entity list.\n * @public\n */\nexport const EntitySearchBar = () => {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const {\n updateFilters,\n queryParameters: { text: textParameter },\n } = useEntityList();\n\n const queryParamTextFilter = useMemo(\n () => [textParameter].flat()[0],\n [textParameter],\n );\n\n const [search, setSearch] = useState(queryParamTextFilter ?? '');\n\n useDebounce(\n () => {\n updateFilters({\n text: search.length ? new EntityTextFilter(search) : undefined,\n });\n },\n 250,\n [search, updateFilters],\n );\n\n useEffect(() => {\n if (queryParamTextFilter) {\n setSearch(queryParamTextFilter);\n }\n }, [queryParamTextFilter]);\n\n return (\n <Toolbar className={classes.searchToolbar}>\n <FormControl>\n <Input\n aria-label=\"search\"\n id=\"input-with-icon-adornment\"\n className={classes.input}\n placeholder={t('entitySearchBar.placeholder')}\n autoComplete=\"off\"\n onChange={event => setSearch(event.target.value)}\n value={search}\n startAdornment={\n <InputAdornment position=\"start\">\n <Search />\n </InputAdornment>\n }\n endAdornment={\n <InputAdornment position=\"end\">\n <IconButton\n aria-label=\"clear search\"\n onClick={() => setSearch('')}\n edge=\"end\"\n disabled={search.length === 0}\n >\n <Clear />\n </IconButton>\n </InputAdornment>\n }\n />\n </FormControl>\n </Toolbar>\n );\n};\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ReactElement } from 'react';\nimport { EntitySearchBar } from '@backstage/plugin-catalog-react';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\n\n/** @public */\nexport type CatalogTableToolbarClassKey = 'root' | 'text';\n\nconst useToolbarStyles = makeStyles(\n theme => ({\n root: {\n paddingTop: theme.spacing(1.25),\n paddingLeft: theme.spacing(2.5),\n paddingBottom: theme.spacing(0.75),\n display: 'flex',\n justifyContent: 'space-between',\n },\n text: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n }),\n { name: 'PluginCatalogTableToolbar' },\n);\n\nexport function CatalogTableToolbar(props: {\n title?: string | ReactElement<any>;\n}) {\n const styles = useToolbarStyles();\n return (\n <Toolbar className={styles.root}>\n <Typography variant=\"h5\" className={styles.text}>\n {props.title}\n </Typography>\n <EntitySearchBar />\n </Toolbar>\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useEffect } from 'react';\n\nimport { Table, TableProps } from '@backstage/core-components';\nimport { CatalogTableRow } from './types';\nimport { useEntityList } from '@backstage/plugin-catalog-react';\nimport { CatalogTableToolbar } from './CatalogTableToolbar';\n\n/**\n * @internal\n */\nexport function OffsetPaginatedCatalogTable(\n props: TableProps<CatalogTableRow>,\n) {\n const { columns, data, options, ...restProps } = props;\n const { setLimit, setOffset, limit, totalItems, offset } = useEntityList();\n\n const [page, setPage] = useState(\n offset && limit ? Math.floor(offset / limit) : 0,\n );\n\n useEffect(() => {\n if (totalItems && page * limit >= totalItems) {\n setOffset!(Math.max(0, totalItems - limit));\n } else {\n setOffset!(Math.max(0, page * limit));\n }\n }, [setOffset, page, limit, totalItems]);\n\n return (\n <Table\n columns={columns}\n data={data}\n options={{\n pageSizeOptions: [5, 10, 20, 50, 100],\n pageSize: limit,\n emptyRowsWhenPaging: false,\n ...options,\n }}\n components={{\n Toolbar: CatalogTableToolbar,\n }}\n page={page}\n onPageChange={setPage}\n onRowsPerPageChange={setLimit}\n totalCount={totalItems}\n {...restProps}\n />\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Table, TableProps } from '@backstage/core-components';\nimport { CatalogTableRow } from './types';\nimport { CatalogTableToolbar } from './CatalogTableToolbar';\n\ntype PaginatedCatalogTableProps = {\n prev?(): void;\n next?(): void;\n} & TableProps<CatalogTableRow>;\n\n/**\n * @internal\n */\n\nexport function CursorPaginatedCatalogTable(props: PaginatedCatalogTableProps) {\n const { columns, data, next, prev, options, ...restProps } = props;\n\n return (\n <Table\n columns={columns}\n data={data}\n options={{\n ...options,\n // These settings are configured to force server side pagination\n pageSizeOptions: [],\n showFirstLastPageButtons: false,\n pageSize: Number.MAX_SAFE_INTEGER,\n emptyRowsWhenPaging: false,\n }}\n onPageChange={page => {\n if (page > 0) {\n next?.();\n } else {\n prev?.();\n }\n }}\n components={{\n Toolbar: CatalogTableToolbar,\n }}\n /* this will enable the prev button accordingly */\n page={prev ? 1 : 0}\n /* this will enable the next button accordingly */\n totalCount={next ? Number.MAX_VALUE : Number.MAX_SAFE_INTEGER}\n localization={{ pagination: { labelDisplayedRows: '' } }}\n {...restProps}\n />\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TableColumn } from '@backstage/core-components';\nimport { columnFactories } from './columns';\nimport { CatalogTableColumnsFunc, CatalogTableRow } from './types';\n\n// The defaultCatalogTableColumnsFunc symbol is not directly exported, but through the\n// CatalogTable.defaultColumnsFunc field.\n/** @public */\nexport const defaultCatalogTableColumnsFunc: CatalogTableColumnsFunc = ({\n filters,\n entities,\n}) => {\n const showTypeColumn = filters.type === undefined;\n\n return [\n columnFactories.createTitleColumn({ hidden: true }),\n columnFactories.createNameColumn({ defaultKind: filters.kind?.value }),\n ...createEntitySpecificColumns(),\n ];\n\n function createEntitySpecificColumns(): TableColumn<CatalogTableRow>[] {\n const descriptionTagColumns = [\n columnFactories.createMetadataDescriptionColumn(),\n columnFactories.createTagsColumn(),\n ];\n const baseColumns = [\n columnFactories.createSystemColumn(),\n columnFactories.createOwnerColumn(),\n columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }),\n columnFactories.createSpecLifecycleColumn(),\n ];\n switch (filters.kind?.value) {\n case 'user':\n return [...descriptionTagColumns];\n case 'domain':\n case 'system':\n return [columnFactories.createOwnerColumn(), ...descriptionTagColumns];\n case 'group':\n case 'template':\n return [\n columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }),\n ...descriptionTagColumns,\n ];\n case 'location':\n return [\n columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }),\n columnFactories.createSpecTargetsColumn(),\n ];\n default:\n return entities.every(entity => entity.metadata.namespace === 'default')\n ? [...baseColumns, ...descriptionTagColumns]\n : [\n ...baseColumns,\n columnFactories.createNamespaceColumn(),\n ...descriptionTagColumns,\n ];\n }\n }\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport { default } from './plugin';\n\nexport { NfsDefaultCatalogPage as CatalogIndexPage } from '../components/CatalogPage';\nexport type { DefaultCatalogPageProps as CatalogIndexPageProps } from '../components/CatalogPage';\nexport type {\n CatalogTableRow,\n CatalogTableColumnsFunc,\n} from '../components/CatalogTable';\n\nimport { catalogTranslationRef as _catalogTranslationRef } from './translation';\n\n/**\n * @alpha\n * @deprecated Import from `@backstage/plugin-catalog` instead.\n */\nexport const catalogTranslationRef = _catalogTranslationRef;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ANNOTATION_EDIT_URL,\n ANNOTATION_VIEW_URL,\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n getEntityRelations,\n useEntityList,\n useStarredEntities,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport Typography from '@material-ui/core/Typography';\nimport { visuallyHidden } from '@mui/utils';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport { capitalize, sortBy } from 'lodash';\nimport pluralize from 'pluralize';\nimport { ReactNode, useMemo } from 'react';\nimport { columnFactories } from './columns';\nimport { CatalogTableColumnsFunc, CatalogTableRow } from './types';\nimport { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable';\nimport { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable';\nimport { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../alpha';\nimport { FavoriteToggleIcon } from '@backstage/core-components';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n /**\n * A static title to use for the table. If not provided, a title will be\n * generated based on the current Kind and Type filters and total number of items.\n */\n title?: string;\n subtitle?: string;\n}\n\nconst sortEntities = (entities: Entity[], api?: EntityPresentationApi) => {\n return sortBy(\n entities,\n e =>\n entityPresentationSnapshot(e, { defaultKind: 'Component' }, api)\n .primaryTitle,\n );\n};\n\n/**\n * CatalogTable is a wrapper around the Table component that is pre-configured\n * to display catalog entities.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/features/software-catalog/catalog-customization}\n *\n * @public\n */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const {\n columns = defaultCatalogTableColumnsFunc,\n tableOptions,\n subtitle,\n emptyContent,\n } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const entityListContext = useEntityList();\n\n const {\n loading,\n error,\n entities,\n filters,\n pageInfo,\n totalItems,\n paginationMode,\n } = entityListContext;\n\n // For non-paginated tables, only show the full loading indicator when\n // there's no data yet (initial load). During filter changes we keep stale\n // data visible and let the new results swap in seamlessly. For paginated\n // tables we always show loading, since stale data from a different page\n // would be misleading.\n const isLoading =\n paginationMode === 'none' ? loading && entities.length === 0 : loading;\n\n const tableColumns = useMemo(\n () =>\n typeof columns === 'function' ? columns(entityListContext) : columns,\n [columns, entityListContext],\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title={t('catalogTable.warningPanelTitle')}\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<CatalogTableRow>['actions'] = [\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_VIEW_URL];\n const title = t('catalogTable.viewActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <OpenInNew fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n const title = t('catalogTable.editActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <Edit fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n const title = isStarred\n ? t('catalogTable.unStarActionTitle')\n : t('catalogTable.starActionTitle');\n\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => <FavoriteToggleIcon isFavorite={isStarred} />,\n tooltip: title,\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n const currentKind = filters.kind?.label || '';\n const currentType = filters.type?.value || '';\n const currentCount = typeof totalItems === 'number' ? `(${totalItems})` : '';\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(\n filters.user?.value ?? t('catalogTable.allFilters'),\n );\n const titleText =\n props.title ||\n [titlePreamble, currentType, pluralize(currentKind), currentCount]\n .filter(s => s)\n .join(' ');\n const title =\n loading && !isLoading ? (\n <span\n style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5em' }}\n >\n {titleText}\n <CircularProgress size=\"0.8em\" data-testid=\"loading-indicator\" />\n </span>\n ) : (\n titleText\n );\n\n const actions = props.actions || defaultActions;\n const options: TableProps['options'] = {\n actionsColumnIndex: -1,\n loadingType: 'linear' as const,\n showEmptyDataSourceMessage: !isLoading,\n padding: 'dense' as const,\n ...tableOptions,\n };\n\n if (paginationMode === 'cursor') {\n return (\n <CursorPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n next={pageInfo?.next}\n prev={pageInfo?.prev}\n />\n );\n } else if (paginationMode === 'offset') {\n return (\n <OffsetPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n />\n );\n }\n\n const rows = sortEntities(entities, entityPresentationApi).map(e =>\n toEntityRow(e, entityPresentationApi),\n );\n const pageSize = 20;\n const showPagination = rows.length > pageSize;\n\n return (\n <Table<CatalogTableRow>\n isLoading={isLoading}\n columns={tableColumns}\n options={{\n paging: showPagination,\n pageSize: pageSize,\n pageSizeOptions: [20, 50, 100],\n ...options,\n }}\n title={title}\n data={rows}\n actions={actions}\n subtitle={subtitle}\n emptyContent={emptyContent}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\nCatalogTable.defaultColumnsFunc = defaultCatalogTableColumnsFunc;\n\nfunction toEntityRow(entity: Entity, api?: EntityPresentationApi) {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n // This name is here for backwards compatibility mostly; the\n // presentation of refs in the table should in general be handled with\n // EntityRefLink / EntityName components\n name: entityPresentationSnapshot(\n entity,\n { defaultKind: 'Component' },\n api,\n ).primaryTitle,\n entityRef: stringifyEntityRef(entity),\n ownedByRelationsTitle: ownedByRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'group' }, api)\n .primaryTitle,\n )\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'system' }, api)\n .primaryTitle,\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { HeaderPage } from '@backstage/ui';\nimport {\n CatalogFilterLayout,\n DefaultFilters,\n EntityListPagination,\n EntityListProvider,\n EntityOwnerPickerProps,\n UserListFilterKind,\n} from '@backstage/plugin-catalog-react';\nimport { ReactNode } from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable, CatalogTableRow } from '../CatalogTable';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogTableColumnsFunc } from '../CatalogTable/types';\nimport { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';\nimport { usePermission } from '@backstage/plugin-permission-react';\n\n/** @internal */\nexport type BaseCatalogPageProps = {\n filters: ReactNode;\n content?: ReactNode;\n pagination?: EntityListPagination;\n};\n\nfunction CatalogPageContent(props: BaseCatalogPageProps) {\n const { filters, content = <CatalogTable />, pagination } = props;\n\n return (\n <EntityListProvider pagination={pagination}>\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>{filters}</CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>{content}</CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </EntityListProvider>\n );\n}\n\n/** @internal */\nexport function BaseCatalogPage(props: BaseCatalogPageProps) {\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n const headerActions = (\n <>\n {allowed && (\n <CreateButton\n title={t('indexPage.createButtonTitle')}\n to={createComponentLink && createComponentLink()}\n />\n )}\n <SupportButton>{t('indexPage.supportButtonContent')}</SupportButton>\n </>\n );\n\n return (\n <PageWithHeader title={t('indexPage.title', { orgName })} themeId=\"home\">\n <Content>\n <ContentHeader title=\"\">{headerActions}</ContentHeader>\n <CatalogPageContent {...props} />\n </Content>\n </PageWithHeader>\n );\n}\n\nfunction NfsBaseCatalogPage(props: BaseCatalogPageProps) {\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n\n return (\n <>\n <HeaderPage\n title={t('indexPage.title', { orgName })}\n customActions={\n <>\n {allowed && (\n <CreateButton\n title={t('indexPage.createButtonTitle')}\n to={createComponentLink && createComponentLink()}\n />\n )}\n <SupportButton>{t('indexPage.supportButtonContent')}</SupportButton>\n </>\n }\n />\n <Content>\n <CatalogPageContent {...props} />\n </Content>\n </>\n );\n}\n\n/**\n * Props for root catalog pages.\n *\n * @public\n */\nexport interface DefaultCatalogPageProps {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n initialKind?: string;\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n filters?: ReactNode;\n initiallySelectedNamespaces?: string[];\n pagination?: EntityListPagination;\n}\n\nexport function DefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n } = props;\n\n return (\n <BaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n />\n );\n}\n\n/** @public */\nexport function NfsDefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n } = props;\n\n return (\n <NfsBaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n />\n );\n}\n"],"names":["useStyles","makeStyles","FavoriteToggleIcon","props","isFavorite","classes","Typography","StarIcon","UnstarredIcon","FavoriteToggle","id","title","value","onChange","iconButtonProps","Tooltip","IconButton","line","OverflowTooltip","theme","createStyles","SvgIcon","BootstrapInput","withStyles","InputBase","SelectComponent","multiple","items","label","placeholder","selected","triggerReset","native","disabled","margin","dataTestId","setValue","useState","isOpen","setOpen","useEffect","Box","FormControl","InputLabel","Select","event","previous","HTMLElement","s","selectedValue","item","el","Chip","CancelIcon","newValue","chip","OpenedDropdown","ClosedDropdown","MenuItem","Checkbox","useFilterStyles","Filters","onChangeFilters","t","useTranslationRef","coreComponentsTranslationRef","selectedFilters","setSelectedFilters","reset","Button","filter","TableLoadingBody","CircularProgress","tableIcons","forwardRef","ref","AddBox","Check","Clear","DeleteOutline","ChevronRight","Edit","SaveAlt","FilterList","FirstPage","LastPage","ChevronLeft","Search","ArrowUpward","Remove","ViewColumn","extractValueByField","data","field","path","i","undefined","StyledMTableHeader","MTableHeader","StyledMTableToolbar","MTableToolbar","useTableStyles","defaultInitialState","TableToolbar","toolbarProps","toolbarRef","setSearch","hasFilters","selectedFiltersLength","toggleFilters","filtersClasses","onSearchChanged","useCallback","searchText","Table","filterConfig","dataValue","columns","emptyContent","options","subtitle","localization","filters","initialState","onStateChange","components","loading","style","restProps","tableClasses","useTheme","calculatedInitialState","filtersOpen","setFiltersOpen","v","search","state","transform","result","key","isEqual","defaultState","getFieldByTitle","titleValue","tableData","useMemo","selectedFiltersArray","Object","filterValue","fieldValue","Array","Toolbar","hasNoRows","columnCount","Body","makeBody","bodyProps","MTableBody","distinctValues","addValue","Set","c","MTable","column","headerStyle","cellStyle","cellStyleFn","rowData","rowColumn","entityPresentationSnapshot","entityOrRef","context","entityPresentationApi","stringifyEntityRef","defaultEntityPresentation","BootstrapAutocomplete","Autocomplete","PopperComponent","Popper","TransitionProps","Grow","PaperComponent","Paper","CatalogAutocomplete","name","LabelProps","TextFieldProps","rest","renderInput","params","TextField","merge","autocomplete","ExpandMoreIcon","classNames","CatalogFilterLayout","Grid","isScreenSmallerThanBreakpoint","useMediaQuery","filterDrawerOpen","setFilterDrawerOpen","catalogReactTranslationRef","FilterListIcon","Drawer","icon","CheckBoxOutlineBlankIcon","checkedIcon","CheckBoxIcon","OptionCheckbox","EntityAutocompletePickerOption","memo","availableOptions","showCounts","FormControlLabel","EntityAutocompletePicker","Filter","InputProps","initialSelectedOptions","filtersForAvailableValues","hidden","updateFilters","queryParameter","useEntityList","catalogApi","useApi","catalogApiRef","availableValuesFilters","f","availableValues","useAsync","facets","reduceBackendCatalogFilters","Boolean","count","queryParameters","filteredOptions","selectedOptions","setSelectedOptions","shouldAddFilter","newSelectedOptions","String","_event","option","EntityKindPicker","availableKinds","kindsMap","allowedKinds","initialFilter","alertApi","alertApiRef","error","allKinds","selectedKind","setSelectedKind","useEntityKindFilter","opts","kindParameter","queryParamKind","useAllKinds","Map","kindFacets","kind","selectedKindLabel","EntityKindFilter","k","forcedKinds","EntityLifecyclePicker","EntityLifecycleFilter","EntityNamespacePicker","initiallySelectedNamespaces","EntityNamespaceFilter","FixedWidthFormControlLabel","_theme","RenderOptionLabel","isGroup","useEntityPresentation","GroupIcon","PersonIcon","EntityOwnerPicker","mode","apis","useApiHolder","entityPresentationApiRef","ownersParameter","text","setText","queryParamOwners","selectedOwners","setSelectedOwners","handleFetch","cache","useFetchEntities","initialSelectedOwnersRefs","isOwnersOnlyMode","queryEntitiesResponse","useAsyncFn","request","limit","cursorRequest","response","initialRequest","facetsEntitiesResponse","useFacetsEntities","enabled","facetsPromise","facet","e","namespace","parseEntityRef","a","b","start","isFacetsResponse","JSON","atob","filteredRefs","entity","normalizedText","end","encodeCursor","entities","payload","btoa","useSelectedOwners","allEntities","useRef","initialSelectedEntities","useMountEffect","entityRef","useDebouncedEffect","availableOwners","EntityOwnerFilter","o","_","owners","x","_e","inputValue","element","hasReachedEnd","Math","EntityProcessingStatusPicker","selectedAdvancedItems","setSelectedAdvancedItems","EntityOrphanFilter","EntityErrorFilter","EntityTableColumnTitle","translationKey","EntityTagPicker","EntityTagFilter","EntityTypePicker","availableTypes","selectedTypes","setSelectedTypes","useEntityTypeFilter","kindFilter","typeFilter","typeParameter","flattenedQueryTypes","setAvailableTypes","facetsRef","oldFacets","newTypes","sortBy","stillValidTypes","EntityTypeFilter","type","UserListPicker","availableFilters","alwaysKeepFilters","configApi","configApiRef","orgName","userParameter","userAndGroupFilterIds","filterGroups","getFilterGroups","SettingsIcon","filterGroup","ownedEntitiesCount","loadingOwnedEntities","ownedEntitiesFilter","useOwnedEntitiesCount","identityApi","identityApiRef","ownershipEntityRefs","loadingEntityRefs","user","allFilters","orderFields","catalogFilters","reduceCatalogFilters","compact","loadingEntityOwnership","fetchEntities","req","ownedClaims","getOwnedCountClaims","ownersRefs","commonOwnedBy","intersection","metadata","totalItems","useDeepCompareEffect","EntityUserFilter","allCount","useAllEntitiesCount","prevRequest","compacted","newRequest","starredEntitiesCount","starredEntitiesFilter","loadingStarredEntities","useStarredEntitiesCount","starredEntities","useStarredEntities","queryParamUserFilter","selectedUserFilter","setSelectedUserFilter","filterCounts","Card","group","Fragment","List","index","ListItemIcon","ListItemText","ListItemSecondaryAction","values","EntityTextFilter","words","exactMatch","partialMatch","word","m","fullRefs","err","getEntityRelations","RELATION_OWNED_BY","refs","starredEntityRefs","relations","UserListFilter","isOwnedEntity","isStarredEntity","orphan","NewEntityListContext","createVersionedContext","OldEntityListContext","createContext","EntityListProvider","isMounted","useMountedState","requestedFilters","setRequestedFilters","location","useLocation","paginationMode","paginationLimit","initialCursor","initialOffset","initialLimit","parsed","qs","queryLimit","Number","isNaN","offset","cursor","setCursor","setOffset","setLimit","outputState","setOutputState","resolvedValue","refresh","kindValue","adjustedFilters","entityFilter","reduceEntityFilters","backendFilter","previousBackendFilter","useDebounce","queryParams","oldParams","newParams","newUrl","window","document","update","prevFilters","newFilters","latestOutput","pageInfo","prevCursor","nextCursor","createVersionedValueMap","versionedHolder","useVersionedContext","oldContext","useContext","Error","getEntityRef","starredEntitiesApi","starredEntitiesApiRef","useObservable","toggleStarredEntity","isEntityTextFilter","isEntityOrderFilter","condensedFilters","compoundFilter","fullTextFilter","backendCatalogFilters","CreateButton","to","isXSScreen","RouterLink","AddCircleOutline","DefaultFilters","initialKind","initiallySelectedFilter","ownerPickerMode","columnFactories","formatContent","entity1","entity2","EntityRefLink","query","row","systemNames","resolved","EntityRefLinks","targets","keyLabel","labels","specifiedLabelValue","EntitySearchBar","textParameter","queryParamTextFilter","Input","InputAdornment","useToolbarStyles","CatalogTableToolbar","styles","OffsetPaginatedCatalogTable","page","setPage","CursorPaginatedCatalogTable","next","prev","defaultCatalogTableColumnsFunc","showTypeColumn","createEntitySpecificColumns","descriptionTagColumns","baseColumns","catalogTranslationRef","_catalogTranslationRef","CatalogTable","tableOptions","entityListContext","isLoading","tableColumns","WarningPanel","CodeSnippet","defaultActions","url","ANNOTATION_VIEW_URL","visuallyHidden","OpenInNew","ANNOTATION_EDIT_URL","isStarred","currentKind","currentType","currentCount","titlePreamble","capitalize","titleText","pluralize","actions","toEntityRow","rows","sortEntities","showPagination","api","partOfSystemRelations","RELATION_PART_OF","ownedByRelations","r","CatalogPageContent","content","pagination","NfsBaseCatalogPage","createComponentLink","useRouteRef","createComponentRouteRef","allowed","usePermission","catalogEntityCreatePermission","HeaderPage","SupportButton","Content","NfsDefaultCatalogPage"],"mappings":"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"}