@backstage-community/plugin-apiiro 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +91 -12
  3. package/config.d.ts +14 -0
  4. package/dist/App.esm.js +96 -4
  5. package/dist/App.esm.js.map +1 -1
  6. package/dist/api/index.esm.js +6 -0
  7. package/dist/api/index.esm.js.map +1 -1
  8. package/dist/assets/SettingIcon.esm.js +1 -0
  9. package/dist/assets/SettingIcon.esm.js.map +1 -1
  10. package/dist/components/ApiiroSidebar.esm.js.map +1 -1
  11. package/dist/components/CalendarDatePicker.esm.js.map +1 -1
  12. package/dist/components/DataGrid/DataGrid.esm.js +1 -0
  13. package/dist/components/DataGrid/DataGrid.esm.js.map +1 -1
  14. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js +28 -4
  15. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js.map +1 -1
  16. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js +30 -7
  17. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js.map +1 -1
  18. package/dist/components/RiskLevel.esm.js +1 -0
  19. package/dist/components/RiskLevel.esm.js.map +1 -1
  20. package/dist/components/charts/GaugeChart.esm.js +8 -6
  21. package/dist/components/charts/GaugeChart.esm.js.map +1 -1
  22. package/dist/components/common/StatusContainer.esm.js +123 -0
  23. package/dist/components/common/StatusContainer.esm.js.map +1 -0
  24. package/dist/components/filters/DiscoveredOnFilter.esm.js +1 -1
  25. package/dist/components/filters/DiscoveredOnFilter.esm.js.map +1 -1
  26. package/dist/components/tiles/MttrVsSLATile.esm.js +31 -14
  27. package/dist/components/tiles/MttrVsSLATile.esm.js.map +1 -1
  28. package/dist/components/tiles/RiskOverTimeTile.esm.js +15 -12
  29. package/dist/components/tiles/RiskOverTimeTile.esm.js.map +1 -1
  30. package/dist/components/tiles/SLAAdherenceTile.esm.js +15 -12
  31. package/dist/components/tiles/SLAAdherenceTile.esm.js.map +1 -1
  32. package/dist/components/tiles/StatusTile.esm.js +98 -66
  33. package/dist/components/tiles/StatusTile.esm.js.map +1 -1
  34. package/dist/components/tiles/TopLanguagesTile.esm.js +1 -0
  35. package/dist/components/tiles/TopLanguagesTile.esm.js.map +1 -1
  36. package/dist/components/tiles/TopRiskTile.esm.js +19 -16
  37. package/dist/components/tiles/TopRiskTile.esm.js.map +1 -1
  38. package/dist/index.d.ts +31 -6
  39. package/dist/index.esm.js +2 -1
  40. package/dist/index.esm.js.map +1 -1
  41. package/dist/pages/Applications/Applications.esm.js +104 -0
  42. package/dist/pages/Applications/Applications.esm.js.map +1 -0
  43. package/dist/pages/Applications/tableConfig.esm.js +147 -0
  44. package/dist/pages/Applications/tableConfig.esm.js.map +1 -0
  45. package/dist/pages/Repositories/Repositories.esm.js +26 -26
  46. package/dist/pages/Repositories/Repositories.esm.js.map +1 -1
  47. package/dist/pages/Repositories/tableConfig.esm.js +3 -2
  48. package/dist/pages/Repositories/tableConfig.esm.js.map +1 -1
  49. package/dist/pages/Risks/Risks.esm.js +9 -3
  50. package/dist/pages/Risks/Risks.esm.js.map +1 -1
  51. package/dist/pages/Risks/tableConfig.esm.js +25 -11
  52. package/dist/pages/Risks/tableConfig.esm.js.map +1 -1
  53. package/dist/pages/tab/ComponentTab.esm.js +72 -0
  54. package/dist/pages/tab/ComponentTab.esm.js.map +1 -0
  55. package/dist/pages/tab/SystemTab.esm.js +159 -0
  56. package/dist/pages/tab/SystemTab.esm.js.map +1 -0
  57. package/dist/pages/tab/TabProvider.esm.js +9 -3
  58. package/dist/pages/tab/TabProvider.esm.js.map +1 -1
  59. package/dist/pages/widget/ComponentWidget.esm.js +67 -0
  60. package/dist/pages/widget/ComponentWidget.esm.js.map +1 -0
  61. package/dist/pages/widget/SystemWidget.esm.js +81 -0
  62. package/dist/pages/widget/SystemWidget.esm.js.map +1 -0
  63. package/dist/pages/widget/WidgetProvider.esm.js +9 -3
  64. package/dist/pages/widget/WidgetProvider.esm.js.map +1 -1
  65. package/dist/plugin.esm.js.map +1 -1
  66. package/dist/queries/application.queries.esm.js +64 -0
  67. package/dist/queries/application.queries.esm.js.map +1 -0
  68. package/dist/queries/mttr-statistics.queries.esm.js +19 -12
  69. package/dist/queries/mttr-statistics.queries.esm.js.map +1 -1
  70. package/dist/queries/repository.queries.esm.js +19 -8
  71. package/dist/queries/repository.queries.esm.js.map +1 -1
  72. package/dist/queries/risk-score-over-time.queries.esm.js +19 -12
  73. package/dist/queries/risk-score-over-time.queries.esm.js.map +1 -1
  74. package/dist/queries/risks.queries.esm.js +19 -7
  75. package/dist/queries/risks.queries.esm.js.map +1 -1
  76. package/dist/queries/sla-breach.queries.esm.js +22 -11
  77. package/dist/queries/sla-breach.queries.esm.js.map +1 -1
  78. package/dist/queries/top-risks.queries.esm.js +19 -7
  79. package/dist/queries/top-risks.queries.esm.js.map +1 -1
  80. package/dist/theme/themeUtils.esm.js +5 -2
  81. package/dist/theme/themeUtils.esm.js.map +1 -1
  82. package/dist/utils/utils.esm.js +3 -2
  83. package/dist/utils/utils.esm.js.map +1 -1
  84. package/package.json +12 -12
  85. package/dist/pages/tab/Tab.esm.js +0 -147
  86. package/dist/pages/tab/Tab.esm.js.map +0 -1
  87. package/dist/pages/widget/Widget.esm.js +0 -161
  88. package/dist/pages/widget/Widget.esm.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @backstage-community/plugin-apiiro
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - ff337ee: Implemented Application View functionality to enable risk display and navigation for System Entities.
8
+ Fixed the UI component to support the Informational risk level type.
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies [ff337ee]
13
+ - @backstage-community/plugin-apiiro-common@1.0.0
14
+
15
+ ## 0.2.0
16
+
17
+ ### Minor Changes
18
+
19
+ - cd2ccac: Backstage version bump to v1.48.2
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [cd2ccac]
24
+ - @backstage-community/plugin-apiiro-common@0.2.0
25
+
3
26
  ## 0.1.0
4
27
 
5
28
  ### Minor Changes
package/README.md CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  The Apiiro plugin for Backstage integrates Apiiro's application risk management capabilities directly into your Backstage developer portal. This plugin empowers developers to code securely by automatically checking for security vulnerabilities and enables them to review and address newly introduced vulnerabilities directly in Backstage.
4
4
 
5
- ## Plugin Compatibility
6
-
7
- The plugin has been successfully tested with Backstage v1.44.0 If you are using a newer version of Backstage, please file an issue, and we will provide guidance on the best integration practices for your specific version.
8
-
9
5
  ## Features
10
6
 
11
7
  - **Dashboard View**: Repository list with statistics sourced from Apiiro
12
- - **Apiiro Tab**: In-depth view of repository open risks and detailed metrics
8
+ - **Application List**: Comprehensive list of all applications integrated with Apiiro
9
+ - **Apiiro Tab**: In-depth view of open risks and detailed metrics of repositories and applications
13
10
  - **Apiiro Widget**: High-level overview widget that can be embedded in custom entity tabs
14
11
  - **Permission Control**: Conditional permissions for fine-grained access control to Apiiro metrics
15
12
 
13
+ > [!NOTE]
14
+ > The Application List and Apiiro Tab (System) require the Backstage connector to be configured in Apiiro to function properly.
15
+
16
16
  ## Views
17
17
 
18
18
  ### Dashboard – Repository List
@@ -21,18 +21,36 @@ Displays the list of integrated repositories along with statistics sourced from
21
21
 
22
22
  ![Dashboard Repository List](../../assets/dashboard.png)
23
23
 
24
- ### Apiiro Tab
24
+ ### Apiiro Tab (Component)
25
25
 
26
- Provides an in-depth look at each repository's open risks and detailed metrics retrieved from Apiiro.
26
+ Provides an in-depth look at each repository's open risks and detailed metrics retrieved from Apiiro. The risk view links and "Go to Apiiro" button redirect to the development risks tab in Apiiro.
27
27
 
28
28
  ![Apiiro Tab](../../assets/apiiro-tab.png)
29
29
 
30
30
  ### Apiiro Widget
31
31
 
32
- Offers a high-level overview of the repository, including programming languages and top risk details. Can be added to any custom entity tab.
32
+ Offers a high-level overview of the repository, including programming languages and top risk details. Can be added to any custom entity tab. "Go to Apiiro" button redirect to the development risks tab in Apiiro.
33
33
 
34
34
  ![Apiiro Widget](../../assets/apiiro-widget.png)
35
35
 
36
+ ### Application List
37
+
38
+ Displays a comprehensive list of all applications integrated with Apiiro, including risk scores, repository counts, and key metrics. This view is available when the applications view is enabled in the configuration.
39
+
40
+ > [!NOTE]
41
+ > This feature requires the Backstage connector to be configured in Apiiro.
42
+
43
+ ![Application List](../../assets/application-list.png)
44
+
45
+ ### Apiiro Tab (System)
46
+
47
+ Provides a detailed view of applications with comprehensive risk insights, associated repositories, and security metrics. This tab displays application-level statistics and allows navigation between repositories and risks within the application context. The risks view links and "Go to Apiiro" button redirect to the development risks tab in Apiiro.
48
+
49
+ > [!NOTE]
50
+ > This feature requires the Backstage connector to be configured in Apiiro.
51
+
52
+ ![Apiiro Tab System](../../assets/application-tab.png)
53
+
36
54
  ## Prerequisites
37
55
 
38
56
  - The entity for a repository must be present within Backstage to see Apiiro results
@@ -51,17 +69,32 @@ Offers a high-level overview of the repository, including programming languages
51
69
  Add the following annotation into your catalog.
52
70
  To be able to use the Apiiro plugin you need to add the following annotation to any entities you want to use it with:
53
71
 
72
+ **For Component entities (repositories):**
73
+
54
74
  ```yaml
55
75
  apiiro.com/repo-id: <apiiro-repo-key>
56
- apiiro.com/allow-metrics-view: "true" or "false" (controls whether the Metrics view appears in the Apiiro tab and Apiiro widget)
76
+ apiiro.com/allow-metrics-view: "true" or "false" (controls whether the Metrics view appears in the Component Apiiro tab and Apiiro widget)
57
77
  ```
58
78
 
59
- Let's break this down a little: `<apiiro-repo-key>` will be the key of your repository in Apiiro.
79
+ **For System entities (applications):**
80
+
81
+ ```yaml
82
+ apiiro.com/application-id: <apiiro-application-key>
83
+ apiiro.com/allow-metrics-view: "true" or "false" (controls whether the Metrics view and repository list appears in the System Apiiro tab and Apiiro widget)
84
+ ```
85
+
86
+ > [!NOTE]
87
+ > Application annotations require the Backstage connector to be configured in Apiiro and `enableApplicationsView` set to `true` in the configuration.
88
+
89
+ Let's break this down:
90
+
91
+ - `<apiiro-repo-key>` is the key of your repository in Apiiro
92
+ - `<apiiro-application-key>` is the key of your application in Apiiro
60
93
 
61
94
  Here's what that will look like in action:
62
95
 
63
96
  ```yaml
64
- # Example catalog-info.yaml entity definition file
97
+ # Example catalog-info.yaml for Component entity
65
98
  apiVersion: backstage.io/v1alpha1
66
99
  kind: Component
67
100
  metadata:
@@ -69,6 +102,15 @@ metadata:
69
102
  annotations:
70
103
  apiiro.com/repo-id: my-repo-key
71
104
  apiiro.com/allow-metrics-view: 'true'
105
+ ---
106
+ # Example catalog-info.yaml for System entity
107
+ apiVersion: backstage.io/v1alpha1
108
+ kind: System
109
+ metadata:
110
+ name: my-application
111
+ annotations:
112
+ apiiro.com/application-id: my-application-key
113
+ apiiro.com/allow-metrics-view: 'true'
72
114
  ```
73
115
 
74
116
  Please find the steps to add the annotation automatically [here](../apiiro-backend/README.md#automatically-adding-apiiro-annotations-optional).
@@ -91,6 +133,8 @@ Add your Apiiro Access Token to your `app-config.yaml` or `app-config.production
91
133
  apiiro:
92
134
  accessToken: ${APIIRO_TOKEN}
93
135
  defaultAllowMetricsView: true
136
+ enableApplicationsView: false
137
+ redirectDevView: false
94
138
  # Optional: Configure default risk filters for the Apiiro Risk Table (Example configuration)
95
139
  defaultRiskFilters:
96
140
  RiskLevel:
@@ -114,6 +158,8 @@ Where:
114
158
 
115
159
  - `accessToken` is your Apiiro Access Token
116
160
  - `defaultAllowMetricsView` is a boolean value that controls whether the Metrics view appears in the Apiiro Tab and Apiiro Widget by default. If annotation is not set, this value will be used. Default value is `true`.
161
+ - `enableApplicationsView` is a boolean value that enables the Application List and Apiiro Tab on System Entity. Default value is `false`. **Note:** This feature requires the Backstage connector to be configured in Apiiro.
162
+ - `redirectDevView` (optional) redirects to the development view of risks in Apiiro. Default value is `false`.
117
163
  - `defaultRiskFilters` (optional) configures default filters for the Apiiro Risk Table. Please refer to the [backend documentation](../apiiro-backend/README.md#configure-default-risk-filters-optional) for more details.
118
164
 
119
165
  **How to Retrieve an Access Token from Apiiro:**
@@ -199,7 +245,40 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
199
245
  );
200
246
  ```
201
247
 
202
- ### 6. Add Apiiro Widget to Custom Entity Tab (Optional)
248
+ ### 6. Add Apiiro Tab to System Entity Page (Optional)
249
+
250
+ To enable application-level insights for System entities, add the Apiiro Tab to your system entity page.
251
+
252
+ In `packages/app/src/components/Catalog/EntityPage.tsx`:
253
+
254
+ ```tsx
255
+ // Import the Apiiro tab
256
+ import {
257
+ ApiiroTab,
258
+ isApiiroApplicationAvailable,
259
+ } from '@backstage-community/plugin-apiiro';
260
+
261
+ // Add the route to your system page
262
+ const systemPage = (
263
+ <EntityLayout>
264
+ <EntityLayout.Route path="/" title="Overview">
265
+ {/* ... other elements */}
266
+ </EntityLayout.Route>
267
+
268
+ <EntityLayout.Route
269
+ if={isApiiroApplicationAvailable}
270
+ path="/apiiro"
271
+ title="Apiiro"
272
+ >
273
+ <ApiiroTab />
274
+ </EntityLayout.Route>
275
+
276
+ {/* ... other elements */}
277
+ </EntityLayout>
278
+ );
279
+ ```
280
+
281
+ ### 7. Add Apiiro Widget to Custom Entity Tab (Optional)
203
282
 
204
283
  The Apiiro plugin for Backstage includes a widget that can be embedded in a custom tab of the Backstage entity. This widget provides an overview of the risk associated with that entity, alongside your other valuable insights.
205
284
  To add the widget, include the following component in your custom entity tab:
package/config.d.ts CHANGED
@@ -26,5 +26,19 @@ export interface Config {
26
26
  * @default true
27
27
  */
28
28
  defaultAllowMetricsView?: boolean;
29
+
30
+ /**
31
+ * Default value for the enable applications view annotation
32
+ * @visibility frontend
33
+ * @default false
34
+ */
35
+ enableApplicationsView?: boolean;
36
+
37
+ /**
38
+ * Configuration to enable the devView for risks after redirect from Backstage to Apiiro
39
+ * @visibility frontend
40
+ * @default false
41
+ */
42
+ redirectDevView?: boolean;
29
43
  };
30
44
  }
package/dist/App.esm.js CHANGED
@@ -1,11 +1,103 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useState } from 'react';
2
3
  import { Routes, Route } from 'react-router-dom';
3
- import { Repositories } from './pages/Repositories/Repositories.esm.js';
4
+ import { Page, Content } from '@backstage/core-components';
5
+ import { useApi } from '@backstage/core-plugin-api';
6
+ import Tab from '@mui/material/Tab';
7
+ import Tabs from '@mui/material/Tabs';
8
+ import Box from '@mui/material/Box';
9
+ import Typography from '@mui/material/Typography';
10
+ import { Repositories, RepositoriesContent } from './pages/Repositories/Repositories.esm.js';
11
+ import { Applications } from './pages/Applications/Applications.esm.js';
12
+ import { Header } from './components/Header.esm.js';
4
13
  import { QueryClientProvider } from '@tanstack/react-query';
5
- import { queryClient } from './api/index.esm.js';
14
+ import { queryClient, apiiroApiRef } from './api/index.esm.js';
6
15
 
16
+ const TabbedHome = () => {
17
+ const [activeTab, setActiveTab] = useState(0);
18
+ const handleTabChange = (_, newValue) => {
19
+ setActiveTab(newValue);
20
+ };
21
+ return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
22
+ /* @__PURE__ */ jsx(Header, {}),
23
+ /* @__PURE__ */ jsxs(Content, { children: [
24
+ /* @__PURE__ */ jsx(Box, { sx: { borderBottom: 1, borderColor: "divider", mb: 2 }, children: /* @__PURE__ */ jsxs(
25
+ Tabs,
26
+ {
27
+ value: activeTab,
28
+ onChange: handleTabChange,
29
+ "aria-label": "Apiiro navigation tabs",
30
+ textColor: "inherit",
31
+ TabIndicatorProps: {
32
+ style: { backgroundColor: "currentColor" }
33
+ },
34
+ children: [
35
+ /* @__PURE__ */ jsx(
36
+ Tab,
37
+ {
38
+ label: /* @__PURE__ */ jsx(
39
+ Typography,
40
+ {
41
+ variant: "h5",
42
+ sx: {
43
+ color: "text.primary",
44
+ opacity: activeTab === 0 ? 1 : 0.6
45
+ },
46
+ children: "Applications"
47
+ }
48
+ ),
49
+ sx: {
50
+ textTransform: "none",
51
+ minWidth: "auto",
52
+ px: 2,
53
+ "&:hover": {
54
+ backgroundColor: "action.hover"
55
+ }
56
+ }
57
+ }
58
+ ),
59
+ /* @__PURE__ */ jsx(
60
+ Tab,
61
+ {
62
+ label: /* @__PURE__ */ jsx(
63
+ Typography,
64
+ {
65
+ variant: "h5",
66
+ sx: {
67
+ color: "text.primary",
68
+ opacity: activeTab === 1 ? 1 : 0.6
69
+ },
70
+ children: "Repositories"
71
+ }
72
+ ),
73
+ sx: {
74
+ textTransform: "none",
75
+ minWidth: "auto",
76
+ px: 2,
77
+ "&:hover": {
78
+ backgroundColor: "action.hover"
79
+ }
80
+ }
81
+ }
82
+ )
83
+ ]
84
+ }
85
+ ) }),
86
+ activeTab === 0 && /* @__PURE__ */ jsx(Applications, {}),
87
+ activeTab === 1 && /* @__PURE__ */ jsx(RepositoriesContent, {})
88
+ ] })
89
+ ] });
90
+ };
91
+ const AppContent = () => {
92
+ const connectApi = useApi(apiiroApiRef);
93
+ const enableApplicationsView = connectApi.getEnableApplicationsView();
94
+ if (enableApplicationsView) {
95
+ return /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(TabbedHome, {}) }) });
96
+ }
97
+ return /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(Repositories, {}) }) });
98
+ };
7
99
  const App = () => {
8
- return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(Repositories, {}) }) }) });
100
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(AppContent, {}) });
9
101
  };
10
102
 
11
103
  export { App };
@@ -1 +1 @@
1
- {"version":3,"file":"App.esm.js","sources":["../src/App.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Routes, Route } from 'react-router-dom';\nimport { Repositories } from './pages/Repositories';\nimport { QueryClientProvider } from '@tanstack/react-query';\nimport { queryClient } from './api';\n\nexport const App = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <Routes>\n <Route path=\"/\" element={<Repositories />} />\n </Routes>\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":";;;;;;AAoBO,MAAM,MAAM,MAAM;AACvB,EAAA,uBACE,GAAA,CAAC,mBAAA,EAAA,EAAoB,MAAA,EAAQ,WAAA,EAC3B,8BAAC,MAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAK,KAAI,OAAA,kBAAS,GAAA,CAAC,YAAA,EAAA,EAAa,CAAA,EAAI,GAC7C,CAAA,EACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"App.esm.js","sources":["../src/App.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState } from 'react';\nimport { Routes, Route } from 'react-router-dom';\nimport { Content, Page } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport Tab from '@mui/material/Tab';\nimport Tabs from '@mui/material/Tabs';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { Repositories, RepositoriesContent } from './pages/Repositories';\nimport { Applications } from './pages/Applications';\nimport { Header } from './components/Header';\nimport { QueryClientProvider } from '@tanstack/react-query';\nimport { queryClient, apiiroApiRef } from './api';\n\nconst TabbedHome = () => {\n const [activeTab, setActiveTab] = useState(0);\n\n const handleTabChange = (_: React.SyntheticEvent, newValue: number) => {\n setActiveTab(newValue);\n };\n\n return (\n <Page themeId=\"tool\">\n <Header />\n <Content>\n <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 2 }}>\n <Tabs\n value={activeTab}\n onChange={handleTabChange}\n aria-label=\"Apiiro navigation tabs\"\n textColor=\"inherit\"\n TabIndicatorProps={{\n style: { backgroundColor: 'currentColor' },\n }}\n >\n <Tab\n label={\n <Typography\n variant=\"h5\"\n sx={{\n color: 'text.primary',\n opacity: activeTab === 0 ? 1 : 0.6,\n }}\n >\n Applications\n </Typography>\n }\n sx={{\n textTransform: 'none',\n minWidth: 'auto',\n px: 2,\n '&:hover': {\n backgroundColor: 'action.hover',\n },\n }}\n />\n <Tab\n label={\n <Typography\n variant=\"h5\"\n sx={{\n color: 'text.primary',\n opacity: activeTab === 1 ? 1 : 0.6,\n }}\n >\n Repositories\n </Typography>\n }\n sx={{\n textTransform: 'none',\n minWidth: 'auto',\n px: 2,\n '&:hover': {\n backgroundColor: 'action.hover',\n },\n }}\n />\n </Tabs>\n </Box>\n\n {activeTab === 0 && <Applications />}\n {activeTab === 1 && <RepositoriesContent />}\n </Content>\n </Page>\n );\n};\n\nconst AppContent = () => {\n const connectApi = useApi(apiiroApiRef);\n const enableApplicationsView = connectApi.getEnableApplicationsView();\n\n if (enableApplicationsView) {\n return (\n <Routes>\n <Route path=\"/\" element={<TabbedHome />} />\n </Routes>\n );\n }\n\n return (\n <Routes>\n <Route path=\"/\" element={<Repositories />} />\n </Routes>\n );\n};\n\nexport const App = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <AppContent />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -14,6 +14,12 @@ class ApiiroClient {
14
14
  getDefaultAllowMetricsView() {
15
15
  return this.configApi.getOptionalBoolean("apiiro.defaultAllowMetricsView") ?? true;
16
16
  }
17
+ getEnableApplicationsView() {
18
+ return this.configApi.getOptionalBoolean("apiiro.enableApplicationsView") ?? false;
19
+ }
20
+ getRedirectDevView() {
21
+ return this.configApi.getOptionalBoolean("apiiro.redirectDevView") ?? false;
22
+ }
17
23
  }
18
24
  const queryClient = new QueryClient();
19
25
  function assembleUri(uri, params) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { QueryClient } from '@tanstack/react-query';\nimport {\n ConfigApi,\n createApiRef,\n DiscoveryApi,\n} from '@backstage/core-plugin-api';\n\n/**\n * Plugin API\n */\nexport type ApiiroApi = {\n discoveryApi: DiscoveryApi;\n getDefaultAllowMetricsView: () => boolean;\n};\n\nexport const apiiroApiRef = createApiRef<ApiiroApi>({\n id: 'plugin.apiiro.service',\n});\n\nexport class ApiiroClient implements ApiiroApi {\n discoveryApi: DiscoveryApi;\n private readonly configApi: ConfigApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; configApi: ConfigApi }) {\n this.discoveryApi = options.discoveryApi;\n this.configApi = options.configApi;\n }\n\n getDefaultAllowMetricsView(): boolean {\n return (\n this.configApi.getOptionalBoolean('apiiro.defaultAllowMetricsView') ??\n true\n );\n }\n}\n\n/**\n * React Query Client\n */\nexport const queryClient = new QueryClient();\n\n/**\n * Fetch: GET, POST\n */\ntype QueryParams = Record<string, string>;\n\ntype RequestHeaders = Record<string, string>;\n\nenum ApiHeaders {\n CONTENT_TYPE = 'Content-Type',\n}\n\nenum REQUEST_METHOD {\n GET = 'GET',\n POST = 'POST',\n}\n\ninterface RequestOptions {\n body?: any;\n headers?: RequestHeaders;\n params?: Record<string, any> | null;\n signal?: AbortSignal;\n}\n\nfunction assembleUri(uri: string, params?: QueryParams): string {\n if (!params) {\n return uri;\n }\n\n const queryString = new URLSearchParams(params).toString();\n return `${uri}?${queryString}`;\n}\n\nfunction buildHeaders(optionHeaders: RequestHeaders): Headers {\n const headers = new Headers();\n headers.set(ApiHeaders.CONTENT_TYPE, 'application/json');\n\n Object.keys(optionHeaders).forEach(header => {\n const headerValue = optionHeaders[header];\n if (headerValue) {\n headers.set(header, headerValue);\n }\n });\n\n return headers;\n}\n\nfunction fetchRequest(\n fetchApi: typeof fetch,\n method: REQUEST_METHOD,\n url: string,\n opts: RequestOptions,\n): Promise<any> {\n const { params, body, headers, signal } = opts;\n\n const requestURL = params ? assembleUri(url, params) : url;\n\n const requestParams: RequestInit = {\n headers: buildHeaders(headers || {}),\n method,\n signal,\n };\n\n if (body) {\n requestParams.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n return fetchApi(requestURL, requestParams);\n}\n\nfunction toJson(response: Response): Promise<any> {\n if (response.status === 204 || response.body === null) {\n return Promise.resolve({});\n }\n\n return response.json().then(json => {\n return response.ok ? json : Promise.reject(json);\n });\n}\n\nconst defaultOpts: RequestOptions = {\n body: null,\n headers: {},\n params: null,\n};\n\nexport function get<T>(\n fetchApi: typeof fetch,\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(fetchApi, REQUEST_METHOD.GET, url, opts).then(toJson);\n}\n\nexport function post<T>(\n fetchApi: typeof fetch,\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(fetchApi, REQUEST_METHOD.POST, url, opts).then(toJson);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { QueryClient } from '@tanstack/react-query';\nimport {\n ConfigApi,\n createApiRef,\n DiscoveryApi,\n} from '@backstage/core-plugin-api';\n\n/**\n * Plugin API\n */\nexport type ApiiroApi = {\n discoveryApi: DiscoveryApi;\n getDefaultAllowMetricsView: () => boolean;\n getEnableApplicationsView: () => boolean;\n getRedirectDevView: () => boolean;\n};\n\nexport const apiiroApiRef = createApiRef<ApiiroApi>({\n id: 'plugin.apiiro.service',\n});\n\nexport class ApiiroClient implements ApiiroApi {\n discoveryApi: DiscoveryApi;\n private readonly configApi: ConfigApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; configApi: ConfigApi }) {\n this.discoveryApi = options.discoveryApi;\n this.configApi = options.configApi;\n }\n\n getDefaultAllowMetricsView(): boolean {\n return (\n this.configApi.getOptionalBoolean('apiiro.defaultAllowMetricsView') ??\n true\n );\n }\n\n getEnableApplicationsView(): boolean {\n return (\n this.configApi.getOptionalBoolean('apiiro.enableApplicationsView') ??\n false\n );\n }\n\n getRedirectDevView(): boolean {\n return this.configApi.getOptionalBoolean('apiiro.redirectDevView') ?? false;\n }\n}\n\n/**\n * React Query Client\n */\nexport const queryClient = new QueryClient();\n\n/**\n * Fetch: GET, POST\n */\ntype QueryParams = Record<string, string>;\n\ntype RequestHeaders = Record<string, string>;\n\nenum ApiHeaders {\n CONTENT_TYPE = 'Content-Type',\n}\n\nenum REQUEST_METHOD {\n GET = 'GET',\n POST = 'POST',\n}\n\ninterface RequestOptions {\n body?: any;\n headers?: RequestHeaders;\n params?: Record<string, any> | null;\n signal?: AbortSignal;\n}\n\nfunction assembleUri(uri: string, params?: QueryParams): string {\n if (!params) {\n return uri;\n }\n\n const queryString = new URLSearchParams(params).toString();\n return `${uri}?${queryString}`;\n}\n\nfunction buildHeaders(optionHeaders: RequestHeaders): Headers {\n const headers = new Headers();\n headers.set(ApiHeaders.CONTENT_TYPE, 'application/json');\n\n Object.keys(optionHeaders).forEach(header => {\n const headerValue = optionHeaders[header];\n if (headerValue) {\n headers.set(header, headerValue);\n }\n });\n\n return headers;\n}\n\nfunction fetchRequest(\n fetchApi: typeof fetch,\n method: REQUEST_METHOD,\n url: string,\n opts: RequestOptions,\n): Promise<any> {\n const { params, body, headers, signal } = opts;\n\n const requestURL = params ? assembleUri(url, params) : url;\n\n const requestParams: RequestInit = {\n headers: buildHeaders(headers || {}),\n method,\n signal,\n };\n\n if (body) {\n requestParams.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n return fetchApi(requestURL, requestParams);\n}\n\nfunction toJson(response: Response): Promise<any> {\n if (response.status === 204 || response.body === null) {\n return Promise.resolve({});\n }\n\n return response.json().then(json => {\n return response.ok ? json : Promise.reject(json);\n });\n}\n\nconst defaultOpts: RequestOptions = {\n body: null,\n headers: {},\n params: null,\n};\n\nexport function get<T>(\n fetchApi: typeof fetch,\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(fetchApi, REQUEST_METHOD.GET, url, opts).then(toJson);\n}\n\nexport function post<T>(\n fetchApi: typeof fetch,\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(fetchApi, REQUEST_METHOD.POST, url, opts).then(toJson);\n}\n"],"names":[],"mappings":";;;AAgCO,MAAM,eAAe,YAAA,CAAwB;AAAA,EAClD,EAAA,EAAI;AACN,CAAC;AAEM,MAAM,YAAA,CAAkC;AAAA,EAC7C,YAAA;AAAA,EACiB,SAAA;AAAA,EAEjB,YAAY,OAAA,EAA+D;AACzE,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AAAA,EAC3B;AAAA,EAEA,0BAAA,GAAsC;AACpC,IAAA,OACE,IAAA,CAAK,SAAA,CAAU,kBAAA,CAAmB,gCAAgC,CAAA,IAClE,IAAA;AAAA,EAEJ;AAAA,EAEA,yBAAA,GAAqC;AACnC,IAAA,OACE,IAAA,CAAK,SAAA,CAAU,kBAAA,CAAmB,+BAA+B,CAAA,IACjE,KAAA;AAAA,EAEJ;AAAA,EAEA,kBAAA,GAA8B;AAC5B,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,kBAAA,CAAmB,wBAAwB,CAAA,IAAK,KAAA;AAAA,EACxE;AACF;AAKO,MAAM,WAAA,GAAc,IAAI,WAAA;AAyB/B,SAAS,WAAA,CAAY,KAAa,MAAA,EAA8B;AAC9D,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,IAAI,eAAA,CAAgB,MAAM,EAAE,QAAA,EAAS;AACzD,EAAA,OAAO,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA;AAC9B;AAEA,SAAS,aAAa,aAAA,EAAwC;AAC5D,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,OAAA,CAAQ,GAAA,CAAI,mCAAyB,kBAAkB,CAAA;AAEvD,EAAA,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,CAAE,OAAA,CAAQ,CAAA,MAAA,KAAU;AAC3C,IAAA,MAAM,WAAA,GAAc,cAAc,MAAM,CAAA;AACxC,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,OAAA,CAAQ,GAAA,CAAI,QAAQ,WAAW,CAAA;AAAA,IACjC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,YAAA,CACP,QAAA,EACA,MAAA,EACA,GAAA,EACA,IAAA,EACc;AACd,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,QAAO,GAAI,IAAA;AAE1C,EAAA,MAAM,UAAA,GAAa,MAAA,GAAS,WAAA,CAAY,GAAA,EAAK,MAAM,CAAA,GAAI,GAAA;AAEvD,EAAA,MAAM,aAAA,GAA6B;AAAA,IACjC,OAAA,EAAS,YAAA,CAAa,OAAA,IAAW,EAAE,CAAA;AAAA,IACnC,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,aAAA,CAAc,OAAO,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAO,QAAA,CAAS,YAAY,aAAa,CAAA;AAC3C;AAEA,SAAS,OAAO,QAAA,EAAkC;AAChD,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,GAAA,IAAO,QAAA,CAAS,SAAS,IAAA,EAAM;AACrD,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,QAAA,CAAS,IAAA,EAAK,CAAE,IAAA,CAAK,CAAA,IAAA,KAAQ;AAClC,IAAA,OAAO,QAAA,CAAS,EAAA,GAAK,IAAA,GAAO,OAAA,CAAQ,OAAO,IAAI,CAAA;AAAA,EACjD,CAAC,CAAA;AACH;AAEA,MAAM,WAAA,GAA8B;AAAA,EAClC,IAAA,EAAM,IAAA;AAAA,EACN,SAAS,EAAC;AAAA,EACV,MAAA,EAAQ;AACV,CAAA;AAEO,SAAS,GAAA,CACd,QAAA,EACA,GAAA,EACA,IAAA,GAAuB,WAAA,EACX;AACZ,EAAA,OAAO,aAAa,QAAA,EAAU,KAAA,YAAoB,KAAK,IAAI,CAAA,CAAE,KAAK,MAAM,CAAA;AAC1E;AAEO,SAAS,IAAA,CACd,QAAA,EACA,GAAA,EACA,IAAA,GAAuB,WAAA,EACX;AACZ,EAAA,OAAO,aAAa,QAAA,EAAU,MAAA,aAAqB,KAAK,IAAI,CAAA,CAAE,KAAK,MAAM,CAAA;AAC3E;;;;"}
@@ -4,6 +4,7 @@ import '../components/common/ChartBox.esm.js';
4
4
  import { CustomTooltip } from '../components/common/CustomTooltip.esm.js';
5
5
  import '@mui/material/Box';
6
6
  import '@mui/material/Typography';
7
+ import '../components/common/StatusContainer.esm.js';
7
8
 
8
9
  const StyledSvg = styled("svg")({
9
10
  cursor: "pointer",
@@ -1 +1 @@
1
- {"version":3,"file":"SettingIcon.esm.js","sources":["../../src/assets/SettingIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useTheme } from '@mui/material/styles';\nimport { styled } from '@mui/material/styles';\nimport { CustomTooltip } from '../components/common';\n\nconst StyledSvg = styled('svg')({\n cursor: 'pointer',\n '&:hover': {\n '& path': {\n opacity: 0.8,\n },\n },\n});\n\nexport const SettingIcon = () => {\n const theme = useTheme();\n const iconColor = theme.palette.text.secondary;\n\n return (\n <CustomTooltip\n title=\"Configure branches via connection page\"\n placement=\"top\"\n >\n <StyledSvg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 24 24\"\n data-name=\"Settings\"\n data-size=\"small\"\n >\n <path\n fill=\"none\"\n stroke={iconColor}\n strokeWidth=\"1.2\"\n d=\"m9.479 5.423.613-1.537c.103-.26.284-.484.52-.642s.517-.243.804-.244h1.168c.287 0 .567.086.803.244s.418.382.521.642l.613 1.537 2.08 1.163 1.68-.25c.28-.036.565.009.818.13.254.12.465.312.606.55l.57.969a1.355 1.355 0 0 1-.114 1.564l-1.04 1.288v2.326l1.069 1.288a1.353 1.353 0 0 1 .114 1.565l-.57.969a1.4 1.4 0 0 1-.606.55 1.46 1.46 0 0 1-.818.128l-1.681-.25-2.08 1.164-.612 1.537c-.103.26-.285.484-.521.642a1.45 1.45 0 0 1-.804.244h-1.196c-.287 0-.567-.086-.803-.244a1.4 1.4 0 0 1-.521-.642l-.613-1.537-2.08-1.163-1.68.25a1.46 1.46 0 0 1-.818-.13 1.4 1.4 0 0 1-.606-.55l-.57-.969a1.35 1.35 0 0 1 .114-1.564l1.04-1.288v-2.326L3.81 9.549a1.354 1.354 0 0 1-.114-1.565l.57-.969a1.4 1.4 0 0 1 .606-.55 1.46 1.46 0 0 1 .818-.128l1.681.25 2.08-1.163zM9.151 12c0 .548.168 1.083.48 1.539.314.455.758.81 1.279 1.02s1.093.264 1.646.157a2.87 2.87 0 0 0 1.458-.758c.399-.387.67-.88.78-1.418a2.7 2.7 0 0 0-.162-1.6 2.8 2.8 0 0 0-1.05-1.243A2.9 2.9 0 0 0 12 9.231a2.9 2.9 0 0 0-2.014.81 2.73 2.73 0 0 0-.835 1.96z\"\n />\n </StyledSvg>\n </CustomTooltip>\n );\n};\n\nexport default SettingIcon;\n"],"names":[],"mappings":";;;;;;;AAmBA,MAAM,SAAA,GAAY,MAAA,CAAO,KAAK,CAAA,CAAE;AAAA,EAC9B,MAAA,EAAQ,SAAA;AAAA,EACR,SAAA,EAAW;AAAA,IACT,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA;AACX;AAEJ,CAAC,CAAA;AAEM,MAAM,cAAc,MAAM;AAC/B,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAErC,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,wCAAA;AAAA,MACN,SAAA,EAAU,KAAA;AAAA,MAEV,QAAA,kBAAA,GAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,4BAAA;AAAA,UACN,KAAA,EAAM,IAAA;AAAA,UACN,MAAA,EAAO,IAAA;AAAA,UACP,OAAA,EAAQ,WAAA;AAAA,UACR,WAAA,EAAU,UAAA;AAAA,UACV,WAAA,EAAU,OAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,MAAA;AAAA,cACL,MAAA,EAAQ,SAAA;AAAA,cACR,WAAA,EAAY,KAAA;AAAA,cACZ,CAAA,EAAE;AAAA;AAAA;AACJ;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
1
+ {"version":3,"file":"SettingIcon.esm.js","sources":["../../src/assets/SettingIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useTheme } from '@mui/material/styles';\nimport { styled } from '@mui/material/styles';\nimport { CustomTooltip } from '../components/common';\n\nconst StyledSvg = styled('svg')({\n cursor: 'pointer',\n '&:hover': {\n '& path': {\n opacity: 0.8,\n },\n },\n});\n\nexport const SettingIcon = () => {\n const theme = useTheme();\n const iconColor = theme.palette.text.secondary;\n\n return (\n <CustomTooltip\n title=\"Configure branches via connection page\"\n placement=\"top\"\n >\n <StyledSvg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"28\"\n height=\"28\"\n viewBox=\"0 0 24 24\"\n data-name=\"Settings\"\n data-size=\"small\"\n >\n <path\n fill=\"none\"\n stroke={iconColor}\n strokeWidth=\"1.2\"\n d=\"m9.479 5.423.613-1.537c.103-.26.284-.484.52-.642s.517-.243.804-.244h1.168c.287 0 .567.086.803.244s.418.382.521.642l.613 1.537 2.08 1.163 1.68-.25c.28-.036.565.009.818.13.254.12.465.312.606.55l.57.969a1.355 1.355 0 0 1-.114 1.564l-1.04 1.288v2.326l1.069 1.288a1.353 1.353 0 0 1 .114 1.565l-.57.969a1.4 1.4 0 0 1-.606.55 1.46 1.46 0 0 1-.818.128l-1.681-.25-2.08 1.164-.612 1.537c-.103.26-.285.484-.521.642a1.45 1.45 0 0 1-.804.244h-1.196c-.287 0-.567-.086-.803-.244a1.4 1.4 0 0 1-.521-.642l-.613-1.537-2.08-1.163-1.68.25a1.46 1.46 0 0 1-.818-.13 1.4 1.4 0 0 1-.606-.55l-.57-.969a1.35 1.35 0 0 1 .114-1.564l1.04-1.288v-2.326L3.81 9.549a1.354 1.354 0 0 1-.114-1.565l.57-.969a1.4 1.4 0 0 1 .606-.55 1.46 1.46 0 0 1 .818-.128l1.681.25 2.08-1.163zM9.151 12c0 .548.168 1.083.48 1.539.314.455.758.81 1.279 1.02s1.093.264 1.646.157a2.87 2.87 0 0 0 1.458-.758c.399-.387.67-.88.78-1.418a2.7 2.7 0 0 0-.162-1.6 2.8 2.8 0 0 0-1.05-1.243A2.9 2.9 0 0 0 12 9.231a2.9 2.9 0 0 0-2.014.81 2.73 2.73 0 0 0-.835 1.96z\"\n />\n </StyledSvg>\n </CustomTooltip>\n );\n};\n\nexport default SettingIcon;\n"],"names":[],"mappings":";;;;;;;;AAmBA,MAAM,SAAA,GAAY,MAAA,CAAO,KAAK,CAAA,CAAE;AAAA,EAC9B,MAAA,EAAQ,SAAA;AAAA,EACR,SAAA,EAAW;AAAA,IACT,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA;AACX;AAEJ,CAAC,CAAA;AAEM,MAAM,cAAc,MAAM;AAC/B,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAErC,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,wCAAA;AAAA,MACN,SAAA,EAAU,KAAA;AAAA,MAEV,QAAA,kBAAA,GAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,4BAAA;AAAA,UACN,KAAA,EAAM,IAAA;AAAA,UACN,MAAA,EAAO,IAAA;AAAA,UACP,OAAA,EAAQ,WAAA;AAAA,UACR,WAAA,EAAU,UAAA;AAAA,UACV,WAAA,EAAU,OAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,MAAA;AAAA,cACL,MAAA,EAAQ,SAAA;AAAA,cACR,WAAA,EAAY,KAAA;AAAA,cACZ,CAAA,EAAE;AAAA;AAAA;AACJ;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ApiiroSidebar.esm.js","sources":["../../src/components/ApiiroSidebar.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { SidebarItem } from '@backstage/core-components';\nimport { ApiiroSidebar as ApiiroSidebarIcon } from '../assets/apiiroLogo/apiiroSidebar';\n\n/** @public */\nexport const ApiiroSidebar = (): JSX.Element => {\n return <SidebarItem icon={ApiiroSidebarIcon} to=\"apiiro\" text=\"apiiro\" />;\n};\n"],"names":["ApiiroSidebarIcon"],"mappings":";;;;AAmBO,MAAM,gBAAgB,MAAmB;AAC9C,EAAA,2BAAQ,WAAA,EAAA,EAAY,IAAA,EAAMA,iBAAmB,EAAA,EAAG,QAAA,EAAS,MAAK,QAAA,EAAS,CAAA;AACzE;;;;"}
1
+ {"version":3,"file":"ApiiroSidebar.esm.js","sources":["../../src/components/ApiiroSidebar.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { SidebarItem } from '@backstage/core-components';\nimport { ApiiroSidebar as ApiiroSidebarIcon } from '../assets/apiiroLogo/apiiroSidebar';\n\n/**\n * Sidebar navigation item for the Apiiro plugin.\n * Displays the Apiiro icon and links to the Apiiro page.\n * @public\n */\nexport const ApiiroSidebar = (): JSX.Element => {\n return <SidebarItem icon={ApiiroSidebarIcon} to=\"apiiro\" text=\"apiiro\" />;\n};\n"],"names":["ApiiroSidebarIcon"],"mappings":";;;;AAuBO,MAAM,gBAAgB,MAAmB;AAC9C,EAAA,2BAAQ,WAAA,EAAA,EAAY,IAAA,EAAMA,iBAAmB,EAAA,EAAG,QAAA,EAAS,MAAK,QAAA,EAAS,CAAA;AACzE;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"CalendarDatePicker.esm.js","sources":["../../src/components/CalendarDatePicker.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport 'react-calendar/dist/Calendar.css';\n\nimport { forwardRef, useCallback, useMemo } from 'react';\nimport { CalendarProps } from 'react-calendar';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport ChevronLeftIcon from '@mui/icons-material/ChevronLeft';\nimport ChevronRightIcon from '@mui/icons-material/ChevronRight';\nimport { useTheme } from '@mui/material/styles';\nimport {\n CalendarContainer,\n StyledCalendar,\n QuickRangeList,\n QuickRangeItem,\n QuickRangeText,\n} from './CalendarDatePicker.styles';\nimport { LooseValue } from 'react-calendar/dist/cjs/shared/types';\n\ntype Value = Date | Date[] | null;\n\nexport type CalendarDateValue = Date | [Date, Date] | [];\n\nexport type CalendarQuickRange = {\n label: string;\n value: string;\n getRange: () => CalendarDateValue | null;\n};\n\ntype CalendarDatePickerProps = {\n value?: CalendarDateValue;\n onChange?: (date: CalendarDateValue) => void;\n quickRanges?: CalendarQuickRange[];\n selectedQuickRange?: string;\n onQuickRangeSelect?: (quickRange: CalendarQuickRange) => void;\n showQuickRanges?: boolean;\n tileStyle?: (args: {\n date: Date;\n view: string;\n }) => globalThis.React.CSSProperties;\n} & Pick<\n CalendarProps,\n | 'activeStartDate'\n | 'minDate'\n | 'maxDate'\n | 'tileClassName'\n | 'tileContent'\n | 'tileDisabled'\n | 'selectRange'\n | 'onActiveStartDateChange'\n>;\n\nexport const createDefaultQuickRanges = (): CalendarQuickRange[] => {\n const today = new Date();\n\n const startOfDay = (date: Date) => {\n const copy = new Date(date);\n copy.setHours(0, 0, 0, 0);\n return copy;\n };\n\n const endOfDay = (date: Date) => {\n const copy = new Date(date);\n copy.setHours(23, 59, 59, 999);\n return copy;\n };\n\n const subtractDays = (amount: number) => {\n const date = new Date();\n date.setDate(date.getDate() - amount);\n return date;\n };\n\n return [\n {\n label: 'All Dates',\n value: 'all',\n getRange: () => [subtractDays(365 * 10), endOfDay(new Date())],\n },\n {\n label: 'Last 7 days',\n value: 'last-7-days',\n getRange: () => [startOfDay(subtractDays(6)), endOfDay(today)],\n },\n {\n label: 'Last 14 days',\n value: 'last-14-days',\n getRange: () => [startOfDay(subtractDays(13)), endOfDay(today)],\n },\n {\n label: 'Last 30 days',\n value: 'last-30-days',\n getRange: () => [startOfDay(subtractDays(29)), endOfDay(today)],\n },\n {\n label: 'Last 90 days',\n value: 'last-90-days',\n getRange: () => [startOfDay(subtractDays(89)), endOfDay(today)],\n },\n {\n label: 'Custom',\n value: 'custom',\n getRange: () => [],\n },\n ];\n};\n\nexport const CalendarDatePicker = forwardRef<\n HTMLDivElement,\n CalendarDatePickerProps\n>(\n (\n {\n selectRange = true,\n showQuickRanges = true,\n quickRanges,\n selectedQuickRange,\n onQuickRangeSelect,\n value,\n onChange,\n ...props\n },\n ref,\n ) => {\n const theme = useTheme();\n\n const computedQuickRanges = useMemo(\n () => quickRanges ?? createDefaultQuickRanges(),\n [quickRanges],\n );\n\n const formatShortWeekday = useCallback(\n (locale: string | undefined, date: Date) =>\n date\n .toLocaleDateString(locale || 'en-US', { weekday: 'short' })\n .slice(0, 1),\n [],\n );\n\n const handleCalendarChange = useCallback(\n (calendarValue: Value) => {\n if (onChange) {\n onChange(calendarValue as CalendarDateValue);\n }\n },\n [onChange],\n );\n\n const handleQuickRangeSelect = (range: CalendarQuickRange) => {\n if (onQuickRangeSelect) {\n onQuickRangeSelect(range);\n }\n const nextValue = range.getRange();\n if (nextValue && onChange) {\n onChange(nextValue);\n }\n };\n\n return (\n <CalendarContainer ref={ref}>\n <StyledCalendar\n value={value as LooseValue}\n onChange={handleCalendarChange as any}\n selectRange={selectRange}\n formatShortWeekday={formatShortWeekday}\n prev2Label={null}\n next2Label={null}\n prevLabel={<ChevronLeftIcon />}\n nextLabel={<ChevronRightIcon />}\n minDetail=\"decade\"\n {...props}\n />\n {showQuickRanges && (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n backgroundColor: theme.palette.background.paper,\n }}\n >\n <Typography\n variant=\"subtitle2\"\n sx={{\n color: theme.palette.text.secondary,\n fontWeight: 600,\n mb: 0.5,\n }}\n >\n Presets\n </Typography>\n <QuickRangeList>\n {computedQuickRanges.map(range => (\n <QuickRangeItem\n key={range.value}\n $selected={selectedQuickRange === range.value}\n onClick={() => handleQuickRangeSelect(range)}\n >\n <QuickRangeText primary={range.label} />\n </QuickRangeItem>\n ))}\n </QuickRangeList>\n </Box>\n )}\n </CalendarContainer>\n );\n },\n);\n\nCalendarDatePicker.displayName = 'CalendarDatePicker';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CalendarDatePicker.esm.js","sources":["../../src/components/CalendarDatePicker.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport 'react-calendar/dist/Calendar.css';\n\nimport { forwardRef, useCallback, useMemo } from 'react';\nimport { CalendarProps } from 'react-calendar';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport ChevronLeftIcon from '@mui/icons-material/ChevronLeft';\nimport ChevronRightIcon from '@mui/icons-material/ChevronRight';\nimport { useTheme } from '@mui/material/styles';\nimport {\n CalendarContainer,\n StyledCalendar,\n QuickRangeList,\n QuickRangeItem,\n QuickRangeText,\n} from './CalendarDatePicker.styles';\n\ntype Value = Date | Date[] | null;\n\nexport type CalendarDateValue = Date | [Date, Date] | [];\n\nexport type CalendarQuickRange = {\n label: string;\n value: string;\n getRange: () => CalendarDateValue | null;\n};\n\ntype CalendarDatePickerProps = {\n value?: CalendarDateValue;\n onChange?: (date: CalendarDateValue) => void;\n quickRanges?: CalendarQuickRange[];\n selectedQuickRange?: string;\n onQuickRangeSelect?: (quickRange: CalendarQuickRange) => void;\n showQuickRanges?: boolean;\n tileStyle?: (args: {\n date: Date;\n view: string;\n }) => globalThis.React.CSSProperties;\n} & Pick<\n CalendarProps,\n | 'activeStartDate'\n | 'minDate'\n | 'maxDate'\n | 'tileClassName'\n | 'tileContent'\n | 'tileDisabled'\n | 'selectRange'\n | 'onActiveStartDateChange'\n>;\n\nexport const createDefaultQuickRanges = (): CalendarQuickRange[] => {\n const today = new Date();\n\n const startOfDay = (date: Date) => {\n const copy = new Date(date);\n copy.setHours(0, 0, 0, 0);\n return copy;\n };\n\n const endOfDay = (date: Date) => {\n const copy = new Date(date);\n copy.setHours(23, 59, 59, 999);\n return copy;\n };\n\n const subtractDays = (amount: number) => {\n const date = new Date();\n date.setDate(date.getDate() - amount);\n return date;\n };\n\n return [\n {\n label: 'All Dates',\n value: 'all',\n getRange: () => [subtractDays(365 * 10), endOfDay(new Date())],\n },\n {\n label: 'Last 7 days',\n value: 'last-7-days',\n getRange: () => [startOfDay(subtractDays(6)), endOfDay(today)],\n },\n {\n label: 'Last 14 days',\n value: 'last-14-days',\n getRange: () => [startOfDay(subtractDays(13)), endOfDay(today)],\n },\n {\n label: 'Last 30 days',\n value: 'last-30-days',\n getRange: () => [startOfDay(subtractDays(29)), endOfDay(today)],\n },\n {\n label: 'Last 90 days',\n value: 'last-90-days',\n getRange: () => [startOfDay(subtractDays(89)), endOfDay(today)],\n },\n {\n label: 'Custom',\n value: 'custom',\n getRange: () => [],\n },\n ];\n};\n\nexport const CalendarDatePicker = forwardRef<\n HTMLDivElement,\n CalendarDatePickerProps\n>(\n (\n {\n selectRange = true,\n showQuickRanges = true,\n quickRanges,\n selectedQuickRange,\n onQuickRangeSelect,\n value,\n onChange,\n ...props\n },\n ref,\n ) => {\n const theme = useTheme();\n\n const computedQuickRanges = useMemo(\n () => quickRanges ?? createDefaultQuickRanges(),\n [quickRanges],\n );\n\n const formatShortWeekday = useCallback(\n (locale: string | undefined, date: Date) =>\n date\n .toLocaleDateString(locale || 'en-US', { weekday: 'short' })\n .slice(0, 1),\n [],\n );\n\n const handleCalendarChange = useCallback(\n (calendarValue: Value) => {\n if (onChange) {\n onChange(calendarValue as CalendarDateValue);\n }\n },\n [onChange],\n );\n\n const handleQuickRangeSelect = (range: CalendarQuickRange) => {\n if (onQuickRangeSelect) {\n onQuickRangeSelect(range);\n }\n const nextValue = range.getRange();\n if (nextValue && onChange) {\n onChange(nextValue);\n }\n };\n\n return (\n <CalendarContainer ref={ref}>\n <StyledCalendar\n value={value as any}\n onChange={handleCalendarChange as any}\n selectRange={selectRange}\n formatShortWeekday={formatShortWeekday}\n prev2Label={null}\n next2Label={null}\n prevLabel={<ChevronLeftIcon />}\n nextLabel={<ChevronRightIcon />}\n minDetail=\"decade\"\n {...props}\n />\n {showQuickRanges && (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n backgroundColor: theme.palette.background.paper,\n }}\n >\n <Typography\n variant=\"subtitle2\"\n sx={{\n color: theme.palette.text.secondary,\n fontWeight: 600,\n mb: 0.5,\n }}\n >\n Presets\n </Typography>\n <QuickRangeList>\n {computedQuickRanges.map(range => (\n <QuickRangeItem\n key={range.value}\n $selected={selectedQuickRange === range.value}\n onClick={() => handleQuickRangeSelect(range)}\n >\n <QuickRangeText primary={range.label} />\n </QuickRangeItem>\n ))}\n </QuickRangeList>\n </Box>\n )}\n </CalendarContainer>\n );\n },\n);\n\nCalendarDatePicker.displayName = 'CalendarDatePicker';\n"],"names":[],"mappings":";;;;;;;;;;AAiEO,MAAM,2BAA2B,MAA4B;AAClE,EAAA,MAAM,KAAA,uBAAY,IAAA,EAAK;AAEvB,EAAA,MAAM,UAAA,GAAa,CAAC,IAAA,KAAe;AACjC,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,IAAI,CAAA;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACxB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,KAAe;AAC/B,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,IAAI,CAAA;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,GAAG,CAAA;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,MAAA,KAAmB;AACvC,IAAA,MAAM,IAAA,uBAAW,IAAA,EAAK;AACtB,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAQ,GAAI,MAAM,CAAA;AACpC,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO;AAAA,IACL;AAAA,MACE,KAAA,EAAO,WAAA;AAAA,MACP,KAAA,EAAO,KAAA;AAAA,MACP,QAAA,EAAU,MAAM,CAAC,YAAA,CAAa,GAAA,GAAM,EAAE,CAAA,EAAG,QAAA,iBAAS,IAAI,IAAA,EAAM,CAAC;AAAA,KAC/D;AAAA,IACA;AAAA,MACE,KAAA,EAAO,aAAA;AAAA,MACP,KAAA,EAAO,aAAA;AAAA,MACP,QAAA,EAAU,MAAM,CAAC,UAAA,CAAW,YAAA,CAAa,CAAC,CAAC,CAAA,EAAG,QAAA,CAAS,KAAK,CAAC;AAAA,KAC/D;AAAA,IACA;AAAA,MACE,KAAA,EAAO,cAAA;AAAA,MACP,KAAA,EAAO,cAAA;AAAA,MACP,QAAA,EAAU,MAAM,CAAC,UAAA,CAAW,YAAA,CAAa,EAAE,CAAC,CAAA,EAAG,QAAA,CAAS,KAAK,CAAC;AAAA,KAChE;AAAA,IACA;AAAA,MACE,KAAA,EAAO,cAAA;AAAA,MACP,KAAA,EAAO,cAAA;AAAA,MACP,QAAA,EAAU,MAAM,CAAC,UAAA,CAAW,YAAA,CAAa,EAAE,CAAC,CAAA,EAAG,QAAA,CAAS,KAAK,CAAC;AAAA,KAChE;AAAA,IACA;AAAA,MACE,KAAA,EAAO,cAAA;AAAA,MACP,KAAA,EAAO,cAAA;AAAA,MACP,QAAA,EAAU,MAAM,CAAC,UAAA,CAAW,YAAA,CAAa,EAAE,CAAC,CAAA,EAAG,QAAA,CAAS,KAAK,CAAC;AAAA,KAChE;AAAA,IACA;AAAA,MACE,KAAA,EAAO,QAAA;AAAA,MACP,KAAA,EAAO,QAAA;AAAA,MACP,QAAA,EAAU,MAAM;AAAC;AACnB,GACF;AACF;AAEO,MAAM,kBAAA,GAAqB,UAAA;AAAA,EAIhC,CACE;AAAA,IACE,WAAA,GAAc,IAAA;AAAA,IACd,eAAA,GAAkB,IAAA;AAAA,IAClB,WAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,QAAQ,QAAA,EAAS;AAEvB,IAAA,MAAM,mBAAA,GAAsB,OAAA;AAAA,MAC1B,MAAM,eAAe,wBAAA,EAAyB;AAAA,MAC9C,CAAC,WAAW;AAAA,KACd;AAEA,IAAA,MAAM,kBAAA,GAAqB,WAAA;AAAA,MACzB,CAAC,MAAA,EAA4B,IAAA,KAC3B,IAAA,CACG,mBAAmB,MAAA,IAAU,OAAA,EAAS,EAAE,OAAA,EAAS,OAAA,EAAS,CAAA,CAC1D,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,MACf;AAAC,KACH;AAEA,IAAA,MAAM,oBAAA,GAAuB,WAAA;AAAA,MAC3B,CAAC,aAAA,KAAyB;AACxB,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,QAAA,CAAS,aAAkC,CAAA;AAAA,QAC7C;AAAA,MACF,CAAA;AAAA,MACA,CAAC,QAAQ;AAAA,KACX;AAEA,IAAA,MAAM,sBAAA,GAAyB,CAAC,KAAA,KAA8B;AAC5D,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA,kBAAA,CAAmB,KAAK,CAAA;AAAA,MAC1B;AACA,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,EAAS;AACjC,MAAA,IAAI,aAAa,QAAA,EAAU;AACzB,QAAA,QAAA,CAAS,SAAS,CAAA;AAAA,MACpB;AAAA,IACF,CAAA;AAEA,IAAA,uBACE,IAAA,CAAC,qBAAkB,GAAA,EACjB,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,KAAA;AAAA,UACA,QAAA,EAAU,oBAAA;AAAA,UACV,WAAA;AAAA,UACA,kBAAA;AAAA,UACA,UAAA,EAAY,IAAA;AAAA,UACZ,UAAA,EAAY,IAAA;AAAA,UACZ,SAAA,sBAAY,eAAA,EAAA,EAAgB,CAAA;AAAA,UAC5B,SAAA,sBAAY,gBAAA,EAAA,EAAiB,CAAA;AAAA,UAC7B,SAAA,EAAU,QAAA;AAAA,UACT,GAAG;AAAA;AAAA,OACN;AAAA,MACC,eAAA,oBACC,IAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,EAAA,EAAI;AAAA,YACF,OAAA,EAAS,MAAA;AAAA,YACT,aAAA,EAAe,QAAA;AAAA,YACf,GAAA,EAAK,CAAA;AAAA,YACL,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,WAC5C;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,WAAA;AAAA,gBACR,EAAA,EAAI;AAAA,kBACF,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,kBAC1B,UAAA,EAAY,GAAA;AAAA,kBACZ,EAAA,EAAI;AAAA,iBACN;AAAA,gBACD,QAAA,EAAA;AAAA;AAAA,aAED;AAAA,4BACA,GAAA,CAAC,cAAA,EAAA,EACE,QAAA,EAAA,mBAAA,CAAoB,GAAA,CAAI,CAAA,KAAA,qBACvB,GAAA;AAAA,cAAC,cAAA;AAAA,cAAA;AAAA,gBAEC,SAAA,EAAW,uBAAuB,KAAA,CAAM,KAAA;AAAA,gBACxC,OAAA,EAAS,MAAM,sBAAA,CAAuB,KAAK,CAAA;AAAA,gBAE3C,QAAA,kBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAS,KAAA,CAAM,KAAA,EAAO;AAAA,eAAA;AAAA,cAJjC,KAAA,CAAM;AAAA,aAMd,CAAA,EACH;AAAA;AAAA;AAAA;AACF,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AAEA,kBAAA,CAAmB,WAAA,GAAc,oBAAA;;;;"}
@@ -10,6 +10,7 @@ import '../common/ChartBox.esm.js';
10
10
  import 'react-dom';
11
11
  import { NotFound } from '../common/NotFound.esm.js';
12
12
  import '@mui/material/Typography';
13
+ import '../common/StatusContainer.esm.js';
13
14
  import { LogoSpinner } from '../common/logoSpinner.esm.js';
14
15
 
15
16
  function DataGrid({
@@ -1 +1 @@
1
- {"version":3,"file":"DataGrid.esm.js","sources":["../../../src/components/DataGrid/DataGrid.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useEffect, useState, useCallback } from 'react';\nimport {\n DataGrid as DataGridMUI,\n GridColDef,\n GridPaginationModel,\n useGridApiRef,\n GridValidRowModel,\n} from '@mui/x-data-grid';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport { CustomColumnMenu } from './CustomColumnMenu';\nimport { CustomPagination } from './CustomPagination';\nimport { CustomSearchToolbar } from './CustomSearchToolbar';\nimport { DataGridProps, GridLayout } from './types';\nimport { NotFound } from '../common';\nimport { LogoSpinner } from '../common/logoSpinner';\n\nexport function DataGrid<T extends GridValidRowModel>({\n // Required props\n tableKey,\n columns: propColumns,\n rows: propRows,\n\n // Optional configuration\n dataLabel = 'items',\n searchBarPlaceHolder = 'Search',\n features = {},\n styling = {},\n\n // Pagination\n initialPageSize = 20,\n pageSizeOptions = [20, 50, 100],\n\n // Event handlers\n onRowClick,\n onSelectionChange,\n\n // Custom components\n customFilters,\n columnVisibility,\n\n // Loading state\n loading,\n\n // custom Row ID\n getRowId,\n\n // Initial Table state\n initialState,\n}: DataGridProps<T>) {\n const theme = useTheme();\n const apiRef = useGridApiRef();\n\n // Default feature flags\n const {\n quickSearch = true,\n columnPinning = true,\n columnReordering = true,\n customPagination = true,\n columnMenu = true,\n persistLayout = true,\n } = features;\n\n // Default styling\n const {\n borderRadius = '12px',\n headerBackgroundColor = theme.palette.mode === 'dark'\n ? theme.palette.background.paper\n : theme.palette.grey[100],\n backgroundColor = theme.palette.background.paper,\n height = 'auto',\n } = styling;\n\n const [columns, setColumns] = useState<GridColDef<T>[]>(propColumns);\n const [pinned, setPinned] = useState<string[]>([]);\n const [dragCol, setDragCol] = useState<string | null>(null);\n const [dropTarget, setDropTarget] = useState<string | null>(null);\n const [dropSide, setDropSide] = useState<'left' | 'right' | null>(null);\n const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({\n page: 0,\n pageSize: initialPageSize,\n });\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useState<\n Record<string, boolean>\n >(columnVisibility || {});\n\n // Load saved layout\n useEffect(() => {\n if (!persistLayout) return;\n\n try {\n const saved = localStorage.getItem(`apiiro-gridLayout-${tableKey}`);\n if (saved) {\n const {\n order,\n pinned: savedPinned,\n columnVisibility: savedVisibility,\n } = JSON.parse(saved) as GridLayout;\n setPinned(savedPinned || []);\n\n // Restore column visibility if saved\n if (savedVisibility) {\n setColumnVisibilityModel(savedVisibility);\n }\n\n const orderedColumns = order\n .map(field => propColumns.find(c => c.field === field))\n .filter((c): c is GridColDef<T> => !!c);\n setColumns(orderedColumns);\n }\n } catch (error) {\n // Failed to load grid layout - using default\n }\n }, [propColumns, persistLayout, tableKey]);\n\n const saveLayout = useCallback(\n (\n cols: GridColDef<T>[],\n pinnedCols: string[],\n visibility?: Record<string, boolean>,\n ) => {\n if (!persistLayout) return;\n\n const layout: GridLayout = {\n order: cols.map(c => c.field),\n pinned: pinnedCols,\n columnVisibility: visibility || columnVisibilityModel,\n };\n localStorage.setItem(\n `apiiro-gridLayout-${tableKey}`,\n JSON.stringify(layout),\n );\n },\n [persistLayout, tableKey, columnVisibilityModel],\n );\n\n // Save column visibility changes to gridLayout\n useEffect(() => {\n if (persistLayout) {\n saveLayout(columns, pinned, columnVisibilityModel);\n }\n }, [columnVisibilityModel, persistLayout, saveLayout, columns, pinned]);\n\n const handleDragStart = (field: string) => setDragCol(field);\n\n const handleDragOver = (\n e: React.DragEvent<HTMLDivElement>,\n targetField: string,\n ) => {\n e.preventDefault();\n if (dragCol === targetField) return;\n const targetRect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - targetRect.left;\n setDropTarget(targetField);\n setDropSide(x < targetRect.width / 2 ? 'left' : 'right');\n };\n\n const handleDragLeave = () => setDropTarget(null);\n\n const handleDrop = (targetField: string) => {\n if (!dragCol || dragCol === targetField) return;\n\n const dragIsPinned = pinned.includes(dragCol);\n const targetIsPinned = pinned.includes(targetField);\n\n if (dragIsPinned !== targetIsPinned) {\n setDragCol(null);\n setDropTarget(null);\n return;\n }\n\n const currentList = dragIsPinned\n ? columns.filter(c => pinned.includes(c.field))\n : columns.filter(c => !pinned.includes(c.field));\n\n const dragIndex = currentList.findIndex(c => c.field === dragCol);\n const targetIndex = currentList.findIndex(c => c.field === targetField);\n\n const newIndex = dropSide === 'left' ? targetIndex : targetIndex + 1;\n const reordered = [...currentList];\n const [moved] = reordered.splice(dragIndex, 1);\n reordered.splice(newIndex, 0, moved);\n\n const finalColumns = dragIsPinned\n ? [...reordered, ...columns.filter(c => !pinned.includes(c.field))]\n : [...columns.filter(c => pinned.includes(c.field)), ...reordered];\n\n setColumns(finalColumns);\n setDragCol(null);\n setDropTarget(null);\n saveLayout(finalColumns, pinned);\n };\n\n const togglePin = useCallback(\n (field: string) => {\n setPinned(prev => {\n const next = prev.includes(field)\n ? prev.filter(f => f !== field)\n : [...prev, field];\n saveLayout(columns, next);\n return next;\n });\n },\n [columns, saveLayout],\n );\n\n const CustomColumnMenuWithProps = useCallback(\n (props: any) => {\n return (\n <CustomColumnMenu\n {...props}\n isPinned={pinned.includes(props.colDef.field)}\n onTogglePin={togglePin}\n />\n );\n },\n [pinned, togglePin],\n );\n\n const CustomPaginationComponent = useCallback(\n () => (\n <CustomPagination\n onPageSizeChange={pageSize => setPaginationModel({ page: 0, pageSize })}\n pageSizeOptions={pageSizeOptions}\n dataLabel={dataLabel}\n />\n ),\n [dataLabel, pageSizeOptions],\n );\n\n const finalColumns = columnReordering\n ? columns.map(col => ({\n ...col,\n renderHeader: () => (\n <Box\n draggable={columnReordering}\n onDragStart={() => handleDragStart(col.field)}\n onDragOver={e => handleDragOver(e, col.field)}\n onDragLeave={handleDragLeave}\n onDrop={() => handleDrop(col.field)}\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n cursor: columnReordering ? 'grab' : 'default',\n userSelect: 'none',\n position: 'relative',\n fontWeight:\n columnPinning && pinned.includes(col.field) ? 'bold' : 'normal',\n px: 1,\n '&::before': columnReordering\n ? {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n bottom: 0,\n left:\n dropTarget === col.field && dropSide === 'left'\n ? 0\n : 'auto',\n right:\n dropTarget === col.field && dropSide === 'right'\n ? 0\n : 'auto',\n width: '3px',\n backgroundColor:\n dropTarget === col.field\n ? theme.palette.primary.main\n : 'transparent',\n transition: 'background 0.1s ease',\n }\n : {},\n }}\n >\n {col.headerName}\n </Box>\n ),\n }))\n : columns;\n\n const orderedColumns = columnPinning\n ? [\n ...finalColumns\n .filter(c => pinned.includes(c.field))\n .map(col => ({ ...col, resizable: false })),\n ...finalColumns.filter(c => !pinned.includes(c.field)),\n ]\n : finalColumns;\n\n // Sticky offsets\n const pinnedOffsets: Record<string, number> = {};\n let leftOffset = 0;\n for (const col of orderedColumns) {\n if (pinned.includes(col.field)) {\n pinnedOffsets[col.field] = leftOffset;\n leftOffset += col.minWidth || col.width || 200;\n }\n }\n\n // Create pinned column styles\n const pinnedColumnStyles: Record<string, any> = {};\n if (columnPinning) {\n pinned.forEach(field => {\n pinnedColumnStyles[`& [data-field=\"${field}\"]`] = {\n position: 'sticky',\n left: pinnedOffsets[field],\n zIndex: 9999,\n backgroundColor: backgroundColor,\n boxShadow: '2px 0 2px rgba(0,0,0,0.05)',\n };\n });\n }\n\n return (\n <Box\n sx={{\n height,\n width: '100%',\n overflowX: 'auto',\n }}\n >\n {quickSearch && (\n <CustomSearchToolbar\n apiRef={apiRef}\n placeholder={searchBarPlaceHolder}\n customFilters={customFilters}\n />\n )}\n <DataGridMUI\n key={tableKey}\n apiRef={apiRef}\n rows={propRows}\n columns={orderedColumns}\n initialState={{\n ...initialState,\n }}\n columnVisibilityModel={columnVisibilityModel}\n onColumnVisibilityModelChange={setColumnVisibilityModel}\n disableVirtualization\n getRowId={getRowId}\n loading={loading}\n paginationModel={paginationModel}\n onPaginationModelChange={setPaginationModel}\n pageSizeOptions={pageSizeOptions}\n onRowClick={onRowClick ? params => onRowClick(params.row) : undefined}\n onRowSelectionModelChange={\n onSelectionChange\n ? selectionModel => {\n const selectedIds = selectionModel.ids\n ? Array.from(selectionModel.ids)\n : [];\n const selectedRows = propRows.filter(row =>\n selectedIds.some(\n id =>\n String(getRowId ? getRowId(row) : row.id) === String(id),\n ),\n );\n onSelectionChange(selectedRows);\n }\n : undefined\n }\n slots={{\n ...(columnMenu && { columnMenu: CustomColumnMenuWithProps }),\n ...(customPagination && { pagination: CustomPaginationComponent }),\n noResultsOverlay: () => <NotFound />,\n loadingOverlay: () => (\n <Box\n display=\"flex\"\n height=\"100%\"\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <LogoSpinner />\n </Box>\n ),\n }}\n slotProps={{\n loadingOverlay: {\n variant: 'linear-progress',\n noRowsVariant: 'skeleton',\n },\n columnsManagement: {\n disableResetButton: true,\n searchInputProps: {\n type: 'text',\n },\n },\n }}\n sx={{\n backgroundColor,\n '&.MuiDataGrid-root': {\n borderRadius,\n minWidth: 'auto',\n },\n '& .MuiDataGrid-columnHeader:focus, & .MuiDataGrid-columnHeader:focus-within':\n {\n outline: 'none',\n },\n '&.MuiDataGrid-root .MuiDataGrid-columnHeader, &.MuiDataGrid-root .MuiDataGrid-filler':\n {\n backgroundColor: headerBackgroundColor,\n },\n // Column resize line styling\n '& .MuiDataGrid-columnSeparator--resizable': {\n '&:hover': {\n color: theme.palette.primary.main,\n },\n },\n '& .MuiDataGrid-columnSeparator--resizing': {\n color: theme.palette.primary.main,\n opacity: 1,\n },\n ...pinnedColumnStyles,\n }}\n />\n </Box>\n );\n}\n"],"names":["orderedColumns","finalColumns","DataGridMUI"],"mappings":"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"}
1
+ {"version":3,"file":"DataGrid.esm.js","sources":["../../../src/components/DataGrid/DataGrid.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useEffect, useState, useCallback } from 'react';\nimport {\n DataGrid as DataGridMUI,\n GridColDef,\n GridPaginationModel,\n useGridApiRef,\n GridValidRowModel,\n} from '@mui/x-data-grid';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport { CustomColumnMenu } from './CustomColumnMenu';\nimport { CustomPagination } from './CustomPagination';\nimport { CustomSearchToolbar } from './CustomSearchToolbar';\nimport { DataGridProps, GridLayout } from './types';\nimport { NotFound } from '../common';\nimport { LogoSpinner } from '../common/logoSpinner';\n\nexport function DataGrid<T extends GridValidRowModel>({\n // Required props\n tableKey,\n columns: propColumns,\n rows: propRows,\n\n // Optional configuration\n dataLabel = 'items',\n searchBarPlaceHolder = 'Search',\n features = {},\n styling = {},\n\n // Pagination\n initialPageSize = 20,\n pageSizeOptions = [20, 50, 100],\n\n // Event handlers\n onRowClick,\n onSelectionChange,\n\n // Custom components\n customFilters,\n columnVisibility,\n\n // Loading state\n loading,\n\n // custom Row ID\n getRowId,\n\n // Initial Table state\n initialState,\n}: DataGridProps<T>) {\n const theme = useTheme();\n const apiRef = useGridApiRef();\n\n // Default feature flags\n const {\n quickSearch = true,\n columnPinning = true,\n columnReordering = true,\n customPagination = true,\n columnMenu = true,\n persistLayout = true,\n } = features;\n\n // Default styling\n const {\n borderRadius = '12px',\n headerBackgroundColor = theme.palette.mode === 'dark'\n ? theme.palette.background.paper\n : theme.palette.grey[100],\n backgroundColor = theme.palette.background.paper,\n height = 'auto',\n } = styling;\n\n const [columns, setColumns] = useState<GridColDef<T>[]>(propColumns);\n const [pinned, setPinned] = useState<string[]>([]);\n const [dragCol, setDragCol] = useState<string | null>(null);\n const [dropTarget, setDropTarget] = useState<string | null>(null);\n const [dropSide, setDropSide] = useState<'left' | 'right' | null>(null);\n const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({\n page: 0,\n pageSize: initialPageSize,\n });\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useState<\n Record<string, boolean>\n >(columnVisibility || {});\n\n // Load saved layout\n useEffect(() => {\n if (!persistLayout) return;\n\n try {\n const saved = localStorage.getItem(`apiiro-gridLayout-${tableKey}`);\n if (saved) {\n const {\n order,\n pinned: savedPinned,\n columnVisibility: savedVisibility,\n } = JSON.parse(saved) as GridLayout;\n setPinned(savedPinned || []);\n\n // Restore column visibility if saved\n if (savedVisibility) {\n setColumnVisibilityModel(savedVisibility);\n }\n\n const orderedColumns = order\n .map(field => propColumns.find(c => c.field === field))\n .filter((c): c is GridColDef<T> => !!c);\n setColumns(orderedColumns);\n }\n } catch (error) {\n // Failed to load grid layout - using default\n }\n }, [propColumns, persistLayout, tableKey]);\n\n const saveLayout = useCallback(\n (\n cols: GridColDef<T>[],\n pinnedCols: string[],\n visibility?: Record<string, boolean>,\n ) => {\n if (!persistLayout) return;\n\n const layout: GridLayout = {\n order: cols.map(c => c.field),\n pinned: pinnedCols,\n columnVisibility: visibility || columnVisibilityModel,\n };\n localStorage.setItem(\n `apiiro-gridLayout-${tableKey}`,\n JSON.stringify(layout),\n );\n },\n [persistLayout, tableKey, columnVisibilityModel],\n );\n\n // Save column visibility changes to gridLayout\n useEffect(() => {\n if (persistLayout) {\n saveLayout(columns, pinned, columnVisibilityModel);\n }\n }, [columnVisibilityModel, persistLayout, saveLayout, columns, pinned]);\n\n const handleDragStart = (field: string) => setDragCol(field);\n\n const handleDragOver = (\n e: React.DragEvent<HTMLDivElement>,\n targetField: string,\n ) => {\n e.preventDefault();\n if (dragCol === targetField) return;\n const targetRect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - targetRect.left;\n setDropTarget(targetField);\n setDropSide(x < targetRect.width / 2 ? 'left' : 'right');\n };\n\n const handleDragLeave = () => setDropTarget(null);\n\n const handleDrop = (targetField: string) => {\n if (!dragCol || dragCol === targetField) return;\n\n const dragIsPinned = pinned.includes(dragCol);\n const targetIsPinned = pinned.includes(targetField);\n\n if (dragIsPinned !== targetIsPinned) {\n setDragCol(null);\n setDropTarget(null);\n return;\n }\n\n const currentList = dragIsPinned\n ? columns.filter(c => pinned.includes(c.field))\n : columns.filter(c => !pinned.includes(c.field));\n\n const dragIndex = currentList.findIndex(c => c.field === dragCol);\n const targetIndex = currentList.findIndex(c => c.field === targetField);\n\n const newIndex = dropSide === 'left' ? targetIndex : targetIndex + 1;\n const reordered = [...currentList];\n const [moved] = reordered.splice(dragIndex, 1);\n reordered.splice(newIndex, 0, moved);\n\n const finalColumns = dragIsPinned\n ? [...reordered, ...columns.filter(c => !pinned.includes(c.field))]\n : [...columns.filter(c => pinned.includes(c.field)), ...reordered];\n\n setColumns(finalColumns);\n setDragCol(null);\n setDropTarget(null);\n saveLayout(finalColumns, pinned);\n };\n\n const togglePin = useCallback(\n (field: string) => {\n setPinned(prev => {\n const next = prev.includes(field)\n ? prev.filter(f => f !== field)\n : [...prev, field];\n saveLayout(columns, next);\n return next;\n });\n },\n [columns, saveLayout],\n );\n\n const CustomColumnMenuWithProps = useCallback(\n (props: any) => {\n return (\n <CustomColumnMenu\n {...props}\n isPinned={pinned.includes(props.colDef.field)}\n onTogglePin={togglePin}\n />\n );\n },\n [pinned, togglePin],\n );\n\n const CustomPaginationComponent = useCallback(\n () => (\n <CustomPagination\n onPageSizeChange={pageSize => setPaginationModel({ page: 0, pageSize })}\n pageSizeOptions={pageSizeOptions}\n dataLabel={dataLabel}\n />\n ),\n [dataLabel, pageSizeOptions],\n );\n\n const finalColumns = columnReordering\n ? columns.map(col => ({\n ...col,\n renderHeader: () => (\n <Box\n draggable={columnReordering}\n onDragStart={() => handleDragStart(col.field)}\n onDragOver={e => handleDragOver(e, col.field)}\n onDragLeave={handleDragLeave}\n onDrop={() => handleDrop(col.field)}\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n cursor: columnReordering ? 'grab' : 'default',\n userSelect: 'none',\n position: 'relative',\n fontWeight:\n columnPinning && pinned.includes(col.field) ? 'bold' : 'normal',\n px: 1,\n '&::before': columnReordering\n ? {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n bottom: 0,\n left:\n dropTarget === col.field && dropSide === 'left'\n ? 0\n : 'auto',\n right:\n dropTarget === col.field && dropSide === 'right'\n ? 0\n : 'auto',\n width: '3px',\n backgroundColor:\n dropTarget === col.field\n ? theme.palette.primary.main\n : 'transparent',\n transition: 'background 0.1s ease',\n }\n : {},\n }}\n >\n {col.headerName}\n </Box>\n ),\n }))\n : columns;\n\n const orderedColumns = columnPinning\n ? [\n ...finalColumns\n .filter(c => pinned.includes(c.field))\n .map(col => ({ ...col, resizable: false })),\n ...finalColumns.filter(c => !pinned.includes(c.field)),\n ]\n : finalColumns;\n\n // Sticky offsets\n const pinnedOffsets: Record<string, number> = {};\n let leftOffset = 0;\n for (const col of orderedColumns) {\n if (pinned.includes(col.field)) {\n pinnedOffsets[col.field] = leftOffset;\n leftOffset += col.minWidth || col.width || 200;\n }\n }\n\n // Create pinned column styles\n const pinnedColumnStyles: Record<string, any> = {};\n if (columnPinning) {\n pinned.forEach(field => {\n pinnedColumnStyles[`& [data-field=\"${field}\"]`] = {\n position: 'sticky',\n left: pinnedOffsets[field],\n zIndex: 9999,\n backgroundColor: backgroundColor,\n boxShadow: '2px 0 2px rgba(0,0,0,0.05)',\n };\n });\n }\n\n return (\n <Box\n sx={{\n height,\n width: '100%',\n overflowX: 'auto',\n }}\n >\n {quickSearch && (\n <CustomSearchToolbar\n apiRef={apiRef}\n placeholder={searchBarPlaceHolder}\n customFilters={customFilters}\n />\n )}\n <DataGridMUI\n key={tableKey}\n apiRef={apiRef}\n rows={propRows}\n columns={orderedColumns}\n initialState={{\n ...initialState,\n }}\n columnVisibilityModel={columnVisibilityModel}\n onColumnVisibilityModelChange={setColumnVisibilityModel}\n disableVirtualization\n getRowId={getRowId}\n loading={loading}\n paginationModel={paginationModel}\n onPaginationModelChange={setPaginationModel}\n pageSizeOptions={pageSizeOptions}\n onRowClick={onRowClick ? params => onRowClick(params.row) : undefined}\n onRowSelectionModelChange={\n onSelectionChange\n ? selectionModel => {\n const selectedIds = selectionModel.ids\n ? Array.from(selectionModel.ids)\n : [];\n const selectedRows = propRows.filter(row =>\n selectedIds.some(\n id =>\n String(getRowId ? getRowId(row) : row.id) === String(id),\n ),\n );\n onSelectionChange(selectedRows);\n }\n : undefined\n }\n slots={{\n ...(columnMenu && { columnMenu: CustomColumnMenuWithProps }),\n ...(customPagination && { pagination: CustomPaginationComponent }),\n noResultsOverlay: () => <NotFound />,\n loadingOverlay: () => (\n <Box\n display=\"flex\"\n height=\"100%\"\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <LogoSpinner />\n </Box>\n ),\n }}\n slotProps={{\n loadingOverlay: {\n variant: 'linear-progress',\n noRowsVariant: 'skeleton',\n },\n columnsManagement: {\n disableResetButton: true,\n searchInputProps: {\n type: 'text',\n },\n },\n }}\n sx={{\n backgroundColor,\n '&.MuiDataGrid-root': {\n borderRadius,\n minWidth: 'auto',\n },\n '& .MuiDataGrid-columnHeader:focus, & .MuiDataGrid-columnHeader:focus-within':\n {\n outline: 'none',\n },\n '&.MuiDataGrid-root .MuiDataGrid-columnHeader, &.MuiDataGrid-root .MuiDataGrid-filler':\n {\n backgroundColor: headerBackgroundColor,\n },\n // Column resize line styling\n '& .MuiDataGrid-columnSeparator--resizable': {\n '&:hover': {\n color: theme.palette.primary.main,\n },\n },\n '& .MuiDataGrid-columnSeparator--resizing': {\n color: theme.palette.primary.main,\n opacity: 1,\n },\n ...pinnedColumnStyles,\n }}\n />\n </Box>\n );\n}\n"],"names":["orderedColumns","finalColumns","DataGridMUI"],"mappings":";;;;;;;;;;;;;;;AAgCO,SAAS,QAAA,CAAsC;AAAA;AAAA,EAEpD,QAAA;AAAA,EACA,OAAA,EAAS,WAAA;AAAA,EACT,IAAA,EAAM,QAAA;AAAA;AAAA,EAGN,SAAA,GAAY,OAAA;AAAA,EACZ,oBAAA,GAAuB,QAAA;AAAA,EACvB,WAAW,EAAC;AAAA,EACZ,UAAU,EAAC;AAAA;AAAA,EAGX,eAAA,GAAkB,EAAA;AAAA,EAClB,eAAA,GAAkB,CAAC,EAAA,EAAI,EAAA,EAAI,GAAG,CAAA;AAAA;AAAA,EAG9B,UAAA;AAAA,EACA,iBAAA;AAAA;AAAA,EAGA,aAAA;AAAA,EACA,gBAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,QAAA;AAAA;AAAA,EAGA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,SAAS,aAAA,EAAc;AAG7B,EAAA,MAAM;AAAA,IACJ,WAAA,GAAc,IAAA;AAAA,IACd,aAAA,GAAgB,IAAA;AAAA,IAChB,gBAAA,GAAmB,IAAA;AAAA,IACnB,gBAAA,GAAmB,IAAA;AAAA,IACnB,UAAA,GAAa,IAAA;AAAA,IACb,aAAA,GAAgB;AAAA,GAClB,GAAI,QAAA;AAGJ,EAAA,MAAM;AAAA,IACJ,YAAA,GAAe,MAAA;AAAA,IACf,qBAAA,GAAwB,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA,GAC3C,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,KAAA,GACzB,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA;AAAA,IAC1B,eAAA,GAAkB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,KAAA;AAAA,IAC3C,MAAA,GAAS;AAAA,GACX,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAA0B,WAAW,CAAA;AACnE,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AACjD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAwB,IAAI,CAAA;AAC1D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAwB,IAAI,CAAA;AAChE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAkC,IAAI,CAAA;AACtE,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,QAAA,CAA8B;AAAA,IAC1E,IAAA,EAAM,CAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,CAAC,qBAAA,EAAuB,wBAAwB,IAAI,QAAA,CAExD,gBAAA,IAAoB,EAAE,CAAA;AAGxB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,CAAQ,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAE,CAAA;AAClE,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM;AAAA,UACJ,KAAA;AAAA,UACA,MAAA,EAAQ,WAAA;AAAA,UACR,gBAAA,EAAkB;AAAA,SACpB,GAAI,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACpB,QAAA,SAAA,CAAU,WAAA,IAAe,EAAE,CAAA;AAG3B,QAAA,IAAI,eAAA,EAAiB;AACnB,UAAA,wBAAA,CAAyB,eAAe,CAAA;AAAA,QAC1C;AAEA,QAAA,MAAMA,kBAAiB,KAAA,CACpB,GAAA,CAAI,CAAA,KAAA,KAAS,WAAA,CAAY,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,KAAA,KAAU,KAAK,CAAC,CAAA,CACrD,MAAA,CAAO,CAAC,CAAA,KAA0B,CAAC,CAAC,CAAC,CAAA;AACxC,QAAA,UAAA,CAAWA,eAAc,CAAA;AAAA,MAC3B;AAAA,IACF,SAAS,KAAA,EAAO;AAAA,IAEhB;AAAA,EACF,CAAA,EAAG,CAAC,WAAA,EAAa,aAAA,EAAe,QAAQ,CAAC,CAAA;AAEzC,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,CACE,IAAA,EACA,UAAA,EACA,UAAA,KACG;AACH,MAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,MAAA,MAAM,MAAA,GAAqB;AAAA,QACzB,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA;AAAA,QAC5B,MAAA,EAAQ,UAAA;AAAA,QACR,kBAAkB,UAAA,IAAc;AAAA,OAClC;AACA,MAAA,YAAA,CAAa,OAAA;AAAA,QACX,qBAAqB,QAAQ,CAAA,CAAA;AAAA,QAC7B,IAAA,CAAK,UAAU,MAAM;AAAA,OACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,aAAA,EAAe,QAAA,EAAU,qBAAqB;AAAA,GACjD;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,UAAA,CAAW,OAAA,EAAS,QAAQ,qBAAqB,CAAA;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,qBAAA,EAAuB,eAAe,UAAA,EAAY,OAAA,EAAS,MAAM,CAAC,CAAA;AAEtE,EAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAAkB,UAAA,CAAW,KAAK,CAAA;AAE3D,EAAA,MAAM,cAAA,GAAiB,CACrB,CAAA,EACA,WAAA,KACG;AACH,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,IAAI,YAAY,WAAA,EAAa;AAC7B,IAAA,MAAM,UAAA,GAAa,CAAA,CAAE,aAAA,CAAc,qBAAA,EAAsB;AACzD,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,OAAA,GAAU,UAAA,CAAW,IAAA;AACjC,IAAA,aAAA,CAAc,WAAW,CAAA;AACzB,IAAA,WAAA,CAAY,CAAA,GAAI,UAAA,CAAW,KAAA,GAAQ,CAAA,GAAI,SAAS,OAAO,CAAA;AAAA,EACzD,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,MAAM,aAAA,CAAc,IAAI,CAAA;AAEhD,EAAA,MAAM,UAAA,GAAa,CAAC,WAAA,KAAwB;AAC1C,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,KAAY,WAAA,EAAa;AAEzC,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA;AAC5C,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,QAAA,CAAS,WAAW,CAAA;AAElD,IAAA,IAAI,iBAAiB,cAAA,EAAgB;AACnC,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,cAAc,YAAA,GAChB,OAAA,CAAQ,OAAO,CAAA,CAAA,KAAK,MAAA,CAAO,SAAS,CAAA,CAAE,KAAK,CAAC,CAAA,GAC5C,OAAA,CAAQ,OAAO,CAAA,CAAA,KAAK,CAAC,OAAO,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC,CAAA;AAEjD,IAAA,MAAM,YAAY,WAAA,CAAY,SAAA,CAAU,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,OAAO,CAAA;AAChE,IAAA,MAAM,cAAc,WAAA,CAAY,SAAA,CAAU,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,WAAW,CAAA;AAEtE,IAAA,MAAM,QAAA,GAAW,QAAA,KAAa,MAAA,GAAS,WAAA,GAAc,WAAA,GAAc,CAAA;AACnE,IAAA,MAAM,SAAA,GAAY,CAAC,GAAG,WAAW,CAAA;AACjC,IAAA,MAAM,CAAC,KAAK,CAAA,GAAI,SAAA,CAAU,MAAA,CAAO,WAAW,CAAC,CAAA;AAC7C,IAAA,SAAA,CAAU,MAAA,CAAO,QAAA,EAAU,CAAA,EAAG,KAAK,CAAA;AAEnC,IAAA,MAAMC,aAAAA,GAAe,YAAA,GACjB,CAAC,GAAG,SAAA,EAAW,GAAG,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,MAAA,CAAO,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA,GAChE,CAAC,GAAG,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,MAAA,CAAO,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,GAAG,SAAS,CAAA;AAEnE,IAAA,UAAA,CAAWA,aAAY,CAAA;AACvB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,UAAA,CAAWA,eAAc,MAAM,CAAA;AAAA,EACjC,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAChB,CAAC,KAAA,KAAkB;AACjB,MAAA,SAAA,CAAU,CAAA,IAAA,KAAQ;AAChB,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,KAAK,IAC5B,IAAA,CAAK,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,KAAM,KAAK,CAAA,GAC5B,CAAC,GAAG,MAAM,KAAK,CAAA;AACnB,QAAA,UAAA,CAAW,SAAS,IAAI,CAAA;AACxB,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,SAAS,UAAU;AAAA,GACtB;AAEA,EAAA,MAAM,yBAAA,GAA4B,WAAA;AAAA,IAChC,CAAC,KAAA,KAAe;AACd,MAAA,uBACE,GAAA;AAAA,QAAC,gBAAA;AAAA,QAAA;AAAA,UACE,GAAG,KAAA;AAAA,UACJ,QAAA,EAAU,MAAA,CAAO,QAAA,CAAS,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,UAC5C,WAAA,EAAa;AAAA;AAAA,OACf;AAAA,IAEJ,CAAA;AAAA,IACA,CAAC,QAAQ,SAAS;AAAA,GACpB;AAEA,EAAA,MAAM,yBAAA,GAA4B,WAAA;AAAA,IAChC,sBACE,GAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,kBAAkB,CAAA,QAAA,KAAY,kBAAA,CAAmB,EAAE,IAAA,EAAM,CAAA,EAAG,UAAU,CAAA;AAAA,QACtE,eAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,IAEF,CAAC,WAAW,eAAe;AAAA,GAC7B;AAEA,EAAA,MAAM,YAAA,GAAe,gBAAA,GACjB,OAAA,CAAQ,GAAA,CAAI,CAAA,GAAA,MAAQ;AAAA,IAClB,GAAG,GAAA;AAAA,IACH,cAAc,sBACZ,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,gBAAA;AAAA,QACX,WAAA,EAAa,MAAM,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAA;AAAA,QAC5C,UAAA,EAAY,CAAA,CAAA,KAAK,cAAA,CAAe,CAAA,EAAG,IAAI,KAAK,CAAA;AAAA,QAC5C,WAAA,EAAa,eAAA;AAAA,QACb,MAAA,EAAQ,MAAM,UAAA,CAAW,GAAA,CAAI,KAAK,CAAA;AAAA,QAClC,EAAA,EAAI;AAAA,UACF,OAAA,EAAS,MAAA;AAAA,UACT,cAAA,EAAgB,QAAA;AAAA,UAChB,UAAA,EAAY,QAAA;AAAA,UACZ,MAAA,EAAQ,mBAAmB,MAAA,GAAS,SAAA;AAAA,UACpC,UAAA,EAAY,MAAA;AAAA,UACZ,QAAA,EAAU,UAAA;AAAA,UACV,YACE,aAAA,IAAiB,MAAA,CAAO,SAAS,GAAA,CAAI,KAAK,IAAI,MAAA,GAAS,QAAA;AAAA,UACzD,EAAA,EAAI,CAAA;AAAA,UACJ,aAAa,gBAAA,GACT;AAAA,YACE,OAAA,EAAS,IAAA;AAAA,YACT,QAAA,EAAU,UAAA;AAAA,YACV,GAAA,EAAK,CAAA;AAAA,YACL,MAAA,EAAQ,CAAA;AAAA,YACR,MACE,UAAA,KAAe,GAAA,CAAI,KAAA,IAAS,QAAA,KAAa,SACrC,CAAA,GACA,MAAA;AAAA,YACN,OACE,UAAA,KAAe,GAAA,CAAI,KAAA,IAAS,QAAA,KAAa,UACrC,CAAA,GACA,MAAA;AAAA,YACN,KAAA,EAAO,KAAA;AAAA,YACP,iBACE,UAAA,KAAe,GAAA,CAAI,QACf,KAAA,CAAM,OAAA,CAAQ,QAAQ,IAAA,GACtB,aAAA;AAAA,YACN,UAAA,EAAY;AAAA,cAEd;AAAC,SACP;AAAA,QAEC,QAAA,EAAA,GAAA,CAAI;AAAA;AAAA;AACP,IAEF,CAAA,GACF,OAAA;AAEJ,EAAA,MAAM,iBAAiB,aAAA,GACnB;AAAA,IACE,GAAG,YAAA,CACA,MAAA,CAAO,CAAA,CAAA,KAAK,MAAA,CAAO,SAAS,CAAA,CAAE,KAAK,CAAC,CAAA,CACpC,IAAI,CAAA,GAAA,MAAQ,EAAE,GAAG,GAAA,EAAK,SAAA,EAAW,OAAM,CAAE,CAAA;AAAA,IAC5C,GAAG,aAAa,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,MAAA,CAAO,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC;AAAA,GACvD,GACA,YAAA;AAGJ,EAAA,MAAM,gBAAwC,EAAC;AAC/C,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,KAAA,MAAW,OAAO,cAAA,EAAgB;AAChC,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,MAAA,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,GAAI,UAAA;AAC3B,MAAA,UAAA,IAAc,GAAA,CAAI,QAAA,IAAY,GAAA,CAAI,KAAA,IAAS,GAAA;AAAA,IAC7C;AAAA,EACF;AAGA,EAAA,MAAM,qBAA0C,EAAC;AACjD,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAA,CAAO,QAAQ,CAAA,KAAA,KAAS;AACtB,MAAA,kBAAA,CAAmB,CAAA,eAAA,EAAkB,KAAK,CAAA,EAAA,CAAI,CAAA,GAAI;AAAA,QAChD,QAAA,EAAU,QAAA;AAAA,QACV,IAAA,EAAM,cAAc,KAAK,CAAA;AAAA,QACzB,MAAA,EAAQ,IAAA;AAAA,QACR,eAAA;AAAA,QACA,SAAA,EAAW;AAAA,OACb;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,EAAA,EAAI;AAAA,QACF,MAAA;AAAA,QACA,KAAA,EAAO,MAAA;AAAA,QACP,SAAA,EAAW;AAAA,OACb;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,WAAA,oBACC,GAAA;AAAA,UAAC,mBAAA;AAAA,UAAA;AAAA,YACC,MAAA;AAAA,YACA,WAAA,EAAa,oBAAA;AAAA,YACb;AAAA;AAAA,SACF;AAAA,wBAEF,GAAA;AAAA,UAACC,UAAA;AAAA,UAAA;AAAA,YAEC,MAAA;AAAA,YACA,IAAA,EAAM,QAAA;AAAA,YACN,OAAA,EAAS,cAAA;AAAA,YACT,YAAA,EAAc;AAAA,cACZ,GAAG;AAAA,aACL;AAAA,YACA,qBAAA;AAAA,YACA,6BAAA,EAA+B,wBAAA;AAAA,YAC/B,qBAAA,EAAqB,IAAA;AAAA,YACrB,QAAA;AAAA,YACA,OAAA;AAAA,YACA,eAAA;AAAA,YACA,uBAAA,EAAyB,kBAAA;AAAA,YACzB,eAAA;AAAA,YACA,YAAY,UAAA,GAAa,CAAA,MAAA,KAAU,UAAA,CAAW,MAAA,CAAO,GAAG,CAAA,GAAI,MAAA;AAAA,YAC5D,yBAAA,EACE,oBACI,CAAA,cAAA,KAAkB;AAChB,cAAA,MAAM,WAAA,GAAc,eAAe,GAAA,GAC/B,KAAA,CAAM,KAAK,cAAA,CAAe,GAAG,IAC7B,EAAC;AACL,cAAA,MAAM,eAAe,QAAA,CAAS,MAAA;AAAA,gBAAO,SACnC,WAAA,CAAY,IAAA;AAAA,kBACV,CAAA,EAAA,KACE,MAAA,CAAO,QAAA,GAAW,QAAA,CAAS,GAAG,IAAI,GAAA,CAAI,EAAE,CAAA,KAAM,MAAA,CAAO,EAAE;AAAA;AAC3D,eACF;AACA,cAAA,iBAAA,CAAkB,YAAY,CAAA;AAAA,YAChC,CAAA,GACA,MAAA;AAAA,YAEN,KAAA,EAAO;AAAA,cACL,GAAI,UAAA,IAAc,EAAE,UAAA,EAAY,yBAAA,EAA0B;AAAA,cAC1D,GAAI,gBAAA,IAAoB,EAAE,UAAA,EAAY,yBAAA,EAA0B;AAAA,cAChE,gBAAA,EAAkB,sBAAM,GAAA,CAAC,QAAA,EAAA,EAAS,CAAA;AAAA,cAClC,gBAAgB,sBACd,GAAA;AAAA,gBAAC,GAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAQ,MAAA;AAAA,kBACR,MAAA,EAAO,MAAA;AAAA,kBACP,cAAA,EAAe,QAAA;AAAA,kBACf,UAAA,EAAW,QAAA;AAAA,kBAEX,8BAAC,WAAA,EAAA,EAAY;AAAA;AAAA;AACf,aAEJ;AAAA,YACA,SAAA,EAAW;AAAA,cACT,cAAA,EAAgB;AAAA,gBACd,OAAA,EAAS,iBAAA;AAAA,gBACT,aAAA,EAAe;AAAA,eACjB;AAAA,cACA,iBAAA,EAAmB;AAAA,gBACjB,kBAAA,EAAoB,IAAA;AAAA,gBACpB,gBAAA,EAAkB;AAAA,kBAChB,IAAA,EAAM;AAAA;AACR;AACF,aACF;AAAA,YACA,EAAA,EAAI;AAAA,cACF,eAAA;AAAA,cACA,oBAAA,EAAsB;AAAA,gBACpB,YAAA;AAAA,gBACA,QAAA,EAAU;AAAA,eACZ;AAAA,cACA,6EAAA,EACE;AAAA,gBACE,OAAA,EAAS;AAAA,eACX;AAAA,cACF,sFAAA,EACE;AAAA,gBACE,eAAA,EAAiB;AAAA,eACnB;AAAA;AAAA,cAEF,2CAAA,EAA6C;AAAA,gBAC3C,SAAA,EAAW;AAAA,kBACT,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ;AAAA;AAC/B,eACF;AAAA,cACA,0CAAA,EAA4C;AAAA,gBAC1C,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA;AAAA,gBAC7B,OAAA,EAAS;AAAA,eACX;AAAA,cACA,GAAG;AAAA;AACL,WAAA;AAAA,UApFK;AAAA;AAqFP;AAAA;AAAA,GACF;AAEJ;;;;"}