@red-hat-developer-hub/backstage-plugin-adoption-insights 0.2.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.
- package/CHANGELOG.md +13 -0
- package/dist/api/index.esm.js +1 -1
- package/dist/api/index.esm.js.map +1 -1
- package/dist/components/ActiveUsers/ActiveUsers.esm.js +8 -7
- package/dist/components/ActiveUsers/ActiveUsers.esm.js.map +1 -1
- package/dist/components/ActiveUsers/ExportCSVButton.esm.js +1 -0
- package/dist/components/ActiveUsers/ExportCSVButton.esm.js.map +1 -1
- package/dist/components/CatalogEntities/CatalogEntities.esm.js +1 -1
- package/dist/components/CatalogEntities/CatalogEntities.esm.js.map +1 -1
- package/dist/components/Common/ChartTooltip.esm.js +91 -0
- package/dist/components/Common/ChartTooltip.esm.js.map +1 -0
- package/dist/components/Header/Header.esm.js +1 -0
- package/dist/components/Header/Header.esm.js.map +1 -1
- package/dist/components/Plugins/Plugins.esm.js +1 -1
- package/dist/components/Plugins/Plugins.esm.js.map +1 -1
- package/dist/components/Searches/Searches.esm.js +7 -7
- package/dist/components/Searches/Searches.esm.js.map +1 -1
- package/dist/components/Techdocs/Techdocs.esm.js +1 -1
- package/dist/components/Techdocs/Techdocs.esm.js.map +1 -1
- package/dist/components/Templates/Templates.esm.js +1 -1
- package/dist/components/Templates/Templates.esm.js.map +1 -1
- package/dist/components/Users/Tooltip.esm.js +1 -1
- package/dist/components/Users/Tooltip.esm.js.map +1 -1
- package/dist/components/Users/Users.esm.js +2 -2
- package/dist/components/Users/Users.esm.js.map +1 -1
- package/dist/hooks/useActiveUsers.esm.js +5 -3
- package/dist/hooks/useActiveUsers.esm.js.map +1 -1
- package/dist/hooks/useCatalogEntities.esm.js +4 -1
- package/dist/hooks/useCatalogEntities.esm.js.map +1 -1
- package/dist/hooks/usePlugins.esm.js +4 -1
- package/dist/hooks/usePlugins.esm.js.map +1 -1
- package/dist/hooks/useSearches.esm.js +6 -2
- package/dist/hooks/useSearches.esm.js.map +1 -1
- package/dist/hooks/useTechdocs.esm.js +4 -1
- package/dist/hooks/useTechdocs.esm.js.map +1 -1
- package/dist/hooks/useTemplates.esm.js +4 -1
- package/dist/hooks/useTemplates.esm.js.map +1 -1
- package/dist/hooks/useUsers.esm.js +5 -2
- package/dist/hooks/useUsers.esm.js.map +1 -1
- package/dist/utils/utils.esm.js +70 -30
- package/dist/utils/utils.esm.js.map +1 -1
- package/package.json +3 -2
- package/dist/components/ActiveUsers/CustomTooltip.esm.js +0 -98
- package/dist/components/ActiveUsers/CustomTooltip.esm.js.map +0 -1
- package/dist/components/Searches/CustomTooltip.esm.js +0 -71
- package/dist/components/Searches/CustomTooltip.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-adoption-insights
|
2
2
|
|
3
|
+
## 0.2.1
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- 38372b3: Updated dependency `@red-hat-developer-hub/backstage-plugin-theme` to `^0.9.0`.
|
8
|
+
- 586901c: Timezone Fixes for Consistent Data Grouping and Display
|
9
|
+
|
10
|
+
- Backend now accepts an explicit timezone parameter from the frontend instead of relying on Intl.DateTimeFormat().resolvedOptions().timeZone.
|
11
|
+
- This eliminates discrepancies between frontend simulation and backend processing.
|
12
|
+
- Accurate Date Range Construction
|
13
|
+
- Updated PostgreSQL query to respect user timezone.
|
14
|
+
- Tooltips now show formatted times based on user's selected timeszone.
|
15
|
+
|
3
16
|
## 0.2.0
|
4
17
|
|
5
18
|
### Minor Changes
|
package/dist/api/index.esm.js
CHANGED
@@ -103,7 +103,7 @@ class AdoptionInsightsApiClient {
|
|
103
103
|
async downloadBlob(options) {
|
104
104
|
const baseUrl = await this.getBaseUrl();
|
105
105
|
const response = await this.fetchApi.fetch(
|
106
|
-
`${baseUrl}/events?type=${options.type}&start_date=${options.start_date}&end_date=${options.end_date}&format=${options.format}`
|
106
|
+
`${baseUrl}/events?type=${options.type}&start_date=${options.start_date}&end_date=${options.end_date}&format=${options.format}&timezone=${options.timezone}`
|
107
107
|
);
|
108
108
|
const blob = await response.blob();
|
109
109
|
const blobUrl = window.URL.createObjectURL(blob);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"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 { createApiRef, ConfigApi, FetchApi } from '@backstage/core-plugin-api';\nimport {\n AdoptionInsightsApi,\n APIsViewOptions,\n TemplatesResponse,\n CatalogEntitiesResponse,\n PluginTrendResponse,\n UsersResponse,\n TechdocsResponse,\n ActiveUsersResponse,\n SearchesResponse,\n} from '../types';\nimport { generateEventsUrl } from '../utils/utils';\n\nexport interface InsightsApi {\n downloadBlob(options: APIsViewOptions): Promise<any>;\n getActiveUsers(options: APIsViewOptions): Promise<ActiveUsersResponse>;\n getUsers(options: APIsViewOptions): Promise<UsersResponse>;\n getCatalogEntities(\n options: APIsViewOptions,\n ): Promise<CatalogEntitiesResponse>;\n getTemplates(options: APIsViewOptions): Promise<TemplatesResponse>;\n getTechdocs(options: APIsViewOptions): Promise<TechdocsResponse>;\n getPlugins(options: APIsViewOptions): Promise<PluginTrendResponse>;\n getSearches(options: APIsViewOptions): Promise<SearchesResponse>;\n}\n\nexport const adoptionInsightsApiRef = createApiRef<AdoptionInsightsApi>({\n id: 'plugin.adoption-insights.service',\n});\n\nexport type Options = {\n configApi: ConfigApi;\n fetchApi: FetchApi;\n};\n\nconst validateResponse = (response: Response, action: string) => {\n if (!response.body || !response.ok) {\n throw new Error(\n `failed to fetch ${action}, status ${response.status}: ${\n !response.ok ? response.statusText : 'Something went wrong.'\n }`,\n );\n }\n};\n\nexport class AdoptionInsightsApiClient implements AdoptionInsightsApi {\n private readonly configApi: ConfigApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: Options) {\n this.configApi = options.configApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getBaseUrl() {\n return `${this.configApi.getString(\n 'backend.baseUrl',\n )}/api/adoption-insights`;\n }\n\n async getActiveUsers(options: APIsViewOptions): Promise<ActiveUsersResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ grouping: undefined, data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'active users');\n\n const data = await response.json();\n return data as ActiveUsersResponse;\n }\n\n async getUsers(options: APIsViewOptions): Promise<UsersResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'users');\n\n const data = await response.json();\n return data as UsersResponse;\n }\n\n async getCatalogEntities(\n options: APIsViewOptions,\n ): Promise<CatalogEntitiesResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'catalog entities');\n\n const data = await response.json();\n return data as CatalogEntitiesResponse;\n }\n\n async getTemplates(options: APIsViewOptions): Promise<TemplatesResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'templates');\n\n const data = await response.json();\n return data as TemplatesResponse;\n }\n\n async getTechdocs(options: APIsViewOptions): Promise<TechdocsResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'techdocs');\n\n const data = await response.json();\n return data as TechdocsResponse;\n }\n\n async getPlugins(options: APIsViewOptions): Promise<PluginTrendResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'plugins');\n\n const data = await response.json();\n return data as PluginTrendResponse;\n }\n\n async getSearches(options: APIsViewOptions): Promise<SearchesResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ grouping: undefined, data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'searches');\n\n const data = await response.json();\n return data as SearchesResponse;\n }\n\n async downloadBlob(options: APIsViewOptions): Promise<void> {\n const baseUrl = await this.getBaseUrl();\n const response = await this.fetchApi.fetch(\n `${baseUrl}/events?type=${options.type}&start_date=${options.start_date}&end_date=${options.end_date}&format=${options.format}`,\n );\n const blob = await response.blob();\n const blobUrl = window.URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = blobUrl;\n link.download = options.blobName ?? 'active-users';\n document.body.appendChild(link);\n link.click();\n link.parentNode?.removeChild(link);\n }\n}\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"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 { createApiRef, ConfigApi, FetchApi } from '@backstage/core-plugin-api';\nimport {\n AdoptionInsightsApi,\n APIsViewOptions,\n TemplatesResponse,\n CatalogEntitiesResponse,\n PluginTrendResponse,\n UsersResponse,\n TechdocsResponse,\n ActiveUsersResponse,\n SearchesResponse,\n} from '../types';\nimport { generateEventsUrl } from '../utils/utils';\n\nexport interface InsightsApi {\n downloadBlob(options: APIsViewOptions): Promise<any>;\n getActiveUsers(options: APIsViewOptions): Promise<ActiveUsersResponse>;\n getUsers(options: APIsViewOptions): Promise<UsersResponse>;\n getCatalogEntities(\n options: APIsViewOptions,\n ): Promise<CatalogEntitiesResponse>;\n getTemplates(options: APIsViewOptions): Promise<TemplatesResponse>;\n getTechdocs(options: APIsViewOptions): Promise<TechdocsResponse>;\n getPlugins(options: APIsViewOptions): Promise<PluginTrendResponse>;\n getSearches(options: APIsViewOptions): Promise<SearchesResponse>;\n}\n\nexport const adoptionInsightsApiRef = createApiRef<AdoptionInsightsApi>({\n id: 'plugin.adoption-insights.service',\n});\n\nexport type Options = {\n configApi: ConfigApi;\n fetchApi: FetchApi;\n};\n\nconst validateResponse = (response: Response, action: string) => {\n if (!response.body || !response.ok) {\n throw new Error(\n `failed to fetch ${action}, status ${response.status}: ${\n !response.ok ? response.statusText : 'Something went wrong.'\n }`,\n );\n }\n};\n\nexport class AdoptionInsightsApiClient implements AdoptionInsightsApi {\n private readonly configApi: ConfigApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: Options) {\n this.configApi = options.configApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getBaseUrl() {\n return `${this.configApi.getString(\n 'backend.baseUrl',\n )}/api/adoption-insights`;\n }\n\n async getActiveUsers(options: APIsViewOptions): Promise<ActiveUsersResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ grouping: undefined, data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'active users');\n\n const data = await response.json();\n return data as ActiveUsersResponse;\n }\n\n async getUsers(options: APIsViewOptions): Promise<UsersResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'users');\n\n const data = await response.json();\n return data as UsersResponse;\n }\n\n async getCatalogEntities(\n options: APIsViewOptions,\n ): Promise<CatalogEntitiesResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'catalog entities');\n\n const data = await response.json();\n return data as CatalogEntitiesResponse;\n }\n\n async getTemplates(options: APIsViewOptions): Promise<TemplatesResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'templates');\n\n const data = await response.json();\n return data as TemplatesResponse;\n }\n\n async getTechdocs(options: APIsViewOptions): Promise<TechdocsResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'techdocs');\n\n const data = await response.json();\n return data as TechdocsResponse;\n }\n\n async getPlugins(options: APIsViewOptions): Promise<PluginTrendResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'plugins');\n\n const data = await response.json();\n return data as PluginTrendResponse;\n }\n\n async getSearches(options: APIsViewOptions): Promise<SearchesResponse> {\n if (!options.start_date || !options.end_date) {\n return Promise.resolve({ grouping: undefined, data: [] });\n }\n\n const baseUrl = await this.getBaseUrl();\n const url = generateEventsUrl(`${baseUrl}/events`, options);\n\n const response = await this.fetchApi.fetch(url);\n\n validateResponse(response, 'searches');\n\n const data = await response.json();\n return data as SearchesResponse;\n }\n\n async downloadBlob(options: APIsViewOptions): Promise<void> {\n const baseUrl = await this.getBaseUrl();\n const response = await this.fetchApi.fetch(\n `${baseUrl}/events?type=${options.type}&start_date=${options.start_date}&end_date=${options.end_date}&format=${options.format}&timezone=${options.timezone}`,\n );\n const blob = await response.blob();\n const blobUrl = window.URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = blobUrl;\n link.download = options.blobName ?? 'active-users';\n document.body.appendChild(link);\n link.click();\n link.parentNode?.removeChild(link);\n }\n}\n"],"names":[],"mappings":"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"}
|
@@ -5,7 +5,6 @@ import { useTheme } from '@mui/material/styles';
|
|
5
5
|
import CircularProgress from '@mui/material/CircularProgress';
|
6
6
|
import { ResponsiveContainer, AreaChart, CartesianGrid, XAxis, YAxis, Tooltip, Area, Legend } from 'recharts';
|
7
7
|
import CardWrapper from '../CardWrapper/CardWrapper.esm.js';
|
8
|
-
import CustomTooltip from './CustomTooltip.esm.js';
|
9
8
|
import CustomCursor from '../Common/CustomCursor.esm.js';
|
10
9
|
import CustomLegend from './CustomLegend.esm.js';
|
11
10
|
import { getAverage, getXAxisTickValues, getXAxisformat } from '../../utils/utils.esm.js';
|
@@ -13,6 +12,7 @@ import { useActiveUsers } from '../../hooks/useActiveUsers.esm.js';
|
|
13
12
|
import { Typography } from '@material-ui/core';
|
14
13
|
import ExportCSVButton from './ExportCSVButton.esm.js';
|
15
14
|
import EmptyChartState from '../Common/EmptyChartState.esm.js';
|
15
|
+
import ChartTooltip from '../Common/ChartTooltip.esm.js';
|
16
16
|
|
17
17
|
const ActiveUsers = () => {
|
18
18
|
const theme = useTheme();
|
@@ -45,9 +45,9 @@ const ActiveUsers = () => {
|
|
45
45
|
}
|
46
46
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
47
47
|
/* @__PURE__ */ jsxs(Typography, { style: { margin: "20px 36px" }, children: [
|
48
|
-
/* @__PURE__ */ jsx("b", { children: `${Math.round(
|
49
|
-
|
50
|
-
)
|
48
|
+
/* @__PURE__ */ jsx("b", { children: `${Math.round(getAverage(data, "total_users")).toLocaleString(
|
49
|
+
"en-Us"
|
50
|
+
)} active users per ${grouping === "hourly" ? "hour" : "day"}` }),
|
51
51
|
" ",
|
52
52
|
"were conducted during this period."
|
53
53
|
] }),
|
@@ -104,7 +104,7 @@ const ActiveUsers = () => {
|
|
104
104
|
tick: { fill: theme.palette.text.primary },
|
105
105
|
tickLine: false,
|
106
106
|
axisLine: false,
|
107
|
-
tickFormatter: (value) => value.toLocaleString(),
|
107
|
+
tickFormatter: (value) => value.toLocaleString("en-Us"),
|
108
108
|
tickMargin: 20
|
109
109
|
}
|
110
110
|
),
|
@@ -112,7 +112,7 @@ const ActiveUsers = () => {
|
|
112
112
|
Tooltip,
|
113
113
|
{
|
114
114
|
cursor: /* @__PURE__ */ jsx(CustomCursor, { cursorHeight: 250 }),
|
115
|
-
content: /* @__PURE__ */ jsx(
|
115
|
+
content: /* @__PURE__ */ jsx(ChartTooltip, { grouping })
|
116
116
|
}
|
117
117
|
),
|
118
118
|
/* @__PURE__ */ jsx(
|
@@ -137,7 +137,8 @@ const ActiveUsers = () => {
|
|
137
137
|
),
|
138
138
|
/* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(CustomLegend, {}) })
|
139
139
|
]
|
140
|
-
}
|
140
|
+
},
|
141
|
+
JSON.stringify(data.map((d) => d))
|
141
142
|
) }) })
|
142
143
|
] }) });
|
143
144
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ActiveUsers.esm.js","sources":["../../../src/components/ActiveUsers/ActiveUsers.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 { ResponseErrorPanel } from '@backstage/core-components';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport {\n AreaChart,\n CartesianGrid,\n ResponsiveContainer,\n XAxis,\n YAxis,\n Tooltip,\n Area,\n Legend,\n} from 'recharts';\n\nimport CardWrapper from '../CardWrapper';\nimport CustomTooltip from './CustomTooltip';\nimport CustomCursor from '../Common/CustomCursor';\nimport CustomLegend from './CustomLegend';\nimport {\n getAverage,\n getXAxisformat,\n getXAxisTickValues,\n} from '../../utils/utils';\nimport { useActiveUsers } from '../../hooks/useActiveUsers';\nimport { Typography } from '@material-ui/core';\nimport ExportCSVButton from './ExportCSVButton';\nimport EmptyChartState from '../Common/EmptyChartState';\n\nconst ActiveUsers = () => {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n\n const { activeUsers, loading, error } = useActiveUsers();\n const { data, grouping = 'daily' } = activeUsers;\n\n if (error) {\n return (\n <CardWrapper title=\"Active users\">\n <ResponseErrorPanel error={error} />\n </CardWrapper>\n );\n }\n\n if (!data || data?.length === 0 || (!data?.[0] && !loading)) {\n return (\n <CardWrapper title=\"Active users\">\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=\"Active users\" filter={<ExportCSVButton />}>\n {loading ? (\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n height={200}\n >\n <CircularProgress />\n </Box>\n ) : (\n <>\n <Typography style={{ margin: '20px 36px' }}>\n <b>\n {`${Math.round(\n getAverage(data, 'total_users'),\n ).toLocaleString()} active users per ${\n grouping === 'hourly' ? 'hour' : 'day'\n }`}\n </b>{' '}\n were conducted during this period.\n </Typography>\n <Box sx={{ height: 310, mt: 4, mb: 4, ml: 0, mr: 0 }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart\n data={data}\n margin={{ top: 10, right: 50, left: 20, bottom: 0 }}\n >\n <defs>\n <linearGradient id=\"new_users\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor=\"#1976d2\" stopOpacity={0.8} />\n <stop offset=\"95%\" stopColor=\"#1976d2\" stopOpacity={0.2} />\n </linearGradient>\n <linearGradient\n id=\"returning_users\"\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop offset=\"5%\" stopColor=\"#B8BBBE\" stopOpacity={0.8} />\n <stop offset=\"95%\" stopColor=\"#B8BBBE\" stopOpacity={0.2} />\n </linearGradient>\n </defs>\n\n <CartesianGrid\n stroke={isDarkMode ? '#666' : '#E5E7EB'}\n strokeDasharray={0}\n vertical={false}\n />\n\n <XAxis\n dataKey=\"date\"\n tickFormatter={date => getXAxisformat(date, grouping)}\n ticks={getXAxisTickValues(data, grouping)}\n tick={{ fill: theme.palette.text.primary }}\n axisLine={false}\n tickLine={false}\n padding={{ left: 30, right: 30 }}\n tickMargin={10}\n />\n <YAxis\n tick={{ fill: theme.palette.text.primary }}\n tickLine={false}\n axisLine={false}\n tickFormatter={value => value.toLocaleString()}\n tickMargin={20}\n />\n <Tooltip\n cursor={<CustomCursor cursorHeight={250} />}\n content={<CustomTooltip grouping={grouping} />}\n />\n <Area\n type=\"linear\"\n dataKey=\"returning_users\"\n stroke=\"#555\"\n fill=\"url(#returning_users)\"\n strokeWidth={1}\n />\n <Area\n type=\"linear\"\n dataKey=\"new_users\"\n stroke=\"#1976d2\"\n fill=\"url(#new_users)\"\n strokeWidth={1}\n />\n <Legend content={<CustomLegend />} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n </>\n )}\n </CardWrapper>\n );\n};\n\nexport default ActiveUsers;\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"ActiveUsers.esm.js","sources":["../../../src/components/ActiveUsers/ActiveUsers.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 { ResponseErrorPanel } from '@backstage/core-components';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport {\n AreaChart,\n CartesianGrid,\n ResponsiveContainer,\n XAxis,\n YAxis,\n Tooltip,\n Area,\n Legend,\n} from 'recharts';\n\nimport CardWrapper from '../CardWrapper';\nimport CustomCursor from '../Common/CustomCursor';\nimport CustomLegend from './CustomLegend';\nimport {\n getAverage,\n getXAxisformat,\n getXAxisTickValues,\n} from '../../utils/utils';\nimport { useActiveUsers } from '../../hooks/useActiveUsers';\nimport { Typography } from '@material-ui/core';\nimport ExportCSVButton from './ExportCSVButton';\nimport EmptyChartState from '../Common/EmptyChartState';\nimport ChartTooltip from '../Common/ChartTooltip';\n\nconst ActiveUsers = () => {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n\n const { activeUsers, loading, error } = useActiveUsers();\n const { data, grouping = 'daily' } = activeUsers;\n if (error) {\n return (\n <CardWrapper title=\"Active users\">\n <ResponseErrorPanel error={error} />\n </CardWrapper>\n );\n }\n\n if (!data || data?.length === 0 || (!data?.[0] && !loading)) {\n return (\n <CardWrapper title=\"Active users\">\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=\"Active users\" filter={<ExportCSVButton />}>\n {loading ? (\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n height={200}\n >\n <CircularProgress />\n </Box>\n ) : (\n <>\n <Typography style={{ margin: '20px 36px' }}>\n <b>\n {`${Math.round(getAverage(data, 'total_users')).toLocaleString(\n 'en-Us',\n )} active users per ${grouping === 'hourly' ? 'hour' : 'day'}`}\n </b>{' '}\n were conducted during this period.\n </Typography>\n <Box sx={{ height: 310, mt: 4, mb: 4, ml: 0, mr: 0 }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart\n data={data}\n margin={{ top: 10, right: 50, left: 20, bottom: 0 }}\n key={JSON.stringify(data.map(d => d))}\n >\n <defs>\n <linearGradient id=\"new_users\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor=\"#1976d2\" stopOpacity={0.8} />\n <stop offset=\"95%\" stopColor=\"#1976d2\" stopOpacity={0.2} />\n </linearGradient>\n <linearGradient\n id=\"returning_users\"\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop offset=\"5%\" stopColor=\"#B8BBBE\" stopOpacity={0.8} />\n <stop offset=\"95%\" stopColor=\"#B8BBBE\" stopOpacity={0.2} />\n </linearGradient>\n </defs>\n\n <CartesianGrid\n stroke={isDarkMode ? '#666' : '#E5E7EB'}\n strokeDasharray={0}\n vertical={false}\n />\n\n <XAxis\n dataKey=\"date\"\n tickFormatter={date => getXAxisformat(date, grouping)}\n ticks={getXAxisTickValues(data, grouping)}\n tick={{ fill: theme.palette.text.primary }}\n axisLine={false}\n tickLine={false}\n padding={{ left: 30, right: 30 }}\n tickMargin={10}\n />\n <YAxis\n tick={{ fill: theme.palette.text.primary }}\n tickLine={false}\n axisLine={false}\n tickFormatter={value => value.toLocaleString('en-Us')}\n tickMargin={20}\n />\n <Tooltip\n cursor={<CustomCursor cursorHeight={250} />}\n content={<ChartTooltip grouping={grouping} />}\n />\n <Area\n type=\"linear\"\n dataKey=\"returning_users\"\n stroke=\"#555\"\n fill=\"url(#returning_users)\"\n strokeWidth={1}\n />\n <Area\n type=\"linear\"\n dataKey=\"new_users\"\n stroke=\"#1976d2\"\n fill=\"url(#new_users)\"\n strokeWidth={1}\n />\n <Legend content={<CustomLegend />} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n </>\n )}\n </CardWrapper>\n );\n};\n\nexport default ActiveUsers;\n"],"names":[],"mappings":"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"}
|
@@ -21,6 +21,7 @@ const ExportCSVButton = () => {
|
|
21
21
|
type: "active_users",
|
22
22
|
start_date: startDateRange ? format(startDateRange, "yyyy-MM-dd") : void 0,
|
23
23
|
end_date: endDateRange ? format(endDateRange, "yyyy-MM-dd") : void 0,
|
24
|
+
timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone,
|
24
25
|
format: "csv"
|
25
26
|
});
|
26
27
|
} catch (error) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ExportCSVButton.esm.js","sources":["../../../src/components/ActiveUsers/ExportCSVButton.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 { useRef, useState } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport Button from '@mui/material/Button';\nimport FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport { format } from 'date-fns';\n\nimport { adoptionInsightsApiRef } from '../../api';\nimport { useDateRange } from '../Header/DateRangeContext';\n\nconst ExportCSVButton = () => {\n const [loading, setLoading] = useState(false);\n const api = useApi(adoptionInsightsApiRef);\n const { startDateRange, endDateRange } = useDateRange();\n const theme = useTheme();\n const debounceRef = useRef<NodeJS.Timeout | null>(null);\n\n const handleCSVDownload = async () => {\n try {\n await api.downloadBlob({\n type: 'active_users',\n start_date: startDateRange\n ? format(startDateRange, 'yyyy-MM-dd')\n : undefined,\n end_date: endDateRange ? format(endDateRange, 'yyyy-MM-dd') : undefined,\n format: 'csv',\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('CSV Download failed:', error);\n } finally {\n setLoading(false);\n }\n };\n\n const debouncedHandleCSVDownload = () => {\n setLoading(true);\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n debounceRef.current = setTimeout(() => {\n handleCSVDownload();\n }, 500);\n };\n\n return (\n <Box\n sx={{\n height: '100%',\n minWidth: 160,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Button\n variant=\"text\"\n startIcon={<FileDownloadOutlinedIcon />}\n onClick={debouncedHandleCSVDownload}\n sx={{\n color: theme.palette.primary.main,\n textTransform: 'none',\n fontSize: '1rem',\n fontWeight: 400,\n textDecoration: 'none',\n '&:hover': {\n backgroundColor: 'transparent',\n textDecoration: 'none',\n },\n }}\n >\n {loading ? 'Downloading...' : 'Export CSV'}\n </Button>\n </Box>\n );\n};\n\nexport default ExportCSVButton;\n"],"names":[],"mappings":";;;;;;;;;;;AA2BA,MAAM,kBAAkB,MAAM;AAC5B,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAM,MAAA,GAAA,GAAM,OAAO,sBAAsB,CAAA;AACzC,EAAA,MAAM,EAAE,cAAA,EAAgB,YAAa,EAAA,GAAI,YAAa,EAAA;AACtD,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAM,MAAA,WAAA,GAAc,OAA8B,IAAI,CAAA;AAEtD,EAAA,MAAM,oBAAoB,YAAY;AACpC,IAAI,IAAA;AACF,MAAA,MAAM,IAAI,YAAa,CAAA;AAAA,QACrB,IAAM,EAAA,cAAA;AAAA,QACN,UAAY,EAAA,cAAA,GACR,MAAO,CAAA,cAAA,EAAgB,YAAY,CACnC,GAAA,KAAA,CAAA;AAAA,QACJ,QAAU,EAAA,YAAA,GAAe,MAAO,CAAA,YAAA,EAAc,YAAY,CAAI,GAAA,KAAA,CAAA;AAAA,QAC9D,MAAQ,EAAA;AAAA,OACT,CAAA;AAAA,aACM,KAAO,EAAA;AAEd,MAAQ,OAAA,CAAA,KAAA,CAAM,wBAAwB,KAAK,CAAA;AAAA,KAC3C,SAAA;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAClB,GACF;AAEA,EAAA,MAAM,6BAA6B,MAAM;AACvC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI,YAAY,OAAS,EAAA;AACvB,MAAA,YAAA,CAAa,YAAY,OAAO,CAAA;AAAA;AAElC,IAAY,WAAA,CAAA,OAAA,GAAU,WAAW,MAAM;AACrC,MAAkB,iBAAA,EAAA;AAAA,OACjB,GAAG,CAAA;AAAA,GACR;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA;AAAA,QACF,MAAQ,EAAA,MAAA;AAAA,QACR,QAAU,EAAA,GAAA;AAAA,QACV,OAAS,EAAA,MAAA;AAAA,QACT,UAAY,EAAA,QAAA;AAAA,QACZ,cAAgB,EAAA;AAAA,OAClB;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,MAAA;AAAA,UACR,SAAA,sBAAY,wBAAyB,EAAA,EAAA,CAAA;AAAA,UACrC,OAAS,EAAA,0BAAA;AAAA,UACT,EAAI,EAAA;AAAA,YACF,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA;AAAA,YAC7B,aAAe,EAAA,MAAA;AAAA,YACf,QAAU,EAAA,MAAA;AAAA,YACV,UAAY,EAAA,GAAA;AAAA,YACZ,cAAgB,EAAA,MAAA;AAAA,YAChB,SAAW,EAAA;AAAA,cACT,eAAiB,EAAA,aAAA;AAAA,cACjB,cAAgB,EAAA;AAAA;AAClB,WACF;AAAA,UAEC,oBAAU,gBAAmB,GAAA;AAAA;AAAA;AAChC;AAAA,GACF;AAEJ;;;;"}
|
1
|
+
{"version":3,"file":"ExportCSVButton.esm.js","sources":["../../../src/components/ActiveUsers/ExportCSVButton.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 { useRef, useState } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport Button from '@mui/material/Button';\nimport FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport { format } from 'date-fns';\n\nimport { adoptionInsightsApiRef } from '../../api';\nimport { useDateRange } from '../Header/DateRangeContext';\n\nconst ExportCSVButton = () => {\n const [loading, setLoading] = useState(false);\n const api = useApi(adoptionInsightsApiRef);\n const { startDateRange, endDateRange } = useDateRange();\n const theme = useTheme();\n const debounceRef = useRef<NodeJS.Timeout | null>(null);\n\n const handleCSVDownload = async () => {\n try {\n await api.downloadBlob({\n type: 'active_users',\n start_date: startDateRange\n ? format(startDateRange, 'yyyy-MM-dd')\n : undefined,\n end_date: endDateRange ? format(endDateRange, 'yyyy-MM-dd') : undefined,\n timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone,\n format: 'csv',\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('CSV Download failed:', error);\n } finally {\n setLoading(false);\n }\n };\n\n const debouncedHandleCSVDownload = () => {\n setLoading(true);\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n debounceRef.current = setTimeout(() => {\n handleCSVDownload();\n }, 500);\n };\n\n return (\n <Box\n sx={{\n height: '100%',\n minWidth: 160,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Button\n variant=\"text\"\n startIcon={<FileDownloadOutlinedIcon />}\n onClick={debouncedHandleCSVDownload}\n sx={{\n color: theme.palette.primary.main,\n textTransform: 'none',\n fontSize: '1rem',\n fontWeight: 400,\n textDecoration: 'none',\n '&:hover': {\n backgroundColor: 'transparent',\n textDecoration: 'none',\n },\n }}\n >\n {loading ? 'Downloading...' : 'Export CSV'}\n </Button>\n </Box>\n );\n};\n\nexport default ExportCSVButton;\n"],"names":[],"mappings":";;;;;;;;;;;AA2BA,MAAM,kBAAkB,MAAM;AAC5B,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAM,MAAA,GAAA,GAAM,OAAO,sBAAsB,CAAA;AACzC,EAAA,MAAM,EAAE,cAAA,EAAgB,YAAa,EAAA,GAAI,YAAa,EAAA;AACtD,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAM,MAAA,WAAA,GAAc,OAA8B,IAAI,CAAA;AAEtD,EAAA,MAAM,oBAAoB,YAAY;AACpC,IAAI,IAAA;AACF,MAAA,MAAM,IAAI,YAAa,CAAA;AAAA,QACrB,IAAM,EAAA,cAAA;AAAA,QACN,UAAY,EAAA,cAAA,GACR,MAAO,CAAA,cAAA,EAAgB,YAAY,CACnC,GAAA,KAAA,CAAA;AAAA,QACJ,QAAU,EAAA,YAAA,GAAe,MAAO,CAAA,YAAA,EAAc,YAAY,CAAI,GAAA,KAAA,CAAA;AAAA,QAC9D,UAAU,IAAI,IAAA,CAAK,cAAe,EAAA,CAAE,iBAAkB,CAAA,QAAA;AAAA,QACtD,MAAQ,EAAA;AAAA,OACT,CAAA;AAAA,aACM,KAAO,EAAA;AAEd,MAAQ,OAAA,CAAA,KAAA,CAAM,wBAAwB,KAAK,CAAA;AAAA,KAC3C,SAAA;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAClB,GACF;AAEA,EAAA,MAAM,6BAA6B,MAAM;AACvC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI,YAAY,OAAS,EAAA;AACvB,MAAA,YAAA,CAAa,YAAY,OAAO,CAAA;AAAA;AAElC,IAAY,WAAA,CAAA,OAAA,GAAU,WAAW,MAAM;AACrC,MAAkB,iBAAA,EAAA;AAAA,OACjB,GAAG,CAAA;AAAA,GACR;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA;AAAA,QACF,MAAQ,EAAA,MAAA;AAAA,QACR,QAAU,EAAA,GAAA;AAAA,QACV,OAAS,EAAA,MAAA;AAAA,QACT,UAAY,EAAA,QAAA;AAAA,QACZ,cAAgB,EAAA;AAAA,OAClB;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,MAAA;AAAA,UACR,SAAA,sBAAY,wBAAyB,EAAA,EAAA,CAAA;AAAA,UACrC,OAAS,EAAA,0BAAA;AAAA,UACT,EAAI,EAAA;AAAA,YACF,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA;AAAA,YAC7B,aAAe,EAAA,MAAA;AAAA,YACf,QAAU,EAAA,MAAA;AAAA,YACV,UAAY,EAAA,GAAA;AAAA,YACZ,cAAgB,EAAA,MAAA;AAAA,YAChB,SAAW,EAAA;AAAA,cACT,eAAiB,EAAA,aAAA;AAAA,cACjB,cAAgB,EAAA;AAAA;AAClB,WACF;AAAA,UAEC,oBAAU,gBAAmB,GAAA;AAAA;AAAA;AAChC;AAAA,GACF;AAEJ;;;;"}
|
@@ -135,7 +135,7 @@ const CatalogEntities = () => {
|
|
135
135
|
) }),
|
136
136
|
/* @__PURE__ */ jsx(TableCell, { sx: { width: "25%" }, children: entity.kind?.charAt(0).toLocaleUpperCase("en-US") + entity.kind?.slice(1) || "--" }),
|
137
137
|
/* @__PURE__ */ jsx(TableCell, { sx: { width: "25%" }, children: getLastUsedDay(entity.last_used) ?? "--" }),
|
138
|
-
/* @__PURE__ */ jsx(TableCell, { sx: { width: "25%" }, children: Number(entity.count).toLocaleString() ?? "--" })
|
138
|
+
/* @__PURE__ */ jsx(TableCell, { sx: { width: "25%" }, children: Number(entity.count).toLocaleString("en-US") ?? "--" })
|
139
139
|
]
|
140
140
|
},
|
141
141
|
`${entity.kind}-${entity.name}`
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CatalogEntities.esm.js","sources":["../../../src/components/CatalogEntities/CatalogEntities.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, useEffect, useMemo, useCallback } from 'react';\nimport type { ChangeEvent } from 'react';\n\nimport { ResponseErrorPanel } from '@backstage/core-components';\nimport Box from '@mui/material/Box';\nimport { SelectChangeEvent } from '@mui/material/Select';\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 Link from '@mui/material/Link';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nimport CardWrapper from '../CardWrapper';\nimport {\n CATALOG_ENTITIES_TABLE_HEADERS,\n CATALOG_ENTITIES_TITLE,\n} from '../../utils/constants';\nimport { useCatalogEntities } from '../../hooks/useCatalogEntities';\nimport TableFooterPagination from '../CardFooter';\nimport { getLastUsedDay, getUniqueCatalogEntityKinds } from '../../utils/utils';\nimport FilterDropdown from './FilterDropdown';\nimport EmptyChartState from '../Common/EmptyChartState';\n\nconst CatalogEntities = () => {\n const [page, setPage] = useState(0);\n const [limit] = useState(20);\n const [rowsPerPage, setRowsPerPage] = useState(3);\n const [selectedOption, setSelectedOption] = useState('');\n const [uniqueCatalogEntityKinds, setUniqueCatalogEntityKinds] = useState<\n string[]\n >([]);\n\n const entityLink = useRouteRef(entityRouteRef);\n\n const { catalogEntities, loading, error } = useCatalogEntities({\n limit,\n kind: selectedOption === 'All' ? '' : selectedOption.toLocaleLowerCase(),\n });\n\n useEffect(() => {\n if (\n catalogEntities?.data?.length > 0 &&\n uniqueCatalogEntityKinds?.length === 0\n ) {\n const uniqueKinds = getUniqueCatalogEntityKinds(catalogEntities.data);\n setUniqueCatalogEntityKinds(uniqueKinds);\n }\n }, [catalogEntities, uniqueCatalogEntityKinds]);\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 handleChange = useCallback((event: SelectChangeEvent<string>) => {\n setSelectedOption(event.target.value);\n }, []);\n\n const visibleCatalogEntities = useMemo(() => {\n return catalogEntities.data\n ?.filter(entity => {\n if (selectedOption && selectedOption !== 'All') {\n return (\n entity.kind.toLocaleLowerCase() ===\n selectedOption.toLocaleLowerCase()\n );\n }\n return true;\n })\n .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);\n }, [catalogEntities, page, rowsPerPage, selectedOption]);\n\n if (error) {\n return (\n <CardWrapper title={CATALOG_ENTITIES_TITLE}>\n <ResponseErrorPanel error={error} />\n </CardWrapper>\n );\n }\n\n if (\n (!visibleCatalogEntities || visibleCatalogEntities?.length === 0) &&\n !loading\n ) {\n return (\n <CardWrapper title={CATALOG_ENTITIES_TITLE}>\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\n title={CATALOG_ENTITIES_TITLE}\n filter={\n <FilterDropdown\n selectedOption={selectedOption}\n handleChange={handleChange}\n uniqueCatalogEntityKinds={uniqueCatalogEntityKinds}\n />\n }\n >\n <Table aria-labelledby=\"Catalog entities\" sx={{ width: '100%' }}>\n <TableHead>\n <TableRow>\n {CATALOG_ENTITIES_TABLE_HEADERS.map(header => (\n <TableCell\n key={header.id}\n align=\"left\"\n sx={{\n borderBottom: theme => `1px solid ${theme.palette.grey[300]}`,\n width: '25%',\n }}\n >\n {header.title}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell\n colSpan={CATALOG_ENTITIES_TABLE_HEADERS.length}\n align=\"center\"\n >\n <CircularProgress />\n </TableCell>\n </TableRow>\n ) : (\n visibleCatalogEntities?.map(entity => (\n <TableRow\n key={`${entity.kind}-${entity.name}`}\n sx={{\n '&:nth-of-type(odd)': { backgroundColor: 'inherit' },\n borderBottom: theme => `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n <TableCell sx={{ width: '25%' }}>\n <Link\n component=\"a\"\n href={entityLink({\n kind: entity.kind,\n namespace: entity.namespace,\n name: entity.name,\n })}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={{\n textDecoration: 'none',\n '&:hover': {\n textDecoration: 'none',\n },\n }}\n >\n {entity.name ?? '--'}\n </Link>\n </TableCell>\n <TableCell sx={{ width: '25%' }}>\n {entity.kind?.charAt(0).toLocaleUpperCase('en-US') +\n entity.kind?.slice(1) || '--'}\n </TableCell>\n <TableCell sx={{ width: '25%' }}>\n {getLastUsedDay(entity.last_used) ?? '--'}\n </TableCell>\n <TableCell sx={{ width: '25%' }}>\n {Number(entity.count).toLocaleString() ?? '--'}\n </TableCell>\n </TableRow>\n ))\n )}\n </TableBody>\n <TableFooter>\n <TableRow>\n <TableCell\n colSpan={CATALOG_ENTITIES_TABLE_HEADERS.length}\n sx={{ padding: 0 }}\n >\n <TableFooterPagination\n count={catalogEntities.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 CatalogEntities;\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"CatalogEntities.esm.js","sources":["../../../src/components/CatalogEntities/CatalogEntities.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, useEffect, useMemo, useCallback } from 'react';\nimport type { ChangeEvent } from 'react';\n\nimport { ResponseErrorPanel } from '@backstage/core-components';\nimport Box from '@mui/material/Box';\nimport { SelectChangeEvent } from '@mui/material/Select';\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 Link from '@mui/material/Link';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nimport CardWrapper from '../CardWrapper';\nimport {\n CATALOG_ENTITIES_TABLE_HEADERS,\n CATALOG_ENTITIES_TITLE,\n} from '../../utils/constants';\nimport { useCatalogEntities } from '../../hooks/useCatalogEntities';\nimport TableFooterPagination from '../CardFooter';\nimport { getLastUsedDay, getUniqueCatalogEntityKinds } from '../../utils/utils';\nimport FilterDropdown from './FilterDropdown';\nimport EmptyChartState from '../Common/EmptyChartState';\n\nconst CatalogEntities = () => {\n const [page, setPage] = useState(0);\n const [limit] = useState(20);\n const [rowsPerPage, setRowsPerPage] = useState(3);\n const [selectedOption, setSelectedOption] = useState('');\n const [uniqueCatalogEntityKinds, setUniqueCatalogEntityKinds] = useState<\n string[]\n >([]);\n\n const entityLink = useRouteRef(entityRouteRef);\n\n const { catalogEntities, loading, error } = useCatalogEntities({\n limit,\n kind: selectedOption === 'All' ? '' : selectedOption.toLocaleLowerCase(),\n });\n\n useEffect(() => {\n if (\n catalogEntities?.data?.length > 0 &&\n uniqueCatalogEntityKinds?.length === 0\n ) {\n const uniqueKinds = getUniqueCatalogEntityKinds(catalogEntities.data);\n setUniqueCatalogEntityKinds(uniqueKinds);\n }\n }, [catalogEntities, uniqueCatalogEntityKinds]);\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 handleChange = useCallback((event: SelectChangeEvent<string>) => {\n setSelectedOption(event.target.value);\n }, []);\n\n const visibleCatalogEntities = useMemo(() => {\n return catalogEntities.data\n ?.filter(entity => {\n if (selectedOption && selectedOption !== 'All') {\n return (\n entity.kind.toLocaleLowerCase() ===\n selectedOption.toLocaleLowerCase()\n );\n }\n return true;\n })\n .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);\n }, [catalogEntities, page, rowsPerPage, selectedOption]);\n\n if (error) {\n return (\n <CardWrapper title={CATALOG_ENTITIES_TITLE}>\n <ResponseErrorPanel error={error} />\n </CardWrapper>\n );\n }\n\n if (\n (!visibleCatalogEntities || visibleCatalogEntities?.length === 0) &&\n !loading\n ) {\n return (\n <CardWrapper title={CATALOG_ENTITIES_TITLE}>\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\n title={CATALOG_ENTITIES_TITLE}\n filter={\n <FilterDropdown\n selectedOption={selectedOption}\n handleChange={handleChange}\n uniqueCatalogEntityKinds={uniqueCatalogEntityKinds}\n />\n }\n >\n <Table aria-labelledby=\"Catalog entities\" sx={{ width: '100%' }}>\n <TableHead>\n <TableRow>\n {CATALOG_ENTITIES_TABLE_HEADERS.map(header => (\n <TableCell\n key={header.id}\n align=\"left\"\n sx={{\n borderBottom: theme => `1px solid ${theme.palette.grey[300]}`,\n width: '25%',\n }}\n >\n {header.title}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell\n colSpan={CATALOG_ENTITIES_TABLE_HEADERS.length}\n align=\"center\"\n >\n <CircularProgress />\n </TableCell>\n </TableRow>\n ) : (\n visibleCatalogEntities?.map(entity => (\n <TableRow\n key={`${entity.kind}-${entity.name}`}\n sx={{\n '&:nth-of-type(odd)': { backgroundColor: 'inherit' },\n borderBottom: theme => `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n <TableCell sx={{ width: '25%' }}>\n <Link\n component=\"a\"\n href={entityLink({\n kind: entity.kind,\n namespace: entity.namespace,\n name: entity.name,\n })}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={{\n textDecoration: 'none',\n '&:hover': {\n textDecoration: 'none',\n },\n }}\n >\n {entity.name ?? '--'}\n </Link>\n </TableCell>\n <TableCell sx={{ width: '25%' }}>\n {entity.kind?.charAt(0).toLocaleUpperCase('en-US') +\n entity.kind?.slice(1) || '--'}\n </TableCell>\n <TableCell sx={{ width: '25%' }}>\n {getLastUsedDay(entity.last_used) ?? '--'}\n </TableCell>\n <TableCell sx={{ width: '25%' }}>\n {Number(entity.count).toLocaleString('en-US') ?? '--'}\n </TableCell>\n </TableRow>\n ))\n )}\n </TableBody>\n <TableFooter>\n <TableRow>\n <TableCell\n colSpan={CATALOG_ENTITIES_TABLE_HEADERS.length}\n sx={{ padding: 0 }}\n >\n <TableFooterPagination\n count={catalogEntities.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 CatalogEntities;\n"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
2
|
+
import Paper from '@mui/material/Paper';
|
3
|
+
import Typography from '@mui/material/Typography';
|
4
|
+
import { useTheme } from '@mui/material/styles';
|
5
|
+
import Box from '@mui/material/Box';
|
6
|
+
import { formatInTimeZone } from 'date-fns-tz';
|
7
|
+
import { formatTooltipHeaderLabel, formatDateWithRange, formatWeeklyBucket, formatHourlyBucket } from '../../utils/utils.esm.js';
|
8
|
+
import { useDateRange } from '../Header/DateRangeContext.esm.js';
|
9
|
+
|
10
|
+
const labelOverrides = {
|
11
|
+
count: "Number of searches"
|
12
|
+
};
|
13
|
+
const ChartTooltip = ({
|
14
|
+
active,
|
15
|
+
payload,
|
16
|
+
label,
|
17
|
+
grouping
|
18
|
+
}) => {
|
19
|
+
const theme = useTheme();
|
20
|
+
const { startDateRange, endDateRange } = useDateRange();
|
21
|
+
const timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
22
|
+
const getLabel = (key) => labelOverrides[key] || formatTooltipHeaderLabel(key);
|
23
|
+
const formatBucketLabel = (date2) => {
|
24
|
+
switch (grouping) {
|
25
|
+
case "hourly":
|
26
|
+
return formatHourlyBucket(date2);
|
27
|
+
case "weekly":
|
28
|
+
return formatWeeklyBucket(date2);
|
29
|
+
case "monthly":
|
30
|
+
return formatDateWithRange(date2, startDateRange, endDateRange);
|
31
|
+
default:
|
32
|
+
return formatInTimeZone(date2, timeZone, "MMMM d, yyyy");
|
33
|
+
}
|
34
|
+
};
|
35
|
+
if (!active || !payload || payload?.length === 0) {
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
const date = label ? new Date(formatInTimeZone(label, timeZone, "yyyy-MM-dd'T'HH:mm:ssXXX")) : /* @__PURE__ */ new Date();
|
39
|
+
return /* @__PURE__ */ jsxs(
|
40
|
+
Paper,
|
41
|
+
{
|
42
|
+
elevation: 1,
|
43
|
+
sx: {
|
44
|
+
padding: "12px 16px",
|
45
|
+
boxShadow: 4,
|
46
|
+
borderRadius: 2
|
47
|
+
},
|
48
|
+
children: [
|
49
|
+
/* @__PURE__ */ jsx(
|
50
|
+
Typography,
|
51
|
+
{
|
52
|
+
sx: {
|
53
|
+
fontSize: "0.875rem",
|
54
|
+
fontWeight: 500,
|
55
|
+
marginBottom: "12px"
|
56
|
+
},
|
57
|
+
children: formatBucketLabel(date).split("\n").map((line, i) => /* @__PURE__ */ jsx("div", { children: line }, i))
|
58
|
+
}
|
59
|
+
),
|
60
|
+
/* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", children: payload.map(({ dataKey, value }, index) => /* @__PURE__ */ jsxs(Box, { mr: index === payload.length - 1 ? 0 : 3, children: [
|
61
|
+
/* @__PURE__ */ jsx(
|
62
|
+
Typography,
|
63
|
+
{
|
64
|
+
sx: {
|
65
|
+
fontSize: "0.875rem",
|
66
|
+
fontWeight: 500,
|
67
|
+
color: theme.palette.text.secondary
|
68
|
+
},
|
69
|
+
children: getLabel(dataKey)
|
70
|
+
}
|
71
|
+
),
|
72
|
+
/* @__PURE__ */ jsx(
|
73
|
+
Typography,
|
74
|
+
{
|
75
|
+
sx: {
|
76
|
+
fontSize: "2.5rem",
|
77
|
+
fontWeight: 500,
|
78
|
+
color: "#009596",
|
79
|
+
lineHeight: 1.2
|
80
|
+
},
|
81
|
+
children: value
|
82
|
+
}
|
83
|
+
)
|
84
|
+
] })) })
|
85
|
+
]
|
86
|
+
}
|
87
|
+
);
|
88
|
+
};
|
89
|
+
|
90
|
+
export { ChartTooltip as default };
|
91
|
+
//# sourceMappingURL=ChartTooltip.esm.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ChartTooltip.esm.js","sources":["../../../src/components/Common/ChartTooltip.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 Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport Box from '@mui/material/Box';\nimport { formatInTimeZone } from 'date-fns-tz';\nimport {\n formatHourlyBucket,\n formatDateWithRange,\n formatTooltipHeaderLabel,\n formatWeeklyBucket,\n} from '../../utils/utils';\nimport { useDateRange } from '../Header/DateRangeContext';\n\nconst labelOverrides: Record<string, string> = {\n count: 'Number of searches',\n};\n\nconst ChartTooltip = ({\n active,\n payload,\n label,\n grouping,\n}: {\n active?: boolean;\n payload?: any[];\n label?: string;\n grouping?: string;\n}) => {\n const theme = useTheme();\n const { startDateRange, endDateRange } = useDateRange();\n\n const timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n const getLabel = (key: string) =>\n labelOverrides[key] || formatTooltipHeaderLabel(key);\n const formatBucketLabel = (date: Date) => {\n switch (grouping) {\n case 'hourly':\n return formatHourlyBucket(date);\n case 'weekly':\n return formatWeeklyBucket(date);\n case 'monthly':\n return formatDateWithRange(date, startDateRange, endDateRange);\n default:\n return formatInTimeZone(date, timeZone, 'MMMM d, yyyy');\n }\n };\n\n if (!active || !payload || payload?.length === 0) {\n return null;\n }\n\n const date = label\n ? new Date(formatInTimeZone(label, timeZone, \"yyyy-MM-dd'T'HH:mm:ssXXX\"))\n : new Date();\n return (\n <Paper\n elevation={1}\n sx={{\n padding: '12px 16px',\n boxShadow: 4,\n borderRadius: 2,\n }}\n >\n <Typography\n sx={{\n fontSize: '0.875rem',\n fontWeight: 500,\n marginBottom: '12px',\n }}\n >\n {formatBucketLabel(date)\n .split('\\n')\n .map((line, i) => (\n <div key={i}>{line}</div>\n ))}\n </Typography>\n\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\">\n {payload.map(({ dataKey, value }, index) => (\n <Box mr={index === payload.length - 1 ? 0 : 3}>\n <Typography\n sx={{\n fontSize: '0.875rem',\n fontWeight: 500,\n color: theme.palette.text.secondary,\n }}\n >\n {getLabel(dataKey)}\n </Typography>\n <Typography\n sx={{\n fontSize: '2.5rem',\n fontWeight: 500,\n color: '#009596',\n lineHeight: 1.2,\n }}\n >\n {value}\n </Typography>\n </Box>\n ))}\n </Box>\n </Paper>\n );\n};\n\nexport default ChartTooltip;\n"],"names":["date"],"mappings":"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"}
|
@@ -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 { 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 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,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
|
+
{"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":"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"}
|
@@ -98,7 +98,7 @@ const Plugins = () => {
|
|
98
98
|
"%"
|
99
99
|
] })
|
100
100
|
] }) }),
|
101
|
-
/* @__PURE__ */ jsx(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" }, children: Number(plugin.visit_count).toLocaleString() ?? "--" })
|
101
|
+
/* @__PURE__ */ jsx(TableCell, { sx: isDefaultDateRange ? {} : { width: "20%" }, children: Number(plugin.visit_count).toLocaleString("en-US") ?? "--" })
|
102
102
|
]
|
103
103
|
},
|
104
104
|
plugin.plugin_id
|
@@ -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 { 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() ?? '--'}\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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"}
|
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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"}
|
@@ -9,8 +9,8 @@ import CardWrapper from '../CardWrapper/CardWrapper.esm.js';
|
|
9
9
|
import { useSearches } from '../../hooks/useSearches.esm.js';
|
10
10
|
import { getTotal, getAverage, getXAxisTickValues, getXAxisformat } from '../../utils/utils.esm.js';
|
11
11
|
import CustomCursor from '../Common/CustomCursor.esm.js';
|
12
|
-
import CustomTooltip from './CustomTooltip.esm.js';
|
13
12
|
import EmptyChartState from '../Common/EmptyChartState.esm.js';
|
13
|
+
import ChartTooltip from '../Common/ChartTooltip.esm.js';
|
14
14
|
|
15
15
|
const Searches = () => {
|
16
16
|
const theme = useTheme();
|
@@ -35,7 +35,7 @@ const Searches = () => {
|
|
35
35
|
return /* @__PURE__ */ jsx(
|
36
36
|
CardWrapper,
|
37
37
|
{
|
38
|
-
title: `${getTotal(data, "count")?.toLocaleString()} searches`,
|
38
|
+
title: `${getTotal(data, "count")?.toLocaleString("en-US")} searches`,
|
39
39
|
children: loading ? /* @__PURE__ */ jsx(
|
40
40
|
Box,
|
41
41
|
{
|
@@ -49,9 +49,9 @@ const Searches = () => {
|
|
49
49
|
/* @__PURE__ */ jsxs(Typography, { style: { margin: "20px 36px" }, children: [
|
50
50
|
"An average of",
|
51
51
|
" ",
|
52
|
-
/* @__PURE__ */ jsx("b", { children: `${Math.round(
|
53
|
-
|
54
|
-
)
|
52
|
+
/* @__PURE__ */ jsx("b", { children: `${Math.round(getAverage(data, "count")).toLocaleString(
|
53
|
+
"en-US"
|
54
|
+
)} searches per ${grouping === "hourly" ? "hour" : "day"}` }),
|
55
55
|
" ",
|
56
56
|
"were conducted during this period."
|
57
57
|
] }),
|
@@ -88,7 +88,7 @@ const Searches = () => {
|
|
88
88
|
tickLine: false,
|
89
89
|
axisLine: false,
|
90
90
|
tick: { fill: theme.palette.text.primary },
|
91
|
-
tickFormatter: (value) => value.toLocaleString(),
|
91
|
+
tickFormatter: (value) => value.toLocaleString("en-US"),
|
92
92
|
tickMargin: 20
|
93
93
|
}
|
94
94
|
),
|
@@ -96,7 +96,7 @@ const Searches = () => {
|
|
96
96
|
Tooltip,
|
97
97
|
{
|
98
98
|
cursor: /* @__PURE__ */ jsx(CustomCursor, { cursorHeight: 280 }),
|
99
|
-
content: /* @__PURE__ */ jsx(
|
99
|
+
content: /* @__PURE__ */ jsx(ChartTooltip, { grouping })
|
100
100
|
}
|
101
101
|
),
|
102
102
|
/* @__PURE__ */ jsx(
|