@perses-dev/alert-manager-plugin 0.1.1 → 0.2.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mf/js/AlertManager.42d95b33.js +7 -0
- package/__mf/js/async/1299.d5af4767.js +1 -0
- package/__mf/js/async/1522.04dc197d.js +22 -0
- package/__mf/js/async/1616.0c9baa4c.js +1 -0
- package/__mf/js/async/1871.5e21fb62.js +1 -0
- package/__mf/js/async/1969.e54f3991.js +1 -0
- package/__mf/js/async/2043.4e8f2371.js +2 -0
- package/__mf/js/async/{430.74d85c4b.js.LICENSE.txt → 2043.4e8f2371.js.LICENSE.txt} +1 -41
- package/__mf/js/async/2197.53bcb69e.js +1 -0
- package/__mf/js/async/2218.8b7e30c2.js +2 -0
- package/__mf/js/async/2317.e656eab3.js +2 -0
- package/__mf/js/async/2377.5295b064.js +1 -0
- package/__mf/js/async/2650.0b5955b5.js +3 -0
- package/__mf/js/async/2657.e6a11726.js +1 -0
- package/__mf/js/async/3222.6ad1b128.js +1 -0
- package/__mf/js/async/3514.e71d5cb9.js +2 -0
- package/__mf/js/async/3910.1bd28e15.js +1 -0
- package/__mf/js/async/392.26ae5cc4.js +2 -0
- package/__mf/js/async/3963.181d3782.js +1 -0
- package/__mf/js/async/4077.91abd1da.js +1 -0
- package/__mf/js/async/4121.f9595b70.js +2 -0
- package/__mf/js/async/4133.cc678ae9.js +28 -0
- package/__mf/js/async/4213.005a1a65.js +1 -0
- package/__mf/js/async/{4466.a8145edd.js → 4466.7cca717d.js} +3 -3
- package/__mf/js/async/4481.5bc5aa13.js +2 -0
- package/__mf/js/async/4496.3760da2f.js +1 -0
- package/__mf/js/async/4978.f1550309.js +1 -0
- package/__mf/js/async/5038.b1e9133a.js +2 -0
- package/__mf/js/async/5071.eeb1c9b1.js +1 -0
- package/__mf/js/async/5428.6922d4df.js +1 -0
- package/__mf/js/async/5759.84fc4d0b.js +7 -0
- package/__mf/js/async/{3540.96681482.js.LICENSE.txt → 5759.84fc4d0b.js.LICENSE.txt} +41 -1
- package/__mf/js/async/6274.9f68ee7d.js +2 -0
- package/__mf/js/async/6390.0fd40bd8.js +2 -0
- package/__mf/js/async/6401.7bf2c4c2.js +1 -0
- package/__mf/js/async/6594.b3a19fc1.js +2 -0
- package/__mf/js/async/6854.f05f8da0.js +1 -0
- package/__mf/js/async/6911.bc380f0c.js +37 -0
- package/__mf/js/async/7177.83345474.js +1 -0
- package/__mf/js/async/7192.715c4cb3.js +1 -0
- package/__mf/js/async/733.8bc3bc96.js +1 -0
- package/__mf/js/async/7862.10a19eef.js +2 -0
- package/__mf/js/async/7978.4ca49c3a.js +1 -0
- package/__mf/js/async/8470.7ebe8e66.js +2 -0
- package/__mf/js/async/8697.7b6d10e1.js +1 -0
- package/__mf/js/async/873.fcc6e5b7.js +1 -0
- package/__mf/js/async/8907.5d1f9505.js +1 -0
- package/__mf/js/async/{9040.94717f28.js → 9040.8de751d6.js} +4 -4
- package/__mf/js/async/9184.307e83da.js +1 -0
- package/__mf/js/async/9235.1b0d1de0.js +1 -0
- package/__mf/js/async/941.36858244.js +2 -0
- package/__mf/js/async/9588.31544c69.js +1 -0
- package/__mf/js/async/9836.e4cf02db.js +1 -0
- package/__mf/js/async/__federation_expose_AlertManagerAlertsExplorer.4fbf2fa1.js +2 -0
- package/__mf/js/async/__federation_expose_AlertManagerAlertsQuery.27d99dac.js +1 -0
- package/__mf/js/async/__federation_expose_AlertManagerDatasource.c2b36e70.js +2 -0
- package/__mf/js/async/__federation_expose_AlertManagerSilencesExplorer.65e1901a.js +2 -0
- package/__mf/js/async/__federation_expose_AlertManagerSilencesQuery.f619a448.js +2 -0
- package/__mf/js/async/__federation_expose_AlertTable.6c37126b.js +1 -0
- package/__mf/js/async/__federation_expose_SilenceTable.3a614a2f.js +1 -0
- package/__mf/js/async/lib-router.20ba053c.js +2 -0
- package/__mf/js/{main.259f5b24.js → main.babca431.js} +2 -2
- package/lib/bootstrap.js +2 -2
- package/lib/components/ColumnsEditor.d.ts +1 -1
- package/lib/components/ColumnsEditor.d.ts.map +1 -1
- package/lib/components/ColumnsEditor.js +7 -7
- package/lib/components/ColumnsEditor.js.map +1 -1
- package/lib/components/LazyTextField.d.ts +1 -1
- package/lib/components/LazyTextField.d.ts.map +1 -1
- package/lib/components/LazyTextField.js +2 -2
- package/lib/components/LazyTextField.js.map +1 -1
- package/lib/components/MatcherEditor.d.ts +1 -1
- package/lib/components/MatcherEditor.d.ts.map +1 -1
- package/lib/components/MatcherEditor.js +4 -4
- package/lib/components/MatcherEditor.js.map +1 -1
- package/lib/components/MatchersList.d.ts +2 -2
- package/lib/components/MatchersList.d.ts.map +1 -1
- package/lib/components/MatchersList.js +1 -1
- package/lib/components/MatchersList.js.map +1 -1
- package/lib/components/SilenceForm.d.ts +2 -2
- package/lib/components/SilenceForm.d.ts.map +1 -1
- package/lib/components/SilenceForm.js +4 -4
- package/lib/components/SilenceForm.js.map +1 -1
- package/lib/components/StatusBadge.d.ts +1 -1
- package/lib/components/StatusBadge.d.ts.map +1 -1
- package/lib/components/StatusBadge.js +1 -1
- package/lib/components/StatusBadge.js.map +1 -1
- package/lib/components/index.js +5 -5
- package/lib/components/index.js.map +1 -1
- package/lib/explore/AlertManagerAlertsExplorer.d.ts +1 -1
- package/lib/explore/AlertManagerAlertsExplorer.d.ts.map +1 -1
- package/lib/explore/AlertManagerAlertsExplorer.js +5 -5
- package/lib/explore/AlertManagerAlertsExplorer.js.map +1 -1
- package/lib/explore/AlertManagerSilencesExplorer.d.ts +1 -1
- package/lib/explore/AlertManagerSilencesExplorer.d.ts.map +1 -1
- package/lib/explore/AlertManagerSilencesExplorer.js +10 -10
- package/lib/explore/AlertManagerSilencesExplorer.js.map +1 -1
- package/lib/getPluginModule.d.ts +1 -1
- package/lib/getPluginModule.d.ts.map +1 -1
- package/lib/getPluginModule.js +3 -1
- package/lib/getPluginModule.js.map +1 -1
- package/lib/index-federation.js +1 -1
- package/lib/index.js +4 -4
- package/lib/index.js.map +1 -1
- package/lib/model/alertmanager-client.d.ts +3 -3
- package/lib/model/alertmanager-client.d.ts.map +1 -1
- package/lib/model/alertmanager-client.js +4 -2
- package/lib/model/alertmanager-client.js.map +1 -1
- package/lib/model/alertmanager-selectors.d.ts +2 -2
- package/lib/model/alertmanager-selectors.d.ts.map +1 -1
- package/lib/model/alertmanager-selectors.js +1 -1
- package/lib/model/alertmanager-selectors.js.map +1 -1
- package/lib/model/index.js +3 -3
- package/lib/model/index.js.map +1 -1
- package/lib/plugins/AlertManagerDatasourceEditor.d.ts +2 -2
- package/lib/plugins/AlertManagerDatasourceEditor.d.ts.map +1 -1
- package/lib/plugins/AlertManagerDatasourceEditor.js +1 -1
- package/lib/plugins/AlertManagerDatasourceEditor.js.map +1 -1
- package/lib/plugins/alert-table/AlertTable.d.ts +3 -3
- package/lib/plugins/alert-table/AlertTable.d.ts.map +1 -1
- package/lib/plugins/alert-table/AlertTable.js +5 -5
- package/lib/plugins/alert-table/AlertTable.js.map +1 -1
- package/lib/plugins/alert-table/AlertTableColumnsEditor.d.ts +3 -3
- package/lib/plugins/alert-table/AlertTableColumnsEditor.d.ts.map +1 -1
- package/lib/plugins/alert-table/AlertTableColumnsEditor.js +4 -4
- package/lib/plugins/alert-table/AlertTableColumnsEditor.js.map +1 -1
- package/lib/plugins/alert-table/AlertTableDeduplicationEditor.d.ts +3 -3
- package/lib/plugins/alert-table/AlertTableDeduplicationEditor.d.ts.map +1 -1
- package/lib/plugins/alert-table/AlertTableDeduplicationEditor.js +4 -4
- package/lib/plugins/alert-table/AlertTableDeduplicationEditor.js.map +1 -1
- package/lib/plugins/alert-table/AlertTableLabelsEditor.d.ts +3 -3
- package/lib/plugins/alert-table/AlertTableLabelsEditor.d.ts.map +1 -1
- package/lib/plugins/alert-table/AlertTableLabelsEditor.js +6 -6
- package/lib/plugins/alert-table/AlertTableLabelsEditor.js.map +1 -1
- package/lib/plugins/alert-table/AlertTableOptionsEditor.d.ts +3 -3
- package/lib/plugins/alert-table/AlertTableOptionsEditor.d.ts.map +1 -1
- package/lib/plugins/alert-table/AlertTableOptionsEditor.js +5 -5
- package/lib/plugins/alert-table/AlertTableOptionsEditor.js.map +1 -1
- package/lib/plugins/alert-table/AlertTablePanel.d.ts +4 -4
- package/lib/plugins/alert-table/AlertTablePanel.d.ts.map +1 -1
- package/lib/plugins/alert-table/AlertTablePanel.js +21 -21
- package/lib/plugins/alert-table/AlertTablePanel.js.map +1 -1
- package/lib/plugins/alert-table/alert-table-model.d.ts +1 -1
- package/lib/plugins/alert-table/alert-table-model.d.ts.map +1 -1
- package/lib/plugins/alert-table/alert-table-model.js +2 -2
- package/lib/plugins/alert-table/alert-table-model.js.map +1 -1
- package/lib/plugins/alert-table/alert-table-sorting.d.ts +2 -2
- package/lib/plugins/alert-table/alert-table-sorting.d.ts.map +1 -1
- package/lib/plugins/alert-table/alert-table-sorting.js +1 -1
- package/lib/plugins/alert-table/alert-table-sorting.js.map +1 -1
- package/lib/plugins/alert-table/label-colors.d.ts +1 -1
- package/lib/plugins/alert-table/label-colors.d.ts.map +1 -1
- package/lib/plugins/alert-table/label-colors.js.map +1 -1
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQuery.d.ts +2 -2
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQuery.d.ts.map +1 -1
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQuery.js +3 -3
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQuery.js.map +1 -1
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQueryEditor.d.ts +2 -2
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQueryEditor.d.ts.map +1 -1
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQueryEditor.js +7 -7
- package/lib/plugins/alertmanager-alerts-query/AlertManagerAlertsQueryEditor.js.map +1 -1
- package/lib/plugins/alertmanager-alerts-query/get-alerts-data.d.ts +3 -3
- package/lib/plugins/alertmanager-alerts-query/get-alerts-data.d.ts.map +1 -1
- package/lib/plugins/alertmanager-alerts-query/get-alerts-data.js +2 -2
- package/lib/plugins/alertmanager-alerts-query/get-alerts-data.js.map +1 -1
- package/lib/plugins/alertmanager-datasource.d.ts +3 -3
- package/lib/plugins/alertmanager-datasource.d.ts.map +1 -1
- package/lib/plugins/alertmanager-datasource.js +2 -2
- package/lib/plugins/alertmanager-datasource.js.map +1 -1
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQuery.d.ts +2 -2
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQuery.d.ts.map +1 -1
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQuery.js +3 -3
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQuery.js.map +1 -1
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQueryEditor.d.ts +2 -2
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQueryEditor.d.ts.map +1 -1
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQueryEditor.js +7 -7
- package/lib/plugins/alertmanager-silences-query/AlertManagerSilencesQueryEditor.js.map +1 -1
- package/lib/plugins/alertmanager-silences-query/get-silences-data.d.ts +3 -3
- package/lib/plugins/alertmanager-silences-query/get-silences-data.d.ts.map +1 -1
- package/lib/plugins/alertmanager-silences-query/get-silences-data.js +2 -2
- package/lib/plugins/alertmanager-silences-query/get-silences-data.js.map +1 -1
- package/lib/plugins/index.js +16 -16
- package/lib/plugins/index.js.map +1 -1
- package/lib/plugins/silence-table/SilenceTable.d.ts +2 -2
- package/lib/plugins/silence-table/SilenceTable.d.ts.map +1 -1
- package/lib/plugins/silence-table/SilenceTable.js +3 -3
- package/lib/plugins/silence-table/SilenceTable.js.map +1 -1
- package/lib/plugins/silence-table/SilenceTableColumnsEditor.d.ts +3 -3
- package/lib/plugins/silence-table/SilenceTableColumnsEditor.d.ts.map +1 -1
- package/lib/plugins/silence-table/SilenceTableColumnsEditor.js +5 -5
- package/lib/plugins/silence-table/SilenceTableColumnsEditor.js.map +1 -1
- package/lib/plugins/silence-table/SilenceTableOptionsEditor.d.ts +3 -3
- package/lib/plugins/silence-table/SilenceTableOptionsEditor.d.ts.map +1 -1
- package/lib/plugins/silence-table/SilenceTableOptionsEditor.js +5 -5
- package/lib/plugins/silence-table/SilenceTableOptionsEditor.js.map +1 -1
- package/lib/plugins/silence-table/SilenceTablePanel.d.ts +4 -4
- package/lib/plugins/silence-table/SilenceTablePanel.d.ts.map +1 -1
- package/lib/plugins/silence-table/SilenceTablePanel.js +13 -13
- package/lib/plugins/silence-table/SilenceTablePanel.js.map +1 -1
- package/lib/plugins/silence-table/silence-table-model.d.ts +1 -1
- package/lib/plugins/silence-table/silence-table-model.d.ts.map +1 -1
- package/lib/plugins/silence-table/silence-table-model.js.map +1 -1
- package/lib/plugins/silence-table/silence-table-sorting.d.ts +2 -2
- package/lib/plugins/silence-table/silence-table-sorting.d.ts.map +1 -1
- package/lib/plugins/silence-table/silence-table-sorting.js +1 -1
- package/lib/plugins/silence-table/silence-table-sorting.js.map +1 -1
- package/lib/plugins/types.d.ts +3 -3
- package/lib/plugins/types.d.ts.map +1 -1
- package/lib/plugins/types.js.map +1 -1
- package/lib/setup-tests.d.ts +1 -1
- package/lib/setup-tests.d.ts.map +1 -1
- package/lib/setup-tests.js +2 -2
- package/lib/setup-tests.js.map +1 -1
- package/mf-manifest.json +302 -308
- package/mf-stats.json +308 -314
- package/package.json +12 -12
- package/__mf/js/AlertManager.377d377b.js +0 -7
- package/__mf/js/async/1616.24f00c9d.js +0 -1
- package/__mf/js/async/1728.8a326412.js +0 -1
- package/__mf/js/async/1871.23ff54b3.js +0 -1
- package/__mf/js/async/1969.a83b1b48.js +0 -1
- package/__mf/js/async/2218.7829c9d9.js +0 -2
- package/__mf/js/async/2377.f8875a4e.js +0 -1
- package/__mf/js/async/2657.fe8dd44f.js +0 -1
- package/__mf/js/async/2842.993baf22.js +0 -1
- package/__mf/js/async/3468.1679f87f.js +0 -1
- package/__mf/js/async/3540.96681482.js +0 -2
- package/__mf/js/async/392.7e11dd69.js +0 -2
- package/__mf/js/async/3963.fb6246d2.js +0 -1
- package/__mf/js/async/3981.84d12fdc.js +0 -4
- package/__mf/js/async/3981.84d12fdc.js.LICENSE.txt +0 -24
- package/__mf/js/async/4121.ec666be2.js +0 -2
- package/__mf/js/async/4133.e94df4f8.js +0 -28
- package/__mf/js/async/4213.a0c4f2eb.js +0 -1
- package/__mf/js/async/430.74d85c4b.js +0 -7
- package/__mf/js/async/4788.49ffeac3.js +0 -1
- package/__mf/js/async/5038.269393e3.js +0 -2
- package/__mf/js/async/5481.cf6703fd.js +0 -2
- package/__mf/js/async/5570.d4dd47e0.js +0 -1
- package/__mf/js/async/573.ce8ce2ef.js +0 -2
- package/__mf/js/async/6274.8c77cb1a.js +0 -2
- package/__mf/js/async/6390.3f6f279d.js +0 -2
- package/__mf/js/async/6401.1a59dbad.js +0 -1
- package/__mf/js/async/6594.b02adfd9.js +0 -2
- package/__mf/js/async/663.5445c7e0.js +0 -1
- package/__mf/js/async/6854.1d628838.js +0 -1
- package/__mf/js/async/7177.27c86137.js +0 -1
- package/__mf/js/async/7192.ede9860b.js +0 -1
- package/__mf/js/async/7283.8c1cb6ee.js +0 -2
- package/__mf/js/async/7984.163a6ddb.js +0 -22
- package/__mf/js/async/804.23da0d30.js +0 -37
- package/__mf/js/async/8470.2df0db71.js +0 -2
- package/__mf/js/async/8697.c13c6603.js +0 -1
- package/__mf/js/async/8711.c7dc09b8.js +0 -2
- package/__mf/js/async/8907.9e3edf43.js +0 -1
- package/__mf/js/async/9184.27a439a4.js +0 -1
- package/__mf/js/async/9235.00f9412f.js +0 -1
- package/__mf/js/async/941.d3bc6208.js +0 -2
- package/__mf/js/async/9537.36ff6f15.js +0 -1
- package/__mf/js/async/9634.3a366799.js +0 -1
- package/__mf/js/async/983.36857235.js +0 -1
- package/__mf/js/async/9836.cc839227.js +0 -1
- package/__mf/js/async/__federation_expose_AlertManagerAlertsExplorer.47ee46dc.js +0 -2
- package/__mf/js/async/__federation_expose_AlertManagerAlertsQuery.22b0e5bc.js +0 -1
- package/__mf/js/async/__federation_expose_AlertManagerDatasource.7ee7440a.js +0 -2
- package/__mf/js/async/__federation_expose_AlertManagerSilencesExplorer.35860f1b.js +0 -2
- package/__mf/js/async/__federation_expose_AlertManagerSilencesQuery.52a24c9e.js +0 -2
- package/__mf/js/async/__federation_expose_AlertTable.5d005bae.js +0 -1
- package/__mf/js/async/__federation_expose_SilenceTable.3fc487a4.js +0 -2
- package/__mf/js/async/__federation_expose_SilenceTable.3fc487a4.js.LICENSE.txt +0 -9
- package/__mf/js/async/lib-router.19f64904.js +0 -2
- package/lib/cjs/bootstrap.js +0 -26
- package/lib/cjs/components/ColumnsEditor.js +0 -271
- package/lib/cjs/components/LazyTextField.js +0 -50
- package/lib/cjs/components/MatcherEditor.js +0 -153
- package/lib/cjs/components/MatchersList.js +0 -46
- package/lib/cjs/components/SilenceForm.js +0 -205
- package/lib/cjs/components/StatusBadge.js +0 -71
- package/lib/cjs/components/index.js +0 -44
- package/lib/cjs/explore/AlertManagerAlertsExplorer.js +0 -79
- package/lib/cjs/explore/AlertManagerSilencesExplorer.js +0 -153
- package/lib/cjs/getPluginModule.js +0 -39
- package/lib/cjs/index-federation.js +0 -55
- package/lib/cjs/index.js +0 -39
- package/lib/cjs/model/alertmanager-client.js +0 -128
- package/lib/cjs/model/alertmanager-selectors.js +0 -66
- package/lib/cjs/model/api-types.js +0 -22
- package/lib/cjs/model/index.js +0 -32
- package/lib/cjs/plugins/AlertManagerDatasourceEditor.js +0 -71
- package/lib/cjs/plugins/alert-table/AlertTable.js +0 -56
- package/lib/cjs/plugins/alert-table/AlertTableColumnsEditor.js +0 -110
- package/lib/cjs/plugins/alert-table/AlertTableDeduplicationEditor.js +0 -138
- package/lib/cjs/plugins/alert-table/AlertTableLabelsEditor.js +0 -277
- package/lib/cjs/plugins/alert-table/AlertTableOptionsEditor.js +0 -128
- package/lib/cjs/plugins/alert-table/AlertTablePanel.js +0 -773
- package/lib/cjs/plugins/alert-table/alert-table-model.js +0 -142
- package/lib/cjs/plugins/alert-table/alert-table-sorting.js +0 -205
- package/lib/cjs/plugins/alert-table/label-colors.js +0 -170
- package/lib/cjs/plugins/alertmanager-alerts-query/AlertManagerAlertsQuery.js +0 -51
- package/lib/cjs/plugins/alertmanager-alerts-query/AlertManagerAlertsQueryEditor.js +0 -138
- package/lib/cjs/plugins/alertmanager-alerts-query/get-alerts-data.js +0 -124
- package/lib/cjs/plugins/alertmanager-datasource.js +0 -69
- package/lib/cjs/plugins/alertmanager-silences-query/AlertManagerSilencesQuery.js +0 -45
- package/lib/cjs/plugins/alertmanager-silences-query/AlertManagerSilencesQueryEditor.js +0 -78
- package/lib/cjs/plugins/alertmanager-silences-query/get-silences-data.js +0 -64
- package/lib/cjs/plugins/index.js +0 -74
- package/lib/cjs/plugins/silence-table/SilenceTable.js +0 -42
- package/lib/cjs/plugins/silence-table/SilenceTableColumnsEditor.js +0 -137
- package/lib/cjs/plugins/silence-table/SilenceTableOptionsEditor.js +0 -63
- package/lib/cjs/plugins/silence-table/SilenceTablePanel.js +0 -345
- package/lib/cjs/plugins/silence-table/silence-table-model.js +0 -116
- package/lib/cjs/plugins/silence-table/silence-table-sorting.js +0 -68
- package/lib/cjs/plugins/types.js +0 -16
- package/lib/cjs/setup-tests.js +0 -18
- /package/__mf/css/async/{430.85c2cbf6.css → 5759.85c2cbf6.css} +0 -0
- /package/__mf/js/async/{7984.163a6ddb.js.LICENSE.txt → 1522.04dc197d.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{2218.7829c9d9.js.LICENSE.txt → 2218.8b7e30c2.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5038.269393e3.js.LICENSE.txt → 2317.e656eab3.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{6390.3f6f279d.js.LICENSE.txt → 3514.e71d5cb9.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{392.7e11dd69.js.LICENSE.txt → 392.26ae5cc4.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{4121.ec666be2.js.LICENSE.txt → 4121.f9595b70.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{6594.b02adfd9.js.LICENSE.txt → 5038.b1e9133a.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{6274.8c77cb1a.js.LICENSE.txt → 6274.9f68ee7d.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{7283.8c1cb6ee.js.LICENSE.txt → 6390.0fd40bd8.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{8711.c7dc09b8.js.LICENSE.txt → 6594.b3a19fc1.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5481.cf6703fd.js.LICENSE.txt → 7862.10a19eef.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{8470.2df0db71.js.LICENSE.txt → 8470.7ebe8e66.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{9040.94717f28.js.LICENSE.txt → 9040.8de751d6.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{941.d3bc6208.js.LICENSE.txt → 941.36858244.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{__federation_expose_AlertManagerAlertsExplorer.47ee46dc.js.LICENSE.txt → __federation_expose_AlertManagerAlertsExplorer.4fbf2fa1.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{__federation_expose_AlertManagerDatasource.7ee7440a.js.LICENSE.txt → __federation_expose_AlertManagerDatasource.c2b36e70.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{__federation_expose_AlertManagerSilencesExplorer.35860f1b.js.LICENSE.txt → __federation_expose_AlertManagerSilencesExplorer.65e1901a.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{__federation_expose_AlertManagerSilencesQuery.52a24c9e.js.LICENSE.txt → __federation_expose_AlertManagerSilencesQuery.f619a448.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{lib-router.19f64904.js.LICENSE.txt → lib-router.20ba053c.js.LICENSE.txt} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/plugins/alert-table/AlertTableLabelsEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n Box,\n Button,\n Checkbox,\n Divider,\n FormControl,\n FormControlLabel,\n IconButton,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n TextField,\n Typography,\n} from '@mui/material';\nimport { OptionsEditorGroup } from '@perses-dev/components';\nimport { OptionsEditorProps } from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport DeleteIcon from 'mdi-material-ui/Delete';\nimport PlusIcon from 'mdi-material-ui/Plus';\nimport { ReactElement, useCallback } from 'react';\nimport { AlertTableOptions, LabelColorMapping, LabelColorOverride } from './alert-table-model';\n\nconst MODE_LABELS: Record<LabelColorMapping['mode'], string> = {\n auto: 'Auto (hash-derived colors)',\n severity: 'Severity (built-in defaults)',\n manual: 'Manual (overrides only)',\n};\n\nfunction LabelMappingEntry({\n mapping,\n index,\n onUpdate,\n onRemove,\n}: {\n mapping: LabelColorMapping;\n index: number;\n onUpdate: (index: number, updater: (draft: LabelColorMapping) => void) => void;\n onRemove: (index: number) => void;\n}): ReactElement {\n const handleAddOverride = useCallback((): void => {\n onUpdate(index, (draft) => {\n if (!draft.overrides) draft.overrides = [];\n draft.overrides.push({ value: '', isRegex: false, color: '#1976d2' });\n });\n }, [index, onUpdate]);\n\n const handleRemoveOverride = useCallback(\n (overrideIndex: number): void => {\n onUpdate(index, (draft) => {\n draft.overrides?.splice(overrideIndex, 1);\n });\n },\n [index, onUpdate]\n );\n\n const handleUpdateOverride = useCallback(\n (overrideIndex: number, field: keyof LabelColorOverride, fieldValue: string | boolean): void => {\n onUpdate(index, (draft) => {\n const override = draft.overrides?.[overrideIndex];\n if (override) {\n if (field === 'isRegex') {\n override.isRegex = fieldValue as boolean;\n } else {\n override[field] = fieldValue as string;\n }\n }\n });\n },\n [index, onUpdate]\n );\n\n return (\n <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 1, p: 2 }}>\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" justifyContent=\"space-between\">\n <Typography variant=\"subtitle2\">{mapping.labelKey || 'New label'}</Typography>\n <IconButton size=\"small\" onClick={() => onRemove(index)} aria-label=\"Remove label mapping\">\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Stack>\n <TextField\n label=\"Label key\"\n value={mapping.labelKey}\n onChange={(e) =>\n onUpdate(index, (draft) => {\n draft.labelKey = e.target.value;\n })\n }\n size=\"small\"\n fullWidth\n />\n <FormControl size=\"small\" fullWidth>\n <InputLabel id={`color-mode-label-${index}`}>Mode</InputLabel>\n <Select\n labelId={`color-mode-label-${index}`}\n value={mapping.mode}\n onChange={(e) =>\n onUpdate(index, (draft) => {\n draft.mode = e.target.value as LabelColorMapping['mode'];\n })\n }\n label=\"Mode\"\n >\n {(Object.keys(MODE_LABELS) as Array<LabelColorMapping['mode']>).map((mode) => (\n <MenuItem key={mode} value={mode}>\n {MODE_LABELS[mode]}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n Overrides\n </Typography>\n <Stack spacing={1}>\n {(mapping.overrides ?? []).map((override, overrideIndex) => (\n <Stack key={overrideIndex} direction=\"row\" spacing={1} alignItems=\"center\">\n <TextField\n label=\"Value / Pattern\"\n value={override.value}\n onChange={(e) => handleUpdateOverride(overrideIndex, 'value', e.target.value)}\n size=\"small\"\n sx={{ flex: 1 }}\n />\n <FormControlLabel\n control={\n <Checkbox\n checked={override.isRegex}\n onChange={(e) => handleUpdateOverride(overrideIndex, 'isRegex', e.target.checked)}\n size=\"small\"\n />\n }\n label=\"Regex\"\n />\n <input\n type=\"color\"\n value={override.color}\n onChange={(e) => handleUpdateOverride(overrideIndex, 'color', e.target.value)}\n style={{ width: 36, height: 28, border: 'none', cursor: 'pointer' }}\n />\n <IconButton\n size=\"small\"\n onClick={() => handleRemoveOverride(overrideIndex)}\n aria-label=\"Remove override\"\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Stack>\n ))}\n <Button size=\"small\" startIcon={<PlusIcon />} onClick={handleAddOverride}>\n Add override\n </Button>\n </Stack>\n </Box>\n </Stack>\n </Box>\n );\n}\n\nexport function AlertTableLabelsEditor(props: OptionsEditorProps<AlertTableOptions>): ReactElement {\n const { value, onChange } = props;\n const mappings = value.labelColorMappings ?? [];\n\n const handleAddMapping = useCallback((): void => {\n onChange(\n produce(value, (draft) => {\n if (!draft.labelColorMappings) draft.labelColorMappings = [];\n draft.labelColorMappings.push({ labelKey: '', mode: 'auto' });\n })\n );\n }, [value, onChange]);\n\n const handleRemoveMapping = useCallback(\n (index: number): void => {\n onChange(\n produce(value, (draft) => {\n draft.labelColorMappings?.splice(index, 1);\n })\n );\n },\n [value, onChange]\n );\n\n const handleUpdateMapping = useCallback(\n (index: number, updater: (draft: LabelColorMapping) => void): void => {\n onChange(\n produce(value, (draft) => {\n const mapping = draft.labelColorMappings?.[index];\n if (mapping) {\n updater(mapping);\n }\n })\n );\n },\n [value, onChange]\n );\n\n return (\n <OptionsEditorGroup title=\"Label Color Mappings\">\n <Stack spacing={2}>\n {mappings.length === 0 && (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No label color mappings configured. Add one to color label values in the table.\n </Typography>\n )}\n {mappings.map((mapping, index) => (\n <Box key={index}>\n {index > 0 && <Divider sx={{ mb: 2 }} />}\n <LabelMappingEntry\n mapping={mapping}\n index={index}\n onUpdate={handleUpdateMapping}\n onRemove={handleRemoveMapping}\n />\n </Box>\n ))}\n <Button variant=\"outlined\" size=\"small\" startIcon={<PlusIcon />} onClick={handleAddMapping}>\n Add label mapping\n </Button>\n </Stack>\n </OptionsEditorGroup>\n );\n}\n"],"names":["Box","Button","Checkbox","Divider","FormControl","FormControlLabel","IconButton","InputLabel","MenuItem","Select","Stack","TextField","Typography","OptionsEditorGroup","produce","DeleteIcon","PlusIcon","useCallback","MODE_LABELS","auto","severity","manual","LabelMappingEntry","mapping","index","onUpdate","onRemove","handleAddOverride","draft","overrides","push","value","isRegex","color","handleRemoveOverride","overrideIndex","splice","handleUpdateOverride","field","fieldValue","override","sx","border","borderColor","borderRadius","p","spacing","direction","alignItems","justifyContent","variant","labelKey","size","onClick","aria-label","fontSize","label","onChange","e","target","fullWidth","id","labelId","mode","Object","keys","map","mb","flex","control","checked","input","type","style","width","height","cursor","startIcon","AlertTableLabelsEditor","props","mappings","labelColorMappings","handleAddMapping","handleRemoveMapping","handleUpdateMapping","updater","title","length"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/plugins/alert-table/AlertTableLabelsEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n Box,\n Button,\n Checkbox,\n Divider,\n FormControl,\n FormControlLabel,\n IconButton,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n TextField,\n Typography,\n} from '@mui/material';\nimport { OptionsEditorGroup } from '@perses-dev/components';\nimport type { OptionsEditorProps } from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport DeleteIcon from 'mdi-material-ui/Delete';\nimport PlusIcon from 'mdi-material-ui/Plus';\nimport type { ReactElement } from 'react';\nimport { useCallback } from 'react';\n\nimport type { AlertTableOptions, LabelColorMapping, LabelColorOverride } from './alert-table-model';\n\nconst MODE_LABELS: Record<LabelColorMapping['mode'], string> = {\n auto: 'Auto (hash-derived colors)',\n severity: 'Severity (built-in defaults)',\n manual: 'Manual (overrides only)',\n};\n\nfunction LabelMappingEntry({\n mapping,\n index,\n onUpdate,\n onRemove,\n}: {\n mapping: LabelColorMapping;\n index: number;\n onUpdate: (index: number, updater: (draft: LabelColorMapping) => void) => void;\n onRemove: (index: number) => void;\n}): ReactElement {\n const handleAddOverride = useCallback((): void => {\n onUpdate(index, (draft) => {\n if (!draft.overrides) draft.overrides = [];\n draft.overrides.push({ value: '', isRegex: false, color: '#1976d2' });\n });\n }, [index, onUpdate]);\n\n const handleRemoveOverride = useCallback(\n (overrideIndex: number): void => {\n onUpdate(index, (draft) => {\n draft.overrides?.splice(overrideIndex, 1);\n });\n },\n [index, onUpdate],\n );\n\n const handleUpdateOverride = useCallback(\n (overrideIndex: number, field: keyof LabelColorOverride, fieldValue: string | boolean): void => {\n onUpdate(index, (draft) => {\n const override = draft.overrides?.[overrideIndex];\n if (override) {\n if (field === 'isRegex') {\n override.isRegex = fieldValue as boolean;\n } else {\n override[field] = fieldValue as string;\n }\n }\n });\n },\n [index, onUpdate],\n );\n\n return (\n <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 1, p: 2 }}>\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" justifyContent=\"space-between\">\n <Typography variant=\"subtitle2\">{mapping.labelKey || 'New label'}</Typography>\n <IconButton size=\"small\" onClick={() => onRemove(index)} aria-label=\"Remove label mapping\">\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Stack>\n <TextField\n label=\"Label key\"\n value={mapping.labelKey}\n onChange={(e) =>\n onUpdate(index, (draft) => {\n draft.labelKey = e.target.value;\n })\n }\n size=\"small\"\n fullWidth\n />\n <FormControl size=\"small\" fullWidth>\n <InputLabel id={`color-mode-label-${index}`}>Mode</InputLabel>\n <Select\n labelId={`color-mode-label-${index}`}\n value={mapping.mode}\n onChange={(e) =>\n onUpdate(index, (draft) => {\n draft.mode = e.target.value as LabelColorMapping['mode'];\n })\n }\n label=\"Mode\"\n >\n {(Object.keys(MODE_LABELS) as Array<LabelColorMapping['mode']>).map((mode) => (\n <MenuItem key={mode} value={mode}>\n {MODE_LABELS[mode]}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n Overrides\n </Typography>\n <Stack spacing={1}>\n {(mapping.overrides ?? []).map((override, overrideIndex) => (\n <Stack key={overrideIndex} direction=\"row\" spacing={1} alignItems=\"center\">\n <TextField\n label=\"Value / Pattern\"\n value={override.value}\n onChange={(e) => handleUpdateOverride(overrideIndex, 'value', e.target.value)}\n size=\"small\"\n sx={{ flex: 1 }}\n />\n <FormControlLabel\n control={\n <Checkbox\n checked={override.isRegex}\n onChange={(e) => handleUpdateOverride(overrideIndex, 'isRegex', e.target.checked)}\n size=\"small\"\n />\n }\n label=\"Regex\"\n />\n <input\n type=\"color\"\n value={override.color}\n onChange={(e) => handleUpdateOverride(overrideIndex, 'color', e.target.value)}\n style={{ width: 36, height: 28, border: 'none', cursor: 'pointer' }}\n />\n <IconButton\n size=\"small\"\n onClick={() => handleRemoveOverride(overrideIndex)}\n aria-label=\"Remove override\"\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Stack>\n ))}\n <Button size=\"small\" startIcon={<PlusIcon />} onClick={handleAddOverride}>\n Add override\n </Button>\n </Stack>\n </Box>\n </Stack>\n </Box>\n );\n}\n\nexport function AlertTableLabelsEditor(props: OptionsEditorProps<AlertTableOptions>): ReactElement {\n const { value, onChange } = props;\n const mappings = value.labelColorMappings ?? [];\n\n const handleAddMapping = useCallback((): void => {\n onChange(\n produce(value, (draft) => {\n if (!draft.labelColorMappings) draft.labelColorMappings = [];\n draft.labelColorMappings.push({ labelKey: '', mode: 'auto' });\n }),\n );\n }, [value, onChange]);\n\n const handleRemoveMapping = useCallback(\n (index: number): void => {\n onChange(\n produce(value, (draft) => {\n draft.labelColorMappings?.splice(index, 1);\n }),\n );\n },\n [value, onChange],\n );\n\n const handleUpdateMapping = useCallback(\n (index: number, updater: (draft: LabelColorMapping) => void): void => {\n onChange(\n produce(value, (draft) => {\n const mapping = draft.labelColorMappings?.[index];\n if (mapping) {\n updater(mapping);\n }\n }),\n );\n },\n [value, onChange],\n );\n\n return (\n <OptionsEditorGroup title=\"Label Color Mappings\">\n <Stack spacing={2}>\n {mappings.length === 0 && (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No label color mappings configured. Add one to color label values in the table.\n </Typography>\n )}\n {mappings.map((mapping, index) => (\n <Box key={index}>\n {index > 0 && <Divider sx={{ mb: 2 }} />}\n <LabelMappingEntry\n mapping={mapping}\n index={index}\n onUpdate={handleUpdateMapping}\n onRemove={handleRemoveMapping}\n />\n </Box>\n ))}\n <Button variant=\"outlined\" size=\"small\" startIcon={<PlusIcon />} onClick={handleAddMapping}>\n Add label mapping\n </Button>\n </Stack>\n </OptionsEditorGroup>\n );\n}\n"],"names":["Box","Button","Checkbox","Divider","FormControl","FormControlLabel","IconButton","InputLabel","MenuItem","Select","Stack","TextField","Typography","OptionsEditorGroup","produce","DeleteIcon","PlusIcon","useCallback","MODE_LABELS","auto","severity","manual","LabelMappingEntry","mapping","index","onUpdate","onRemove","handleAddOverride","draft","overrides","push","value","isRegex","color","handleRemoveOverride","overrideIndex","splice","handleUpdateOverride","field","fieldValue","override","sx","border","borderColor","borderRadius","p","spacing","direction","alignItems","justifyContent","variant","labelKey","size","onClick","aria-label","fontSize","label","onChange","e","target","fullWidth","id","labelId","mode","Object","keys","map","mb","flex","control","checked","input","type","style","width","height","cursor","startIcon","AlertTableLabelsEditor","props","mappings","labelColorMappings","handleAddMapping","handleRemoveMapping","handleUpdateMapping","updater","title","length"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { OptionsEditorProps } from '@perses-dev/plugin-system';
|
|
2
|
-
import { ReactElement } from 'react';
|
|
3
|
-
import { AlertTableOptions } from './alert-table-model';
|
|
1
|
+
import type { OptionsEditorProps } from '@perses-dev/plugin-system';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
import type { AlertTableOptions } from './alert-table-model';
|
|
4
4
|
export declare function AlertTableOptionsEditor(props: OptionsEditorProps<AlertTableOptions>): ReactElement;
|
|
5
5
|
//# sourceMappingURL=AlertTableOptionsEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertTableOptionsEditor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/AlertTableOptionsEditor.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"AlertTableOptionsEditor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/AlertTableOptionsEditor.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,KAAK,EAAe,YAAY,EAAkB,MAAM,OAAO,CAAC;AAGvE,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAQ1E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,GAAG,YAAY,CA4GlG"}
|
|
@@ -11,11 +11,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
11
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
|
-
import { Autocomplete, Checkbox, Chip, FormControlLabel, TextField } from
|
|
15
|
-
import { OptionsEditorGroup } from
|
|
16
|
-
import { produce } from
|
|
17
|
-
import { useCallback } from
|
|
18
|
-
import { ALL_ALERT_ACTIONS } from
|
|
14
|
+
import { Autocomplete, Checkbox, Chip, FormControlLabel, TextField } from "@mui/material";
|
|
15
|
+
import { OptionsEditorGroup } from "@perses-dev/components";
|
|
16
|
+
import { produce } from "immer";
|
|
17
|
+
import { useCallback } from "react";
|
|
18
|
+
import { ALL_ALERT_ACTIONS } from "./alert-table-model.js";
|
|
19
19
|
const ACTION_LABELS = {
|
|
20
20
|
silence: 'Silence alert',
|
|
21
21
|
runbook: 'View runbook'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/plugins/alert-table/AlertTableOptionsEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\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 { Autocomplete, Checkbox, Chip, FormControlLabel, TextField } from '@mui/material';\nimport { OptionsEditorGroup } from '@perses-dev/components';\nimport { OptionsEditorProps } from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport { ChangeEvent, ReactElement, SyntheticEvent
|
|
1
|
+
{"version":3,"sources":["../../../../src/plugins/alert-table/AlertTableOptionsEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\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 { Autocomplete, Checkbox, Chip, FormControlLabel, TextField } from '@mui/material';\nimport { OptionsEditorGroup } from '@perses-dev/components';\nimport type { OptionsEditorProps } from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport type { ChangeEvent, ReactElement, SyntheticEvent } from 'react';\nimport { useCallback } from 'react';\n\nimport type { AlertAction, AlertTableOptions } from './alert-table-model';\nimport { ALL_ALERT_ACTIONS } from './alert-table-model';\n\nconst ACTION_LABELS: Record<AlertAction, string> = {\n silence: 'Silence alert',\n runbook: 'View runbook',\n};\n\nexport function AlertTableOptionsEditor(props: OptionsEditorProps<AlertTableOptions>): ReactElement {\n const { value, onChange } = props;\n const effectiveActions = value.allowedActions ?? ALL_ALERT_ACTIONS;\n const groupBy = value.defaultGroupBy ?? ['alertname'];\n\n const handleGroupByChange = useCallback(\n (_event: SyntheticEvent, newValue: string[]): void => {\n onChange(\n produce(value, (draft) => {\n draft.defaultGroupBy = newValue.length > 0 ? newValue : undefined;\n }),\n );\n },\n [value, onChange],\n );\n\n const handleRunbookKeyChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>): void => {\n onChange(\n produce(value, (draft) => {\n const trimmed = e.target.value.trim();\n draft.runbookAnnotationKey = trimmed || undefined;\n }),\n );\n },\n [value, onChange],\n );\n\n const handleToggle = useCallback(\n (action: AlertAction, checked: boolean) => {\n onChange(\n produce(value, (draft) => {\n const current = draft.allowedActions ?? [...ALL_ALERT_ACTIONS];\n if (checked) {\n if (!current.includes(action)) current.push(action);\n } else {\n const idx = current.indexOf(action);\n if (idx >= 0) current.splice(idx, 1);\n }\n draft.allowedActions = current;\n }),\n );\n },\n [value, onChange],\n );\n\n return (\n <>\n <OptionsEditorGroup title=\"Group By\">\n <Autocomplete<string, true, false, true>\n multiple\n freeSolo\n options={[] as string[]}\n value={groupBy}\n onChange={handleGroupByChange}\n renderTags={(tagValues, getTagProps): ReactElement[] =>\n tagValues.map((option, index) => {\n const { key, ...rest } = getTagProps({ index });\n const isVariable = option.includes('$');\n return (\n <Chip\n key={key}\n label={option}\n size=\"small\"\n variant={isVariable ? 'filled' : 'outlined'}\n color={isVariable ? 'primary' : 'default'}\n {...rest}\n />\n );\n })\n }\n renderInput={(params) => (\n <TextField\n {...params}\n size=\"small\"\n placeholder=\"Type a label key or $variable and press Enter\"\n helperText=\"Label keys to group alerts by. Supports $variable interpolation.\"\n />\n )}\n />\n </OptionsEditorGroup>\n <OptionsEditorGroup title=\"Actions\">\n {ALL_ALERT_ACTIONS.map((action) => (\n <FormControlLabel\n key={action}\n control={\n <Checkbox\n checked={effectiveActions.includes(action)}\n onChange={(e) => handleToggle(action, e.target.checked)}\n size=\"small\"\n />\n }\n label={ACTION_LABELS[action]}\n />\n ))}\n </OptionsEditorGroup>\n <OptionsEditorGroup title=\"Runbook\">\n <TextField\n size=\"small\"\n fullWidth\n value={value.runbookAnnotationKey ?? ''}\n onChange={handleRunbookKeyChange}\n placeholder=\"runbook_url\"\n helperText=\"Annotation key used to extract the runbook URL. Defaults to runbook_url.\"\n />\n </OptionsEditorGroup>\n </>\n );\n}\n"],"names":["Autocomplete","Checkbox","Chip","FormControlLabel","TextField","OptionsEditorGroup","produce","useCallback","ALL_ALERT_ACTIONS","ACTION_LABELS","silence","runbook","AlertTableOptionsEditor","props","value","onChange","effectiveActions","allowedActions","groupBy","defaultGroupBy","handleGroupByChange","_event","newValue","draft","length","undefined","handleRunbookKeyChange","e","trimmed","target","trim","runbookAnnotationKey","handleToggle","action","checked","current","includes","push","idx","indexOf","splice","title","multiple","freeSolo","options","renderTags","tagValues","getTagProps","map","option","index","key","rest","isVariable","label","size","variant","color","renderInput","params","placeholder","helperText","control","fullWidth"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { PanelProps } from '@perses-dev/plugin-system';
|
|
2
|
-
import { AlertsData } from '@perses-dev/spec';
|
|
3
|
-
import { ReactElement } from 'react';
|
|
4
|
-
import { AlertTableOptions } from './alert-table-model';
|
|
1
|
+
import type { PanelProps } from '@perses-dev/plugin-system';
|
|
2
|
+
import type { AlertsData } from '@perses-dev/spec';
|
|
3
|
+
import type { ReactElement } from 'react';
|
|
4
|
+
import type { AlertTableOptions } from './alert-table-model';
|
|
5
5
|
export type AlertTablePanelProps = PanelProps<AlertTableOptions, AlertsData>;
|
|
6
6
|
/**
|
|
7
7
|
* Alert hierarchical table panel component.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertTablePanel.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/AlertTablePanel.tsx"],"names":[],"mappings":"AAoCA,OAAO,
|
|
1
|
+
{"version":3,"file":"AlertTablePanel.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/AlertTablePanel.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAO5D,OAAO,KAAK,EAAS,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAS1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAQ1C,OAAO,KAAK,EAEV,iBAAiB,EAKlB,MAAM,qBAAqB,CAAC;AAiB7B,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC;AA6P7E;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,iBAAiB,EAAE,EAAE,oBAAoB,GAAG,YAAY,CAgX7G"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
1
|
// Copyright The Perses Authors
|
|
3
2
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
3
|
// you may not use this file except in compliance with the License.
|
|
@@ -11,24 +10,25 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
11
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
11
|
// See the License for the specific language governing permissions and
|
|
13
12
|
// limitations under the License.
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
|
+
import { Box, Chip, FormControl, IconButton, InputAdornment, InputLabel, MenuItem, Select, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TableSortLabel, TextField, Tooltip, Typography } from "@mui/material";
|
|
15
|
+
import { useSnackbar } from "@perses-dev/components";
|
|
16
|
+
import { parseVariables, replaceVariablesInString, useAllVariableValues, useDatasourceClient } from "@perses-dev/plugin-system";
|
|
17
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
18
|
+
import BellOffIcon from "mdi-material-ui/BellOff";
|
|
19
|
+
import BookOpenIcon from "mdi-material-ui/BookOpen";
|
|
20
|
+
import ChevronDownIcon from "mdi-material-ui/ChevronDown";
|
|
21
|
+
import ChevronRightIcon from "mdi-material-ui/ChevronRight";
|
|
22
|
+
import MagnifyIcon from "mdi-material-ui/Magnify";
|
|
23
|
+
import UnfoldLessHorizontalIcon from "mdi-material-ui/UnfoldLessHorizontal";
|
|
24
|
+
import UnfoldMoreHorizontalIcon from "mdi-material-ui/UnfoldMoreHorizontal";
|
|
25
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
26
|
+
import { SilenceForm } from "../../components/SilenceForm.js";
|
|
27
|
+
import { StatusBadge } from "../../components/StatusBadge.js";
|
|
28
|
+
import { extractDatasourceSelector } from "../../model/index.js";
|
|
29
|
+
import { ALL_ALERT_ACTIONS, deduplicateAlerts, extractLabelKeys, getGroupKey, getGroupSummary } from "./alert-table-model.js";
|
|
30
|
+
import { compareAlertsByColumn, compareGroupsByColumn, SORT_COL_ALERTNAME, SORT_COL_STATUS } from "./alert-table-sorting.js";
|
|
31
|
+
import { getLabelColor } from "./label-colors.js";
|
|
32
32
|
function GroupSummaryChips({ summary }) {
|
|
33
33
|
return /*#__PURE__*/ _jsxs(Stack, {
|
|
34
34
|
direction: "row",
|
|
@@ -60,7 +60,7 @@ function LabelValueSummaryChips({ summary, mapping }) {
|
|
|
60
60
|
return /*#__PURE__*/ _jsx(Stack, {
|
|
61
61
|
direction: "row",
|
|
62
62
|
spacing: 0.5,
|
|
63
|
-
children: Object.entries(counts).
|
|
63
|
+
children: Object.entries(counts).toSorted(([, a], [, b])=>b - a).map(([value, count])=>{
|
|
64
64
|
const bgColor = getLabelColor(value, mapping);
|
|
65
65
|
return /*#__PURE__*/ _jsx(Chip, {
|
|
66
66
|
label: `${count} ${value}`,
|
|
@@ -232,7 +232,7 @@ function AlertGroupRow({ group, expanded, allowedActions, columnDefs, columnKeyS
|
|
|
232
232
|
children: /*#__PURE__*/ _jsx(Stack, {
|
|
233
233
|
direction: "row",
|
|
234
234
|
spacing: 0.5,
|
|
235
|
-
children: Object.entries(counts).
|
|
235
|
+
children: Object.entries(counts).toSorted(([, a], [, b])=>b - a).map(([value, count])=>/*#__PURE__*/ _jsx(Chip, {
|
|
236
236
|
label: `${count} ${value}`,
|
|
237
237
|
size: "small",
|
|
238
238
|
variant: "outlined"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/plugins/alert-table/AlertTablePanel.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n Box,\n Chip,\n FormControl,\n IconButton,\n InputAdornment,\n InputLabel,\n MenuItem,\n Select,\n SelectChangeEvent,\n Stack,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n TableSortLabel,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport { useSnackbar } from '@perses-dev/components';\nimport {\n PanelProps,\n parseVariables,\n replaceVariablesInString,\n useAllVariableValues,\n useDatasourceClient,\n} from '@perses-dev/plugin-system';\nimport { Alert, AlertsData } from '@perses-dev/spec';\nimport { useQueryClient } from '@tanstack/react-query';\nimport BellOffIcon from 'mdi-material-ui/BellOff';\nimport BookOpenIcon from 'mdi-material-ui/BookOpen';\nimport ChevronDownIcon from 'mdi-material-ui/ChevronDown';\nimport ChevronRightIcon from 'mdi-material-ui/ChevronRight';\nimport MagnifyIcon from 'mdi-material-ui/Magnify';\nimport UnfoldLessHorizontalIcon from 'mdi-material-ui/UnfoldLessHorizontal';\nimport UnfoldMoreHorizontalIcon from 'mdi-material-ui/UnfoldMoreHorizontal';\nimport { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { SilenceForm } from '../../components/SilenceForm';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { AlertManagerClient, extractDatasourceSelector } from '../../model';\nimport { PostableSilence } from '../../model/api-types';\nimport {\n AlertAction,\n AlertTableOptions,\n ALL_ALERT_ACTIONS,\n ColumnDefinition,\n ColumnSortMode,\n deduplicateAlerts,\n extractLabelKeys,\n getGroupKey,\n getGroupSummary,\n GroupSummary,\n LabelColorMapping,\n} from './alert-table-model';\nimport {\n compareAlertsByColumn,\n compareGroupsByColumn,\n SORT_COL_ALERTNAME,\n SORT_COL_STATUS,\n SortState,\n} from './alert-table-sorting';\nimport { getLabelColor } from './label-colors';\n\nexport type AlertTablePanelProps = PanelProps<AlertTableOptions, AlertsData>;\n\ninterface AlertGroup {\n key: string;\n alerts: Alert[];\n summary: GroupSummary;\n}\n\nfunction GroupSummaryChips({ summary }: { summary: GroupSummary }): ReactElement {\n return (\n <Stack direction=\"row\" spacing={0.5}>\n {summary.firing > 0 && <Chip label={`${summary.firing} firing`} color=\"error\" size=\"small\" />}\n {summary.suppressed > 0 && <Chip label={`${summary.suppressed} silenced`} color=\"warning\" size=\"small\" />}\n {summary.pending > 0 && <Chip label={`${summary.pending} pending`} color=\"default\" size=\"small\" />}\n </Stack>\n );\n}\n\nfunction LabelValueSummaryChips({\n summary,\n mapping,\n}: {\n summary: GroupSummary;\n mapping: LabelColorMapping;\n}): ReactElement | null {\n const counts = summary.labelCounts?.[mapping.labelKey];\n if (!counts || Object.keys(counts).length === 0) {\n return null;\n }\n\n return (\n <Stack direction=\"row\" spacing={0.5}>\n {Object.entries(counts)\n .sort(([, a], [, b]) => b - a)\n .map(([value, count]) => {\n const bgColor = getLabelColor(value, mapping);\n return (\n <Chip\n key={value}\n label={`${count} ${value}`}\n size=\"small\"\n sx={{\n backgroundColor: bgColor,\n color: '#fff',\n fontWeight: 500,\n }}\n />\n );\n })}\n </Stack>\n );\n}\n\nfunction AlertRow({\n alert,\n allowedActions,\n columnDefs,\n columnKeySet,\n mappingsByKey,\n runbookAnnotationKey,\n onSilence,\n duplicateCount,\n showDuplicates,\n}: {\n alert: Alert;\n allowedActions: AlertAction[];\n columnDefs: ColumnDefinition[];\n columnKeySet: Set<string>;\n mappingsByKey: Map<string, LabelColorMapping>;\n runbookAnnotationKey: string;\n onSilence: (alert: Alert) => void;\n duplicateCount?: number;\n showDuplicates: boolean;\n}): ReactElement {\n const runbookUrl = alert.annotations?.[runbookAnnotationKey];\n const showActions = allowedActions.length > 0;\n\n return (\n <TableRow hover>\n <TableCell>\n <StatusBadge status={alert.suppressed ? 'suppressed' : alert.state} variant=\"alert\" />\n </TableCell>\n <TableCell>{alert.name}</TableCell>\n {columnDefs.map((col, colIdx) => {\n const value = alert.labels[col.name];\n const mapping = mappingsByKey.get(col.name);\n if (value !== undefined && mapping) {\n const bgColor = getLabelColor(value, mapping);\n return (\n <TableCell key={colIdx}>\n <Chip label={value} size=\"small\" sx={{ backgroundColor: bgColor, color: '#fff', fontWeight: 500 }} />\n </TableCell>\n );\n }\n return <TableCell key={colIdx}>{value ?? ''}</TableCell>;\n })}\n {showDuplicates && (\n <TableCell>\n {duplicateCount !== undefined && (\n <Chip label={`${duplicateCount}`} size=\"small\" variant=\"outlined\" color=\"info\" />\n )}\n </TableCell>\n )}\n <TableCell>\n <Stack direction=\"row\" spacing={0.5} flexWrap=\"wrap\" useFlexGap>\n {Object.entries(alert.labels)\n .filter(([key]) => key !== 'alertname' && !columnKeySet.has(key))\n .map(([key, value]) => {\n const mapping = mappingsByKey.get(key);\n if (mapping) {\n const bgColor = getLabelColor(value, mapping);\n return (\n <Chip\n key={key}\n label={`${key}=${value}`}\n size=\"small\"\n sx={{ backgroundColor: bgColor, color: '#fff', fontWeight: 500 }}\n />\n );\n }\n return <Chip key={key} label={`${key}=${value}`} size=\"small\" variant=\"outlined\" />;\n })}\n </Stack>\n </TableCell>\n {showActions && (\n <TableCell>\n <Stack direction=\"row\" spacing={0.5}>\n {allowedActions.includes('silence') && !alert.suppressed && (\n <Tooltip title=\"Silence this alert\">\n <IconButton size=\"small\" aria-label=\"Silence alert\" onClick={() => onSilence(alert)}>\n <BellOffIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n {allowedActions.includes('runbook') && runbookUrl && (\n <Tooltip title=\"View runbook\">\n <IconButton\n size=\"small\"\n aria-label=\"View runbook\"\n component=\"a\"\n href={runbookUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <BookOpenIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </Stack>\n </TableCell>\n )}\n </TableRow>\n );\n}\n\nfunction AlertGroupRow({\n group,\n expanded,\n allowedActions,\n columnDefs,\n columnKeySet,\n labelColorMappings,\n mappingsByKey,\n runbookAnnotationKey,\n onToggle,\n onSilence,\n duplicateCounts,\n showDuplicates,\n}: {\n group: AlertGroup;\n expanded: boolean;\n allowedActions: AlertAction[];\n columnDefs: ColumnDefinition[];\n columnKeySet: Set<string>;\n labelColorMappings: LabelColorMapping[];\n mappingsByKey: Map<string, LabelColorMapping>;\n runbookAnnotationKey: string;\n onToggle: () => void;\n onSilence: (alert: Alert) => void;\n duplicateCounts: Map<Alert, number>;\n showDuplicates: boolean;\n}): ReactElement {\n const showActions = allowedActions.length > 0;\n\n return (\n <>\n <TableRow sx={{ cursor: 'pointer', '& > td': { fontWeight: 'bold' } }} onClick={onToggle}>\n <TableCell colSpan={2}>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\">\n {expanded ? <ChevronDownIcon /> : <ChevronRightIcon />}\n <Typography variant=\"body2\" fontWeight=\"bold\">\n {group.key || 'Ungrouped'}\n </Typography>\n <Chip label={`${group.summary.total}`} size=\"small\" variant=\"outlined\" />\n </Stack>\n </TableCell>\n {columnDefs.map((col, colIdx) => {\n const counts = group.summary.labelCounts?.[col.name];\n const mapping = mappingsByKey.get(col.name);\n if (counts && mapping) {\n return (\n <TableCell key={colIdx}>\n <LabelValueSummaryChips summary={group.summary} mapping={mapping} />\n </TableCell>\n );\n }\n if (counts) {\n return (\n <TableCell key={colIdx}>\n <Stack direction=\"row\" spacing={0.5}>\n {Object.entries(counts)\n .sort(([, a], [, b]) => b - a)\n .map(([value, count]) => (\n <Chip key={value} label={`${count} ${value}`} size=\"small\" variant=\"outlined\" />\n ))}\n </Stack>\n </TableCell>\n );\n }\n return <TableCell key={colIdx} />;\n })}\n {showDuplicates && <TableCell />}\n <TableCell>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" flexWrap=\"wrap\" useFlexGap>\n <GroupSummaryChips summary={group.summary} />\n {labelColorMappings\n .filter((mapping) => !columnKeySet.has(mapping.labelKey))\n .map((mapping) => (\n <LabelValueSummaryChips key={mapping.labelKey} summary={group.summary} mapping={mapping} />\n ))}\n </Stack>\n </TableCell>\n {showActions && <TableCell />}\n </TableRow>\n {expanded &&\n group.alerts.map((alert, idx) => (\n <AlertRow\n key={alert.id ?? String(idx)}\n alert={alert}\n allowedActions={allowedActions}\n columnDefs={columnDefs}\n columnKeySet={columnKeySet}\n mappingsByKey={mappingsByKey}\n runbookAnnotationKey={runbookAnnotationKey}\n onSilence={onSilence}\n duplicateCount={duplicateCounts.get(alert)}\n showDuplicates={showDuplicates}\n />\n ))}\n </>\n );\n}\n\n/**\n * Alert hierarchical table panel component.\n * Displays alerts grouped by configurable labels with deduplication.\n */\nexport function AlertTablePanel({ spec, queryResults, contentDimensions }: AlertTablePanelProps): ReactElement {\n const datasourceSelector = useMemo(() => extractDatasourceSelector(queryResults), [queryResults]);\n const { data: amClient } = useDatasourceClient<AlertManagerClient>(datasourceSelector);\n const queryClient = useQueryClient();\n\n const [silenceTarget, setSilenceTarget] = useState<Alert | null>(null);\n const silenceKeyRef = useRef(0);\n const handleSetSilenceTarget = useCallback((alert: Alert) => {\n silenceKeyRef.current++;\n setSilenceTarget(alert);\n }, []);\n const [search, setSearch] = useState('');\n const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());\n const { successSnackbar, exceptionSnackbar } = useSnackbar();\n\n const handleSilenceSubmit = useCallback(\n async (silence: PostableSilence) => {\n if (!amClient) return;\n try {\n await amClient.createSilence(silence);\n setSilenceTarget(null);\n successSnackbar('Silence created successfully');\n queryClient.invalidateQueries({ queryKey: ['query', 'AlertsQuery'] });\n queryClient.invalidateQueries({ queryKey: ['query', 'SilencesQuery'] });\n } catch (err) {\n exceptionSnackbar(err);\n }\n },\n [amClient, queryClient, successSnackbar, exceptionSnackbar]\n );\n\n const silenceInitial = useMemo(() => {\n if (!silenceTarget) return undefined;\n return {\n matchers: Object.entries(silenceTarget.labels).map(([name, value]) => ({\n name,\n value,\n isEqual: true,\n isRegex: false,\n })),\n };\n }, [silenceTarget]);\n\n const defaultGroupBy = useMemo(() => spec.defaultGroupBy ?? ['alertname'], [spec.defaultGroupBy]);\n const variableNames = useMemo(\n () => [...new Set(defaultGroupBy.flatMap((entry) => parseVariables(entry)))],\n [defaultGroupBy]\n );\n const variableState = useAllVariableValues(variableNames);\n\n const resolvedDefaultGroupBy = useMemo(() => {\n const result: string[] = [];\n for (const entry of defaultGroupBy) {\n const vars = parseVariables(entry);\n if (vars.length === 0) {\n result.push(entry);\n } else if (vars.length === 1 && (entry === `$${vars[0]}` || entry === `\\${${vars[0]}}`)) {\n const varState = variableState[vars[0] ?? ''];\n if (varState?.value) {\n if (Array.isArray(varState.value)) {\n result.push(...varState.value);\n } else {\n result.push(varState.value);\n }\n }\n } else {\n const resolved = replaceVariablesInString(entry, variableState);\n if (resolved) result.push(resolved);\n }\n }\n return result;\n }, [defaultGroupBy, variableState]);\n\n const [groupBy, setGroupBy] = useState<string[]>(resolvedDefaultGroupBy);\n\n useEffect(() => {\n setGroupBy(resolvedDefaultGroupBy);\n }, [resolvedDefaultGroupBy]);\n\n const effectiveActions = useMemo<AlertAction[]>(\n () => spec.allowedActions ?? ALL_ALERT_ACTIONS,\n [spec.allowedActions]\n );\n const showActionsColumn = effectiveActions.length > 0;\n const runbookAnnotationKey = spec.runbookAnnotationKey || 'runbook_url';\n const columnDefs = useMemo(() => spec.columns ?? [], [spec.columns]);\n const columnKeySet = useMemo(() => new Set(columnDefs.map((c) => c.name)), [columnDefs]);\n const labelColorMappings = useMemo(() => spec.labelColorMappings ?? [], [spec.labelColorMappings]);\n const labelKeys = useMemo(() => labelColorMappings.map((m) => m.labelKey), [labelColorMappings]);\n const mappingsByKey = useMemo(() => new Map(labelColorMappings.map((m) => [m.labelKey, m])), [labelColorMappings]);\n\n const allTrackedKeys = useMemo(\n () => [...new Set([...labelKeys, ...columnDefs.map((c) => c.name)])],\n [labelKeys, columnDefs]\n );\n\n const initialSort = useMemo<SortState | null>(() => {\n const col = columnDefs.find((c) => c.sort && c.enableSorting !== false);\n if (!col?.sort) return null;\n return { columnName: col.name, direction: col.sort, mode: col.sortMode ?? 'alphabetical' };\n }, [columnDefs]);\n const [sortState, setSortState] = useState<SortState | null>(initialSort);\n\n const handleSortClick = useCallback((columnName: string, sortMode: ColumnSortMode = 'alphabetical'): void => {\n setSortState((prev) => {\n if (prev?.columnName === columnName) {\n return prev.direction === 'asc' ? { ...prev, direction: 'desc' } : null;\n }\n return { columnName, direction: 'asc', mode: sortMode };\n });\n }, []);\n\n // Flatten all alerts from all query results\n const allAlerts = useMemo(() => {\n return queryResults.flatMap((result) => result.data?.alerts ?? []);\n }, [queryResults]);\n\n // Deduplicate\n const dedupConfig = useMemo(() => spec.deduplication ?? { mode: 'fingerprint' as const }, [spec.deduplication]);\n const dedupResult = useMemo(() => deduplicateAlerts(allAlerts, dedupConfig), [allAlerts, dedupConfig]);\n const dedupAlerts = dedupResult.alerts;\n const duplicateCounts = dedupResult.duplicateCounts;\n const hasDuplicates = duplicateCounts.size > 0;\n\n // Filter by search term\n const alerts = useMemo(() => {\n const term = search.trim().toLowerCase();\n if (!term) return dedupAlerts;\n return dedupAlerts.filter((a: Alert) => {\n if (a.state.toLowerCase().includes(term)) return true;\n if (a.suppressed && ('suppressed'.includes(term) || 'silenced'.includes(term))) return true;\n if (Object.values(a.labels).some((v) => v.toLowerCase().includes(term))) return true;\n if (a.annotations && Object.values(a.annotations).some((v) => v.toLowerCase().includes(term))) return true;\n return false;\n });\n }, [dedupAlerts, search]);\n\n // Extract available label keys for group-by selector\n const availableLabelKeys = useMemo(() => extractLabelKeys(alerts), [alerts]);\n\n // Group alerts\n const groups = useMemo<AlertGroup[]>(() => {\n let result: AlertGroup[];\n\n if (groupBy.length === 0) {\n result = [{ key: '', alerts: [...alerts], summary: getGroupSummary(alerts, allTrackedKeys) }];\n } else {\n const groupMap = new Map<string, Alert[]>();\n for (const alert of alerts) {\n const key = getGroupKey(alert, groupBy);\n const existing = groupMap.get(key) ?? [];\n existing.push(alert);\n groupMap.set(key, existing);\n }\n\n result = Array.from(groupMap.entries()).map(([key, groupAlerts]) => ({\n key,\n alerts: groupAlerts,\n summary: getGroupSummary(groupAlerts, allTrackedKeys),\n }));\n }\n\n if (sortState) {\n for (const group of result) {\n group.alerts.sort((a, b) => compareAlertsByColumn(a, b, sortState));\n }\n result.sort((a, b) =>\n compareGroupsByColumn(\n a.summary.labelCounts?.[sortState.columnName],\n b.summary.labelCounts?.[sortState.columnName],\n sortState\n )\n );\n }\n\n return result;\n }, [alerts, groupBy, allTrackedKeys, sortState]);\n\n const prevGroupKeysRef = useRef<string>('');\n useEffect(() => {\n const currentKeys = groups.map((g) => g.key).join('\\0');\n if (currentKeys === prevGroupKeysRef.current) return;\n prevGroupKeysRef.current = currentKeys;\n\n if (groups.length === 1) {\n setExpandedGroups(new Set(groups.map((g) => g.key)));\n } else {\n setExpandedGroups(new Set());\n }\n }, [groups]);\n\n const handleToggleGroup = useCallback((key: string) => {\n setExpandedGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) {\n next.delete(key);\n } else {\n next.add(key);\n }\n return next;\n });\n }, []);\n\n const handleExpandAll = useCallback(() => {\n setExpandedGroups(new Set(groups.map((g) => g.key)));\n }, [groups]);\n\n const handleCollapseAll = useCallback(() => {\n setExpandedGroups(new Set());\n }, []);\n\n const handleGroupByChange = (event: SelectChangeEvent<string[]>): void => {\n const value = event.target.value;\n setGroupBy(typeof value === 'string' ? value.split(',') : value);\n };\n\n if (allAlerts.length === 0) {\n return (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: contentDimensions?.height ?? '100%',\n }}\n >\n <Typography>No alerts to display</Typography>\n </Box>\n );\n }\n\n return (\n <Stack spacing={1} sx={{ height: contentDimensions?.height, overflow: 'auto' }}>\n <Stack direction=\"row\" spacing={2} alignItems=\"center\" sx={{ px: 1, pt: 1 }}>\n <TextField\n size=\"small\"\n placeholder=\"Search alerts...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n sx={{ minWidth: 200 }}\n slotProps={{\n htmlInput: { 'aria-label': 'Search alerts' },\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <MagnifyIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n },\n }}\n />\n <FormControl size=\"small\" sx={{ minWidth: 200 }}>\n <InputLabel id=\"group-by-label\">Group by</InputLabel>\n <Select\n labelId=\"group-by-label\"\n multiple\n value={groupBy}\n onChange={handleGroupByChange}\n label=\"Group by\"\n renderValue={(selected) => selected.join(', ')}\n >\n {availableLabelKeys.map((key) => (\n <MenuItem key={key} value={key}>\n {key}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ flexGrow: 1 }}>\n {alerts.length} alert{alerts.length !== 1 ? 's' : ''} in {groups.length} group\n {groups.length !== 1 ? 's' : ''}\n </Typography>\n <Stack direction=\"row\" spacing={0.5}>\n <Tooltip title=\"Expand all groups\">\n <IconButton size=\"small\" aria-label=\"Expand all groups\" onClick={handleExpandAll}>\n <UnfoldMoreHorizontalIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Collapse all groups\">\n <IconButton size=\"small\" aria-label=\"Collapse all groups\" onClick={handleCollapseAll}>\n <UnfoldLessHorizontalIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Stack>\n </Stack>\n <TableContainer>\n <Table size=\"small\" stickyHeader>\n <TableHead>\n <TableRow>\n <TableCell sortDirection={sortState?.columnName === SORT_COL_STATUS ? sortState.direction : false}>\n <TableSortLabel\n active={sortState?.columnName === SORT_COL_STATUS}\n direction={sortState?.columnName === SORT_COL_STATUS ? sortState.direction : 'asc'}\n onClick={() => handleSortClick(SORT_COL_STATUS, 'status')}\n >\n Status\n </TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortState?.columnName === SORT_COL_ALERTNAME ? sortState.direction : false}>\n <TableSortLabel\n active={sortState?.columnName === SORT_COL_ALERTNAME}\n direction={sortState?.columnName === SORT_COL_ALERTNAME ? sortState.direction : 'asc'}\n onClick={() => handleSortClick(SORT_COL_ALERTNAME, 'alphabetical')}\n >\n Alert Name\n </TableSortLabel>\n </TableCell>\n {columnDefs.map((col, colIdx) => (\n <TableCell\n key={colIdx}\n sortDirection={sortState?.columnName === col.name ? sortState.direction : false}\n >\n {col.enableSorting !== false ? (\n <TableSortLabel\n active={sortState?.columnName === col.name}\n direction={sortState?.columnName === col.name ? sortState.direction : 'asc'}\n onClick={() => handleSortClick(col.name, col.sortMode)}\n >\n {col.header ?? col.name}\n </TableSortLabel>\n ) : (\n (col.header ?? col.name)\n )}\n </TableCell>\n ))}\n {hasDuplicates && <TableCell>Duplicates</TableCell>}\n <TableCell>Labels</TableCell>\n {showActionsColumn && <TableCell>Actions</TableCell>}\n </TableRow>\n </TableHead>\n <TableBody>\n {alerts.length === 0 ? (\n <TableRow>\n <TableCell colSpan={99} align=\"center\" sx={{ py: 4 }}>\n <Typography color=\"text.secondary\">No matching alerts</Typography>\n </TableCell>\n </TableRow>\n ) : (\n groups.map((group) => (\n <AlertGroupRow\n key={group.key}\n group={group}\n expanded={expandedGroups.has(group.key)}\n allowedActions={effectiveActions}\n columnDefs={columnDefs}\n columnKeySet={columnKeySet}\n labelColorMappings={labelColorMappings}\n mappingsByKey={mappingsByKey}\n runbookAnnotationKey={runbookAnnotationKey}\n onToggle={() => handleToggleGroup(group.key)}\n onSilence={handleSetSilenceTarget}\n duplicateCounts={duplicateCounts}\n showDuplicates={hasDuplicates}\n />\n ))\n )}\n </TableBody>\n </Table>\n </TableContainer>\n <SilenceForm\n key={silenceKeyRef.current}\n open={!!silenceTarget}\n onClose={() => setSilenceTarget(null)}\n onSubmit={handleSilenceSubmit}\n initialSilence={silenceInitial}\n />\n </Stack>\n );\n}\n"],"names":["Box","Chip","FormControl","IconButton","InputAdornment","InputLabel","MenuItem","Select","Stack","Table","TableBody","TableCell","TableContainer","TableHead","TableRow","TableSortLabel","TextField","Tooltip","Typography","useSnackbar","parseVariables","replaceVariablesInString","useAllVariableValues","useDatasourceClient","useQueryClient","BellOffIcon","BookOpenIcon","ChevronDownIcon","ChevronRightIcon","MagnifyIcon","UnfoldLessHorizontalIcon","UnfoldMoreHorizontalIcon","useCallback","useEffect","useMemo","useRef","useState","SilenceForm","StatusBadge","extractDatasourceSelector","ALL_ALERT_ACTIONS","deduplicateAlerts","extractLabelKeys","getGroupKey","getGroupSummary","compareAlertsByColumn","compareGroupsByColumn","SORT_COL_ALERTNAME","SORT_COL_STATUS","getLabelColor","GroupSummaryChips","summary","direction","spacing","firing","label","color","size","suppressed","pending","LabelValueSummaryChips","mapping","counts","labelCounts","labelKey","Object","keys","length","entries","sort","a","b","map","value","count","bgColor","sx","backgroundColor","fontWeight","AlertRow","alert","allowedActions","columnDefs","columnKeySet","mappingsByKey","runbookAnnotationKey","onSilence","duplicateCount","showDuplicates","runbookUrl","annotations","showActions","hover","status","state","variant","name","col","colIdx","labels","get","undefined","flexWrap","useFlexGap","filter","key","has","includes","title","aria-label","onClick","fontSize","component","href","target","rel","AlertGroupRow","group","expanded","labelColorMappings","onToggle","duplicateCounts","cursor","colSpan","alignItems","total","alerts","idx","id","String","AlertTablePanel","spec","queryResults","contentDimensions","datasourceSelector","data","amClient","queryClient","silenceTarget","setSilenceTarget","silenceKeyRef","handleSetSilenceTarget","current","search","setSearch","expandedGroups","setExpandedGroups","Set","successSnackbar","exceptionSnackbar","handleSilenceSubmit","silence","createSilence","invalidateQueries","queryKey","err","silenceInitial","matchers","isEqual","isRegex","defaultGroupBy","variableNames","flatMap","entry","variableState","resolvedDefaultGroupBy","result","vars","push","varState","Array","isArray","resolved","groupBy","setGroupBy","effectiveActions","showActionsColumn","columns","c","labelKeys","m","Map","allTrackedKeys","initialSort","find","enableSorting","columnName","mode","sortMode","sortState","setSortState","handleSortClick","prev","allAlerts","dedupConfig","deduplication","dedupResult","dedupAlerts","hasDuplicates","term","trim","toLowerCase","values","some","v","availableLabelKeys","groups","groupMap","existing","set","from","groupAlerts","prevGroupKeysRef","currentKeys","g","join","handleToggleGroup","next","delete","add","handleExpandAll","handleCollapseAll","handleGroupByChange","event","split","display","justifyContent","height","overflow","px","pt","placeholder","onChange","e","minWidth","slotProps","htmlInput","input","startAdornment","position","labelId","multiple","renderValue","selected","flexGrow","stickyHeader","sortDirection","active","header","align","py","open","onClose","onSubmit","initialSilence"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/plugins/alert-table/AlertTablePanel.tsx"],"sourcesContent":["// Copyright The Perses Authors\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 type { SelectChangeEvent } from '@mui/material';\nimport {\n Box,\n Chip,\n FormControl,\n IconButton,\n InputAdornment,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n TableSortLabel,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport { useSnackbar } from '@perses-dev/components';\nimport type { PanelProps } from '@perses-dev/plugin-system';\nimport {\n parseVariables,\n replaceVariablesInString,\n useAllVariableValues,\n useDatasourceClient,\n} from '@perses-dev/plugin-system';\nimport type { Alert, AlertsData } from '@perses-dev/spec';\nimport { useQueryClient } from '@tanstack/react-query';\nimport BellOffIcon from 'mdi-material-ui/BellOff';\nimport BookOpenIcon from 'mdi-material-ui/BookOpen';\nimport ChevronDownIcon from 'mdi-material-ui/ChevronDown';\nimport ChevronRightIcon from 'mdi-material-ui/ChevronRight';\nimport MagnifyIcon from 'mdi-material-ui/Magnify';\nimport UnfoldLessHorizontalIcon from 'mdi-material-ui/UnfoldLessHorizontal';\nimport UnfoldMoreHorizontalIcon from 'mdi-material-ui/UnfoldMoreHorizontal';\nimport type { ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { SilenceForm } from '../../components/SilenceForm';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport type { AlertManagerClient } from '../../model';\nimport { extractDatasourceSelector } from '../../model';\nimport type { PostableSilence } from '../../model/api-types';\nimport type {\n AlertAction,\n AlertTableOptions,\n ColumnDefinition,\n ColumnSortMode,\n GroupSummary,\n LabelColorMapping,\n} from './alert-table-model';\nimport {\n ALL_ALERT_ACTIONS,\n deduplicateAlerts,\n extractLabelKeys,\n getGroupKey,\n getGroupSummary,\n} from './alert-table-model';\nimport type { SortState } from './alert-table-sorting';\nimport {\n compareAlertsByColumn,\n compareGroupsByColumn,\n SORT_COL_ALERTNAME,\n SORT_COL_STATUS,\n} from './alert-table-sorting';\nimport { getLabelColor } from './label-colors';\n\nexport type AlertTablePanelProps = PanelProps<AlertTableOptions, AlertsData>;\n\ninterface AlertGroup {\n key: string;\n alerts: Alert[];\n summary: GroupSummary;\n}\n\nfunction GroupSummaryChips({ summary }: { summary: GroupSummary }): ReactElement {\n return (\n <Stack direction=\"row\" spacing={0.5}>\n {summary.firing > 0 && <Chip label={`${summary.firing} firing`} color=\"error\" size=\"small\" />}\n {summary.suppressed > 0 && <Chip label={`${summary.suppressed} silenced`} color=\"warning\" size=\"small\" />}\n {summary.pending > 0 && <Chip label={`${summary.pending} pending`} color=\"default\" size=\"small\" />}\n </Stack>\n );\n}\n\nfunction LabelValueSummaryChips({\n summary,\n mapping,\n}: {\n summary: GroupSummary;\n mapping: LabelColorMapping;\n}): ReactElement | null {\n const counts = summary.labelCounts?.[mapping.labelKey];\n if (!counts || Object.keys(counts).length === 0) {\n return null;\n }\n\n return (\n <Stack direction=\"row\" spacing={0.5}>\n {Object.entries(counts)\n .toSorted(([, a], [, b]) => b - a)\n .map(([value, count]) => {\n const bgColor = getLabelColor(value, mapping);\n return (\n <Chip\n key={value}\n label={`${count} ${value}`}\n size=\"small\"\n sx={{\n backgroundColor: bgColor,\n color: '#fff',\n fontWeight: 500,\n }}\n />\n );\n })}\n </Stack>\n );\n}\n\nfunction AlertRow({\n alert,\n allowedActions,\n columnDefs,\n columnKeySet,\n mappingsByKey,\n runbookAnnotationKey,\n onSilence,\n duplicateCount,\n showDuplicates,\n}: {\n alert: Alert;\n allowedActions: AlertAction[];\n columnDefs: ColumnDefinition[];\n columnKeySet: Set<string>;\n mappingsByKey: Map<string, LabelColorMapping>;\n runbookAnnotationKey: string;\n onSilence: (alert: Alert) => void;\n duplicateCount?: number;\n showDuplicates: boolean;\n}): ReactElement {\n const runbookUrl = alert.annotations?.[runbookAnnotationKey];\n const showActions = allowedActions.length > 0;\n\n return (\n <TableRow hover>\n <TableCell>\n <StatusBadge status={alert.suppressed ? 'suppressed' : alert.state} variant=\"alert\" />\n </TableCell>\n <TableCell>{alert.name}</TableCell>\n {columnDefs.map((col, colIdx) => {\n const value = alert.labels[col.name];\n const mapping = mappingsByKey.get(col.name);\n if (value !== undefined && mapping) {\n const bgColor = getLabelColor(value, mapping);\n return (\n <TableCell key={colIdx}>\n <Chip label={value} size=\"small\" sx={{ backgroundColor: bgColor, color: '#fff', fontWeight: 500 }} />\n </TableCell>\n );\n }\n return <TableCell key={colIdx}>{value ?? ''}</TableCell>;\n })}\n {showDuplicates && (\n <TableCell>\n {duplicateCount !== undefined && (\n <Chip label={`${duplicateCount}`} size=\"small\" variant=\"outlined\" color=\"info\" />\n )}\n </TableCell>\n )}\n <TableCell>\n <Stack direction=\"row\" spacing={0.5} flexWrap=\"wrap\" useFlexGap>\n {Object.entries(alert.labels)\n .filter(([key]) => key !== 'alertname' && !columnKeySet.has(key))\n .map(([key, value]) => {\n const mapping = mappingsByKey.get(key);\n if (mapping) {\n const bgColor = getLabelColor(value, mapping);\n return (\n <Chip\n key={key}\n label={`${key}=${value}`}\n size=\"small\"\n sx={{ backgroundColor: bgColor, color: '#fff', fontWeight: 500 }}\n />\n );\n }\n return <Chip key={key} label={`${key}=${value}`} size=\"small\" variant=\"outlined\" />;\n })}\n </Stack>\n </TableCell>\n {showActions && (\n <TableCell>\n <Stack direction=\"row\" spacing={0.5}>\n {allowedActions.includes('silence') && !alert.suppressed && (\n <Tooltip title=\"Silence this alert\">\n <IconButton size=\"small\" aria-label=\"Silence alert\" onClick={() => onSilence(alert)}>\n <BellOffIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n {allowedActions.includes('runbook') && runbookUrl && (\n <Tooltip title=\"View runbook\">\n <IconButton\n size=\"small\"\n aria-label=\"View runbook\"\n component=\"a\"\n href={runbookUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <BookOpenIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </Stack>\n </TableCell>\n )}\n </TableRow>\n );\n}\n\nfunction AlertGroupRow({\n group,\n expanded,\n allowedActions,\n columnDefs,\n columnKeySet,\n labelColorMappings,\n mappingsByKey,\n runbookAnnotationKey,\n onToggle,\n onSilence,\n duplicateCounts,\n showDuplicates,\n}: {\n group: AlertGroup;\n expanded: boolean;\n allowedActions: AlertAction[];\n columnDefs: ColumnDefinition[];\n columnKeySet: Set<string>;\n labelColorMappings: LabelColorMapping[];\n mappingsByKey: Map<string, LabelColorMapping>;\n runbookAnnotationKey: string;\n onToggle: () => void;\n onSilence: (alert: Alert) => void;\n duplicateCounts: Map<Alert, number>;\n showDuplicates: boolean;\n}): ReactElement {\n const showActions = allowedActions.length > 0;\n\n return (\n <>\n <TableRow sx={{ cursor: 'pointer', '& > td': { fontWeight: 'bold' } }} onClick={onToggle}>\n <TableCell colSpan={2}>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\">\n {expanded ? <ChevronDownIcon /> : <ChevronRightIcon />}\n <Typography variant=\"body2\" fontWeight=\"bold\">\n {group.key || 'Ungrouped'}\n </Typography>\n <Chip label={`${group.summary.total}`} size=\"small\" variant=\"outlined\" />\n </Stack>\n </TableCell>\n {columnDefs.map((col, colIdx) => {\n const counts = group.summary.labelCounts?.[col.name];\n const mapping = mappingsByKey.get(col.name);\n if (counts && mapping) {\n return (\n <TableCell key={colIdx}>\n <LabelValueSummaryChips summary={group.summary} mapping={mapping} />\n </TableCell>\n );\n }\n if (counts) {\n return (\n <TableCell key={colIdx}>\n <Stack direction=\"row\" spacing={0.5}>\n {Object.entries(counts)\n .toSorted(([, a], [, b]) => b - a)\n .map(([value, count]) => (\n <Chip key={value} label={`${count} ${value}`} size=\"small\" variant=\"outlined\" />\n ))}\n </Stack>\n </TableCell>\n );\n }\n return <TableCell key={colIdx} />;\n })}\n {showDuplicates && <TableCell />}\n <TableCell>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" flexWrap=\"wrap\" useFlexGap>\n <GroupSummaryChips summary={group.summary} />\n {labelColorMappings\n .filter((mapping) => !columnKeySet.has(mapping.labelKey))\n .map((mapping) => (\n <LabelValueSummaryChips key={mapping.labelKey} summary={group.summary} mapping={mapping} />\n ))}\n </Stack>\n </TableCell>\n {showActions && <TableCell />}\n </TableRow>\n {expanded &&\n group.alerts.map((alert, idx) => (\n <AlertRow\n key={alert.id ?? String(idx)}\n alert={alert}\n allowedActions={allowedActions}\n columnDefs={columnDefs}\n columnKeySet={columnKeySet}\n mappingsByKey={mappingsByKey}\n runbookAnnotationKey={runbookAnnotationKey}\n onSilence={onSilence}\n duplicateCount={duplicateCounts.get(alert)}\n showDuplicates={showDuplicates}\n />\n ))}\n </>\n );\n}\n\n/**\n * Alert hierarchical table panel component.\n * Displays alerts grouped by configurable labels with deduplication.\n */\nexport function AlertTablePanel({ spec, queryResults, contentDimensions }: AlertTablePanelProps): ReactElement {\n const datasourceSelector = useMemo(() => extractDatasourceSelector(queryResults), [queryResults]);\n const { data: amClient } = useDatasourceClient<AlertManagerClient>(datasourceSelector);\n const queryClient = useQueryClient();\n\n const [silenceTarget, setSilenceTarget] = useState<Alert | null>(null);\n const silenceKeyRef = useRef(0);\n const handleSetSilenceTarget = useCallback((alert: Alert) => {\n silenceKeyRef.current++;\n setSilenceTarget(alert);\n }, []);\n const [search, setSearch] = useState('');\n const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());\n const { successSnackbar, exceptionSnackbar } = useSnackbar();\n\n const handleSilenceSubmit = useCallback(\n async (silence: PostableSilence) => {\n if (!amClient) return;\n try {\n await amClient.createSilence(silence);\n setSilenceTarget(null);\n successSnackbar('Silence created successfully');\n queryClient.invalidateQueries({ queryKey: ['query', 'AlertsQuery'] });\n queryClient.invalidateQueries({ queryKey: ['query', 'SilencesQuery'] });\n } catch (err) {\n exceptionSnackbar(err);\n }\n },\n [amClient, queryClient, successSnackbar, exceptionSnackbar],\n );\n\n const silenceInitial = useMemo(() => {\n if (!silenceTarget) return undefined;\n return {\n matchers: Object.entries(silenceTarget.labels).map(([name, value]) => ({\n name,\n value,\n isEqual: true,\n isRegex: false,\n })),\n };\n }, [silenceTarget]);\n\n const defaultGroupBy = useMemo(() => spec.defaultGroupBy ?? ['alertname'], [spec.defaultGroupBy]);\n const variableNames = useMemo(\n () => [...new Set(defaultGroupBy.flatMap((entry) => parseVariables(entry)))],\n [defaultGroupBy],\n );\n const variableState = useAllVariableValues(variableNames);\n\n const resolvedDefaultGroupBy = useMemo(() => {\n const result: string[] = [];\n for (const entry of defaultGroupBy) {\n const vars = parseVariables(entry);\n if (vars.length === 0) {\n result.push(entry);\n } else if (vars.length === 1 && (entry === `$${vars[0]}` || entry === `\\${${vars[0]}}`)) {\n const varState = variableState[vars[0] ?? ''];\n if (varState?.value) {\n if (Array.isArray(varState.value)) {\n result.push(...varState.value);\n } else {\n result.push(varState.value);\n }\n }\n } else {\n const resolved = replaceVariablesInString(entry, variableState);\n if (resolved) result.push(resolved);\n }\n }\n return result;\n }, [defaultGroupBy, variableState]);\n\n const [groupBy, setGroupBy] = useState<string[]>(resolvedDefaultGroupBy);\n\n useEffect(() => {\n setGroupBy(resolvedDefaultGroupBy);\n }, [resolvedDefaultGroupBy]);\n\n const effectiveActions = useMemo<AlertAction[]>(\n () => spec.allowedActions ?? ALL_ALERT_ACTIONS,\n [spec.allowedActions],\n );\n const showActionsColumn = effectiveActions.length > 0;\n const runbookAnnotationKey = spec.runbookAnnotationKey || 'runbook_url';\n const columnDefs = useMemo(() => spec.columns ?? [], [spec.columns]);\n const columnKeySet = useMemo(() => new Set(columnDefs.map((c) => c.name)), [columnDefs]);\n const labelColorMappings = useMemo(() => spec.labelColorMappings ?? [], [spec.labelColorMappings]);\n const labelKeys = useMemo(() => labelColorMappings.map((m) => m.labelKey), [labelColorMappings]);\n const mappingsByKey = useMemo(() => new Map(labelColorMappings.map((m) => [m.labelKey, m])), [labelColorMappings]);\n\n const allTrackedKeys = useMemo(\n () => [...new Set([...labelKeys, ...columnDefs.map((c) => c.name)])],\n [labelKeys, columnDefs],\n );\n\n const initialSort = useMemo<SortState | null>(() => {\n const col = columnDefs.find((c) => c.sort && c.enableSorting !== false);\n if (!col?.sort) return null;\n return { columnName: col.name, direction: col.sort, mode: col.sortMode ?? 'alphabetical' };\n }, [columnDefs]);\n const [sortState, setSortState] = useState<SortState | null>(initialSort);\n\n const handleSortClick = useCallback((columnName: string, sortMode: ColumnSortMode = 'alphabetical'): void => {\n setSortState((prev) => {\n if (prev?.columnName === columnName) {\n return prev.direction === 'asc' ? { ...prev, direction: 'desc' } : null;\n }\n return { columnName, direction: 'asc', mode: sortMode };\n });\n }, []);\n\n // Flatten all alerts from all query results\n const allAlerts = useMemo(() => {\n return queryResults.flatMap((result) => result.data?.alerts ?? []);\n }, [queryResults]);\n\n // Deduplicate\n const dedupConfig = useMemo(() => spec.deduplication ?? { mode: 'fingerprint' as const }, [spec.deduplication]);\n const dedupResult = useMemo(() => deduplicateAlerts(allAlerts, dedupConfig), [allAlerts, dedupConfig]);\n const dedupAlerts = dedupResult.alerts;\n const duplicateCounts = dedupResult.duplicateCounts;\n const hasDuplicates = duplicateCounts.size > 0;\n\n // Filter by search term\n const alerts = useMemo(() => {\n const term = search.trim().toLowerCase();\n if (!term) return dedupAlerts;\n return dedupAlerts.filter((a: Alert) => {\n if (a.state.toLowerCase().includes(term)) return true;\n if (a.suppressed && ('suppressed'.includes(term) || 'silenced'.includes(term))) return true;\n if (Object.values(a.labels).some((v) => v.toLowerCase().includes(term))) return true;\n if (a.annotations && Object.values(a.annotations).some((v) => v.toLowerCase().includes(term))) return true;\n return false;\n });\n }, [dedupAlerts, search]);\n\n // Extract available label keys for group-by selector\n const availableLabelKeys = useMemo(() => extractLabelKeys(alerts), [alerts]);\n\n // Group alerts\n const groups = useMemo<AlertGroup[]>(() => {\n let result: AlertGroup[];\n\n if (groupBy.length === 0) {\n result = [{ key: '', alerts: [...alerts], summary: getGroupSummary(alerts, allTrackedKeys) }];\n } else {\n const groupMap = new Map<string, Alert[]>();\n for (const alert of alerts) {\n const key = getGroupKey(alert, groupBy);\n const existing = groupMap.get(key) ?? [];\n existing.push(alert);\n groupMap.set(key, existing);\n }\n\n result = Array.from(groupMap.entries()).map(([key, groupAlerts]) => ({\n key,\n alerts: groupAlerts,\n summary: getGroupSummary(groupAlerts, allTrackedKeys),\n }));\n }\n\n if (sortState) {\n for (const group of result) {\n group.alerts.sort((a, b) => compareAlertsByColumn(a, b, sortState));\n }\n result.sort((a, b) =>\n compareGroupsByColumn(\n a.summary.labelCounts?.[sortState.columnName],\n b.summary.labelCounts?.[sortState.columnName],\n sortState,\n ),\n );\n }\n\n return result;\n }, [alerts, groupBy, allTrackedKeys, sortState]);\n\n const prevGroupKeysRef = useRef<string>('');\n useEffect(() => {\n const currentKeys = groups.map((g) => g.key).join('\\0');\n if (currentKeys === prevGroupKeysRef.current) return;\n prevGroupKeysRef.current = currentKeys;\n\n if (groups.length === 1) {\n setExpandedGroups(new Set(groups.map((g) => g.key)));\n } else {\n setExpandedGroups(new Set());\n }\n }, [groups]);\n\n const handleToggleGroup = useCallback((key: string) => {\n setExpandedGroups((prev) => {\n const next = new Set(prev);\n if (next.has(key)) {\n next.delete(key);\n } else {\n next.add(key);\n }\n return next;\n });\n }, []);\n\n const handleExpandAll = useCallback(() => {\n setExpandedGroups(new Set(groups.map((g) => g.key)));\n }, [groups]);\n\n const handleCollapseAll = useCallback(() => {\n setExpandedGroups(new Set());\n }, []);\n\n const handleGroupByChange = (event: SelectChangeEvent<string[]>): void => {\n const value = event.target.value;\n setGroupBy(typeof value === 'string' ? value.split(',') : value);\n };\n\n if (allAlerts.length === 0) {\n return (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: contentDimensions?.height ?? '100%',\n }}\n >\n <Typography>No alerts to display</Typography>\n </Box>\n );\n }\n\n return (\n <Stack spacing={1} sx={{ height: contentDimensions?.height, overflow: 'auto' }}>\n <Stack direction=\"row\" spacing={2} alignItems=\"center\" sx={{ px: 1, pt: 1 }}>\n <TextField\n size=\"small\"\n placeholder=\"Search alerts...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n sx={{ minWidth: 200 }}\n slotProps={{\n htmlInput: { 'aria-label': 'Search alerts' },\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <MagnifyIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n },\n }}\n />\n <FormControl size=\"small\" sx={{ minWidth: 200 }}>\n <InputLabel id=\"group-by-label\">Group by</InputLabel>\n <Select\n labelId=\"group-by-label\"\n multiple\n value={groupBy}\n onChange={handleGroupByChange}\n label=\"Group by\"\n renderValue={(selected) => selected.join(', ')}\n >\n {availableLabelKeys.map((key) => (\n <MenuItem key={key} value={key}>\n {key}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ flexGrow: 1 }}>\n {alerts.length} alert{alerts.length !== 1 ? 's' : ''} in {groups.length} group\n {groups.length !== 1 ? 's' : ''}\n </Typography>\n <Stack direction=\"row\" spacing={0.5}>\n <Tooltip title=\"Expand all groups\">\n <IconButton size=\"small\" aria-label=\"Expand all groups\" onClick={handleExpandAll}>\n <UnfoldMoreHorizontalIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Collapse all groups\">\n <IconButton size=\"small\" aria-label=\"Collapse all groups\" onClick={handleCollapseAll}>\n <UnfoldLessHorizontalIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Stack>\n </Stack>\n <TableContainer>\n <Table size=\"small\" stickyHeader>\n <TableHead>\n <TableRow>\n <TableCell sortDirection={sortState?.columnName === SORT_COL_STATUS ? sortState.direction : false}>\n <TableSortLabel\n active={sortState?.columnName === SORT_COL_STATUS}\n direction={sortState?.columnName === SORT_COL_STATUS ? sortState.direction : 'asc'}\n onClick={() => handleSortClick(SORT_COL_STATUS, 'status')}\n >\n Status\n </TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortState?.columnName === SORT_COL_ALERTNAME ? sortState.direction : false}>\n <TableSortLabel\n active={sortState?.columnName === SORT_COL_ALERTNAME}\n direction={sortState?.columnName === SORT_COL_ALERTNAME ? sortState.direction : 'asc'}\n onClick={() => handleSortClick(SORT_COL_ALERTNAME, 'alphabetical')}\n >\n Alert Name\n </TableSortLabel>\n </TableCell>\n {columnDefs.map((col, colIdx) => (\n <TableCell\n key={colIdx}\n sortDirection={sortState?.columnName === col.name ? sortState.direction : false}\n >\n {col.enableSorting !== false ? (\n <TableSortLabel\n active={sortState?.columnName === col.name}\n direction={sortState?.columnName === col.name ? sortState.direction : 'asc'}\n onClick={() => handleSortClick(col.name, col.sortMode)}\n >\n {col.header ?? col.name}\n </TableSortLabel>\n ) : (\n (col.header ?? col.name)\n )}\n </TableCell>\n ))}\n {hasDuplicates && <TableCell>Duplicates</TableCell>}\n <TableCell>Labels</TableCell>\n {showActionsColumn && <TableCell>Actions</TableCell>}\n </TableRow>\n </TableHead>\n <TableBody>\n {alerts.length === 0 ? (\n <TableRow>\n <TableCell colSpan={99} align=\"center\" sx={{ py: 4 }}>\n <Typography color=\"text.secondary\">No matching alerts</Typography>\n </TableCell>\n </TableRow>\n ) : (\n groups.map((group) => (\n <AlertGroupRow\n key={group.key}\n group={group}\n expanded={expandedGroups.has(group.key)}\n allowedActions={effectiveActions}\n columnDefs={columnDefs}\n columnKeySet={columnKeySet}\n labelColorMappings={labelColorMappings}\n mappingsByKey={mappingsByKey}\n runbookAnnotationKey={runbookAnnotationKey}\n onToggle={() => handleToggleGroup(group.key)}\n onSilence={handleSetSilenceTarget}\n duplicateCounts={duplicateCounts}\n showDuplicates={hasDuplicates}\n />\n ))\n )}\n </TableBody>\n </Table>\n </TableContainer>\n <SilenceForm\n key={silenceKeyRef.current}\n open={!!silenceTarget}\n onClose={() => setSilenceTarget(null)}\n onSubmit={handleSilenceSubmit}\n initialSilence={silenceInitial}\n />\n </Stack>\n );\n}\n"],"names":["Box","Chip","FormControl","IconButton","InputAdornment","InputLabel","MenuItem","Select","Stack","Table","TableBody","TableCell","TableContainer","TableHead","TableRow","TableSortLabel","TextField","Tooltip","Typography","useSnackbar","parseVariables","replaceVariablesInString","useAllVariableValues","useDatasourceClient","useQueryClient","BellOffIcon","BookOpenIcon","ChevronDownIcon","ChevronRightIcon","MagnifyIcon","UnfoldLessHorizontalIcon","UnfoldMoreHorizontalIcon","useCallback","useEffect","useMemo","useRef","useState","SilenceForm","StatusBadge","extractDatasourceSelector","ALL_ALERT_ACTIONS","deduplicateAlerts","extractLabelKeys","getGroupKey","getGroupSummary","compareAlertsByColumn","compareGroupsByColumn","SORT_COL_ALERTNAME","SORT_COL_STATUS","getLabelColor","GroupSummaryChips","summary","direction","spacing","firing","label","color","size","suppressed","pending","LabelValueSummaryChips","mapping","counts","labelCounts","labelKey","Object","keys","length","entries","toSorted","a","b","map","value","count","bgColor","sx","backgroundColor","fontWeight","AlertRow","alert","allowedActions","columnDefs","columnKeySet","mappingsByKey","runbookAnnotationKey","onSilence","duplicateCount","showDuplicates","runbookUrl","annotations","showActions","hover","status","state","variant","name","col","colIdx","labels","get","undefined","flexWrap","useFlexGap","filter","key","has","includes","title","aria-label","onClick","fontSize","component","href","target","rel","AlertGroupRow","group","expanded","labelColorMappings","onToggle","duplicateCounts","cursor","colSpan","alignItems","total","alerts","idx","id","String","AlertTablePanel","spec","queryResults","contentDimensions","datasourceSelector","data","amClient","queryClient","silenceTarget","setSilenceTarget","silenceKeyRef","handleSetSilenceTarget","current","search","setSearch","expandedGroups","setExpandedGroups","Set","successSnackbar","exceptionSnackbar","handleSilenceSubmit","silence","createSilence","invalidateQueries","queryKey","err","silenceInitial","matchers","isEqual","isRegex","defaultGroupBy","variableNames","flatMap","entry","variableState","resolvedDefaultGroupBy","result","vars","push","varState","Array","isArray","resolved","groupBy","setGroupBy","effectiveActions","showActionsColumn","columns","c","labelKeys","m","Map","allTrackedKeys","initialSort","find","sort","enableSorting","columnName","mode","sortMode","sortState","setSortState","handleSortClick","prev","allAlerts","dedupConfig","deduplication","dedupResult","dedupAlerts","hasDuplicates","term","trim","toLowerCase","values","some","v","availableLabelKeys","groups","groupMap","existing","set","from","groupAlerts","prevGroupKeysRef","currentKeys","g","join","handleToggleGroup","next","delete","add","handleExpandAll","handleCollapseAll","handleGroupByChange","event","split","display","justifyContent","height","overflow","px","pt","placeholder","onChange","e","minWidth","slotProps","htmlInput","input","startAdornment","position","labelId","multiple","renderValue","selected","flexGrow","stickyHeader","sortDirection","active","header","align","py","open","onClose","onSubmit","initialSilence"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert-table-model.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/alert-table-model.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"alert-table-model.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/alert-table-model.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAI9C;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,eAAe,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAEhD,eAAO,MAAM,iBAAiB,EAAE,WAAW,EAA2B,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;IACrC,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAClC;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,cAAc,CAAC,EAAE,WAAW,EAAE,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,wBAAwB,GAAG,mBAAmB,CAmCxG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAQ1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,CAmDnF"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
import { getEffectiveStatus, SORT_COL_ALERTNAME, SORT_COL_STATUS } from
|
|
13
|
+
import { getEffectiveStatus, SORT_COL_ALERTNAME, SORT_COL_STATUS } from "./alert-table-sorting.js";
|
|
14
14
|
export const ALL_ALERT_ACTIONS = [
|
|
15
15
|
'silence',
|
|
16
16
|
'runbook'
|
|
@@ -65,7 +65,7 @@ export const ALL_ALERT_ACTIONS = [
|
|
|
65
65
|
keys.add(key);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
return Array.from(keys).
|
|
68
|
+
return Array.from(keys).toSorted();
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
71
|
* Build a group key string from an alert's labels and the specified group-by labels.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/plugins/alert-table/alert-table-model.ts"],"sourcesContent":["// Copyright The Perses Authors\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 { Alert } from '@perses-dev/spec';\nimport { getEffectiveStatus, SORT_COL_ALERTNAME, SORT_COL_STATUS } from './alert-table-sorting';\n\n/**\n * Configuration for how alerts should be deduplicated across datasources.\n */\nexport interface AlertDeduplicationConfig {\n mode: 'none' | 'fingerprint' | 'labels';\n labels?: string[];\n}\n\nexport interface DeduplicationResult {\n alerts: Alert[];\n duplicateCounts: Map<Alert, number>;\n}\n\nexport type AlertAction = 'silence' | 'runbook';\n\nexport const ALL_ALERT_ACTIONS: AlertAction[] = ['silence', 'runbook'];\n\nexport interface LabelColorOverride {\n value: string;\n isRegex: boolean;\n color: string;\n}\n\nexport interface LabelColorMapping {\n labelKey: string;\n mode: 'auto' | 'severity' | 'manual';\n overrides?: LabelColorOverride[];\n}\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport type ColumnSortMode = 'alphabetical' | 'numeric' | 'severity' | 'status';\n\nexport interface ColumnDefinition {\n name: string;\n header?: string;\n enableSorting?: boolean;\n sort?: SortDirection;\n sortMode?: ColumnSortMode;\n}\n\n/**\n * Options for the AlertTable panel plugin.\n */\nexport interface AlertTableOptions {\n defaultGroupBy?: string[];\n columns?: ColumnDefinition[];\n deduplication?: AlertDeduplicationConfig;\n allowedActions?: AlertAction[];\n runbookAnnotationKey?: string;\n labelColorMappings?: LabelColorMapping[];\n}\n\n/**\n * Summary of alert counts by state within a group.\n */\nexport interface GroupSummary {\n total: number;\n firing: number;\n suppressed: number;\n pending: number;\n labelCounts?: Record<string, Record<string, number>>;\n}\n\n/**\n * Deduplicate alerts based on the configured deduplication mode.\n * - 'fingerprint' (default): Uses the alert's fingerprint field.\n * - 'labels': Uses a combination of specified label values.\n */\nexport function deduplicateAlerts(alerts: Alert[], config: AlertDeduplicationConfig): DeduplicationResult {\n if (alerts.length === 0 || config.mode === 'none') return { alerts, duplicateCounts: new Map() };\n\n const seen = new Map<string, Alert>();\n const counts = new Map<string, number>();\n const result: Alert[] = [];\n\n for (const alert of alerts) {\n let key: string;\n if (config.mode === 'labels' && config.labels) {\n key = config.labels.map((l) => `${l}=${alert.labels[l] ?? ''}`).join(',');\n } else if (alert.id) {\n key = alert.id;\n } else {\n key = JSON.stringify(alert.labels);\n }\n\n if (!seen.has(key)) {\n seen.set(key, alert);\n counts.set(key, 1);\n result.push(alert);\n } else {\n counts.set(key, (counts.get(key) ?? 1) + 1);\n }\n }\n\n const duplicateCounts = new Map<Alert, number>();\n for (const [key, alert] of seen) {\n const count = counts.get(key) ?? 1;\n if (count > 1) {\n duplicateCounts.set(alert, count);\n }\n }\n\n return { alerts: result, duplicateCounts };\n}\n\n/**\n * Extract all unique label keys from a list of alerts.\n */\nexport function extractLabelKeys(alerts: Alert[]): string[] {\n const keys = new Set<string>();\n for (const alert of alerts) {\n for (const key of Object.keys(alert.labels)) {\n keys.add(key);\n }\n }\n return Array.from(keys).
|
|
1
|
+
{"version":3,"sources":["../../../../src/plugins/alert-table/alert-table-model.ts"],"sourcesContent":["// Copyright The Perses Authors\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 type { Alert } from '@perses-dev/spec';\n\nimport { getEffectiveStatus, SORT_COL_ALERTNAME, SORT_COL_STATUS } from './alert-table-sorting';\n\n/**\n * Configuration for how alerts should be deduplicated across datasources.\n */\nexport interface AlertDeduplicationConfig {\n mode: 'none' | 'fingerprint' | 'labels';\n labels?: string[];\n}\n\nexport interface DeduplicationResult {\n alerts: Alert[];\n duplicateCounts: Map<Alert, number>;\n}\n\nexport type AlertAction = 'silence' | 'runbook';\n\nexport const ALL_ALERT_ACTIONS: AlertAction[] = ['silence', 'runbook'];\n\nexport interface LabelColorOverride {\n value: string;\n isRegex: boolean;\n color: string;\n}\n\nexport interface LabelColorMapping {\n labelKey: string;\n mode: 'auto' | 'severity' | 'manual';\n overrides?: LabelColorOverride[];\n}\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport type ColumnSortMode = 'alphabetical' | 'numeric' | 'severity' | 'status';\n\nexport interface ColumnDefinition {\n name: string;\n header?: string;\n enableSorting?: boolean;\n sort?: SortDirection;\n sortMode?: ColumnSortMode;\n}\n\n/**\n * Options for the AlertTable panel plugin.\n */\nexport interface AlertTableOptions {\n defaultGroupBy?: string[];\n columns?: ColumnDefinition[];\n deduplication?: AlertDeduplicationConfig;\n allowedActions?: AlertAction[];\n runbookAnnotationKey?: string;\n labelColorMappings?: LabelColorMapping[];\n}\n\n/**\n * Summary of alert counts by state within a group.\n */\nexport interface GroupSummary {\n total: number;\n firing: number;\n suppressed: number;\n pending: number;\n labelCounts?: Record<string, Record<string, number>>;\n}\n\n/**\n * Deduplicate alerts based on the configured deduplication mode.\n * - 'fingerprint' (default): Uses the alert's fingerprint field.\n * - 'labels': Uses a combination of specified label values.\n */\nexport function deduplicateAlerts(alerts: Alert[], config: AlertDeduplicationConfig): DeduplicationResult {\n if (alerts.length === 0 || config.mode === 'none') return { alerts, duplicateCounts: new Map() };\n\n const seen = new Map<string, Alert>();\n const counts = new Map<string, number>();\n const result: Alert[] = [];\n\n for (const alert of alerts) {\n let key: string;\n if (config.mode === 'labels' && config.labels) {\n key = config.labels.map((l) => `${l}=${alert.labels[l] ?? ''}`).join(',');\n } else if (alert.id) {\n key = alert.id;\n } else {\n key = JSON.stringify(alert.labels);\n }\n\n if (!seen.has(key)) {\n seen.set(key, alert);\n counts.set(key, 1);\n result.push(alert);\n } else {\n counts.set(key, (counts.get(key) ?? 1) + 1);\n }\n }\n\n const duplicateCounts = new Map<Alert, number>();\n for (const [key, alert] of seen) {\n const count = counts.get(key) ?? 1;\n if (count > 1) {\n duplicateCounts.set(alert, count);\n }\n }\n\n return { alerts: result, duplicateCounts };\n}\n\n/**\n * Extract all unique label keys from a list of alerts.\n */\nexport function extractLabelKeys(alerts: Alert[]): string[] {\n const keys = new Set<string>();\n for (const alert of alerts) {\n for (const key of Object.keys(alert.labels)) {\n keys.add(key);\n }\n }\n return Array.from(keys).toSorted();\n}\n\n/**\n * Build a group key string from an alert's labels and the specified group-by labels.\n */\nexport function getGroupKey(alert: Alert, groupBy: string[]): string {\n return groupBy.map((label) => `${label}=${alert.labels[label] ?? ''}`).join(',');\n}\n\n/**\n * Compute a summary of alert counts by state for a group of alerts.\n */\nexport function getGroupSummary(alerts: Alert[], labelKeys?: string[]): GroupSummary {\n const summary: GroupSummary = { total: 0, firing: 0, suppressed: 0, pending: 0 };\n const labelCounts: Record<string, Record<string, number>> = {};\n\n labelCounts[SORT_COL_STATUS] = {};\n labelCounts[SORT_COL_ALERTNAME] = {};\n\n if (labelKeys) {\n for (const key of labelKeys) {\n labelCounts[key] = {};\n }\n }\n\n for (const alert of alerts) {\n summary.total++;\n if (alert.suppressed) {\n summary.suppressed++;\n } else {\n switch (alert.state) {\n case 'firing':\n summary.firing++;\n break;\n case 'pending':\n summary.pending++;\n break;\n }\n }\n\n const status = getEffectiveStatus(alert);\n labelCounts[SORT_COL_STATUS]![status] = (labelCounts[SORT_COL_STATUS]![status] ?? 0) + 1;\n\n if (alert.name) {\n labelCounts[SORT_COL_ALERTNAME]![alert.name] = (labelCounts[SORT_COL_ALERTNAME]![alert.name] ?? 0) + 1;\n }\n\n if (labelKeys) {\n for (const key of labelKeys) {\n const labelValue = alert.labels[key];\n if (labelValue !== undefined) {\n const counts = labelCounts[key];\n if (counts) {\n counts[labelValue] = (counts[labelValue] ?? 0) + 1;\n }\n }\n }\n }\n }\n\n summary.labelCounts = labelCounts;\n\n return summary;\n}\n"],"names":["getEffectiveStatus","SORT_COL_ALERTNAME","SORT_COL_STATUS","ALL_ALERT_ACTIONS","deduplicateAlerts","alerts","config","length","mode","duplicateCounts","Map","seen","counts","result","alert","key","labels","map","l","join","id","JSON","stringify","has","set","push","get","count","extractLabelKeys","keys","Set","Object","add","Array","from","toSorted","getGroupKey","groupBy","label","getGroupSummary","labelKeys","summary","total","firing","suppressed","pending","labelCounts","state","status","name","labelValue","undefined"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Alert } from '@perses-dev/spec';
|
|
2
|
-
import { ColumnSortMode, SortDirection } from './alert-table-model';
|
|
1
|
+
import type { Alert } from '@perses-dev/spec';
|
|
2
|
+
import type { ColumnSortMode, SortDirection } from './alert-table-model';
|
|
3
3
|
export declare const SORT_COL_STATUS = "__status__";
|
|
4
4
|
export declare const SORT_COL_ALERTNAME = "__alertname__";
|
|
5
5
|
export interface SortState {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert-table-sorting.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/alert-table-sorting.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"alert-table-sorting.d.ts","sourceRoot":"","sources":["../../../../src/plugins/alert-table/alert-table-sorting.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzE,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;CACtB;AAUD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEvD;AAkCD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CA0BjF;AA4CD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,IAAI,EAAE,SAAS,GACd,MAAM,CAoDR"}
|