From f96637b5fcb4863ac7085c3c5a741922af3de6d5 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Wed, 22 Mar 2023 11:09:44 -0700 Subject: [PATCH] Live: Remove (alpha) ability to configure live pipelines (#65138) --- .betterer.results | 30 ---- .../feature-toggles/index.md | 1 - .../src/types/featureToggles.gen.ts | 1 - pkg/api/api.go | 15 -- pkg/services/featuremgmt/registry.go | 6 - pkg/services/featuremgmt/toggles_gen.csv | 1 - pkg/services/featuremgmt/toggles_gen.go | 4 - pkg/services/featuremgmt/toggles_gen_test.go | 1 - pkg/services/live/live.go | 48 ------ pkg/services/navtree/navtreeimpl/navtree.go | 25 --- pkg/tsdb/testdatasource/stream_handler.go | 10 -- .../NavBar/navBarItem-translations.ts | 8 - public/app/features/live/pages/AddNewRule.tsx | 132 ---------------- .../features/live/pages/CloudAdminPage.tsx | 51 ------- .../features/live/pages/FeatureTogglePage.tsx | 22 --- .../features/live/pages/LiveStatusPage.tsx | 14 -- .../features/live/pages/PipelineAdminPage.tsx | 67 --------- .../app/features/live/pages/PipelineTable.tsx | 142 ------------------ public/app/features/live/pages/RuleModal.tsx | 128 ---------------- .../features/live/pages/RuleSettingsArray.tsx | 51 ------- .../live/pages/RuleSettingsEditor.tsx | 48 ------ public/app/features/live/pages/RuleTest.tsx | 78 ---------- public/app/features/live/pages/routes.ts | 40 ----- public/app/features/live/pages/types.ts | 61 -------- public/app/features/live/pages/utils.ts | 31 ---- .../app/features/live/pipeline/models.gen.ts | 132 ---------------- public/app/routes/routes.tsx | 2 - public/locales/de-DE/grafana.json | 12 -- public/locales/en-US/grafana.json | 12 -- public/locales/es-ES/grafana.json | 12 -- public/locales/fr-FR/grafana.json | 12 -- public/locales/pseudo-LOCALE/grafana.json | 12 -- public/locales/zh-Hans/grafana.json | 12 -- 33 files changed, 1221 deletions(-) delete mode 100644 public/app/features/live/pages/AddNewRule.tsx delete mode 100644 public/app/features/live/pages/CloudAdminPage.tsx delete mode 100644 public/app/features/live/pages/FeatureTogglePage.tsx delete mode 100644 public/app/features/live/pages/LiveStatusPage.tsx delete mode 100644 public/app/features/live/pages/PipelineAdminPage.tsx delete mode 100644 public/app/features/live/pages/PipelineTable.tsx delete mode 100644 public/app/features/live/pages/RuleModal.tsx delete mode 100644 public/app/features/live/pages/RuleSettingsArray.tsx delete mode 100644 public/app/features/live/pages/RuleSettingsEditor.tsx delete mode 100644 public/app/features/live/pages/RuleTest.tsx delete mode 100644 public/app/features/live/pages/routes.ts delete mode 100644 public/app/features/live/pages/types.ts delete mode 100644 public/app/features/live/pages/utils.ts delete mode 100644 public/app/features/live/pipeline/models.gen.ts diff --git a/.betterer.results b/.betterer.results index b8fea9a9d92..d342b246ecc 100644 --- a/.betterer.results +++ b/.betterer.results @@ -3469,36 +3469,6 @@ exports[`better eslint`] = { "public/app/features/live/index.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/live/pages/AddNewRule.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/live/pages/PipelineAdminPage.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/live/pages/PipelineTable.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/live/pages/RuleModal.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], - "public/app/features/live/pages/RuleTest.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], - "public/app/features/live/pages/types.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"] - ], - "public/app/features/live/pages/utils.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/logs/components/LogRowContextProvider.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 2598387920d..f52a3ad6937 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -56,7 +56,6 @@ Alpha features might be changed or removed without prior notice. | ---------------------------------- | --------------------------------------------------------------------------------------------------------- | | `alertingBigTransactions` | Use big transactions for alerting database writes | | `dashboardPreviews` | Create and show thumbnails for dashboard search results | -| `live-pipeline` | Enable a generic live processing pipeline | | `live-service-web-worker` | This will use a webworker thread to processes events rather than the main thread | | `queryOverLive` | Use Grafana Live WebSocket to execute backend queries | | `publicDashboards` | Enables public access to dashboards | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 481f57b3e40..f0a1ab161d6 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -23,7 +23,6 @@ export interface FeatureToggles { disableEnvelopeEncryption?: boolean; database_metrics?: boolean; dashboardPreviews?: boolean; - ['live-pipeline']?: boolean; ['live-service-web-worker']?: boolean; queryOverLive?: boolean; panelTitleSearch?: boolean; diff --git a/pkg/api/api.go b/pkg/api/api.go index fac67562ad8..d1489b9f705 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -591,21 +591,6 @@ func (hs *HTTPServer) registerRoutes() { // Some channels may have info liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP)) - - if hs.Features.IsEnabled(featuremgmt.FlagLivePipeline) { - // POST Live data to be processed according to channel rules. - liveRoute.Post("/pipeline/push/*", hs.LivePushGateway.HandlePipelinePush) - liveRoute.Post("/pipeline-convert-test", routing.Wrap(hs.Live.HandlePipelineConvertTestHTTP), reqOrgAdmin) - liveRoute.Get("/pipeline-entities", routing.Wrap(hs.Live.HandlePipelineEntitiesListHTTP), reqOrgAdmin) - liveRoute.Get("/channel-rules", routing.Wrap(hs.Live.HandleChannelRulesListHTTP), reqOrgAdmin) - liveRoute.Post("/channel-rules", routing.Wrap(hs.Live.HandleChannelRulesPostHTTP), reqOrgAdmin) - liveRoute.Put("/channel-rules", routing.Wrap(hs.Live.HandleChannelRulesPutHTTP), reqOrgAdmin) - liveRoute.Delete("/channel-rules", routing.Wrap(hs.Live.HandleChannelRulesDeleteHTTP), reqOrgAdmin) - liveRoute.Get("/write-configs", routing.Wrap(hs.Live.HandleWriteConfigsListHTTP), reqOrgAdmin) - liveRoute.Post("/write-configs", routing.Wrap(hs.Live.HandleWriteConfigsPostHTTP), reqOrgAdmin) - liveRoute.Put("/write-configs", routing.Wrap(hs.Live.HandleWriteConfigsPutHTTP), reqOrgAdmin) - liveRoute.Delete("/write-configs", routing.Wrap(hs.Live.HandleWriteConfigsDeleteHTTP), reqOrgAdmin) - } }) // short urls diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index d7516b81d31..ac8a478cd74 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -39,12 +39,6 @@ var ( State: FeatureStateAlpha, Owner: grafanaAppPlatformSquad, }, - { - Name: "live-pipeline", - Description: "Enable a generic live processing pipeline", - State: FeatureStateAlpha, - Owner: grafanaAppPlatformSquad, - }, { Name: "live-service-web-worker", Description: "This will use a webworker thread to processes events rather than the main thread", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index c7d6321d583..d2eaa563be5 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -4,7 +4,6 @@ trimDefaults,beta,@grafana/grafana-as-code,false,false,false,false disableEnvelopeEncryption,stable,@grafana/grafana-as-code,false,false,false,false database_metrics,stable,@grafana/hosted-grafana-team,false,false,false,false dashboardPreviews,alpha,@grafana/grafana-app-platform-squad,false,false,false,false -live-pipeline,alpha,@grafana/grafana-app-platform-squad,false,false,false,false live-service-web-worker,alpha,@grafana/grafana-app-platform-squad,false,false,false,true queryOverLive,alpha,@grafana/grafana-app-platform-squad,false,false,false,true panelTitleSearch,beta,@grafana/grafana-app-platform-squad,false,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index e26943309e9..85dc2ae81fb 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -27,10 +27,6 @@ const ( // Create and show thumbnails for dashboard search results FlagDashboardPreviews = "dashboardPreviews" - // FlagLivePipeline - // Enable a generic live processing pipeline - FlagLivePipeline = "live-pipeline" - // FlagLiveServiceWebWorker // This will use a webworker thread to processes events rather than the main thread FlagLiveServiceWebWorker = "live-service-web-worker" diff --git a/pkg/services/featuremgmt/toggles_gen_test.go b/pkg/services/featuremgmt/toggles_gen_test.go index afb33892f08..a24ca2ff708 100644 --- a/pkg/services/featuremgmt/toggles_gen_test.go +++ b/pkg/services/featuremgmt/toggles_gen_test.go @@ -24,7 +24,6 @@ func TestFeatureToggleFiles(t *testing.T) { "httpclientprovider_azure_auth": true, "service-accounts": true, "database_metrics": true, - "live-pipeline": true, "live-service-web-worker": true, "k8s": true, // Camel case does not like this one } diff --git a/pkg/services/live/live.go b/pkg/services/live/live.go index bf127195f31..2ac2186db99 100644 --- a/pkg/services/live/live.go +++ b/pkg/services/live/live.go @@ -8,7 +8,6 @@ import ( "io" "net/http" "net/url" - "os" "strconv" "strings" "sync" @@ -182,53 +181,6 @@ func ProvideService(plugCtxProvider *plugincontext.Provider, cfg *setting.Cfg, r } g.ManagedStreamRunner = managedStreamRunner - if g.Features.IsEnabled(featuremgmt.FlagLivePipeline) { - var builder pipeline.RuleBuilder - if os.Getenv("GF_LIVE_DEV_BUILDER") != "" { - builder = &pipeline.DevRuleBuilder{ - Node: node, - ManagedStream: g.ManagedStreamRunner, - FrameStorage: pipeline.NewFrameStorage(), - ChannelHandlerGetter: g, - } - } else { - storage := &pipeline.FileStorage{ - DataPath: cfg.DataPath, - SecretsService: g.SecretsService, - } - g.pipelineStorage = storage - builder = &pipeline.StorageRuleBuilder{ - Node: node, - ManagedStream: g.ManagedStreamRunner, - FrameStorage: pipeline.NewFrameStorage(), - Storage: storage, - ChannelHandlerGetter: g, - SecretsService: g.SecretsService, - } - } - channelRuleGetter := pipeline.NewCacheSegmentedTree(builder) - - // Pre-build/validate channel rules for all organizations on start. - // This can be unreasonable to have in production scenario with many - // organizations. - orgQuery := &org.SearchOrgsQuery{} - - result, err := orgService.Search(context.Background(), orgQuery) - if err != nil { - return nil, fmt.Errorf("can't get org list: %w", err) - } - for _, org := range result { - _, _, err := channelRuleGetter.Get(org.ID, "") - if err != nil { - return nil, fmt.Errorf("error building channel rules for org %d: %w", org.ID, err) - } - } - - g.Pipeline, err = pipeline.New(channelRuleGetter) - if err != nil { - return nil, err - } - } g.contextGetter = liveplugin.NewContextGetter(g.PluginContextProvider, g.DataSourceCache) pipelinedChannelLocalPublisher := liveplugin.NewChannelLocalPublisher(node, g.Pipeline) diff --git a/pkg/services/navtree/navtreeimpl/navtree.go b/pkg/services/navtree/navtreeimpl/navtree.go index aa9a5ea018c..74bec2a2967 100644 --- a/pkg/services/navtree/navtreeimpl/navtree.go +++ b/pkg/services/navtree/navtreeimpl/navtree.go @@ -149,31 +149,6 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, hasEditPerm bool, p } } - if s.features.IsEnabled(featuremgmt.FlagLivePipeline) { - liveNavLinks := []*navtree.NavLink{} - - liveNavLinks = append(liveNavLinks, &navtree.NavLink{ - Text: "Status", Id: "live-status", Url: s.cfg.AppSubURL + "/live", Icon: "exchange-alt", - }) - liveNavLinks = append(liveNavLinks, &navtree.NavLink{ - Text: "Pipeline", Id: "live-pipeline", Url: s.cfg.AppSubURL + "/live/pipeline", Icon: "arrow-to-right", - }) - liveNavLinks = append(liveNavLinks, &navtree.NavLink{ - Text: "Cloud", Id: "live-cloud", Url: s.cfg.AppSubURL + "/live/cloud", Icon: "cloud-upload", - }) - - treeRoot.AddSection(&navtree.NavLink{ - Id: "live", - Text: "Live", - SubTitle: "Event streaming", - Icon: "exchange-alt", - Url: s.cfg.AppSubURL + "/live", - Children: liveNavLinks, - Section: navtree.NavSectionConfig, - HideFromTabs: true, - }) - } - orgAdminNode, err := s.getOrgAdminNode(c) if orgAdminNode != nil { diff --git a/pkg/tsdb/testdatasource/stream_handler.go b/pkg/tsdb/testdatasource/stream_handler.go index 1b7c7a1c40e..9583ceb3d26 100644 --- a/pkg/tsdb/testdatasource/stream_handler.go +++ b/pkg/tsdb/testdatasource/stream_handler.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/grafana/grafana/pkg/services/featuremgmt" ) var random20HzStreamRegex = regexp.MustCompile(`random-20Hz-stream(-\d+)?`) @@ -34,11 +33,6 @@ func (s *Service) SubscribeStream(ctx context.Context, req *backend.SubscribeStr } } - if s.features.IsEnabled(featuremgmt.FlagLivePipeline) { - // While developing Live pipeline avoid sending initial data. - initialData = nil - } - return &backend.SubscribeStreamResponse{ Status: backend.SubscribeStreamStatusOK, InitialData: initialData, @@ -121,10 +115,6 @@ func (s *Service) runTestStream(ctx context.Context, path string, conf testStrea } mode := data.IncludeDataOnly - if s.features.IsEnabled(featuremgmt.FlagLivePipeline) { - mode = data.IncludeAll - } - delta := rand.Float64() - 0.5 walker += delta diff --git a/public/app/core/components/NavBar/navBarItem-translations.ts b/public/app/core/components/NavBar/navBarItem-translations.ts index 4452debe52a..b3e6b845b75 100644 --- a/public/app/core/components/NavBar/navBarItem-translations.ts +++ b/public/app/core/components/NavBar/navBarItem-translations.ts @@ -109,14 +109,6 @@ export function getNavTitle(navId: string | undefined) { return t('nav.storage.title', 'Storage'); case 'upgrading': return t('nav.upgrading.title', 'Stats and license'); - case 'live': - return t('nav.live.title', 'Event streaming'); - case 'live-status': - return t('nav.live-status.title', 'Status'); - case 'live-pipeline': - return t('nav.live-pipeline.title', 'Pipeline'); - case 'live-cloud': - return t('nav.live-cloud.title', 'Cloud'); case 'monitoring': return t('nav.monitoring.title', 'Monitoring'); case 'apps': diff --git a/public/app/features/live/pages/AddNewRule.tsx b/public/app/features/live/pages/AddNewRule.tsx deleted file mode 100644 index fea6a9fa681..00000000000 --- a/public/app/features/live/pages/AddNewRule.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import React, { useState } from 'react'; - -import { DataSourceRef, LiveChannelScope, SelectableValue } from '@grafana/data'; -import { DataSourcePicker, getBackendSrv } from '@grafana/runtime'; -import { Input, Field, Button, ValuePicker, HorizontalGroup } from '@grafana/ui'; -import { useAppNotification } from 'app/core/copy/appNotification'; - -import { Rule } from './types'; - -interface Props { - onRuleAdded: (rule: Rule) => void; -} - -type PatternType = 'ds' | 'any'; - -const patternTypes: Array> = [ - { - label: 'Data source', - description: 'Configure a channel scoped to a data source instance', - value: 'ds', - }, - { - label: 'Any', - description: 'Enter an arbitray channel pattern', - value: 'any', - }, -]; - -export function AddNewRule({ onRuleAdded }: Props) { - const [patternType, setPatternType] = useState(); - const [pattern, setPattern] = useState(); - const [patternPrefix, setPatternPrefix] = useState(''); - const [datasource, setDatasource] = useState(); - const notifyApp = useAppNotification(); - - const onSubmit = () => { - if (!pattern) { - notifyApp.error('Enter path'); - return; - } - if (patternType === 'ds' && !patternPrefix.length) { - notifyApp.error('Select datasource'); - return; - } - - getBackendSrv() - .post(`api/live/channel-rules`, { - pattern: patternPrefix + pattern, - settings: { - converter: { - type: 'jsonAuto', - }, - frameOutputs: [ - { - type: 'managedStream', - }, - ], - }, - }) - .then((v: any) => { - console.log('ADDED', v); - setPattern(undefined); - setPatternType(undefined); - onRuleAdded(v.rule); - }) - .catch((e) => { - notifyApp.error('Error adding rule', e); - e.isHandled = true; - }); - }; - - if (patternType) { - return ( -
- - {patternType === 'any' && ( - - setPattern(e.currentTarget.value)} - placeholder="scope/namespace/path" - /> - - )} - {patternType === 'ds' && ( - <> - - { - setDatasource(ds); - setPatternPrefix(`${LiveChannelScope.DataSource}/${ds.uid}/`); - }} - /> - - - setPattern(e.currentTarget.value)} placeholder="path" /> - - - )} - - - - - - - - - -
- ); - } - - return ( -
- setPatternType(v.value)} - /> -
- ); -} diff --git a/public/app/features/live/pages/CloudAdminPage.tsx b/public/app/features/live/pages/CloudAdminPage.tsx deleted file mode 100644 index 9a6fd74ca26..00000000000 --- a/public/app/features/live/pages/CloudAdminPage.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { css } from '@emotion/css'; -import React, { useEffect, useState } from 'react'; - -import { getBackendSrv } from '@grafana/runtime'; -import { Page } from 'app/core/components/Page/Page'; -import { useNavModel } from 'app/core/hooks/useNavModel'; - -import { GrafanaCloudBackend } from './types'; - -export default function CloudAdminPage() { - const navModel = useNavModel('live-cloud'); - const [cloud, setCloud] = useState([]); - const [error, setError] = useState(); - - useEffect(() => { - getBackendSrv() - .get(`api/live/write-configs`) - .then((data) => { - setCloud(data.writeConfigs); - }) - .catch((e) => { - if (e.data) { - setError(JSON.stringify(e.data, null, 2)); - } - }); - }, []); - - return ( - - - {error &&
{error}
} - {!cloud && <>Loading cloud definitions} - {cloud && - cloud.map((v) => { - return ( -
-

{v.uid}

-
{JSON.stringify(v.settings, null, 2)}
-
- ); - })} -
-
- ); -} - -const styles = { - row: css` - cursor: pointer; - `, -}; diff --git a/public/app/features/live/pages/FeatureTogglePage.tsx b/public/app/features/live/pages/FeatureTogglePage.tsx deleted file mode 100644 index 35b19509a05..00000000000 --- a/public/app/features/live/pages/FeatureTogglePage.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; - -import { Page } from 'app/core/components/Page/Page'; -import { useNavModel } from 'app/core/hooks/useNavModel'; - -export default function FeatureTogglePage() { - const navModel = useNavModel('live-status'); - - return ( - - -

Pipeline is not enabled

- To enable pipelines, enable the feature toggle: -
-          {`[feature_toggles] 
-enable = live-pipeline
-`}
-        
-
-
- ); -} diff --git a/public/app/features/live/pages/LiveStatusPage.tsx b/public/app/features/live/pages/LiveStatusPage.tsx deleted file mode 100644 index 485aacfe8d5..00000000000 --- a/public/app/features/live/pages/LiveStatusPage.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; - -import { Page } from 'app/core/components/Page/Page'; -import { useNavModel } from 'app/core/hooks/useNavModel'; - -export default function CloudAdminPage() { - const navModel = useNavModel('live-status'); - - return ( - - Live/Live/Live - - ); -} diff --git a/public/app/features/live/pages/PipelineAdminPage.tsx b/public/app/features/live/pages/PipelineAdminPage.tsx deleted file mode 100644 index 7d33b38b595..00000000000 --- a/public/app/features/live/pages/PipelineAdminPage.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React, { useEffect, useState, ChangeEvent } from 'react'; - -import { getBackendSrv } from '@grafana/runtime'; -import { Input } from '@grafana/ui'; -import { Page } from 'app/core/components/Page/Page'; -import { useNavModel } from 'app/core/hooks/useNavModel'; - -import { AddNewRule } from './AddNewRule'; -import { PipelineTable } from './PipelineTable'; -import { Rule } from './types'; - -export default function PipelineAdminPage() { - const [rules, setRules] = useState([]); - const [defaultRules, setDefaultRules] = useState([]); - const [newRule, setNewRule] = useState(); - const navModel = useNavModel('live-pipeline'); - const [error, setError] = useState(); - - const loadRules = () => { - getBackendSrv() - .get(`api/live/channel-rules`) - .then((data) => { - setRules(data.rules ?? []); - setDefaultRules(data.rules ?? []); - }) - .catch((e) => { - if (e.data) { - setError(JSON.stringify(e.data, null, 2)); - } - }); - }; - - useEffect(() => { - loadRules(); - }, []); - - const onSearchQueryChange = (e: ChangeEvent) => { - if (e.target.value) { - setRules(rules.filter((rule) => rule.pattern.toLowerCase().includes(e.target.value.toLowerCase()))); - } else { - setRules(defaultRules); - } - }; - - return ( - - - {error &&
{error}
} -
-
- -
-
- - - - { - console.log('GOT', r, 'vs', rules[0]); - setNewRule(r); - loadRules(); - }} - /> -
-
- ); -} diff --git a/public/app/features/live/pages/PipelineTable.tsx b/public/app/features/live/pages/PipelineTable.tsx deleted file mode 100644 index 791aa62f9d2..00000000000 --- a/public/app/features/live/pages/PipelineTable.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { css } from '@emotion/css'; -import React, { useEffect, useState } from 'react'; - -import { getBackendSrv } from '@grafana/runtime'; -import { Tag, IconButton } from '@grafana/ui'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; - -import { RuleModal } from './RuleModal'; -import { Rule, Output, RuleType } from './types'; - -function renderOutputTags(key: string, output?: Output): React.ReactNode { - if (!output?.type) { - return null; - } - return ; -} - -interface Props { - rules: Rule[]; - onRuleChanged: () => void; - selectRule?: Rule; -} - -export const PipelineTable = (props: Props) => { - const { rules } = props; - const [isOpen, setOpen] = useState(false); - const [selectedRule, setSelectedRule] = useState(); - const [clickColumn, setClickColumn] = useState('converter'); - - const onRowClick = (rule: Rule, event?: any) => { - if (!rule) { - return; - } - let column = event?.target?.getAttribute('data-column'); - if (!column || column === 'pattern') { - column = 'converter'; - } - setClickColumn(column); - setSelectedRule(rule); - setOpen(true); - }; - - // Supports selecting a rule from external config (after add rule) - useEffect(() => { - if (props.selectRule) { - onRowClick(props.selectRule); - } - }, [props.selectRule]); - - const onRemoveRule = (pattern: string) => { - getBackendSrv() - .delete(`api/live/channel-rules`, JSON.stringify({ pattern: pattern })) - .catch((e) => console.error(e)) - .finally(() => { - props.onRuleChanged(); - }); - }; - - const renderPattern = (pattern: string) => { - if (pattern.startsWith('ds/')) { - const idx = pattern.indexOf('/', 4); - if (idx > 3) { - const uid = pattern.substring(3, idx); - const ds = getDatasourceSrv().getInstanceSettings(uid); - if (ds) { - return ( -
-   - {pattern.substring(idx + 1)} -
- ); - } - } - } - return pattern; - }; - - return ( -
-
- - - - - - - - - - - - {rules.map((rule) => ( - onRowClick(rule, e)} className={styles.row}> - - - - - - - ))} - -
ChannelConverterProcessorOutput 
- {renderPattern(rule.pattern)} - - {rule.settings?.converter?.type} - - {rule.settings?.frameProcessors?.map((processor) => ( - {processor.type} - ))} - - {rule.settings?.frameOutputs?.map((output) => ( - {renderOutputTags('out', output)} - ))} - - { - e.stopPropagation(); - onRemoveRule(rule.pattern); - }} - > -
-
- {isOpen && selectedRule && ( - { - setOpen(false); - }} - clickColumn={clickColumn} - /> - )} -
- ); -}; - -const styles = { - row: css` - cursor: pointer; - `, -}; diff --git a/public/app/features/live/pages/RuleModal.tsx b/public/app/features/live/pages/RuleModal.tsx deleted file mode 100644 index 8d1465b07ec..00000000000 --- a/public/app/features/live/pages/RuleModal.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import { css } from '@emotion/css'; -import React, { useState, useMemo } from 'react'; - -import { getBackendSrv } from '@grafana/runtime'; -import { Modal, TabContent, TabsBar, Tab, Button } from '@grafana/ui'; - -import { RuleSettingsArray } from './RuleSettingsArray'; -import { RuleSettingsEditor } from './RuleSettingsEditor'; -import { RuleTest } from './RuleTest'; -import { Rule, RuleType, PipeLineEntitiesInfo, RuleSetting } from './types'; -import { getPipeLineEntities } from './utils'; - -interface Props { - rule: Rule; - isOpen: boolean; - onClose: () => void; - clickColumn: RuleType; -} -interface TabInfo { - label: string; - type?: RuleType; - isTest?: boolean; - isConverter?: boolean; - icon?: string; -} -const tabs: TabInfo[] = [ - { label: 'Converter', type: 'converter', isConverter: true }, - { label: 'Processors', type: 'frameProcessors' }, - { label: 'Outputs', type: 'frameOutputs' }, - { label: 'Test', isTest: true, icon: 'flask' }, -]; - -export const RuleModal = (props: Props) => { - const { isOpen, onClose, clickColumn } = props; - const [rule, setRule] = useState(props.rule); - const [activeTab, setActiveTab] = useState(tabs.find((t) => t.type === clickColumn)); - // to show color of Save button - const [hasChange, setChange] = useState(false); - const [ruleSetting, setRuleSetting] = useState(activeTab?.type ? rule?.settings?.[activeTab.type] : undefined); - const [entitiesInfo, setEntitiesInfo] = useState(); - - const onRuleSettingChange = (value: RuleSetting | RuleSetting[]) => { - setChange(true); - if (activeTab?.type) { - setRule({ - ...rule, - settings: { - ...rule.settings, - [activeTab?.type]: value, - }, - }); - } - setRuleSetting(value); - }; - - // load pipeline entities info - useMemo(() => { - getPipeLineEntities().then((data) => { - setEntitiesInfo(data); - }); - }, []); - - const onSave = () => { - getBackendSrv() - .put(`api/live/channel-rules`, rule) - .then(() => { - setChange(false); - onClose(); - }) - .catch((e) => console.error(e)); - }; - - return ( - - - {tabs.map((tab, index) => { - return ( - { - setActiveTab(tab); - if (tab.type) { - // to notify children of the new rule - setRuleSetting(rule?.settings?.[tab.type]); - } - }} - /> - ); - })} - - - {entitiesInfo && rule && activeTab && ( - <> - {activeTab?.isTest && } - {activeTab.isConverter && ( - - )} - {!activeTab.isConverter && activeTab.type && ( - - )} - - )} - - - - ); -}; - -const styles = { - save: css` - margin-top: 5px; - `, -}; diff --git a/public/app/features/live/pages/RuleSettingsArray.tsx b/public/app/features/live/pages/RuleSettingsArray.tsx deleted file mode 100644 index 8183cd334db..00000000000 --- a/public/app/features/live/pages/RuleSettingsArray.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { useState } from 'react'; - -import { SelectableValue } from '@grafana/data'; -import { Select } from '@grafana/ui'; - -import { RuleSettingsEditor } from './RuleSettingsEditor'; -import { RuleType, RuleSetting, PipeLineEntitiesInfo } from './types'; - -interface Props { - ruleType: RuleType; - onChange: (value: RuleSetting[]) => void; - value: RuleSetting[]; - entitiesInfo: PipeLineEntitiesInfo; -} - -export const RuleSettingsArray = ({ onChange, value, ruleType, entitiesInfo }: Props) => { - const [index, setIndex] = useState(0); - const arr = value ?? []; - const onRuleChange = (v: RuleSetting) => { - if (!value) { - onChange([v]); - } else { - const copy = [...value]; - copy[index] = v; - onChange(copy); - } - }; - // create array of value.length + 1 - let indexArr: Array> = []; - for (let i = 0; i <= arr.length; i++) { - indexArr.push({ - label: `${ruleType}: ${i}`, - value: i, - }); - } - - return ( - <> - - - - ); -}; diff --git a/public/app/features/live/pages/RuleSettingsEditor.tsx b/public/app/features/live/pages/RuleSettingsEditor.tsx deleted file mode 100644 index d82de4bd77e..00000000000 --- a/public/app/features/live/pages/RuleSettingsEditor.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; - -import { CodeEditor, Select } from '@grafana/ui'; - -import { RuleType, RuleSetting, PipeLineEntitiesInfo } from './types'; - -interface Props { - ruleType: RuleType; - onChange: (value: RuleSetting) => void; - value: RuleSetting; - entitiesInfo: PipeLineEntitiesInfo; -} - -export const RuleSettingsEditor = ({ onChange, value, ruleType, entitiesInfo }: Props) => { - return ( - <> -