@red-hat-developer-hub/backstage-plugin-adoption-insights 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/api/index.esm.js +1 -1
  3. package/dist/api/index.esm.js.map +1 -1
  4. package/dist/components/ActiveUsers/ActiveUsers.esm.js +108 -90
  5. package/dist/components/ActiveUsers/ActiveUsers.esm.js.map +1 -1
  6. package/dist/components/ActiveUsers/CustomLegend.esm.js +40 -35
  7. package/dist/components/ActiveUsers/CustomLegend.esm.js.map +1 -1
  8. package/dist/components/ActiveUsers/ExportCSVButton.esm.js +27 -25
  9. package/dist/components/ActiveUsers/ExportCSVButton.esm.js.map +1 -1
  10. package/dist/components/AdoptionInsightsPage/AdoptionInsightsPage.esm.js +13 -2
  11. package/dist/components/AdoptionInsightsPage/AdoptionInsightsPage.esm.js.map +1 -1
  12. package/dist/components/CardFooter/TableFooterPagination.esm.js +42 -42
  13. package/dist/components/CardFooter/TableFooterPagination.esm.js.map +1 -1
  14. package/dist/components/CardWrapper/CardWrapper.esm.js +29 -24
  15. package/dist/components/CardWrapper/CardWrapper.esm.js.map +1 -1
  16. package/dist/components/CatalogEntities/CatalogEntities.esm.js +96 -92
  17. package/dist/components/CatalogEntities/CatalogEntities.esm.js.map +1 -1
  18. package/dist/components/CatalogEntities/FilterDropdown.esm.js +22 -17
  19. package/dist/components/CatalogEntities/FilterDropdown.esm.js.map +1 -1
  20. package/dist/components/Common/ChartTooltip.esm.js +91 -0
  21. package/dist/components/Common/ChartTooltip.esm.js.map +1 -0
  22. package/dist/components/Common/CustomCursor.esm.js +2 -2
  23. package/dist/components/Common/CustomCursor.esm.js.map +1 -1
  24. package/dist/components/Common/EmptyChartState.esm.js +2 -2
  25. package/dist/components/Common/EmptyChartState.esm.js.map +1 -1
  26. package/dist/components/Common/PermissionRequiredIcon.esm.js +2 -2
  27. package/dist/components/Common/PermissionRequiredIcon.esm.js.map +1 -1
  28. package/dist/components/Common/PermissionRequiredState.esm.js +29 -23
  29. package/dist/components/Common/PermissionRequiredState.esm.js.map +1 -1
  30. package/dist/components/Header/DateRangeContext.esm.js +7 -6
  31. package/dist/components/Header/DateRangeContext.esm.js.map +1 -1
  32. package/dist/components/Header/DateRangePicker.esm.js +67 -59
  33. package/dist/components/Header/DateRangePicker.esm.js.map +1 -1
  34. package/dist/components/Header/Header.esm.js +117 -106
  35. package/dist/components/Header/Header.esm.js.map +1 -1
  36. package/dist/components/Plugins/Plugins.esm.js +74 -64
  37. package/dist/components/Plugins/Plugins.esm.js.map +1 -1
  38. package/dist/components/Searches/Searches.esm.js +86 -75
  39. package/dist/components/Searches/Searches.esm.js.map +1 -1
  40. package/dist/components/Techdocs/Techdocs.esm.js +85 -81
  41. package/dist/components/Techdocs/Techdocs.esm.js.map +1 -1
  42. package/dist/components/Templates/Templates.esm.js +74 -70
  43. package/dist/components/Templates/Templates.esm.js.map +1 -1
  44. package/dist/components/Users/Info.esm.js +12 -12
  45. package/dist/components/Users/Info.esm.js.map +1 -1
  46. package/dist/components/Users/Tooltip.esm.js +27 -23
  47. package/dist/components/Users/Tooltip.esm.js.map +1 -1
  48. package/dist/components/Users/Users.esm.js +119 -95
  49. package/dist/components/Users/Users.esm.js.map +1 -1
  50. package/dist/hooks/useActiveUsers.esm.js +10 -8
  51. package/dist/hooks/useActiveUsers.esm.js.map +1 -1
  52. package/dist/hooks/useCatalogEntities.esm.js +9 -6
  53. package/dist/hooks/useCatalogEntities.esm.js.map +1 -1
  54. package/dist/hooks/usePlugins.esm.js +9 -6
  55. package/dist/hooks/usePlugins.esm.js.map +1 -1
  56. package/dist/hooks/useSearches.esm.js +11 -7
  57. package/dist/hooks/useSearches.esm.js.map +1 -1
  58. package/dist/hooks/useTechdocs.esm.js +9 -6
  59. package/dist/hooks/useTechdocs.esm.js.map +1 -1
  60. package/dist/hooks/useTemplates.esm.js +9 -6
  61. package/dist/hooks/useTemplates.esm.js.map +1 -1
  62. package/dist/hooks/useUsers.esm.js +10 -7
  63. package/dist/hooks/useUsers.esm.js.map +1 -1
  64. package/dist/index.d.ts +2 -3
  65. package/dist/utils/utils.esm.js +70 -30
  66. package/dist/utils/utils.esm.js.map +1 -1
  67. package/package.json +19 -17
  68. package/dist/components/ActiveUsers/CustomTooltip.esm.js +0 -87
  69. package/dist/components/ActiveUsers/CustomTooltip.esm.js.map +0 -1
  70. package/dist/components/Searches/CustomTooltip.esm.js +0 -66
  71. package/dist/components/Searches/CustomTooltip.esm.js.map +0 -1
@@ -1,4 +1,5 @@
1
- import React__default from 'react';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect, useCallback, useMemo } from 'react';
2
3
  import { Header } from '@backstage/core-components';
3
4
  import MenuItem from '@mui/material/MenuItem';
4
5
  import Select from '@mui/material/Select';
@@ -14,11 +15,11 @@ import { subDays, format } from 'date-fns';
14
15
  import { getDateRange } from '../../utils/utils.esm.js';
15
16
 
16
17
  const InsightsHeader = ({ title }) => {
17
- const [selectedOption, setSelectedOption] = React__default.useState("last-28-days");
18
- const [anchorEl, setAnchorEl] = React__default.useState(null);
19
- const [startDate, setStartDate] = React__default.useState(null);
20
- const [endDate, setEndDate] = React__default.useState(null);
21
- const [menuOpen, setMenuOpen] = React__default.useState(false);
18
+ const [selectedOption, setSelectedOption] = useState("last-28-days");
19
+ const [anchorEl, setAnchorEl] = useState(null);
20
+ const [startDate, setStartDate] = useState(null);
21
+ const [endDate, setEndDate] = useState(null);
22
+ const [menuOpen, setMenuOpen] = useState(false);
22
23
  const {
23
24
  startDateRange,
24
25
  setStartDateRange,
@@ -26,12 +27,12 @@ const InsightsHeader = ({ title }) => {
26
27
  setEndDateRange,
27
28
  setIsDefaultDateRange
28
29
  } = useDateRange();
29
- React__default.useEffect(() => {
30
+ useEffect(() => {
30
31
  const today = /* @__PURE__ */ new Date();
31
32
  setStartDateRange(subDays(today, 27));
32
33
  setEndDateRange(today);
33
34
  }, [setStartDateRange, setEndDateRange]);
34
- const handleChange = React__default.useCallback(
35
+ const handleChange = useCallback(
35
36
  (event) => {
36
37
  const value = event.target.value;
37
38
  if (!value) return;
@@ -50,10 +51,10 @@ const InsightsHeader = ({ title }) => {
50
51
  const handleDateRangeClick = (event) => {
51
52
  setAnchorEl(event.currentTarget);
52
53
  };
53
- const handleClose = React__default.useCallback(() => {
54
+ const handleClose = useCallback(() => {
54
55
  setAnchorEl(null);
55
56
  }, []);
56
- const handleDateRange = React__default.useCallback(() => {
57
+ const handleDateRange = useCallback(() => {
57
58
  if (startDate && endDate) {
58
59
  setStartDateRange(startDate);
59
60
  setEndDateRange(endDate);
@@ -70,7 +71,7 @@ const InsightsHeader = ({ title }) => {
70
71
  handleClose,
71
72
  setIsDefaultDateRange
72
73
  ]);
73
- const getLabel = React__default.useMemo(() => {
74
+ const getLabel = useMemo(() => {
74
75
  return (value) => {
75
76
  if (value === "dateRange" && startDateRange && endDateRange)
76
77
  return `${format(startDateRange, "PP")} - ${format(
@@ -81,113 +82,123 @@ const InsightsHeader = ({ title }) => {
81
82
  return option ? option.label : "Last 28 days";
82
83
  };
83
84
  }, [startDateRange, endDateRange]);
84
- return /* @__PURE__ */ React__default.createElement(
85
+ return /* @__PURE__ */ jsxs(
85
86
  Header,
86
87
  {
87
- title: /* @__PURE__ */ React__default.createElement(
88
+ pageTitleOverride: "Adoption Insights",
89
+ title: /* @__PURE__ */ jsx(
88
90
  Typography,
89
91
  {
90
92
  variant: "h3",
91
93
  color: "textPrimary",
92
- sx: { fontWeight: "bold" }
93
- },
94
- title
94
+ sx: { fontWeight: "bold" },
95
+ children: title
96
+ }
95
97
  ),
96
- style: { background: "none" }
97
- },
98
- /* @__PURE__ */ React__default.createElement(
99
- Select,
100
- {
101
- displayEmpty: true,
102
- open: menuOpen,
103
- onOpen: () => setMenuOpen(true),
104
- onClose: () => setMenuOpen(false),
105
- value: selectedOption,
106
- onChange: handleChange,
107
- renderValue: (selected) => getLabel(selected),
108
- sx: {
109
- minWidth: 190,
110
- marginRight: "10px"
111
- },
112
- MenuProps: {
113
- PaperProps: {
98
+ style: { background: "none" },
99
+ children: [
100
+ /* @__PURE__ */ jsxs(
101
+ Select,
102
+ {
103
+ displayEmpty: true,
104
+ open: menuOpen,
105
+ onOpen: () => setMenuOpen(true),
106
+ onClose: () => setMenuOpen(false),
107
+ value: selectedOption,
108
+ onChange: handleChange,
109
+ renderValue: (selected) => getLabel(selected),
114
110
  sx: {
115
111
  minWidth: 190,
116
- boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.2)",
117
- border: (theme) => `1px solid ${theme.palette.grey[300]}`,
118
- overflow: "hidden"
112
+ marginRight: "10px"
119
113
  },
120
- disableScrollLock: true
121
- },
122
- MenuListProps: {
123
- autoFocusItem: false,
124
- sx: { display: "block", flexDirection: "column" }
125
- }
126
- }
127
- },
128
- DATE_RANGE_OPTIONS.map((option) => /* @__PURE__ */ React__default.createElement(
129
- MenuItem,
130
- {
131
- key: option.value,
132
- value: option.value,
133
- sx: { height: "52px" }
134
- },
135
- option.label
136
- )),
137
- /* @__PURE__ */ React__default.createElement(Divider, null),
138
- /* @__PURE__ */ React__default.createElement(
139
- MenuItem,
140
- {
141
- sx: { height: "52px" },
142
- onMouseDown: (event) => {
143
- event.preventDefault();
144
- handleDateRangeClick(event);
114
+ MenuProps: {
115
+ PaperProps: {
116
+ sx: {
117
+ minWidth: 190,
118
+ boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.2)",
119
+ border: (theme) => `1px solid ${theme.palette.grey[300]}`,
120
+ overflow: "hidden"
121
+ },
122
+ disableScrollLock: true
123
+ },
124
+ MenuListProps: {
125
+ autoFocusItem: false,
126
+ sx: { display: "block", flexDirection: "column" }
127
+ }
128
+ },
129
+ children: [
130
+ DATE_RANGE_OPTIONS.map((option) => /* @__PURE__ */ jsx(
131
+ MenuItem,
132
+ {
133
+ value: option.value,
134
+ sx: { height: "52px" },
135
+ children: option.label
136
+ },
137
+ option.value
138
+ )),
139
+ /* @__PURE__ */ jsx(Divider, {}),
140
+ /* @__PURE__ */ jsx(
141
+ MenuItem,
142
+ {
143
+ sx: { height: "52px" },
144
+ onMouseDown: (event) => {
145
+ event.preventDefault();
146
+ handleDateRangeClick(event);
147
+ },
148
+ children: "Date range..."
149
+ }
150
+ )
151
+ ]
145
152
  }
146
- },
147
- "Date range..."
148
- )
149
- ),
150
- /* @__PURE__ */ React__default.createElement(
151
- Popover,
152
- {
153
- open: Boolean(anchorEl),
154
- anchorEl,
155
- onClose: handleClose,
156
- anchorOrigin: { vertical: "top", horizontal: "left" },
157
- transformOrigin: { vertical: "top", horizontal: "right" },
158
- slotProps: {
159
- paper: {
160
- sx: { boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.2)" }
153
+ ),
154
+ /* @__PURE__ */ jsxs(
155
+ Popover,
156
+ {
157
+ open: Boolean(anchorEl),
158
+ anchorEl,
159
+ onClose: handleClose,
160
+ anchorOrigin: { vertical: "top", horizontal: "left" },
161
+ transformOrigin: { vertical: "top", horizontal: "right" },
162
+ slotProps: {
163
+ paper: {
164
+ sx: { boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.2)" }
165
+ }
166
+ },
167
+ children: [
168
+ /* @__PURE__ */ jsx(
169
+ DateRangePicker,
170
+ {
171
+ startDate,
172
+ setStartDate,
173
+ endDate,
174
+ setEndDate
175
+ }
176
+ ),
177
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "flex-end", gap: 1, m: 2 }, children: [
178
+ /* @__PURE__ */ jsx(
179
+ Button,
180
+ {
181
+ onClick: handleClose,
182
+ color: "primary",
183
+ sx: { textTransform: "none" },
184
+ children: "Cancel"
185
+ }
186
+ ),
187
+ /* @__PURE__ */ jsx(
188
+ Button,
189
+ {
190
+ onClick: handleDateRange,
191
+ color: "primary",
192
+ disabled: !(startDate && endDate),
193
+ children: "OK"
194
+ }
195
+ )
196
+ ] })
197
+ ]
161
198
  }
162
- }
163
- },
164
- /* @__PURE__ */ React__default.createElement(
165
- DateRangePicker,
166
- {
167
- startDate,
168
- setStartDate,
169
- endDate,
170
- setEndDate
171
- }
172
- ),
173
- /* @__PURE__ */ React__default.createElement(Box, { sx: { display: "flex", justifyContent: "flex-end", gap: 1, m: 2 } }, /* @__PURE__ */ React__default.createElement(
174
- Button,
175
- {
176
- onClick: handleClose,
177
- color: "primary",
178
- sx: { textTransform: "none" }
179
- },
180
- "Cancel"
181
- ), /* @__PURE__ */ React__default.createElement(
182
- Button,
183
- {
184
- onClick: handleDateRange,
185
- color: "primary",
186
- disabled: !(startDate && endDate)
187
- },
188
- "OK"
189
- ))
190
- )
199
+ )
200
+ ]
201
+ }
191
202
  );
192
203
  };
193
204
 
@@ -1 +1 @@
1
- {"version":3,"file":"Header.esm.js","sources":["../../../src/components/Header/Header.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 React from 'react';\n\nimport { Header } from '@backstage/core-components';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select, { SelectChangeEvent } from '@mui/material/Select';\nimport Typography from '@mui/material/Typography';\nimport Divider from '@mui/material/Divider';\nimport Popover from '@mui/material/Popover';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\n\nimport DateRangePicker from './DateRangePicker';\nimport { useDateRange } from './DateRangeContext';\nimport { DATE_RANGE_OPTIONS } from '../../utils/constants';\nimport { format, subDays } from 'date-fns';\nimport { getDateRange } from '../../utils/utils';\n\ninterface InsightsHeaderProps extends React.HTMLProps<HTMLDivElement> {\n title: string;\n}\n\nconst InsightsHeader: React.FC<InsightsHeaderProps> = ({ title }) => {\n const [selectedOption, setSelectedOption] =\n React.useState<string>('last-28-days');\n const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);\n const [startDate, setStartDate] = React.useState<Date | null>(null);\n const [endDate, setEndDate] = React.useState<Date | null>(null);\n const [menuOpen, setMenuOpen] = React.useState(false);\n\n const {\n startDateRange,\n setStartDateRange,\n endDateRange,\n setEndDateRange,\n setIsDefaultDateRange,\n } = useDateRange();\n\n React.useEffect(() => {\n const today = new Date();\n setStartDateRange(subDays(today, 27));\n setEndDateRange(today);\n }, [setStartDateRange, setEndDateRange]);\n\n const handleChange = React.useCallback(\n (event: SelectChangeEvent<string>) => {\n const value = event.target.value;\n if (!value) return;\n\n const { startDate: newStartDate, endDate: newEndDate } =\n getDateRange(value);\n if (newStartDate && newEndDate) {\n setStartDateRange(new Date(newStartDate));\n setEndDateRange(new Date(newEndDate));\n setIsDefaultDateRange(false);\n }\n setStartDate(null);\n setEndDate(null);\n\n setSelectedOption(value);\n },\n [setStartDateRange, setEndDateRange, setIsDefaultDateRange],\n );\n\n const handleDateRangeClick = (event: React.MouseEvent<HTMLElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const handleClose = React.useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n const handleDateRange = React.useCallback(() => {\n if (startDate && endDate) {\n setStartDateRange(startDate);\n setEndDateRange(endDate);\n setIsDefaultDateRange(false);\n setSelectedOption('dateRange');\n handleClose();\n setMenuOpen(false);\n }\n }, [\n startDate,\n endDate,\n setStartDateRange,\n setEndDateRange,\n handleClose,\n setIsDefaultDateRange,\n ]);\n\n const getLabel = React.useMemo(() => {\n return (value: string) => {\n if (value === 'dateRange' && startDateRange && endDateRange)\n return `${format(startDateRange, 'PP')} - ${format(\n endDateRange,\n 'PP',\n )}`;\n\n const option = DATE_RANGE_OPTIONS.find(opt => opt.value === value);\n return option ? option.label : 'Last 28 days';\n };\n }, [startDateRange, endDateRange]);\n\n return (\n <Header\n title={\n <Typography\n variant=\"h3\"\n color=\"textPrimary\"\n sx={{ fontWeight: 'bold' }}\n >\n {title}\n </Typography>\n }\n style={{ background: 'none' }}\n >\n <Select\n displayEmpty\n open={menuOpen}\n onOpen={() => setMenuOpen(true)}\n onClose={() => setMenuOpen(false)}\n value={selectedOption}\n onChange={handleChange}\n renderValue={(selected: string) => getLabel(selected)}\n sx={{\n minWidth: 190,\n marginRight: '10px',\n }}\n MenuProps={{\n PaperProps: {\n sx: {\n minWidth: 190,\n boxShadow: '0px 4px 10px rgba(0, 0, 0, 0.2)',\n border: theme => `1px solid ${theme.palette.grey[300]}`,\n overflow: 'hidden',\n },\n disableScrollLock: true,\n },\n MenuListProps: {\n autoFocusItem: false,\n sx: { display: 'block', flexDirection: 'column' },\n },\n }}\n >\n {DATE_RANGE_OPTIONS.map(option => (\n <MenuItem\n key={option.value}\n value={option.value}\n sx={{ height: '52px' }}\n >\n {option.label}\n </MenuItem>\n ))}\n <Divider />\n <MenuItem\n sx={{ height: '52px' }}\n onMouseDown={event => {\n event.preventDefault();\n handleDateRangeClick(event);\n }}\n >\n Date range...\n </MenuItem>\n </Select>\n\n <Popover\n open={Boolean(anchorEl)}\n anchorEl={anchorEl}\n onClose={handleClose}\n anchorOrigin={{ vertical: 'top', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{\n paper: {\n sx: { boxShadow: '0px 4px 10px rgba(0, 0, 0, 0.2)' },\n },\n }}\n >\n <DateRangePicker\n startDate={startDate}\n setStartDate={setStartDate}\n endDate={endDate}\n setEndDate={setEndDate}\n />\n\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 1, m: 2 }}>\n <Button\n onClick={handleClose}\n color=\"primary\"\n sx={{ textTransform: 'none' }}\n >\n Cancel\n </Button>\n <Button\n onClick={handleDateRange}\n color=\"primary\"\n disabled={!(startDate && endDate)}\n >\n OK\n </Button>\n </Box>\n </Popover>\n </Header>\n );\n};\n\nexport default InsightsHeader;\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"Header.esm.js","sources":["../../../src/components/Header/Header.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { useState, useMemo, useCallback, useEffect } from 'react';\nimport type { FC, HTMLProps, MouseEvent } from 'react';\n\nimport { Header } from '@backstage/core-components';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select, { SelectChangeEvent } from '@mui/material/Select';\nimport Typography from '@mui/material/Typography';\nimport Divider from '@mui/material/Divider';\nimport Popover from '@mui/material/Popover';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\n\nimport DateRangePicker from './DateRangePicker';\nimport { useDateRange } from './DateRangeContext';\nimport { DATE_RANGE_OPTIONS } from '../../utils/constants';\nimport { format, subDays } from 'date-fns';\nimport { getDateRange } from '../../utils/utils';\n\ninterface InsightsHeaderProps extends HTMLProps<HTMLDivElement> {\n title: string;\n}\n\nconst InsightsHeader: FC<InsightsHeaderProps> = ({ title }) => {\n const [selectedOption, setSelectedOption] = useState<string>('last-28-days');\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const [startDate, setStartDate] = useState<Date | null>(null);\n const [endDate, setEndDate] = useState<Date | null>(null);\n const [menuOpen, setMenuOpen] = useState(false);\n\n const {\n startDateRange,\n setStartDateRange,\n endDateRange,\n setEndDateRange,\n setIsDefaultDateRange,\n } = useDateRange();\n\n useEffect(() => {\n const today = new Date();\n setStartDateRange(subDays(today, 27));\n setEndDateRange(today);\n }, [setStartDateRange, setEndDateRange]);\n\n const handleChange = useCallback(\n (event: SelectChangeEvent<string>) => {\n const value = event.target.value;\n if (!value) return;\n\n const { startDate: newStartDate, endDate: newEndDate } =\n getDateRange(value);\n if (newStartDate && newEndDate) {\n setStartDateRange(new Date(newStartDate));\n setEndDateRange(new Date(newEndDate));\n setIsDefaultDateRange(false);\n }\n setStartDate(null);\n setEndDate(null);\n\n setSelectedOption(value);\n },\n [setStartDateRange, setEndDateRange, setIsDefaultDateRange],\n );\n\n const handleDateRangeClick = (event: MouseEvent<HTMLElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const handleClose = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n const handleDateRange = useCallback(() => {\n if (startDate && endDate) {\n setStartDateRange(startDate);\n setEndDateRange(endDate);\n setIsDefaultDateRange(false);\n setSelectedOption('dateRange');\n handleClose();\n setMenuOpen(false);\n }\n }, [\n startDate,\n endDate,\n setStartDateRange,\n setEndDateRange,\n handleClose,\n setIsDefaultDateRange,\n ]);\n\n const getLabel = useMemo(() => {\n return (value: string) => {\n if (value === 'dateRange' && startDateRange && endDateRange)\n return `${format(startDateRange, 'PP')} - ${format(\n endDateRange,\n 'PP',\n )}`;\n\n const option = DATE_RANGE_OPTIONS.find(opt => opt.value === value);\n return option ? option.label : 'Last 28 days';\n };\n }, [startDateRange, endDateRange]);\n\n return (\n <Header\n pageTitleOverride=\"Adoption Insights\"\n title={\n <Typography\n variant=\"h3\"\n color=\"textPrimary\"\n sx={{ fontWeight: 'bold' }}\n >\n {title}\n </Typography>\n }\n style={{ background: 'none' }}\n >\n <Select\n displayEmpty\n open={menuOpen}\n onOpen={() => setMenuOpen(true)}\n onClose={() => setMenuOpen(false)}\n value={selectedOption}\n onChange={handleChange}\n renderValue={(selected: string) => getLabel(selected)}\n sx={{\n minWidth: 190,\n marginRight: '10px',\n }}\n MenuProps={{\n PaperProps: {\n sx: {\n minWidth: 190,\n boxShadow: '0px 4px 10px rgba(0, 0, 0, 0.2)',\n border: theme => `1px solid ${theme.palette.grey[300]}`,\n overflow: 'hidden',\n },\n disableScrollLock: true,\n },\n MenuListProps: {\n autoFocusItem: false,\n sx: { display: 'block', flexDirection: 'column' },\n },\n }}\n >\n {DATE_RANGE_OPTIONS.map(option => (\n <MenuItem\n key={option.value}\n value={option.value}\n sx={{ height: '52px' }}\n >\n {option.label}\n </MenuItem>\n ))}\n <Divider />\n <MenuItem\n sx={{ height: '52px' }}\n onMouseDown={event => {\n event.preventDefault();\n handleDateRangeClick(event);\n }}\n >\n Date range...\n </MenuItem>\n </Select>\n\n <Popover\n open={Boolean(anchorEl)}\n anchorEl={anchorEl}\n onClose={handleClose}\n anchorOrigin={{ vertical: 'top', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{\n paper: {\n sx: { boxShadow: '0px 4px 10px rgba(0, 0, 0, 0.2)' },\n },\n }}\n >\n <DateRangePicker\n startDate={startDate}\n setStartDate={setStartDate}\n endDate={endDate}\n setEndDate={setEndDate}\n />\n\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 1, m: 2 }}>\n <Button\n onClick={handleClose}\n color=\"primary\"\n sx={{ textTransform: 'none' }}\n >\n Cancel\n </Button>\n <Button\n onClick={handleDateRange}\n color=\"primary\"\n disabled={!(startDate && endDate)}\n >\n OK\n </Button>\n </Box>\n </Popover>\n </Header>\n );\n};\n\nexport default InsightsHeader;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAqCA,MAAM,cAA0C,GAAA,CAAC,EAAE,KAAA,EAAY,KAAA;AAC7D,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAiB,cAAc,CAAA;AAC3E,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA6B,IAAI,CAAA;AACjE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAsB,IAAI,CAAA;AAC5D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAsB,IAAI,CAAA;AACxD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAE9C,EAAM,MAAA;AAAA,IACJ,cAAA;AAAA,IACA,iBAAA;AAAA,IACA,YAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,MACE,YAAa,EAAA;AAEjB,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,KAAA,uBAAY,IAAK,EAAA;AACvB,IAAkB,iBAAA,CAAA,OAAA,CAAQ,KAAO,EAAA,EAAE,CAAC,CAAA;AACpC,IAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,GACpB,EAAA,CAAC,iBAAmB,EAAA,eAAe,CAAC,CAAA;AAEvC,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,KAAqC,KAAA;AACpC,MAAM,MAAA,KAAA,GAAQ,MAAM,MAAO,CAAA,KAAA;AAC3B,MAAA,IAAI,CAAC,KAAO,EAAA;AAEZ,MAAA,MAAM,EAAE,SAAW,EAAA,YAAA,EAAc,SAAS,UAAW,EAAA,GACnD,aAAa,KAAK,CAAA;AACpB,MAAA,IAAI,gBAAgB,UAAY,EAAA;AAC9B,QAAkB,iBAAA,CAAA,IAAI,IAAK,CAAA,YAAY,CAAC,CAAA;AACxC,QAAgB,eAAA,CAAA,IAAI,IAAK,CAAA,UAAU,CAAC,CAAA;AACpC,QAAA,qBAAA,CAAsB,KAAK,CAAA;AAAA;AAE7B,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,UAAA,CAAW,IAAI,CAAA;AAEf,MAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,KACzB;AAAA,IACA,CAAC,iBAAmB,EAAA,eAAA,EAAiB,qBAAqB;AAAA,GAC5D;AAEA,EAAM,MAAA,oBAAA,GAAuB,CAAC,KAAmC,KAAA;AAC/D,IAAA,WAAA,CAAY,MAAM,aAAa,CAAA;AAAA,GACjC;AAEA,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,WAAA,CAAY,IAAI,CAAA;AAAA,GAClB,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,eAAA,GAAkB,YAAY,MAAM;AACxC,IAAA,IAAI,aAAa,OAAS,EAAA;AACxB,MAAA,iBAAA,CAAkB,SAAS,CAAA;AAC3B,MAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,MAAA,qBAAA,CAAsB,KAAK,CAAA;AAC3B,MAAA,iBAAA,CAAkB,WAAW,CAAA;AAC7B,MAAY,WAAA,EAAA;AACZ,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA;AACnB,GACC,EAAA;AAAA,IACD,SAAA;AAAA,IACA,OAAA;AAAA,IACA,iBAAA;AAAA,IACA,eAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAM,MAAA,QAAA,GAAW,QAAQ,MAAM;AAC7B,IAAA,OAAO,CAAC,KAAkB,KAAA;AACxB,MAAI,IAAA,KAAA,KAAU,eAAe,cAAkB,IAAA,YAAA;AAC7C,QAAA,OAAO,CAAG,EAAA,MAAA,CAAO,cAAgB,EAAA,IAAI,CAAC,CAAM,GAAA,EAAA,MAAA;AAAA,UAC1C,YAAA;AAAA,UACA;AAAA,SACD,CAAA,CAAA;AAEH,MAAA,MAAM,SAAS,kBAAmB,CAAA,IAAA,CAAK,CAAO,GAAA,KAAA,GAAA,CAAI,UAAU,KAAK,CAAA;AACjE,MAAO,OAAA,MAAA,GAAS,OAAO,KAAQ,GAAA,cAAA;AAAA,KACjC;AAAA,GACC,EAAA,CAAC,cAAgB,EAAA,YAAY,CAAC,CAAA;AAEjC,EACE,uBAAA,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,iBAAkB,EAAA,mBAAA;AAAA,MAClB,KACE,kBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,IAAA;AAAA,UACR,KAAM,EAAA,aAAA;AAAA,UACN,EAAA,EAAI,EAAE,UAAA,EAAY,MAAO,EAAA;AAAA,UAExB,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,MAEF,KAAA,EAAO,EAAE,UAAA,EAAY,MAAO,EAAA;AAAA,MAE5B,QAAA,EAAA;AAAA,wBAAA,IAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,YAAY,EAAA,IAAA;AAAA,YACZ,IAAM,EAAA,QAAA;AAAA,YACN,MAAA,EAAQ,MAAM,WAAA,CAAY,IAAI,CAAA;AAAA,YAC9B,OAAA,EAAS,MAAM,WAAA,CAAY,KAAK,CAAA;AAAA,YAChC,KAAO,EAAA,cAAA;AAAA,YACP,QAAU,EAAA,YAAA;AAAA,YACV,WAAa,EAAA,CAAC,QAAqB,KAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,YACpD,EAAI,EAAA;AAAA,cACF,QAAU,EAAA,GAAA;AAAA,cACV,WAAa,EAAA;AAAA,aACf;AAAA,YACA,SAAW,EAAA;AAAA,cACT,UAAY,EAAA;AAAA,gBACV,EAAI,EAAA;AAAA,kBACF,QAAU,EAAA,GAAA;AAAA,kBACV,SAAW,EAAA,iCAAA;AAAA,kBACX,QAAQ,CAAS,KAAA,KAAA,CAAA,UAAA,EAAa,MAAM,OAAQ,CAAA,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAAA,kBACrD,QAAU,EAAA;AAAA,iBACZ;AAAA,gBACA,iBAAmB,EAAA;AAAA,eACrB;AAAA,cACA,aAAe,EAAA;AAAA,gBACb,aAAe,EAAA,KAAA;AAAA,gBACf,EAAI,EAAA,EAAE,OAAS,EAAA,OAAA,EAAS,eAAe,QAAS;AAAA;AAClD,aACF;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,kBAAA,CAAmB,IAAI,CACtB,MAAA,qBAAA,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAEC,OAAO,MAAO,CAAA,KAAA;AAAA,kBACd,EAAA,EAAI,EAAE,MAAA,EAAQ,MAAO,EAAA;AAAA,kBAEpB,QAAO,EAAA,MAAA,CAAA;AAAA,iBAAA;AAAA,gBAJH,MAAO,CAAA;AAAA,eAMf,CAAA;AAAA,kCACA,OAAQ,EAAA,EAAA,CAAA;AAAA,8BACT,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,EAAA,EAAI,EAAE,MAAA,EAAQ,MAAO,EAAA;AAAA,kBACrB,aAAa,CAAS,KAAA,KAAA;AACpB,oBAAA,KAAA,CAAM,cAAe,EAAA;AACrB,oBAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,mBAC5B;AAAA,kBACD,QAAA,EAAA;AAAA;AAAA;AAED;AAAA;AAAA,SACF;AAAA,wBAEA,IAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,QAAQ,QAAQ,CAAA;AAAA,YACtB,QAAA;AAAA,YACA,OAAS,EAAA,WAAA;AAAA,YACT,YAAc,EAAA,EAAE,QAAU,EAAA,KAAA,EAAO,YAAY,MAAO,EAAA;AAAA,YACpD,eAAiB,EAAA,EAAE,QAAU,EAAA,KAAA,EAAO,YAAY,OAAQ,EAAA;AAAA,YACxD,SAAW,EAAA;AAAA,cACT,KAAO,EAAA;AAAA,gBACL,EAAA,EAAI,EAAE,SAAA,EAAW,iCAAkC;AAAA;AACrD,aACF;AAAA,YAEA,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,eAAA;AAAA,gBAAA;AAAA,kBACC,SAAA;AAAA,kBACA,YAAA;AAAA,kBACA,OAAA;AAAA,kBACA;AAAA;AAAA,eACF;AAAA,8BAEC,IAAA,CAAA,GAAA,EAAA,EAAI,EAAI,EAAA,EAAE,OAAS,EAAA,MAAA,EAAQ,cAAgB,EAAA,UAAA,EAAY,GAAK,EAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EACjE,EAAA,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,OAAS,EAAA,WAAA;AAAA,oBACT,KAAM,EAAA,SAAA;AAAA,oBACN,EAAA,EAAI,EAAE,aAAA,EAAe,MAAO,EAAA;AAAA,oBAC7B,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACA,GAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,OAAS,EAAA,eAAA;AAAA,oBACT,KAAM,EAAA,SAAA;AAAA,oBACN,QAAA,EAAU,EAAE,SAAa,IAAA,OAAA,CAAA;AAAA,oBAC1B,QAAA,EAAA;AAAA;AAAA;AAED,eACF,EAAA;AAAA;AAAA;AAAA;AACF;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -1,4 +1,5 @@
1
- import React__default from 'react';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useState, useCallback, useMemo } from 'react';
2
3
  import { ResponseErrorPanel } from '@backstage/core-components';
3
4
  import Table from '@mui/material/Table';
4
5
  import TableBody from '@mui/material/TableBody';
@@ -20,97 +21,106 @@ import EmptyChartState from '../Common/EmptyChartState.esm.js';
20
21
  import { useDateRange } from '../Header/DateRangeContext.esm.js';
21
22
 
22
23
  const Plugins = () => {
23
- const [page, setPage] = React__default.useState(0);
24
- const [limit] = React__default.useState(20);
25
- const [rowsPerPage, setRowsPerPage] = React__default.useState(3);
24
+ const [page, setPage] = useState(0);
25
+ const [limit] = useState(20);
26
+ const [rowsPerPage, setRowsPerPage] = useState(3);
26
27
  const { isDefaultDateRange } = useDateRange();
27
28
  const { plugins, loading, error } = usePlugins({ limit });
28
- const handleChangePage = React__default.useCallback(
29
- (_event, newPage) => {
30
- setPage(newPage);
31
- },
32
- []
33
- );
34
- const handleChangeRowsPerPage = React__default.useCallback(
29
+ const handleChangePage = useCallback((_event, newPage) => {
30
+ setPage(newPage);
31
+ }, []);
32
+ const handleChangeRowsPerPage = useCallback(
35
33
  (event) => {
36
34
  setRowsPerPage(+event.target.value);
37
35
  setPage(0);
38
36
  },
39
37
  []
40
38
  );
41
- const visiblePlugins = React__default.useMemo(() => {
39
+ const visiblePlugins = useMemo(() => {
42
40
  return plugins.data?.slice(
43
41
  page * rowsPerPage,
44
42
  page * rowsPerPage + rowsPerPage
45
43
  );
46
44
  }, [plugins, page, rowsPerPage]);
47
45
  if (error) {
48
- return /* @__PURE__ */ React__default.createElement(CardWrapper, { title: "Top plugins" }, /* @__PURE__ */ React__default.createElement(ResponseErrorPanel, { error }));
46
+ return /* @__PURE__ */ jsx(CardWrapper, { title: "Top plugins", children: /* @__PURE__ */ jsx(ResponseErrorPanel, { error }) });
49
47
  }
50
48
  if (!visiblePlugins || visiblePlugins?.length === 0) {
51
- return /* @__PURE__ */ React__default.createElement(CardWrapper, { title: "Top plugins" }, /* @__PURE__ */ React__default.createElement(
49
+ return /* @__PURE__ */ jsx(CardWrapper, { title: "Top plugins", children: /* @__PURE__ */ jsx(
52
50
  Box,
53
51
  {
54
52
  display: "flex",
55
53
  justifyContent: "center",
56
54
  alignItems: "center",
57
- height: 200
58
- },
59
- /* @__PURE__ */ React__default.createElement(EmptyChartState, null)
60
- ));
55
+ height: 200,
56
+ children: /* @__PURE__ */ jsx(EmptyChartState, {})
57
+ }
58
+ ) });
61
59
  }
62
- return /* @__PURE__ */ React__default.createElement(CardWrapper, { title: `Top ${rowsPerPage} plugins` }, /* @__PURE__ */ React__default.createElement(Table, { "aria-labelledby": "Catalog entities", sx: { width: "100%" } }, /* @__PURE__ */ React__default.createElement(TableHead, null, /* @__PURE__ */ React__default.createElement(TableRow, null, PLUGINS_TABLE_HEADERS.map((header) => {
63
- if (isDefaultDateRange && header.id === "percent") return null;
64
- return /* @__PURE__ */ React__default.createElement(
65
- TableCell,
60
+ return /* @__PURE__ */ jsx(CardWrapper, { title: `Top ${rowsPerPage} plugins`, children: /* @__PURE__ */ jsxs(Table, { "aria-labelledby": "Catalog entities", sx: { width: "100%" }, children: [
61
+ /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: PLUGINS_TABLE_HEADERS.map((header) => {
62
+ if (isDefaultDateRange && header.id === "percent") return null;
63
+ return /* @__PURE__ */ jsx(
64
+ TableCell,
65
+ {
66
+ align: "left",
67
+ sx: {
68
+ borderBottom: (theme) => `1px solid ${theme.palette.grey[300]}`
69
+ },
70
+ children: header.title
71
+ },
72
+ header.id
73
+ );
74
+ }) }) }),
75
+ /* @__PURE__ */ jsx(TableBody, { children: loading ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: PLUGINS_TABLE_HEADERS.length, align: "center", children: /* @__PURE__ */ jsx(CircularProgress, {}) }) }) : visiblePlugins?.map((plugin) => /* @__PURE__ */ jsxs(
76
+ TableRow,
66
77
  {
67
- key: header.id,
68
- align: "left",
69
78
  sx: {
79
+ "&:nth-of-type(odd)": { backgroundColor: "inherit" },
70
80
  borderBottom: (theme) => `1px solid ${theme.palette.grey[300]}`
71
- }
81
+ },
82
+ children: [
83
+ /* @__PURE__ */ jsx(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" }, children: plugin.plugin_id ?? "--" }),
84
+ /* @__PURE__ */ jsx(TableCell, { sx: { width: "40%" }, children: plugin.trend?.length > 0 ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: 250, height: 50, children: /* @__PURE__ */ jsx(LineChart, { data: plugin.trend, children: /* @__PURE__ */ jsx(
85
+ Line,
86
+ {
87
+ type: "monotone",
88
+ dataKey: "count",
89
+ stroke: "#9370DB",
90
+ strokeWidth: 2,
91
+ dot: false
92
+ }
93
+ ) }) }) : "--" }),
94
+ !isDefaultDateRange && /* @__PURE__ */ jsx(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" }, children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
95
+ Math.round(Number(plugin.trend_percentage)) < 0 ? /* @__PURE__ */ jsx(TrendingDownIcon, { sx: { color: "red" } }) : /* @__PURE__ */ jsx(TrendingUpIcon, { sx: { color: "green" } }),
96
+ /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
97
+ Math.abs(Math.round(Number(plugin.trend_percentage))),
98
+ "%"
99
+ ] })
100
+ ] }) }),
101
+ /* @__PURE__ */ jsx(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" }, children: Number(plugin.visit_count).toLocaleString("en-US") ?? "--" })
102
+ ]
72
103
  },
73
- header.title
74
- );
75
- }))), /* @__PURE__ */ React__default.createElement(TableBody, null, loading ? /* @__PURE__ */ React__default.createElement(TableRow, null, /* @__PURE__ */ React__default.createElement(TableCell, { colSpan: PLUGINS_TABLE_HEADERS.length, align: "center" }, /* @__PURE__ */ React__default.createElement(CircularProgress, null))) : visiblePlugins?.map((plugin) => /* @__PURE__ */ React__default.createElement(
76
- TableRow,
77
- {
78
- key: plugin.plugin_id,
79
- sx: {
80
- "&:nth-of-type(odd)": { backgroundColor: "inherit" },
81
- borderBottom: (theme) => `1px solid ${theme.palette.grey[300]}`
82
- }
83
- },
84
- /* @__PURE__ */ React__default.createElement(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" } }, plugin.plugin_id ?? "--"),
85
- /* @__PURE__ */ React__default.createElement(TableCell, { sx: { width: "40%" } }, plugin.trend?.length > 0 ? /* @__PURE__ */ React__default.createElement(ResponsiveContainer, { width: 250, height: 50 }, /* @__PURE__ */ React__default.createElement(LineChart, { data: plugin.trend }, /* @__PURE__ */ React__default.createElement(
86
- Line,
87
- {
88
- type: "monotone",
89
- dataKey: "count",
90
- stroke: "#9370DB",
91
- strokeWidth: 2,
92
- dot: false
93
- }
94
- ))) : "--"),
95
- !isDefaultDateRange && /* @__PURE__ */ React__default.createElement(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" } }, /* @__PURE__ */ React__default.createElement(Box, { sx: { display: "flex", alignItems: "center", gap: 1 } }, Math.round(Number(plugin.trend_percentage)) < 0 ? /* @__PURE__ */ React__default.createElement(TrendingDownIcon, { sx: { color: "red" } }) : /* @__PURE__ */ React__default.createElement(TrendingUpIcon, { sx: { color: "green" } }), /* @__PURE__ */ React__default.createElement(Typography, { variant: "body2" }, Math.abs(Math.round(Number(plugin.trend_percentage))), "%"))),
96
- /* @__PURE__ */ React__default.createElement(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" } }, Number(plugin.visit_count).toLocaleString() ?? "--")
97
- ))), /* @__PURE__ */ React__default.createElement(TableFooter, null, /* @__PURE__ */ React__default.createElement(TableRow, null, /* @__PURE__ */ React__default.createElement(
98
- TableCell,
99
- {
100
- colSpan: PLUGINS_TABLE_HEADERS.length,
101
- sx: { padding: 0 }
102
- },
103
- /* @__PURE__ */ React__default.createElement(
104
- TableFooterPagination,
104
+ plugin.plugin_id
105
+ )) }),
106
+ /* @__PURE__ */ jsx(TableFooter, { children: /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(
107
+ TableCell,
105
108
  {
106
- count: plugins.data?.length,
107
- rowsPerPage,
108
- page,
109
- handleChangePage,
110
- handleChangeRowsPerPage
109
+ colSpan: PLUGINS_TABLE_HEADERS.length,
110
+ sx: { padding: 0 },
111
+ children: /* @__PURE__ */ jsx(
112
+ TableFooterPagination,
113
+ {
114
+ count: plugins.data?.length,
115
+ rowsPerPage,
116
+ page,
117
+ handleChangePage,
118
+ handleChangeRowsPerPage
119
+ }
120
+ )
111
121
  }
112
- )
113
- )))));
122
+ ) }) })
123
+ ] }) });
114
124
  };
115
125
 
116
126
  export { Plugins as default };
@@ -1 +1 @@
1
- {"version":3,"file":"Plugins.esm.js","sources":["../../../src/components/Plugins/Plugins.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 React from 'react';\n\nimport { ResponseErrorPanel } from '@backstage/core-components';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableFooter from '@mui/material/TableFooter';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport TrendingUpIcon from '@mui/icons-material/TrendingUp';\nimport TrendingDownIcon from '@mui/icons-material/TrendingDown';\nimport Typography from '@mui/material/Typography';\nimport Box from '@mui/material/Box';\n\nimport CardWrapper from '../CardWrapper';\nimport { PLUGINS_TABLE_HEADERS } from '../../utils/constants';\nimport { usePlugins } from '../../hooks/usePlugins';\nimport TableFooterPagination from '../CardFooter';\nimport { Line, LineChart, ResponsiveContainer } from 'recharts';\nimport EmptyChartState from '../Common/EmptyChartState';\nimport { useDateRange } from '../Header/DateRangeContext';\n\nconst Plugins = () => {\n const [page, setPage] = React.useState(0);\n const [limit] = React.useState(20);\n const [rowsPerPage, setRowsPerPage] = React.useState(3);\n\n const { isDefaultDateRange } = useDateRange();\n const { plugins, loading, error } = usePlugins({ limit });\n\n const handleChangePage = React.useCallback(\n (_event: unknown, newPage: number) => {\n setPage(newPage);\n },\n [],\n );\n\n const handleChangeRowsPerPage = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setRowsPerPage(+event.target.value);\n setPage(0);\n },\n [],\n );\n\n const visiblePlugins = React.useMemo(() => {\n return plugins.data?.slice(\n page * rowsPerPage,\n page * rowsPerPage + rowsPerPage,\n );\n }, [plugins, page, rowsPerPage]);\n\n if (error) {\n return (\n <CardWrapper title=\"Top plugins\">\n <ResponseErrorPanel error={error} />\n </CardWrapper>\n );\n }\n\n if (!visiblePlugins || visiblePlugins?.length === 0) {\n return (\n <CardWrapper title=\"Top plugins\">\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n height={200}\n >\n <EmptyChartState />\n </Box>\n </CardWrapper>\n );\n }\n\n return (\n <CardWrapper title={`Top ${rowsPerPage} plugins`}>\n <Table aria-labelledby=\"Catalog entities\" sx={{ width: '100%' }}>\n <TableHead>\n <TableRow>\n {PLUGINS_TABLE_HEADERS.map(header => {\n if (isDefaultDateRange && header.id === 'percent') return null;\n return (\n <TableCell\n key={header.id}\n align=\"left\"\n sx={{\n borderBottom: theme =>\n `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n {header.title}\n </TableCell>\n );\n })}\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={PLUGINS_TABLE_HEADERS.length} align=\"center\">\n <CircularProgress />\n </TableCell>\n </TableRow>\n ) : (\n visiblePlugins?.map(plugin => (\n <TableRow\n key={plugin.plugin_id}\n sx={{\n '&:nth-of-type(odd)': { backgroundColor: 'inherit' },\n borderBottom: theme => `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n <TableCell sx={isDefaultDateRange ? {} : { width: '20%' }}>\n {plugin.plugin_id ?? '--'}\n </TableCell>\n <TableCell sx={{ width: '40%' }}>\n {plugin.trend?.length > 0 ? (\n <ResponsiveContainer width={250} height={50}>\n <LineChart data={plugin.trend}>\n <Line\n type=\"monotone\"\n dataKey=\"count\"\n stroke=\"#9370DB\"\n strokeWidth={2}\n dot={false}\n />\n </LineChart>\n </ResponsiveContainer>\n ) : (\n '--'\n )}\n </TableCell>\n {!isDefaultDateRange && (\n <TableCell sx={isDefaultDateRange ? {} : { width: '20%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {Math.round(Number(plugin.trend_percentage)) < 0 ? (\n <TrendingDownIcon sx={{ color: 'red' }} />\n ) : (\n <TrendingUpIcon sx={{ color: 'green' }} />\n )}\n <Typography variant=\"body2\">\n {Math.abs(Math.round(Number(plugin.trend_percentage)))}%\n </Typography>\n </Box>\n </TableCell>\n )}\n <TableCell sx={isDefaultDateRange ? {} : { width: '20%' }}>\n {Number(plugin.visit_count).toLocaleString() ?? '--'}\n </TableCell>\n </TableRow>\n ))\n )}\n </TableBody>\n <TableFooter>\n <TableRow>\n <TableCell\n colSpan={PLUGINS_TABLE_HEADERS.length}\n sx={{ padding: 0 }}\n >\n <TableFooterPagination\n count={plugins.data?.length}\n rowsPerPage={rowsPerPage}\n page={page}\n handleChangePage={handleChangePage}\n handleChangeRowsPerPage={handleChangeRowsPerPage}\n />\n </TableCell>\n </TableRow>\n </TableFooter>\n </Table>\n </CardWrapper>\n );\n};\n\nexport default Plugins;\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"Plugins.esm.js","sources":["../../../src/components/Plugins/Plugins.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { useState, useMemo, useCallback } from 'react';\nimport type { ChangeEvent } from 'react';\n\nimport { ResponseErrorPanel } from '@backstage/core-components';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableFooter from '@mui/material/TableFooter';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport TrendingUpIcon from '@mui/icons-material/TrendingUp';\nimport TrendingDownIcon from '@mui/icons-material/TrendingDown';\nimport Typography from '@mui/material/Typography';\nimport Box from '@mui/material/Box';\n\nimport CardWrapper from '../CardWrapper';\nimport { PLUGINS_TABLE_HEADERS } from '../../utils/constants';\nimport { usePlugins } from '../../hooks/usePlugins';\nimport TableFooterPagination from '../CardFooter';\nimport { Line, LineChart, ResponsiveContainer } from 'recharts';\nimport EmptyChartState from '../Common/EmptyChartState';\nimport { useDateRange } from '../Header/DateRangeContext';\n\nconst Plugins = () => {\n const [page, setPage] = useState(0);\n const [limit] = useState(20);\n const [rowsPerPage, setRowsPerPage] = useState(3);\n\n const { isDefaultDateRange } = useDateRange();\n const { plugins, loading, error } = usePlugins({ limit });\n\n const handleChangePage = useCallback((_event: unknown, newPage: number) => {\n setPage(newPage);\n }, []);\n\n const handleChangeRowsPerPage = useCallback(\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setRowsPerPage(+event.target.value);\n setPage(0);\n },\n [],\n );\n\n const visiblePlugins = useMemo(() => {\n return plugins.data?.slice(\n page * rowsPerPage,\n page * rowsPerPage + rowsPerPage,\n );\n }, [plugins, page, rowsPerPage]);\n\n if (error) {\n return (\n <CardWrapper title=\"Top plugins\">\n <ResponseErrorPanel error={error} />\n </CardWrapper>\n );\n }\n\n if (!visiblePlugins || visiblePlugins?.length === 0) {\n return (\n <CardWrapper title=\"Top plugins\">\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n height={200}\n >\n <EmptyChartState />\n </Box>\n </CardWrapper>\n );\n }\n\n return (\n <CardWrapper title={`Top ${rowsPerPage} plugins`}>\n <Table aria-labelledby=\"Catalog entities\" sx={{ width: '100%' }}>\n <TableHead>\n <TableRow>\n {PLUGINS_TABLE_HEADERS.map(header => {\n if (isDefaultDateRange && header.id === 'percent') return null;\n return (\n <TableCell\n key={header.id}\n align=\"left\"\n sx={{\n borderBottom: theme =>\n `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n {header.title}\n </TableCell>\n );\n })}\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={PLUGINS_TABLE_HEADERS.length} align=\"center\">\n <CircularProgress />\n </TableCell>\n </TableRow>\n ) : (\n visiblePlugins?.map(plugin => (\n <TableRow\n key={plugin.plugin_id}\n sx={{\n '&:nth-of-type(odd)': { backgroundColor: 'inherit' },\n borderBottom: theme => `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n <TableCell sx={isDefaultDateRange ? {} : { width: '20%' }}>\n {plugin.plugin_id ?? '--'}\n </TableCell>\n <TableCell sx={{ width: '40%' }}>\n {plugin.trend?.length > 0 ? (\n <ResponsiveContainer width={250} height={50}>\n <LineChart data={plugin.trend}>\n <Line\n type=\"monotone\"\n dataKey=\"count\"\n stroke=\"#9370DB\"\n strokeWidth={2}\n dot={false}\n />\n </LineChart>\n </ResponsiveContainer>\n ) : (\n '--'\n )}\n </TableCell>\n {!isDefaultDateRange && (\n <TableCell sx={isDefaultDateRange ? {} : { width: '20%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {Math.round(Number(plugin.trend_percentage)) < 0 ? (\n <TrendingDownIcon sx={{ color: 'red' }} />\n ) : (\n <TrendingUpIcon sx={{ color: 'green' }} />\n )}\n <Typography variant=\"body2\">\n {Math.abs(Math.round(Number(plugin.trend_percentage)))}%\n </Typography>\n </Box>\n </TableCell>\n )}\n <TableCell sx={isDefaultDateRange ? {} : { width: '20%' }}>\n {Number(plugin.visit_count).toLocaleString('en-US') ?? '--'}\n </TableCell>\n </TableRow>\n ))\n )}\n </TableBody>\n <TableFooter>\n <TableRow>\n <TableCell\n colSpan={PLUGINS_TABLE_HEADERS.length}\n sx={{ padding: 0 }}\n >\n <TableFooterPagination\n count={plugins.data?.length}\n rowsPerPage={rowsPerPage}\n page={page}\n handleChangePage={handleChangePage}\n handleChangeRowsPerPage={handleChangeRowsPerPage}\n />\n </TableCell>\n </TableRow>\n </TableFooter>\n </Table>\n </CardWrapper>\n );\n};\n\nexport default Plugins;\n"],"names":[],"mappings":"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"}