@backstage-community/plugin-apiiro 0.1.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 (223) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +232 -0
  3. package/config.d.ts +30 -0
  4. package/dist/App.esm.js +12 -0
  5. package/dist/App.esm.js.map +1 -0
  6. package/dist/api/index.esm.js +71 -0
  7. package/dist/api/index.esm.js.map +1 -0
  8. package/dist/assets/BulleyeIcon.esm.js +454 -0
  9. package/dist/assets/BulleyeIcon.esm.js.map +1 -0
  10. package/dist/assets/NoResultIcon.esm.js +146 -0
  11. package/dist/assets/NoResultIcon.esm.js.map +1 -0
  12. package/dist/assets/RiskIcon.esm.js +27 -0
  13. package/dist/assets/RiskIcon.esm.js.map +1 -0
  14. package/dist/assets/SettingIcon.esm.js +49 -0
  15. package/dist/assets/SettingIcon.esm.js.map +1 -0
  16. package/dist/assets/apiiroLogo/apiiroLogo.esm.js +21 -0
  17. package/dist/assets/apiiroLogo/apiiroLogo.esm.js.map +1 -0
  18. package/dist/assets/apiiroLogo/apiiroSidebar.esm.js +23 -0
  19. package/dist/assets/apiiroLogo/apiiroSidebar.esm.js.map +1 -0
  20. package/dist/assets/apiiroLogo/apiiroSmall.esm.js +19 -0
  21. package/dist/assets/apiiroLogo/apiiroSmall.esm.js.map +1 -0
  22. package/dist/assets/languageIcons/C.esm.js +7 -0
  23. package/dist/assets/languageIcons/C.esm.js.map +1 -0
  24. package/dist/assets/languageIcons/Cicd.esm.js +7 -0
  25. package/dist/assets/languageIcons/Cicd.esm.js.map +1 -0
  26. package/dist/assets/languageIcons/Clojure.esm.js +7 -0
  27. package/dist/assets/languageIcons/Clojure.esm.js.map +1 -0
  28. package/dist/assets/languageIcons/Cpp.esm.js +7 -0
  29. package/dist/assets/languageIcons/Cpp.esm.js.map +1 -0
  30. package/dist/assets/languageIcons/Csharp.esm.js +7 -0
  31. package/dist/assets/languageIcons/Csharp.esm.js.map +1 -0
  32. package/dist/assets/languageIcons/Dart.esm.js +7 -0
  33. package/dist/assets/languageIcons/Dart.esm.js.map +1 -0
  34. package/dist/assets/languageIcons/Go.esm.js +7 -0
  35. package/dist/assets/languageIcons/Go.esm.js.map +1 -0
  36. package/dist/assets/languageIcons/Groovy.esm.js +7 -0
  37. package/dist/assets/languageIcons/Groovy.esm.js.map +1 -0
  38. package/dist/assets/languageIcons/HTML.esm.js +7 -0
  39. package/dist/assets/languageIcons/HTML.esm.js.map +1 -0
  40. package/dist/assets/languageIcons/HclLanguage.esm.js +7 -0
  41. package/dist/assets/languageIcons/HclLanguage.esm.js.map +1 -0
  42. package/dist/assets/languageIcons/Java.esm.js +7 -0
  43. package/dist/assets/languageIcons/Java.esm.js.map +1 -0
  44. package/dist/assets/languageIcons/Javascript.esm.js +7 -0
  45. package/dist/assets/languageIcons/Javascript.esm.js.map +1 -0
  46. package/dist/assets/languageIcons/Kotlin.esm.js +7 -0
  47. package/dist/assets/languageIcons/Kotlin.esm.js.map +1 -0
  48. package/dist/assets/languageIcons/ObjectiveC.esm.js +7 -0
  49. package/dist/assets/languageIcons/ObjectiveC.esm.js.map +1 -0
  50. package/dist/assets/languageIcons/PHP.esm.js +7 -0
  51. package/dist/assets/languageIcons/PHP.esm.js.map +1 -0
  52. package/dist/assets/languageIcons/Perl.esm.js +13 -0
  53. package/dist/assets/languageIcons/Perl.esm.js.map +1 -0
  54. package/dist/assets/languageIcons/Python.esm.js +7 -0
  55. package/dist/assets/languageIcons/Python.esm.js.map +1 -0
  56. package/dist/assets/languageIcons/Ruby.esm.js +7 -0
  57. package/dist/assets/languageIcons/Ruby.esm.js.map +1 -0
  58. package/dist/assets/languageIcons/Rust.esm.js +7 -0
  59. package/dist/assets/languageIcons/Rust.esm.js.map +1 -0
  60. package/dist/assets/languageIcons/Scala.esm.js +7 -0
  61. package/dist/assets/languageIcons/Scala.esm.js.map +1 -0
  62. package/dist/assets/languageIcons/Swift.esm.js +7 -0
  63. package/dist/assets/languageIcons/Swift.esm.js.map +1 -0
  64. package/dist/assets/languageIcons/Terraform.esm.js +7 -0
  65. package/dist/assets/languageIcons/Terraform.esm.js.map +1 -0
  66. package/dist/assets/languageIcons/Typescript.esm.js +7 -0
  67. package/dist/assets/languageIcons/Typescript.esm.js.map +1 -0
  68. package/dist/assets/languageIcons/Unknown.esm.js +7 -0
  69. package/dist/assets/languageIcons/Unknown.esm.js.map +1 -0
  70. package/dist/assets/languageIcons/VB.esm.js +10 -0
  71. package/dist/assets/languageIcons/VB.esm.js.map +1 -0
  72. package/dist/assets/languageIcons/YAML.esm.js +7 -0
  73. package/dist/assets/languageIcons/YAML.esm.js.map +1 -0
  74. package/dist/assets/providerIcons/Azure.esm.js +7 -0
  75. package/dist/assets/providerIcons/Azure.esm.js.map +1 -0
  76. package/dist/assets/providerIcons/Bitbucket.esm.js +7 -0
  77. package/dist/assets/providerIcons/Bitbucket.esm.js.map +1 -0
  78. package/dist/assets/providerIcons/Gitlab.esm.js +7 -0
  79. package/dist/assets/providerIcons/Gitlab.esm.js.map +1 -0
  80. package/dist/components/ApiiroSidebar.esm.js +10 -0
  81. package/dist/components/ApiiroSidebar.esm.js.map +1 -0
  82. package/dist/components/ApplicationsList/ApplicationsList.esm.js +196 -0
  83. package/dist/components/ApplicationsList/ApplicationsList.esm.js.map +1 -0
  84. package/dist/components/CalendarDatePicker.esm.js +154 -0
  85. package/dist/components/CalendarDatePicker.esm.js.map +1 -0
  86. package/dist/components/CalendarDatePicker.styles.esm.js +198 -0
  87. package/dist/components/CalendarDatePicker.styles.esm.js.map +1 -0
  88. package/dist/components/Chip.esm.js +60 -0
  89. package/dist/components/Chip.esm.js.map +1 -0
  90. package/dist/components/ChipsList.esm.js +207 -0
  91. package/dist/components/ChipsList.esm.js.map +1 -0
  92. package/dist/components/ComponentDisplay.esm.js +42 -0
  93. package/dist/components/ComponentDisplay.esm.js.map +1 -0
  94. package/dist/components/DataGrid/CustomColumnMenu.esm.js +29 -0
  95. package/dist/components/DataGrid/CustomColumnMenu.esm.js.map +1 -0
  96. package/dist/components/DataGrid/CustomPagination.esm.js +113 -0
  97. package/dist/components/DataGrid/CustomPagination.esm.js.map +1 -0
  98. package/dist/components/DataGrid/CustomSearchToolbar.esm.js +117 -0
  99. package/dist/components/DataGrid/CustomSearchToolbar.esm.js.map +1 -0
  100. package/dist/components/DataGrid/DataGrid.esm.js +336 -0
  101. package/dist/components/DataGrid/DataGrid.esm.js.map +1 -0
  102. package/dist/components/DataGrid/PinColumnMenuItem.esm.js +24 -0
  103. package/dist/components/DataGrid/PinColumnMenuItem.esm.js.map +1 -0
  104. package/dist/components/DueDate.esm.js +34 -0
  105. package/dist/components/DueDate.esm.js.map +1 -0
  106. package/dist/components/Header.esm.js +27 -0
  107. package/dist/components/Header.esm.js.map +1 -0
  108. package/dist/components/MainContributors/MainContributors.esm.js +62 -0
  109. package/dist/components/MainContributors/MainContributors.esm.js.map +1 -0
  110. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js +37 -0
  111. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js.map +1 -0
  112. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js +36 -0
  113. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js.map +1 -0
  114. package/dist/components/RepositoryDisplay/RepositoryDisplay.esm.js +121 -0
  115. package/dist/components/RepositoryDisplay/RepositoryDisplay.esm.js.map +1 -0
  116. package/dist/components/RiskLevel.esm.js +88 -0
  117. package/dist/components/RiskLevel.esm.js.map +1 -0
  118. package/dist/components/RiskStatus.esm.js +58 -0
  119. package/dist/components/RiskStatus.esm.js.map +1 -0
  120. package/dist/components/SimpleTooltip.esm.js +24 -0
  121. package/dist/components/SimpleTooltip.esm.js.map +1 -0
  122. package/dist/components/SourcesDisplay.esm.js +47 -0
  123. package/dist/components/SourcesDisplay.esm.js.map +1 -0
  124. package/dist/components/TagsList/TagsList.esm.js +38 -0
  125. package/dist/components/TagsList/TagsList.esm.js.map +1 -0
  126. package/dist/components/TeamsDisplay.esm.js +47 -0
  127. package/dist/components/TeamsDisplay.esm.js.map +1 -0
  128. package/dist/components/charts/ColumnChart.esm.js +402 -0
  129. package/dist/components/charts/ColumnChart.esm.js.map +1 -0
  130. package/dist/components/charts/GaugeChart.esm.js +249 -0
  131. package/dist/components/charts/GaugeChart.esm.js.map +1 -0
  132. package/dist/components/charts/LineChart.esm.js +328 -0
  133. package/dist/components/charts/LineChart.esm.js.map +1 -0
  134. package/dist/components/charts/PieChart.esm.js +233 -0
  135. package/dist/components/charts/PieChart.esm.js.map +1 -0
  136. package/dist/components/common/ChartBox.esm.js +88 -0
  137. package/dist/components/common/ChartBox.esm.js.map +1 -0
  138. package/dist/components/common/CustomTooltip.esm.js +255 -0
  139. package/dist/components/common/CustomTooltip.esm.js.map +1 -0
  140. package/dist/components/common/ErrorSnackbar.esm.js +39 -0
  141. package/dist/components/common/ErrorSnackbar.esm.js.map +1 -0
  142. package/dist/components/common/NotFound.esm.js +30 -0
  143. package/dist/components/common/NotFound.esm.js.map +1 -0
  144. package/dist/components/common/SomethingWentWrong.esm.js +35 -0
  145. package/dist/components/common/SomethingWentWrong.esm.js.map +1 -0
  146. package/dist/components/common/languageIcons.esm.js +61 -0
  147. package/dist/components/common/languageIcons.esm.js.map +1 -0
  148. package/dist/components/common/logoSpinner.esm.js +28 -0
  149. package/dist/components/common/logoSpinner.esm.js.map +1 -0
  150. package/dist/components/common/scmProviders.esm.js +41 -0
  151. package/dist/components/common/scmProviders.esm.js.map +1 -0
  152. package/dist/components/filters/DiscoveredOnFilter.esm.js +284 -0
  153. package/dist/components/filters/DiscoveredOnFilter.esm.js.map +1 -0
  154. package/dist/components/filters/FilterDropdown.esm.js +325 -0
  155. package/dist/components/filters/FilterDropdown.esm.js.map +1 -0
  156. package/dist/components/filters/FilterDropdownClear.esm.js +45 -0
  157. package/dist/components/filters/FilterDropdownClear.esm.js.map +1 -0
  158. package/dist/components/filters/FilterDropdownList.esm.js +102 -0
  159. package/dist/components/filters/FilterDropdownList.esm.js.map +1 -0
  160. package/dist/components/filters/FilterDropdownSearch.esm.js +65 -0
  161. package/dist/components/filters/FilterDropdownSearch.esm.js.map +1 -0
  162. package/dist/components/filters/RiskInsightFilter.esm.js +579 -0
  163. package/dist/components/filters/RiskInsightFilter.esm.js.map +1 -0
  164. package/dist/components/tiles/MttrVsSLATile.esm.js +170 -0
  165. package/dist/components/tiles/MttrVsSLATile.esm.js.map +1 -0
  166. package/dist/components/tiles/RiskOverTimeTile.esm.js +311 -0
  167. package/dist/components/tiles/RiskOverTimeTile.esm.js.map +1 -0
  168. package/dist/components/tiles/SLAAdherenceTile.esm.js +115 -0
  169. package/dist/components/tiles/SLAAdherenceTile.esm.js.map +1 -0
  170. package/dist/components/tiles/StatusTile.esm.js +235 -0
  171. package/dist/components/tiles/StatusTile.esm.js.map +1 -0
  172. package/dist/components/tiles/TopLanguagesTile.esm.js +234 -0
  173. package/dist/components/tiles/TopLanguagesTile.esm.js.map +1 -0
  174. package/dist/components/tiles/TopRiskTile.esm.js +208 -0
  175. package/dist/components/tiles/TopRiskTile.esm.js.map +1 -0
  176. package/dist/hooks/useUrlFilters.esm.js +102 -0
  177. package/dist/hooks/useUrlFilters.esm.js.map +1 -0
  178. package/dist/index.d.ts +28 -0
  179. package/dist/index.esm.js +42 -0
  180. package/dist/index.esm.js.map +1 -0
  181. package/dist/pages/Repositories/Repositories.esm.js +102 -0
  182. package/dist/pages/Repositories/Repositories.esm.js.map +1 -0
  183. package/dist/pages/Repositories/tableConfig.esm.js +294 -0
  184. package/dist/pages/Repositories/tableConfig.esm.js.map +1 -0
  185. package/dist/pages/Risks/Risks.esm.js +258 -0
  186. package/dist/pages/Risks/Risks.esm.js.map +1 -0
  187. package/dist/pages/Risks/tableConfig.esm.js +305 -0
  188. package/dist/pages/Risks/tableConfig.esm.js.map +1 -0
  189. package/dist/pages/tab/Tab.esm.js +147 -0
  190. package/dist/pages/tab/Tab.esm.js.map +1 -0
  191. package/dist/pages/tab/TabProvider.esm.js +11 -0
  192. package/dist/pages/tab/TabProvider.esm.js.map +1 -0
  193. package/dist/pages/widget/Widget.esm.js +161 -0
  194. package/dist/pages/widget/Widget.esm.js.map +1 -0
  195. package/dist/pages/widget/WidgetProvider.esm.js +12 -0
  196. package/dist/pages/widget/WidgetProvider.esm.js.map +1 -0
  197. package/dist/plugin.esm.js +30 -0
  198. package/dist/plugin.esm.js.map +1 -0
  199. package/dist/queries/filterOptions.queries.esm.js +46 -0
  200. package/dist/queries/filterOptions.queries.esm.js.map +1 -0
  201. package/dist/queries/mttr-statistics.queries.esm.js +61 -0
  202. package/dist/queries/mttr-statistics.queries.esm.js.map +1 -0
  203. package/dist/queries/repository.queries.esm.js +60 -0
  204. package/dist/queries/repository.queries.esm.js.map +1 -0
  205. package/dist/queries/risk-score-over-time.queries.esm.js +61 -0
  206. package/dist/queries/risk-score-over-time.queries.esm.js.map +1 -0
  207. package/dist/queries/risks.queries.esm.js +65 -0
  208. package/dist/queries/risks.queries.esm.js.map +1 -0
  209. package/dist/queries/sla-breach.queries.esm.js +57 -0
  210. package/dist/queries/sla-breach.queries.esm.js.map +1 -0
  211. package/dist/queries/top-risks.queries.esm.js +47 -0
  212. package/dist/queries/top-risks.queries.esm.js.map +1 -0
  213. package/dist/routes.esm.js +8 -0
  214. package/dist/routes.esm.js.map +1 -0
  215. package/dist/theme/themeUtils.esm.js +290 -0
  216. package/dist/theme/themeUtils.esm.js.map +1 -0
  217. package/dist/utils/dateFormatter.esm.js +67 -0
  218. package/dist/utils/dateFormatter.esm.js.map +1 -0
  219. package/dist/utils/numberFormatter.esm.js +21 -0
  220. package/dist/utils/numberFormatter.esm.js.map +1 -0
  221. package/dist/utils/utils.esm.js +27 -0
  222. package/dist/utils/utils.esm.js.map +1 -0
  223. package/package.json +90 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterDropdownSearch.esm.js","sources":["../../../src/components/filters/FilterDropdownSearch.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 InputAdornment from '@mui/material/InputAdornment';\nimport TextField from '@mui/material/TextField';\nimport IconButton from '@mui/material/IconButton';\nimport SearchIcon from '@mui/icons-material/Search';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport { alpha, useTheme } from '@mui/material/styles';\n\ninterface FilterDropdownSearchProps {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}\n\nexport const FilterDropdownSearch = ({\n value,\n onChange,\n placeholder,\n}: FilterDropdownSearchProps) => {\n const theme = useTheme();\n\n const handleClear = () => {\n onChange('');\n };\n\n return (\n <TextField\n fullWidth\n value={value}\n onChange={event => onChange(event.target.value)}\n placeholder={placeholder}\n size=\"small\"\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon\n sx={{\n fontSize: 18,\n color: theme.palette.text.secondary,\n }}\n />\n </InputAdornment>\n ),\n endAdornment: value ? (\n <InputAdornment position=\"end\">\n <IconButton\n onClick={handleClear}\n size=\"small\"\n sx={{ color: theme.palette.text.secondary }}\n >\n <ClearIcon fontSize=\"small\" />\n </IconButton>\n </InputAdornment>\n ) : null,\n sx: {\n borderRadius: '10px',\n backgroundColor: alpha(theme.palette.background.default, 0.6),\n '& .MuiOutlinedInput-notchedOutline': {\n borderColor: alpha(theme.palette.divider, 0.6),\n },\n '&:hover .MuiOutlinedInput-notchedOutline': {\n borderColor: alpha(theme.palette.primary.main, 0.4),\n },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': {\n borderColor: theme.palette.primary.main,\n },\n },\n }}\n inputProps={{ sx: { fontSize: 14 } }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA4BO,MAAM,uBAAuB,CAAC;AAAA,EACnC,KAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,KAAiC;AAC/B,EAAA,MAAM,QAAQ,QAAA,EAAS;AAEvB,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,QAAA,CAAS,EAAE,CAAA;AAAA,EACb,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAS,IAAA;AAAA,MACT,KAAA;AAAA,MACA,QAAA,EAAU,CAAA,KAAA,KAAS,QAAA,CAAS,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,MAC9C,WAAA;AAAA,MACA,IAAA,EAAK,OAAA;AAAA,MACL,UAAA,EAAY;AAAA,QACV,cAAA,kBACE,GAAA,CAAC,cAAA,EAAA,EAAe,QAAA,EAAS,OAAA,EACvB,QAAA,kBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,EAAA,EAAI;AAAA,cACF,QAAA,EAAU,EAAA;AAAA,cACV,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK;AAAA;AAC5B;AAAA,SACF,EACF,CAAA;AAAA,QAEF,YAAA,EAAc,KAAA,mBACZ,GAAA,CAAC,cAAA,EAAA,EAAe,UAAS,KAAA,EACvB,QAAA,kBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,WAAA;AAAA,YACT,IAAA,EAAK,OAAA;AAAA,YACL,IAAI,EAAE,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,SAAA,EAAU;AAAA,YAE1C,QAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,QAAA,EAAS,OAAA,EAAQ;AAAA;AAAA,WAEhC,CAAA,GACE,IAAA;AAAA,QACJ,EAAA,EAAI;AAAA,UACF,YAAA,EAAc,MAAA;AAAA,UACd,iBAAiB,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,SAAS,GAAG,CAAA;AAAA,UAC5D,oCAAA,EAAsC;AAAA,YACpC,WAAA,EAAa,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,SAAS,GAAG;AAAA,WAC/C;AAAA,UACA,0CAAA,EAA4C;AAAA,YAC1C,aAAa,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,GAAG;AAAA,WACpD;AAAA,UACA,gDAAA,EAAkD;AAAA,YAChD,WAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ;AAAA;AACrC;AACF,OACF;AAAA,MACA,YAAY,EAAE,EAAA,EAAI,EAAE,QAAA,EAAU,IAAG;AAAE;AAAA,GACrC;AAEJ;;;;"}
@@ -0,0 +1,579 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useMemo } from 'react';
3
+ import Box from '@mui/material/Box';
4
+ import ButtonBase from '@mui/material/ButtonBase';
5
+ import Popper from '@mui/material/Popper';
6
+ import Paper from '@mui/material/Paper';
7
+ import ClickAwayListener from '@mui/material/ClickAwayListener';
8
+ import Typography from '@mui/material/Typography';
9
+ import Checkbox from '@mui/material/Checkbox';
10
+ import Chip from '@mui/material/Chip';
11
+ import IconButton from '@mui/material/IconButton';
12
+ import Collapse from '@mui/material/Collapse';
13
+ import Divider from '@mui/material/Divider';
14
+ import Link from '@mui/material/Link';
15
+ import List from '@mui/material/List';
16
+ import ListItemButton from '@mui/material/ListItemButton';
17
+ import ListItemIcon from '@mui/material/ListItemIcon';
18
+ import ListItemText from '@mui/material/ListItemText';
19
+ import Skeleton from '@mui/material/Skeleton';
20
+ import { SimpleTooltip } from '../SimpleTooltip.esm.js';
21
+ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
22
+ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
23
+ import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
24
+ import { styled, alpha, useTheme } from '@mui/material/styles';
25
+ import { FilterDropdownSearch } from './FilterDropdownSearch.esm.js';
26
+ import { FilterDropdownClear } from './FilterDropdownClear.esm.js';
27
+ import { getCountBadgeColors } from '../../theme/themeUtils.esm.js';
28
+
29
+ const GROUP_DISPLAY_LIMIT = 5;
30
+ const GROUP_OPTION_LIMIT = 4;
31
+ const DropdownButton = styled(ButtonBase, {
32
+ shouldForwardProp: (prop) => prop !== "open" && prop !== "hasSelection"
33
+ })(
34
+ ({ theme, open, hasSelection }) => {
35
+ const primaryMain = theme.palette.primary.main;
36
+ const closedBorder = theme.palette.divider;
37
+ const isDark = theme.palette.mode === "dark";
38
+ const hoverBackground = alpha(primaryMain, isDark ? 0.28 : 0.12);
39
+ const selectedBorder = isDark ? theme.palette.primary.light : theme.palette.primary.dark;
40
+ const selectedBackground = alpha(primaryMain, isDark ? 0.2 : 0.06);
41
+ let buttonBackground = theme.palette.background.paper;
42
+ if (open) {
43
+ buttonBackground = hoverBackground;
44
+ } else if (hasSelection) {
45
+ buttonBackground = selectedBackground;
46
+ }
47
+ let borderColor = closedBorder;
48
+ if (open) {
49
+ borderColor = primaryMain;
50
+ } else if (hasSelection) {
51
+ borderColor = selectedBorder;
52
+ }
53
+ let boxShadow = "none";
54
+ if (open) {
55
+ boxShadow = "0 4px 12px rgba(38, 54, 140, 0.18)";
56
+ } else if (hasSelection) {
57
+ boxShadow = "0 2px 8px rgba(38, 54, 140, 0.12)";
58
+ }
59
+ let hoverColor = hoverBackground;
60
+ if (hasSelection) {
61
+ hoverColor = alpha(primaryMain, isDark ? 0.24 : 0.1);
62
+ }
63
+ return {
64
+ display: "flex",
65
+ alignItems: "center",
66
+ gap: theme.spacing(1),
67
+ padding: theme.spacing(0.75, 1.5),
68
+ borderRadius: 999,
69
+ border: `1px solid ${borderColor}`,
70
+ backgroundColor: buttonBackground,
71
+ transition: "all 0.2s ease",
72
+ boxShadow,
73
+ "&:hover": {
74
+ backgroundColor: hoverColor
75
+ },
76
+ "& .MuiSvgIcon-root": {
77
+ fontSize: 18,
78
+ color: hasSelection ? theme.palette.primary.main : theme.palette.text.secondary
79
+ }
80
+ };
81
+ }
82
+ );
83
+ const sentimentPalette = (theme, sentiment) => {
84
+ const normalized = (sentiment || "").toLowerCase();
85
+ if (normalized === "positive") {
86
+ return {
87
+ color: theme.palette.success.main,
88
+ background: alpha(theme.palette.success.main, 0.12)
89
+ };
90
+ }
91
+ if (normalized === "negative") {
92
+ return {
93
+ color: theme.palette.error.main,
94
+ background: alpha(theme.palette.error.main, 0.12)
95
+ };
96
+ }
97
+ if (normalized === "neutral") {
98
+ return {
99
+ color: theme.palette.info.main,
100
+ background: alpha(theme.palette.info.main, 0.12)
101
+ };
102
+ }
103
+ return {
104
+ color: theme.palette.text.secondary,
105
+ background: alpha(theme.palette.text.secondary, 0.15)
106
+ };
107
+ };
108
+ const sortByPriority = (options) => {
109
+ return [...options].sort((a, b) => {
110
+ const aOrder = a.sortOrder ?? Number.MAX_SAFE_INTEGER;
111
+ const bOrder = b.sortOrder ?? Number.MAX_SAFE_INTEGER;
112
+ if (aOrder !== bOrder) {
113
+ return aOrder - bOrder;
114
+ }
115
+ return a.displayName.localeCompare(b.displayName);
116
+ });
117
+ };
118
+ const groupOptions = (options) => {
119
+ const groups = /* @__PURE__ */ new Map();
120
+ options.forEach((option) => {
121
+ const list = groups.get(option.group) ?? [];
122
+ list.push(option);
123
+ groups.set(option.group, list);
124
+ });
125
+ return [...groups.entries()].map(([groupName, groupItems]) => ({
126
+ groupName,
127
+ groupOrder: groupItems[0]?.groupOrder ?? Number.MAX_SAFE_INTEGER,
128
+ options: sortByPriority(groupItems)
129
+ })).sort((a, b) => {
130
+ if (a.groupOrder !== b.groupOrder) {
131
+ return (a.groupOrder ?? Number.MAX_SAFE_INTEGER) - (b.groupOrder ?? Number.MAX_SAFE_INTEGER);
132
+ }
133
+ return a.groupName.localeCompare(b.groupName);
134
+ });
135
+ };
136
+ const RiskInsightFilter = ({
137
+ label,
138
+ options,
139
+ selectedValues,
140
+ onChange,
141
+ loading = false,
142
+ clearLabel = "Clear selection"
143
+ }) => {
144
+ const theme = useTheme();
145
+ const [anchorEl, setAnchorEl] = useState(null);
146
+ const [search, setSearch] = useState("");
147
+ const [showAll, setShowAll] = useState(false);
148
+ const [expandedGroups, setExpandedGroups] = useState(
149
+ {}
150
+ );
151
+ const [expandedOptions, setExpandedOptions] = useState({});
152
+ const isOpen = Boolean(anchorEl);
153
+ const hasSelection = selectedValues.length > 0;
154
+ const groupedOptions = useMemo(() => groupOptions(options), [options]);
155
+ const filteredGroups = useMemo(() => {
156
+ if (!search.trim()) {
157
+ return groupedOptions;
158
+ }
159
+ const lower = search.trim().toLowerCase();
160
+ return groupedOptions.map((group) => ({
161
+ ...group,
162
+ options: group.options.filter(
163
+ (option) => option.displayName.toLowerCase().includes(lower) || option.group.toLowerCase().includes(lower)
164
+ )
165
+ })).filter((group) => group.options.length > 0);
166
+ }, [groupedOptions, search]);
167
+ const hasMoreGroups = filteredGroups.length > GROUP_DISPLAY_LIMIT;
168
+ const visibleGroups = showAll || search ? filteredGroups : filteredGroups.slice(0, GROUP_DISPLAY_LIMIT);
169
+ const toggleGroup = (groupName) => {
170
+ if (search) return;
171
+ setExpandedGroups((prev) => ({
172
+ ...prev,
173
+ [groupName]: !prev[groupName]
174
+ }));
175
+ };
176
+ const toggleOptions = (groupName) => {
177
+ setExpandedOptions((prev) => ({
178
+ ...prev,
179
+ [groupName]: !prev[groupName]
180
+ }));
181
+ };
182
+ const toggleOption = (name) => {
183
+ const set = new Set(selectedValues);
184
+ if (set.has(name)) {
185
+ set.delete(name);
186
+ } else {
187
+ set.add(name);
188
+ }
189
+ onChange([...set]);
190
+ };
191
+ const handleToggle = (event) => {
192
+ if (anchorEl) {
193
+ setAnchorEl(null);
194
+ return;
195
+ }
196
+ setAnchorEl(event.currentTarget);
197
+ };
198
+ const handleClose = () => {
199
+ setAnchorEl(null);
200
+ };
201
+ const handleClear = () => {
202
+ if (!selectedValues.length) {
203
+ return;
204
+ }
205
+ setSearch("");
206
+ onChange([]);
207
+ };
208
+ const selectedChipLabel = (() => {
209
+ if (!hasSelection) {
210
+ return label;
211
+ }
212
+ const firstSelectedName = selectedValues[0];
213
+ const firstSelected = options.find(
214
+ (option) => option.name === firstSelectedName
215
+ );
216
+ const firstLabel = firstSelected?.displayName ?? firstSelectedName;
217
+ const remainingCount = selectedValues.length - 1;
218
+ if (remainingCount > 0) {
219
+ return `${label}: ${firstLabel} (+${remainingCount})`;
220
+ }
221
+ return `${label}: ${firstLabel}`;
222
+ })();
223
+ const additionalCount = selectedValues.length > 1 ? selectedValues.length - 1 : 0;
224
+ const remainingItemsTooltip = useMemo(() => {
225
+ if (selectedValues.length <= 1) {
226
+ return "";
227
+ }
228
+ const remainingItems = selectedValues.slice(1).map((value) => {
229
+ const option = options.find((opt) => opt.name === value);
230
+ return option?.displayName ?? value;
231
+ });
232
+ return remainingItems.join(", ");
233
+ }, [selectedValues, options]);
234
+ if (loading) {
235
+ return /* @__PURE__ */ jsx(
236
+ Skeleton,
237
+ {
238
+ variant: "rounded",
239
+ width: 120,
240
+ height: 36,
241
+ sx: {
242
+ borderRadius: 999
243
+ }
244
+ }
245
+ );
246
+ }
247
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
248
+ /* @__PURE__ */ jsxs(
249
+ DropdownButton,
250
+ {
251
+ open: isOpen,
252
+ hasSelection,
253
+ onClick: handleToggle,
254
+ children: [
255
+ /* @__PURE__ */ jsx(
256
+ Typography,
257
+ {
258
+ variant: "body2",
259
+ sx: {
260
+ color: theme.palette.text.primary,
261
+ whiteSpace: "nowrap"
262
+ },
263
+ children: selectedChipLabel.replace(/ \(\+\d+\)$/, "")
264
+ }
265
+ ),
266
+ additionalCount > 0 && /* @__PURE__ */ jsx(
267
+ SimpleTooltip,
268
+ {
269
+ title: remainingItemsTooltip,
270
+ placement: "top",
271
+ tooltipProps: {
272
+ componentsProps: {
273
+ tooltip: {
274
+ sx: {
275
+ whiteSpace: "normal",
276
+ maxWidth: "400px"
277
+ }
278
+ }
279
+ }
280
+ },
281
+ children: /* @__PURE__ */ jsx(
282
+ Box,
283
+ {
284
+ sx: {
285
+ display: "inline-flex",
286
+ alignItems: "center",
287
+ justifyContent: "center",
288
+ minWidth: 26,
289
+ px: 1,
290
+ py: 0.25,
291
+ borderRadius: 999,
292
+ backgroundColor: getCountBadgeColors(theme).background,
293
+ color: getCountBadgeColors(theme).text,
294
+ fontSize: 12,
295
+ fontWeight: 600
296
+ },
297
+ children: `+${additionalCount}`
298
+ }
299
+ )
300
+ }
301
+ ),
302
+ /* @__PURE__ */ jsx(
303
+ KeyboardArrowDownIcon,
304
+ {
305
+ fontSize: "small",
306
+ sx: {
307
+ transform: isOpen ? "rotate(180deg)" : "none",
308
+ transition: "transform 0.2s ease",
309
+ color: theme.palette.text.secondary
310
+ }
311
+ }
312
+ )
313
+ ]
314
+ }
315
+ ),
316
+ /* @__PURE__ */ jsx(
317
+ Popper,
318
+ {
319
+ open: isOpen,
320
+ anchorEl,
321
+ placement: "bottom-start",
322
+ modifiers: [{ name: "offset", options: { offset: [0, 8] } }],
323
+ children: /* @__PURE__ */ jsx(ClickAwayListener, { onClickAway: handleClose, children: /* @__PURE__ */ jsxs(
324
+ Paper,
325
+ {
326
+ sx: {
327
+ borderRadius: 3,
328
+ boxShadow: "0 16px 32px rgba(31, 45, 98, 0.18)",
329
+ width: 320,
330
+ display: "flex",
331
+ flexDirection: "column",
332
+ overflow: "hidden",
333
+ backgroundColor: theme.palette.background.paper,
334
+ border: `1px solid ${alpha(theme.palette.common.black, 0.08)}`
335
+ },
336
+ children: [
337
+ /* @__PURE__ */ jsx(
338
+ Box,
339
+ {
340
+ sx: {
341
+ p: 2,
342
+ pb: 1
343
+ },
344
+ children: /* @__PURE__ */ jsx(
345
+ FilterDropdownSearch,
346
+ {
347
+ value: search,
348
+ onChange: setSearch,
349
+ placeholder: "Search..."
350
+ }
351
+ )
352
+ }
353
+ ),
354
+ /* @__PURE__ */ jsx(Box, { sx: { px: 1, pt: 1, pb: 1.5 }, children: filteredGroups.length === 0 ? /* @__PURE__ */ jsx(
355
+ Typography,
356
+ {
357
+ variant: "body2",
358
+ sx: { color: theme.palette.text.secondary, py: 1 },
359
+ children: "No insights found"
360
+ }
361
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
362
+ /* @__PURE__ */ jsx(Box, { sx: { maxHeight: 280, overflowY: "auto" }, children: visibleGroups.map((group) => {
363
+ const isExpanded = search ? true : expandedGroups[group.groupName] ?? false;
364
+ const isOptionExpanded = expandedOptions[group.groupName] ?? false;
365
+ const optionsToRender = isOptionExpanded || search ? group.options : group.options.slice(0, GROUP_OPTION_LIMIT);
366
+ const hasMoreOptions = group.options.length > GROUP_OPTION_LIMIT;
367
+ return /* @__PURE__ */ jsxs(Box, { children: [
368
+ /* @__PURE__ */ jsxs(
369
+ ListItemButton,
370
+ {
371
+ disableRipple: true,
372
+ onClick: () => toggleGroup(group.groupName),
373
+ sx: {
374
+ display: "flex",
375
+ justifyContent: "space-between",
376
+ alignItems: "center",
377
+ "&:hover": {
378
+ backgroundColor: alpha(
379
+ theme.palette.primary.main,
380
+ 0.04
381
+ )
382
+ }
383
+ },
384
+ children: [
385
+ /* @__PURE__ */ jsx(
386
+ ListItemText,
387
+ {
388
+ primaryTypographyProps: {
389
+ fontSize: 12,
390
+ letterSpacing: 0.6,
391
+ color: alpha(theme.palette.text.primary, 0.85),
392
+ textTransform: "uppercase"
393
+ },
394
+ primary: `${group.groupName} (${group.options.length})`
395
+ }
396
+ ),
397
+ /* @__PURE__ */ jsx(
398
+ KeyboardArrowRightIcon,
399
+ {
400
+ sx: {
401
+ transition: "transform 0.2s ease",
402
+ transform: isExpanded ? "rotate(90deg)" : "none",
403
+ color: alpha(theme.palette.text.primary, 0.6)
404
+ }
405
+ }
406
+ )
407
+ ]
408
+ }
409
+ ),
410
+ /* @__PURE__ */ jsxs(
411
+ Collapse,
412
+ {
413
+ in: isExpanded,
414
+ timeout: "auto",
415
+ unmountOnExit: true,
416
+ children: [
417
+ /* @__PURE__ */ jsx(List, { disablePadding: true, sx: { px: 2, py: 1 }, children: optionsToRender.map((option) => {
418
+ const palette = sentimentPalette(
419
+ theme,
420
+ option.sentiment
421
+ );
422
+ return /* @__PURE__ */ jsxs(
423
+ ListItemButton,
424
+ {
425
+ onClick: () => toggleOption(option.name),
426
+ sx: {
427
+ display: "flex",
428
+ py: 0,
429
+ borderRadius: 2,
430
+ alignItems: "center",
431
+ justifyContent: "space-between",
432
+ width: "100%"
433
+ },
434
+ dense: true,
435
+ children: [
436
+ /* @__PURE__ */ jsxs(
437
+ Box,
438
+ {
439
+ sx: {
440
+ display: "flex",
441
+ alignItems: "center",
442
+ flex: 1,
443
+ minWidth: 0
444
+ },
445
+ children: [
446
+ /* @__PURE__ */ jsx(ListItemIcon, { sx: { minWidth: 32 }, children: /* @__PURE__ */ jsx(
447
+ Checkbox,
448
+ {
449
+ edge: "start",
450
+ tabIndex: -1,
451
+ disableRipple: true,
452
+ checked: selectedValues.includes(
453
+ option.name
454
+ )
455
+ }
456
+ ) }),
457
+ /* @__PURE__ */ jsx(
458
+ Chip,
459
+ {
460
+ label: option.displayName,
461
+ size: "small",
462
+ sx: {
463
+ mb: 0,
464
+ fontWeight: 600,
465
+ color: palette.color,
466
+ backgroundColor: palette.background,
467
+ borderRadius: 2,
468
+ maxWidth: "100%",
469
+ "& .MuiChip-label": {
470
+ overflow: "hidden",
471
+ textOverflow: "ellipsis",
472
+ whiteSpace: "nowrap"
473
+ }
474
+ }
475
+ }
476
+ )
477
+ ]
478
+ }
479
+ ),
480
+ /* @__PURE__ */ jsx(
481
+ SimpleTooltip,
482
+ {
483
+ title: option.description || "No description",
484
+ placement: "top",
485
+ tooltipProps: {
486
+ componentsProps: {
487
+ tooltip: {
488
+ sx: {
489
+ whiteSpace: "pre-wrap",
490
+ maxWidth: "300px",
491
+ wordBreak: "break-word"
492
+ }
493
+ }
494
+ }
495
+ },
496
+ children: /* @__PURE__ */ jsx(
497
+ IconButton,
498
+ {
499
+ size: "small",
500
+ sx: { ml: 0.5, flexShrink: 0 },
501
+ children: /* @__PURE__ */ jsx(InfoOutlinedIcon, { fontSize: "small" })
502
+ }
503
+ )
504
+ }
505
+ )
506
+ ]
507
+ },
508
+ option.name
509
+ );
510
+ }) }),
511
+ hasMoreOptions && !search && /* @__PURE__ */ jsx(
512
+ Link,
513
+ {
514
+ component: "button",
515
+ type: "button",
516
+ underline: "hover",
517
+ onClick: () => toggleOptions(group.groupName),
518
+ sx: {
519
+ mx: 2,
520
+ mb: 1,
521
+ display: "inline-flex",
522
+ fontSize: 13,
523
+ fontWeight: 500,
524
+ color: theme.palette.primary.main,
525
+ textUnderlineOffset: "2px"
526
+ },
527
+ children: isOptionExpanded ? "Show less" : "Show full list"
528
+ }
529
+ )
530
+ ]
531
+ }
532
+ ),
533
+ /* @__PURE__ */ jsx(
534
+ Divider,
535
+ {
536
+ sx: {
537
+ borderColor: alpha(theme.palette.divider, 0.1)
538
+ }
539
+ }
540
+ )
541
+ ] }, group.groupName);
542
+ }) }),
543
+ hasMoreGroups && !search && /* @__PURE__ */ jsx(
544
+ Link,
545
+ {
546
+ alignSelf: "center",
547
+ component: "button",
548
+ type: "button",
549
+ underline: "hover",
550
+ onClick: () => setShowAll((prev) => !prev),
551
+ sx: {
552
+ mt: 1,
553
+ fontSize: 13,
554
+ fontWeight: 500,
555
+ color: theme.palette.primary.main,
556
+ textUnderlineOffset: "2px"
557
+ },
558
+ children: showAll ? "Hide full list" : "Show full list"
559
+ }
560
+ )
561
+ ] }) }),
562
+ /* @__PURE__ */ jsx(
563
+ FilterDropdownClear,
564
+ {
565
+ disabled: !hasSelection,
566
+ label: clearLabel,
567
+ onClear: handleClear
568
+ }
569
+ )
570
+ ]
571
+ }
572
+ ) })
573
+ }
574
+ )
575
+ ] });
576
+ };
577
+
578
+ export { RiskInsightFilter };
579
+ //# sourceMappingURL=RiskInsightFilter.esm.js.map