diff --git a/.github/workflows/markdown-lint.yml b/.github/workflows/markdown-lint.yml index 8180471bb..42d82ef9a 100644 --- a/.github/workflows/markdown-lint.yml +++ b/.github/workflows/markdown-lint.yml @@ -14,7 +14,6 @@ jobs: with: globs: | **/*.md - !ui/node_modules !LICENSE.md !pkg/web/openapi/** !.github/*.md diff --git a/.github/workflows/ui-lint.yml b/.github/workflows/ui-lint.yml deleted file mode 100644 index b0f4519fb..000000000 --- a/.github/workflows/ui-lint.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: UI Lint - -on: - # Trigger the workflow on push or pull request, - # but only for the main branch - push: - branches: - - main - paths: - - 'ui/**' - pull_request: - branches: - - main - paths: - - 'ui/**' - -jobs: - lint-app: - name: Run linter - runs-on: ubuntu-latest - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Use Node - uses: actions/setup-node@v4 - with: - node-version: 18.x - - - name: Install dependencies - run: make ui-dependencies - - - name: lint - run: cd ui/ && npm run lint diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml deleted file mode 100644 index 7d2ccaa5f..000000000 --- a/.github/workflows/ui-tests.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: UI tests - -on: - # Trigger the workflow on push or pull request, - # but only for the main branch - push: - branches: - - main - paths: - - 'ui/**' - pull_request: - branches: - - main - paths: - - 'ui/**' - -jobs: - test-app: - name: Running Tests - runs-on: ubuntu-latest - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Use Node - uses: actions/setup-node@v4 - with: - node-version: 18.x - - - name: Install dependencies - run: make ui-dependencies - - - name: ember t - run: make ui-test diff --git a/.gitignore b/.gitignore index 8448637a5..911ec73d6 100644 --- a/.gitignore +++ b/.gitignore @@ -28,41 +28,6 @@ conduit.db /conduit /conduit-pipeline-check -### Conduit UI ### - -# compiled output -/ui/dist/ -/ui/tmp/ -/pkg/web/ui/dist/* -!/pkg/web/ui/dist/.keep - -# dependencies -/.github/actions/node_modules/ -/ui/node_modules/ - -# misc -/ui/.env* -/ui/.pnp* -/ui/.sass-cache -/ui/.eslintcache -/ui/connect.lock -/ui/coverage/ -/ui/libpeerconnection.log -/ui/npm-debug.log* -/ui/testem.log -/ui/yarn-error.log - -# ember-try -/ui/.node_modules.ember-try/ -/ui/bower.json.ember-try -/ui/npm-shrinkwrap.json.ember-try -/ui/package.json.ember-try -/ui/package-lock.json.ember-try -/ui/yarn.lock.ember-try - -# Local Netlify folder -/ui/.netlify - ### OS ### .DS_Store diff --git a/.golangci.yml b/.golangci.yml index b06ed5b7d..6bec72290 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -40,7 +40,6 @@ issues: exclude-dirs-use-default: false exclude-dirs: - ^examples/ - - ^ui/ - ^pkg/plugin/processor/builtin/internal/diff # external code exclude-rules: diff --git a/Dockerfile b/Dockerfile index b972548a8..0b20ac413 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,6 @@ RUN apt-get update &&\ apt-get install -y build-essential &&\ apt-get install -y git -# Install Node@v18 -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - &&\ - apt-get install -y nodejs &&\ - npm update &&\ - npm i -g yarn@1.22.22 - # Build the full app binary WORKDIR /app COPY . . diff --git a/Makefile b/Makefile index 746808d04..205c14053 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,8 @@ GO_VERSION_CHECK=`./scripts/check-go-version.sh` # The build target should stay at the top since we want it to be the default target. .PHONY: build -build: check-go-version pkg/web/ui/dist - go build -ldflags "-X 'github.com/conduitio/conduit/pkg/conduit.version=${VERSION}'" -o conduit -tags ui ./cmd/conduit/main.go +build: check-go-version + go build -ldflags "-X 'github.com/conduitio/conduit/pkg/conduit.version=${VERSION}'" -o conduit ./cmd/conduit/main.go @echo "\nBuild complete. Enjoy using Conduit!" @echo "Get started by running:" @echo " ./conduit" @@ -40,11 +40,6 @@ fmt: lint: golangci-lint run -v -.PHONY: build-server -build-server: check-go-version - go build -ldflags "-X 'github.com/conduitio/conduit/pkg/conduit.version=${VERSION}'" -o conduit ./cmd/conduit/main.go - @echo "build version: ${VERSION}" - .PHONY: run run: go run ./cmd/conduit/main.go @@ -64,7 +59,6 @@ proto-lint: .PHONY: clean clean: @rm -f conduit - @rm -rf pkg/web/ui/dist .PHONY: download download: @@ -81,12 +75,6 @@ install-tools: download generate: go generate -x ./... -pkg/web/ui/dist: - make ui-dist - -ui-%: - @cd ui && make $* - .PHONY: check-go-version check-go-version: @if [ "${GO_VERSION_CHECK}" != "" ]; then\ @@ -96,4 +84,4 @@ check-go-version: .PHONY: markdown-lint markdown-lint: - markdownlint-cli2 "**/*.md" "#ui/node_modules" "#LICENSE.md" "#pkg/web/openapi/**" "#.github/*.md" + markdownlint-cli2 "**/*.md" "#LICENSE.md" "#pkg/web/openapi/**" "#.github/*.md" diff --git a/README.md b/README.md index 13ea66adb..0552947ab 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,7 @@ _Data Integration for Production Data Stores. :dizzy:_ Conduit is a data streaming tool written in Go. It aims to provide the best user experience for building and running real-time data pipelines. Conduit comes with -batteries included, it provides a UI, common connectors, processors and -observability data out of the box. +common connectors, processors and observability data out of the box. Conduit pipelines are built out of simple building blocks which run in their own goroutines and are connected using Go channels. This makes Conduit pipelines @@ -40,43 +39,12 @@ Conduit was created and open-sourced by [Meroxa](https://meroxa.io). - [Connectors](#connectors) - [Processors](#processors) - [API](#api) -- [UI](#ui) - [Documentation](#documentation) - [Contributing](#contributing) ## Quick start -1. Download and extract - the [latest release](https://github.com/conduitio/conduit/releases/latest). -2. Download - the [example pipeline](/examples/pipelines/file-to-file.yaml) - and put it in the directory named `pipelines` in the same directory as the - Conduit binary. -3. Run Conduit (`./conduit`). The example pipeline will start automatically. -4. Write something to file `example.in` in the same directory as the Conduit - binary. - - ```sh - echo "hello conduit" >> example.in - ``` - -5. Read the contents of `example.out` and notice an OpenCDC record: - - ```sh - $ cat example.out - {"position":"MTQ=","operation":"create","metadata":{"file.path":"./example.in","opencdc.readAt":"1663858188836816000","opencdc.version":"v1"},"key":"MQ==","payload":{"before":null,"after":"aGVsbG8gY29uZHVpdA=="}} - ``` - -6. The string `hello conduit` is a base64 encoded string stored in the field - `payload.after`, let's decode it: - - ```sh - $ cat example.out | jq ".payload.after | @base64d" - "hello conduit" - ``` - -7. Explore the UI by opening `http://localhost:8080` and build your own - pipeline! + ## Installation guide @@ -90,8 +58,8 @@ simply run it! ./conduit ``` -Once you see that the service is running you may access a user-friendly web -interface at `http://localhost:8080`. You can also interact with +Once you see that the service is running, the configured pipeline should start +processing records automatically. You can also interact with the [Conduit API](#api) directly, we recommend navigating to `http://localhost:8080/openapi` and exploring the HTTP API through Swagger UI. @@ -132,9 +100,6 @@ rpm -i conduit_0.12.2_Linux_x86_64.rpm Requirements: - [Go](https://golang.org/) -- [Node.js](https://nodejs.org/) (18.x) -- [Yarn](https://yarnpkg.com/) (latest 1.x) -- [Ember CLI](https://ember-cli.com/) - [Make](https://www.gnu.org/software/make/) ```shell @@ -144,11 +109,6 @@ make ./conduit ``` -Note that you can also build Conduit with `make build-server`, which only -compiles the server and skips the UI. This command requires only Go and builds -the binary much faster. That makes it useful for development purposes or for -running Conduit as a simple backend service. - ### Docker Our Docker images are hosted on GitHub's Container Registry. To run the latest @@ -158,9 +118,6 @@ Conduit version, you should run the following command: docker run -p 8080:8080 conduit.docker.scarf.sh/conduitio/conduit:latest ``` -The Docker image includes the [UI](#ui), you can access it by navigating -to `http://localhost:8080`. - ## Configuring Conduit Conduit accepts CLI flags, environment variables and a configuration file to @@ -190,6 +147,10 @@ each configuration option based on the following priorities: connection-string: postgres://localhost:5432/conduitdb # -db.postgres.connection-string or CONDUIT_DB_POSTGRES_CONNECTION_STRING ``` +This parsing configuration is provided thanks to our own CLI library [ecdysis](https://github.com/conduitio/ecdysis), +which builds on top of [Cobra](https://github.com/spf13/cobra) and uses [Viper](https://github.com/spf13/viper) +under the hood. + ## Storage Conduit's own data (information about pipelines, connectors, etc.) can be stored @@ -296,17 +257,6 @@ or run Conduit and navigate to `http://localhost:8080/openapi` to open a [Swagger UI](https://github.com/swagger-api/swagger-ui) which makes it easy to try it out. -## UI - -Conduit comes with a web UI that makes building data pipelines a breeze, you can -access it at `http://localhost:8080`. See -the [installation guide](#build-from-source) for instructions on how to build -Conduit with the UI. - -For more information about the UI refer to the [Readme](ui/README.md) in `/ui`. - -![animation](docs/data/animation.gif) - ## Documentation To learn more about how to use Conduit diff --git a/docs/data/animation.gif b/docs/data/animation.gif deleted file mode 100644 index 7fa69f24d..000000000 Binary files a/docs/data/animation.gif and /dev/null differ diff --git a/go.mod b/go.mod index 314d399dd..e25c31efa 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( buf.build/gen/go/grpc-ecosystem/grpc-gateway/protocolbuffers/go v1.36.0-20240617172850-a48fcebcf8f1.1 github.com/Masterminds/semver/v3 v3.3.1 github.com/Masterminds/sprig/v3 v3.3.0 - github.com/NYTimes/gziphandler v1.1.1 github.com/bufbuild/buf v1.47.2 github.com/conduitio/conduit-commons v0.5.0 github.com/conduitio/conduit-connector-file v0.9.0 diff --git a/go.sum b/go.sum index fe90d802a..f9a7fbc27 100644 --- a/go.sum +++ b/go.sum @@ -94,8 +94,6 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= diff --git a/pkg/conduit/runtime.go b/pkg/conduit/runtime.go index c9c94d2c6..168d78003 100644 --- a/pkg/conduit/runtime.go +++ b/pkg/conduit/runtime.go @@ -62,7 +62,6 @@ import ( "github.com/conduitio/conduit/pkg/schemaregistry" "github.com/conduitio/conduit/pkg/web/api" "github.com/conduitio/conduit/pkg/web/openapi" - "github.com/conduitio/conduit/pkg/web/ui" apiv1 "github.com/conduitio/conduit/proto/api/v1" grpcruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/piotrkowalczuk/promgrpc/v4" @@ -352,7 +351,6 @@ func (r *Runtime) Run(ctx context.Context) (err error) { port = tcpAddr.Port } r.logger.Info(ctx).Send() - r.logger.Info(ctx).Msgf("click here to navigate to Conduit UI: http://localhost:%d/ui", port) r.logger.Info(ctx).Msgf("click here to navigate to explore the HTTP API: http://localhost:%d/openapi", port) r.logger.Info(ctx).Send() } @@ -676,35 +674,6 @@ func (r *Runtime) serveHTTPAPI( return nil, cerrors.Errorf("failed to register openapi redirect handler: %w", err) } - uiHandler, err := ui.Handler() - if err != nil { - return nil, cerrors.Errorf("failed to set up ui handler: %w", err) - } - - uiHandler = http.StripPrefix("/ui", uiHandler) - - err = gwmux.HandlePath( - "GET", - "/ui/**", - func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - uiHandler.ServeHTTP(w, req) - }, - ) - if err != nil { - return nil, cerrors.Errorf("failed to register ui handler: %w", err) - } - - err = gwmux.HandlePath( - "GET", - "/", - func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - http.Redirect(w, req, "/ui", http.StatusFound) - }, - ) - if err != nil { - return nil, cerrors.Errorf("failed to register redirect handler: %w", err) - } - metricsHandler := r.newHTTPMetricsHandler() err = gwmux.HandlePath( "GET", diff --git a/pkg/web/ui/assets.go b/pkg/web/ui/assets.go deleted file mode 100644 index 0b92bf5f6..000000000 --- a/pkg/web/ui/assets.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright © 2022 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build ui - -package ui - -import ( - "embed" - "io/fs" - "net/http" - - "github.com/conduitio/conduit/pkg/foundation/cerrors" -) - -//go:embed dist/* -var distFS embed.FS - -func newUIAssetFS() (http.FileSystem, error) { - return assetFS(distFS, "dist") -} - -func assetFS(embeddedFS embed.FS, dir string) (http.FileSystem, error) { - subFS, err := fs.Sub(embeddedFS, dir) - if err != nil { - panic(cerrors.Errorf("couldn't create sub filesystem: %w", err)) - } - - _, err = subFS.Open("index.html") - if err != nil { - if cerrors.Is(err, fs.ErrNotExist) { - return nil, cerrors.Errorf("UI is enabled but no index.html found: %w", err) - } else { - return nil, err - } - } - - return &SPARoutingFS{FileSystem: http.FS(subFS)}, nil -} diff --git a/pkg/web/ui/distub/index.html b/pkg/web/ui/distub/index.html deleted file mode 100644 index 54fff15f8..000000000 --- a/pkg/web/ui/distub/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Conduit UI - - - - - - - - - - -

Conduit UI is disabled in this build

- - diff --git a/pkg/web/ui/handler.go b/pkg/web/ui/handler.go deleted file mode 100644 index e4d5006f2..000000000 --- a/pkg/web/ui/handler.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © 2022 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package ui - -import ( - "net/http" - - "github.com/NYTimes/gziphandler" - "github.com/conduitio/conduit/pkg/foundation/cerrors" -) - -// Handler serves Conduit UI. -func Handler() (http.Handler, error) { - uiAssetFS, err := newUIAssetFS() - if err != nil { - return nil, cerrors.Errorf("UI assets error: %w", err) - } - return gziphandler.GzipHandler(http.FileServer(uiAssetFS)), nil -} diff --git a/pkg/web/ui/spa_routing.go b/pkg/web/ui/spa_routing.go deleted file mode 100644 index 216a979d0..000000000 --- a/pkg/web/ui/spa_routing.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © 2022 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package ui - -import ( - "io/fs" - "net/http" - - "github.com/conduitio/conduit/pkg/foundation/cerrors" -) - -type SPARoutingFS struct { - FileSystem http.FileSystem -} - -func (spaFS *SPARoutingFS) Open(name string) (http.File, error) { - file, err := spaFS.FileSystem.Open(name) - - if err == nil { - return file, nil - } - - if cerrors.Is(err, fs.ErrNotExist) { - file, err := spaFS.FileSystem.Open("index.html") - return file, err - } - - return nil, err -} diff --git a/pkg/web/ui/stubs.go b/pkg/web/ui/stubs.go deleted file mode 100644 index 34385489d..000000000 --- a/pkg/web/ui/stubs.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © 2022 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !ui - -package ui - -import ( - "embed" - "io/fs" - "net/http" - - "github.com/conduitio/conduit/pkg/foundation/cerrors" -) - -//go:embed distub/* -var distubFS embed.FS - -func newUIAssetFS() (http.FileSystem, error) { - return assetFS(distubFS, "distub") -} - -func assetFS(embeddedFS embed.FS, dir string) (http.FileSystem, error) { - subFS, err := fs.Sub(embeddedFS, dir) - if err != nil { - panic(cerrors.Errorf("couldn't create sub filesystem: %w", err)) - } - - return &SPARoutingFS{FileSystem: http.FS(subFS)}, nil -} diff --git a/ui/.editorconfig b/ui/.editorconfig deleted file mode 100644 index c35a00240..000000000 --- a/ui/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# EditorConfig helps developers define and maintain consistent -# coding styles between different editors and IDEs -# editorconfig.org - -root = true - -[*] -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -indent_style = space -indent_size = 2 - -[*.hbs] -insert_final_newline = false - -[*.{diff,md}] -trim_trailing_whitespace = false diff --git a/ui/.ember-cli b/ui/.ember-cli deleted file mode 100644 index d41bd6394..000000000 --- a/ui/.ember-cli +++ /dev/null @@ -1,15 +0,0 @@ -{ - /** - Ember CLI sends analytics information by default. The data is completely - anonymous, but there are times when you might want to disable this behavior. - - Setting `disableAnalytics` to true will prevent any data from being sent. - */ - "disableAnalytics": false, - "outputPath": "../pkg/web/ui/dist", - /** - Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript - rather than JavaScript by default, when a TypeScript version of a given blueprint is available. - */ - "isTypeScriptProject": false -} diff --git a/ui/.eslintignore b/ui/.eslintignore deleted file mode 100644 index 42457a3f2..000000000 --- a/ui/.eslintignore +++ /dev/null @@ -1,25 +0,0 @@ -# unconventional js -/blueprints/*/files/ -/blueprints/*/index.js -/vendor/ - -# compiled output -/dist/ -/dist-prod/ -/tmp/ - -# dependencies -/bower_components/ -/node_modules/ - -# misc -/coverage/ -!.* -.*/ - -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/npm-shrinkwrap.json.ember-try -/package.json.ember-try -/package-lock.json.ember-try diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js deleted file mode 100644 index fffce5a70..000000000 --- a/ui/.eslintrc.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -module.exports = { - root: true, - parser: '@babel/eslint-parser', - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - requireConfigFile: false, - babelOptions: { - plugins: [ - ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }], - ], - }, - }, - plugins: ['ember'], - extends: [ - 'eslint:recommended', - 'plugin:ember/recommended', - 'plugin:prettier/recommended', - ], - env: { - browser: true, - node: true, - }, - rules: { - // this can be removed once the following is fixed - // https://github.com/mysticatea/eslint-plugin-node/issues/77 - 'node/no-unpublished-require': 'off', - - // TODO: remove this and fix issues raised - 'ember/no-runloop': 'off', - }, - overrides: [ - // node files - { - files: [ - './.eslintrc.js', - './.prettierrc.js', - './.stylelintrc.js', - './.template-lintrc.js', - './ember-cli-build.js', - './testem.js', - './blueprints/*/index.js', - './config/**/*.js', - './lib/*/index.js', - './server/**/*.js', - ], - parserOptions: { - sourceType: 'script', - }, - env: { - browser: false, - node: true, - }, - extends: ['plugin:n/recommended'], - }, - { - // test files - files: ['tests/**/*-test.{js,ts}'], - extends: ['plugin:qunit/recommended'], - }, - ], -}; diff --git a/ui/.netlifyredirects b/ui/.netlifyredirects deleted file mode 100644 index 50a463356..000000000 --- a/ui/.netlifyredirects +++ /dev/null @@ -1 +0,0 @@ -/* /index.html 200 \ No newline at end of file diff --git a/ui/.prettierignore b/ui/.prettierignore deleted file mode 100644 index 6415271b9..000000000 --- a/ui/.prettierignore +++ /dev/null @@ -1,21 +0,0 @@ -/blueprints/*/index.js -/blueprints/*/files/ -/blueprints/*/index.js - -# unconventional js -/blueprints/*/files/ - -# compiled output -/dist/ - -# misc -/coverage/ -!.* -.*/ - -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/npm-shrinkwrap.json.ember-try -/package.json.ember-try -/package-lock.json.ember-try diff --git a/ui/.prettierrc.js b/ui/.prettierrc.js deleted file mode 100644 index bec32d2ff..000000000 --- a/ui/.prettierrc.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -module.exports = { - singleQuote: true, - overrides: [ - { - files: '*.hbs', - options: { - singleQuote: false, - printWidth: 100, - }, - }, - ], -}; diff --git a/ui/.stylelintignore b/ui/.stylelintignore deleted file mode 100644 index 95a6a3d6c..000000000 --- a/ui/.stylelintignore +++ /dev/null @@ -1,10 +0,0 @@ -# unconventional files -/blueprints/*/files/ -/coverage/* - -# compiled output -/dist/ -/dist-prod/ - -# addons -/.node_modules.ember-try/ diff --git a/ui/.stylelintrc.js b/ui/.stylelintrc.js deleted file mode 100644 index 0abc5a468..000000000 --- a/ui/.stylelintrc.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -module.exports = { - extends: ['stylelint-config-standard', 'stylelint-prettier/recommended'], - rules: { - 'at-rule-no-unknown': [ - true, - { - ignoreAtRules: ['/tailwind/'], - }, - ], - }, -}; diff --git a/ui/.template-lintrc.js b/ui/.template-lintrc.js deleted file mode 100644 index a14e4ede0..000000000 --- a/ui/.template-lintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -module.exports = { - extends: 'recommended', - rules: { - 'no-negated-condition': false, - }, -}; diff --git a/ui/.watchmanconfig b/ui/.watchmanconfig deleted file mode 100644 index e7834e3e4..000000000 --- a/ui/.watchmanconfig +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ignore_dirs": ["tmp", "dist"] -} diff --git a/ui/LICENSE b/ui/LICENSE deleted file mode 100644 index e0173ef17..000000000 --- a/ui/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 Meroxa, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/ui/Makefile b/ui/Makefile deleted file mode 100644 index 8b585cefc..000000000 --- a/ui/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -.PHONY: dist dependencies lint lint-fix server test - -dist: - @yarn --ignore-optional - @yarn run build - -dependencies: - @yarn --frozen-lockfile - -lint: - @yarn run lint - -lint-fix: - @yarn run lint:fix - -server: - @yarn run start - -test: - @yarn run test:ember diff --git a/ui/README.md b/ui/README.md deleted file mode 100644 index 3db2dd96e..000000000 --- a/ui/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Conduit UI - -Conduit UI is the web front-end for Conduit built with [Ember](https://emberjs.com/). - -## Architecture - -The UI application is a standard Ember application that is simply rooted in the `ui` directory of the Conduit project. -The UI can then be built and embedded into Conduit's binary during a Conduit build. - -## Prerequisites - -You will need the following things properly installed on your computer. - -- [Git](https://git-scm.com/) -- [Node.js](https://nodejs.org/) -- [Yarn](https://yarnpkg.com/) -- [Ember CLI](https://cli.emberjs.com/release/) -- [Google Chrome](https://google.com/chrome/) - -## Installation - -- `git clone git@github.com:ConduitIO/conduit.git` the Conduit repository -- `cd conduit` -- `make ui-dependencies` - -_Note:_ Commands in this readme are run from the Conduit project root. Alternatively, you can change into the `ui/` -directory to directly use Yarn, [Ember CLI](https://ember-cli.com/), or non-prefixed [UI Makefile](Makefile) commands. - -## Running / Development - -Before running Conduit UI, you must make sure the Conduit server is running - -- `make run` - -Alternatively, if you'd like to develop the UI against the Conduit server binary - -- `make build` -- `./conduit` to run the built binary server - -After confirming that Conduit server is running locally, you can now run the UI - -- `make ui-server` -- Visit your app at [http://localhost:4200](http://localhost:4200). - -### Running Tests - -- `make ui-test` - -### Linting - -- `make ui-lint` -- `make ui-lint-fix` - -### Building Conduit UI - -Conduit UI is built and embedded into the server's binary using [Go embed directives](https://pkg.go.dev/embed). To -build the binary with the embedded UI - -- `make build-with-ui` - -This will build the production UI asset bundle, output it to `pkg/web/ui/dist`, and build the server binary embedded -with the bundle. - -## Further Reading / Useful Links - -- [ember.js](https://emberjs.com/) -- [ember-cli](https://cli.emberjs.com/release/) -- Development Browser Extensions - - [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) - - [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) diff --git a/ui/app/adapters/application.js b/ui/app/adapters/application.js deleted file mode 100644 index de5b561b4..000000000 --- a/ui/app/adapters/application.js +++ /dev/null @@ -1,63 +0,0 @@ -import RESTAdapter from '@ember-data/adapter/rest'; -import { dasherize } from '@ember/string'; -import { pluralize } from 'ember-inflector'; -import config from 'conduit-ui/config/environment'; -import { inject as service } from '@ember/service'; -import { InvalidError } from '@ember-data/adapter/error'; - -export default class ApplicationAdapter extends RESTAdapter { - @service - flashMessages; - - namespace = 'v1'; - host = config.conduitAPIURL; - - pathForType(modelName) { - var dasherized = dasherize(modelName); - return pluralize(dasherized); - } - - handleResponse(status, headers, payload, requestData) { - if (this.isSuccess(status, headers, payload)) { - return payload; - } else if (this.isInvalid(status, headers, payload)) { - return new InvalidError( - typeof payload === 'object' ? payload.details : undefined, - ); - } - - const handledResponse = super.handleResponse( - status, - headers, - payload, - requestData, - ); - - if (handledResponse.isAdapterError) { - this.flashMessages.add({ - type: 'error', - message: payload.message || 'Server Error', - sticky: true, - }); - } - return handledResponse; - } - - normalizeErrorResponse(status, headers, payload) { - if ( - payload && - typeof payload === 'object' && - payload.errors instanceof Array - ) { - return payload.errors; - } else { - return [ - { - status: `${status}`, - title: 'The backend responded with an error', - detail: payload.message, - }, - ]; - } - } -} diff --git a/ui/app/app.js b/ui/app/app.js deleted file mode 100644 index aff74e369..000000000 --- a/ui/app/app.js +++ /dev/null @@ -1,12 +0,0 @@ -import Application from '@ember/application'; -import Resolver from 'ember-resolver'; -import loadInitializers from 'ember-load-initializers'; -import config from 'conduit-ui/config/environment'; - -export default class App extends Application { - modulePrefix = config.modulePrefix; - podModulePrefix = config.podModulePrefix; - Resolver = Resolver; -} - -loadInitializers(App, config.modulePrefix); diff --git a/ui/app/components/.gitkeep b/ui/app/components/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/ui/app/components/notification-card/error.hbs b/ui/app/components/notification-card/error.hbs deleted file mode 100644 index 0f3a67e95..000000000 --- a/ui/app/components/notification-card/error.hbs +++ /dev/null @@ -1,35 +0,0 @@ -
-
-
-
-
- - - -
- {{#if @error}} -

{{@error.message}}

- {{else}} -

{{@errorMessage}}

- {{/if}} -
- {{#if @error.details}} -
-
    - {{#each @error.details as |detail|}} -
  • {{detail}}
  • - {{/each}} -
-
- {{/if}} - -
- - {{or @buttonText "Dismiss"}} - -
-
-
diff --git a/ui/app/components/pipeline-editor.hbs b/ui/app/components/pipeline-editor.hbs deleted file mode 100644 index d76b25fd6..000000000 --- a/ui/app/components/pipeline-editor.hbs +++ /dev/null @@ -1,233 +0,0 @@ -
-
-
-
-
- Pipeline -
- {{#if @pipeline.isRunning}} - -
- You must pause the pipeline if you'd like to add new connectors. -
-
- - {{else}} - - - - - - -
    - {{! template-lint-disable no-invalid-interactive }} -
  • - {{! template-lint-enable no-invalid-interactive }} - - - - Source -
  • -
  • - - - - Destination -
  • -
-
-
- {{/if}} -
-
-
- -
-
-
- {{#if (gt this.allConnectors.length 0)}} -
- -
-
- -
- {{#if (gt this.allConnectors.length 0)}} - - {{/if}} -
- -
-
-
-
- -
- - -
-
-
-
- {{else}} -
-
-
-

- Build your pipeline -

-

- Begin building your pipeline by adding a Source or Destination Connector. -

-
- - Add Source - - - Add Destination - -
-
-
-
- {{/if}} - {{#if this.isConnectorSelectedNode}} - - {{/if}} -
-
-
-
{{app-version shaOnly=true}}
-
-{{#if this.isShowingNewConnectorModal}} - -{{/if}} -{{#if this.isShowingEditConnectorModal}} - -{{/if}} -{{#if this.isShowingDeleteConnectorModal}} - - - {{#if (not this.isLongConnectorName)}} - Deleting a connector cannot be undone. Please input your connector's name - - ( - {{entityName}} - ) - - below to confirm you would like to delete this connector - {{else}} - Deleting a connector cannot be undone. Confirm you would like to delete this connector. - {{/if}} - -{{/if}} - -{{#if this.isShowingStreamInspector}} - -{{/if}} diff --git a/ui/app/components/pipeline-editor.js b/ui/app/components/pipeline-editor.js deleted file mode 100644 index 07c9aa11e..000000000 --- a/ui/app/components/pipeline-editor.js +++ /dev/null @@ -1,310 +0,0 @@ -import Component from '@glimmer/component'; -import { action } from '@ember/object'; -import { tracked } from '@glimmer/tracking'; -import { later, run } from '@ember/runloop'; -import { inject as service } from '@ember/service'; -import { A } from '@ember/array'; -import { Changeset } from 'ember-changeset'; -import lookupValidator from 'ember-changeset-validations'; -import { isChangeset } from 'validated-changeset'; -import { validatePresence } from 'ember-changeset-validations/validators'; -/** - * PLEASE READ THIS NOTE ABOUT CHANGESETS - * - * It turns out, ember-changeset does some magic proxy trapping on "get" and "set" when values - * are set on objects. Also remember ember-data records are essentially global singletons. - * - * Enter the ember-inspector. The ember-inspector does some sort of mutation on ember-data - * objects, I believe around events for teardown. This can actually set strange "willDestroy" - * properties on the changesets. This is not great... - * - * Changeset actually accounts for this via the 'changesetKeys' option we pass into new changesets - * but unfortunately it doesnt work for ember-data objects that have related ember-data objects... - * it registers in changeset as a nested change because the related ember-data model is being mutated - * by the inspector - * - * SEE https://github.com/poteto/ember-changeset/issues/485 - * - * TLDR simply opening the ember-inspector can mess with changesets, thus making debugging - * a nightmare, and messing with your beautiful dashboard experience. - * - * This should never affect any regular users, but could make developing against conduit UI a bad experience. - * I have not seen this issue after cleaning some things up, but it needs a more smoke testing before we can fully rely on 'changes' - */ - -const ConnectorValidations = { - name: validatePresence({ presence: true }), - plugin: validatePresence({ presence: true }), -}; - -export default class PipelineEditorComponent extends Component { - @service - pipelineNodeManager; - - @service - websockets; - - @service - store; - - @tracked - isEditingPipeline = false; - - @tracked - selectedNode = null; - - @tracked - newConnectorType = 'source'; - - @tracked - isShowingNewConnectorModal = false; - - @tracked - isShowingEditConnectorModal = false; - - @tracked - isShowingDeleteConnectorModal = false; - - @tracked - isShowingConfirmPlayModal = false; - - @tracked - isShowingConfirmPauseModal = false; - - @tracked - isShowingStreamInspector = false; - - @tracked - wrappedConnectors = A([]); - - @tracked - wrappedConnectorTransforms = A([]); - - @tracked - pendingConnectors = A([]); - - @tracked - connectorModalModel = null; - - constructor() { - super(...arguments); - this._wrapConnectors(this.args.pipeline); - } - - // Wrap all connectors in changesets - // This lets us validate and queue up changes - // without affecting the underlying model - _wrapConnectors(pipeline) { - this.wrappedConnectors = pipeline.get('connectors').map((connector) => { - return Changeset( - connector, - lookupValidator(ConnectorValidations), - ConnectorValidations, - { - changesetKeys: [ - 'name', - 'plugin', - 'type', - 'config', - 'connectorPlugin', - 'pipeline', - ], - }, - ); - }); - } - - get sourceConnectors() { - let connectors; - if (this.pendingConnectors.length > 0) { - connectors = [...this.wrappedConnectors, ...this.pendingConnectors]; - } else { - connectors = this.wrappedConnectors; - } - - return connectors.filterBy('type', 'source'); - } - - get destinationConnectors() { - let connectors; - if (this.pendingConnectors.length > 0) { - connectors = [...this.wrappedConnectors, ...this.pendingConnectors]; - } else { - connectors = this.wrappedConnectors; - } - - return connectors.filterBy('type', 'destination'); - } - - get allConnectors() { - return A([...this.sourceConnectors, ...this.destinationConnectors]); - } - - get isConnectorSelectedNode() { - if (!this.selectedNode) { - return false; - } - - return ( - isChangeset(this.selectedNode) && - this.selectedNode.data.constructor.modelName === 'connector' - ); - } - - get isLongConnectorName() { - return this.selectedNode?.name.length > 32; - } - - @action - showCreateConnectorModal(connectorType) { - this.newConnectorType = connectorType; - - const connectorModel = this.store.createRecord('connector', { - type: this.newConnectorType, - plugin: '', - config: { name: '', settings: {} }, - pipeline: this.args.pipeline, - }); - - this.connectorModalModel = Changeset( - connectorModel, - lookupValidator(ConnectorValidations), - ConnectorValidations, - { - changesetKeys: [ - 'name', - 'type', - 'plugin', - 'config', - 'connectorPlugin', - 'pipeline', - ], - }, - ); - this.isShowingNewConnectorModal = true; - } - - @action - cancelCreateConnectorModal() { - if ( - this.connectorModalModel && - !(this.store.isDestroying || this.store.isDestroyed) - ) { - this.connectorModalModel.data.unloadRecord(); - } - this.connectorModalModel = null; - this.isShowingNewConnectorModal = false; - } - - @action - showEditConnectorModal(connector) { - this.isShowingEditConnectorModal = true; - this.connectorModalModel = connector; - } - - @action - cancelEditConnectorModal() { - this.connectorModalModel.rollbackProperty('name'); - this.connectorModalModel.rollbackProperty('pluginPath'); - this.connectorModalModel.rollbackProperty('connectorType'); - this.connectorModalModel.rollbackProperty('settings'); - - this.connectorModalModel = null; - this.isShowingEditConnectorModal = false; - } - - @action - async createConnector(connector) { - try { - await connector.save(); - } catch (error) { - return; - } - - this.refreshEditorView(this.wrappedConnectors, connector); - this.isShowingNewConnectorModal = false; - } - - @action - async updateConnector(connector) { - try { - await connector.save(); - } catch (error) { - return; - } - - this.connectorModalModel = null; - this.isShowingEditConnectorModal = false; - } - - @action - async rollbackConnectorChanges(connector) { - connector.connectorTransforms.invoke('rollback'); - connector.rollback(); - } - - @action - async destroyConnector(connector) { - const connectorId = connector.id; - await connector.data.destroyRecord(); - - this.wrappedConnectors.removeObject( - this.wrappedConnectors.findBy('id', connectorId), - ); - this.pipelineNodeManager.regeneratePaths(); - this.selectNode(null); - this.hideDeleteConnectorModal(); - } - - @action - selectNode(node, event) { - later( - this, - function () { - this.selectedNode = node; - }, - 10, - ); - - if (event) { - event.stopPropagation(); - } - } - - @action - showDeleteConnectorModal() { - this.isShowingDeleteConnectorModal = true; - } - - @action - hideDeleteConnectorModal() { - this.isShowingDeleteConnectorModal = false; - } - - unregister(element, [pipelineNodeManager]) { - pipelineNodeManager.unregisterNodes(); - } - - refreshEditorView(recordList, record) { - // Run loops to the rescue - // It might be less fragile to instead explicitly create/destroy stream nodes - // - // This executes the actual changes to the node in one run loop - // and then regenerates the svg paths in another. - // This lets us wait for the stream node to insert itself onto - // the editor before we attempt to regenerate the paths - run(() => { - recordList.pushObject(record); - }); - - run(() => { - this.pipelineNodeManager.regeneratePaths(); - }); - } - - willDestroy() { - super.willDestroy(...arguments); - - this.cancelCreateConnectorModal(); - } -} diff --git a/ui/app/components/pipeline-editor/config-field.hbs b/ui/app/components/pipeline-editor/config-field.hbs deleted file mode 100644 index 803f189e6..000000000 --- a/ui/app/components/pipeline-editor/config-field.hbs +++ /dev/null @@ -1,78 +0,0 @@ -{{! template-lint-disable no-duplicate-id }} -
- {{#if @field.isRequired}} -
- - -
-
- -
- {{else}} - - {{/if}} -
- -{{#if (eq this.fieldType "text")}} - -{{/if}} - -{{#if (eq this.fieldType "number")}} - -{{/if}} - -{{#if (eq this.fieldType "toggle")}} - -{{/if}} - -{{#if (eq this.fieldType "select")}} - -{{/if}} - -{{#if (not this.isFieldValid)}} -
- {{#each @field.error.value.validation as |validation|}} -
{{validation}}
- {{/each}} -
-{{/if}} diff --git a/ui/app/components/pipeline-editor/config-field.js b/ui/app/components/pipeline-editor/config-field.js deleted file mode 100644 index c4712f0f6..000000000 --- a/ui/app/components/pipeline-editor/config-field.js +++ /dev/null @@ -1,108 +0,0 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { action } from '@ember/object'; - -export default class PipelineEditorConfigFieldComponent extends Component { - @tracked - selectSelected; - - selectOptions; - - get isFieldInvalid() { - return this.args.field.hasUserTakenAction && !this.args.field.isValid; - } - - get isFieldValid() { - return !this.isFieldInvalid; - } - - constructor() { - super(...arguments); - - this.fieldType = this.generateFieldType(); - - if (this.fieldType === 'select') { - this.selectOptions = this.generateSelectOptions(); - this.selectSelected = - this.selectOptions.findBy('value', this.args.field.value) || - this.selectOptions.firstObject; - } - } - - generateFieldType() { - const field = this.args.field; - - const isString = field.type === 'TYPE_STRING'; - - const isNumber = field.type === 'TYPE_INT' || field.type === 'TYPE_FLOAT'; - - const isDuration = field.type === 'TYPE_DURATION'; - - // TODO clean this up, and also check for special case of number, but using inclusion validation - // for numbers in a list? - const isTextInput = - (isString || isDuration) && - !field.rawValidations.findBy('type', 'TYPE_INCLUSION'); - const isNumberInput = - isNumber && !field.rawValidations.findBy('type', 'TYPE_INCLUSION'); - const isToggleInput = field.type == 'TYPE_BOOL'; - const isSelectInput = - (isString || isNumber) && - field.rawValidations.findBy('type', 'TYPE_INCLUSION'); - - if (isTextInput) { - return 'text'; - } - - if (isNumberInput) { - return 'number'; - } - - if (isToggleInput) { - return 'toggle'; - } - - if (isSelectInput) { - return 'select'; - } - } - - generateSelectOptions() { - const inclusionValidation = this.args.field.rawValidations.findBy( - 'type', - 'TYPE_INCLUSION', - ); - return inclusionValidation.value.split(',').map((item) => { - return { - name: item, - value: item, - }; - }); - } - - @action - setInputValue() { - if (!this.args.field.hasUserTakenAction) { - this.args.field.hasUserTakenAction = true; - } - this.args.setInputValue(...arguments); - } - - @action - setSelect(changeset, selection) { - this.args.setInputValue(changeset, { target: { value: selection.value } }); - this.selectSelected = selection; - } - - @action - setToggle(changeset, event) { - this.args.setInputValue(changeset, { - target: { value: event.target.checked }, - }); - } - - @action - validateField() { - this.args.field.validate(); - } -} diff --git a/ui/app/components/pipeline-editor/connector-column.hbs b/ui/app/components/pipeline-editor/connector-column.hbs deleted file mode 100644 index 5d2070528..000000000 --- a/ui/app/components/pipeline-editor/connector-column.hbs +++ /dev/null @@ -1,10 +0,0 @@ -
- {{#each @connectors as |connector|}} - - {{/each}} -
diff --git a/ui/app/components/pipeline-editor/connector-modal.hbs b/ui/app/components/pipeline-editor/connector-modal.hbs deleted file mode 100644 index 5d10418e2..000000000 --- a/ui/app/components/pipeline-editor/connector-modal.hbs +++ /dev/null @@ -1,140 +0,0 @@ - -
-
-
- -
-
- - {{#if (not this.isConnectorNameValid)}} -
- {{this.connector.error.name.validation}} -
- {{/if}} -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
- - {{#if this.isShowingFields}} -
- - {{#if this.optionalFields}} - {{! template-lint-disable no-invalid-interactive }} -
- Required -
-
- {{! template-lint-enable no-invalid-interactive }} - Optional -
- {{else}} - {{! template-lint-disable no-invalid-interactive }} -
- {{! template-lint-enable no-invalid-interactive }} - Configure -
- {{/if}} -
- -
- {{#if this.isShowingRequiredTab}} -
- {{#each this.requiredFields as |field|}} - - {{/each}} -
- {{/if}} - - {{#if (not this.isShowingRequiredTab)}} - {{#each this.optionalFields as |field|}} - - {{/each}} - {{/if}} -
- {{/if}} - -
- Cancel - {{#if this.isEditing}} - Update - {{else}} - Create - {{/if}} -
-
diff --git a/ui/app/components/pipeline-editor/connector-modal.js b/ui/app/components/pipeline-editor/connector-modal.js deleted file mode 100644 index 3942d3877..000000000 --- a/ui/app/components/pipeline-editor/connector-modal.js +++ /dev/null @@ -1,172 +0,0 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { A } from '@ember/array'; -import { action } from '@ember/object'; -import { inject as service } from '@ember/service'; -import generateBlueprintFields from 'conduit-ui/utils/blueprints/generate-blueprint-fields'; - -export default class PipelineEditorNewConnectorModal extends Component { - get isValid() { - return this.connector.isValid && this.blueprintFields.isEvery('isValid'); - } - - @service - pipelineNodeManager; - - @tracked - selectedConnectorType = { - name: this.args.newConnectorType, - value: this.args.newConnectorType, - }; - - @tracked - connector; - - @tracked - blueprintFields; - - @tracked - isShowingRequiredTab = true; - - // Connector name is always valid on init - // to prevent showing validations until user action is taken. - @tracked - isConnectorNameValid = true; - - // static - connectorPluginDefault = { - name: 'Please select...', - id: '', - }; - - // static - connectorTypes = [ - { name: 'source', value: 'source' }, - { name: 'destination', value: 'destination' }, - ]; - - constructor() { - super(...arguments); - this.connector = this.args.connector; - if (this.isEditing) { - this.blueprintFields = generateBlueprintFields( - this.connector.plugin.getParams(this.connector.type), - this.connector, - ); - } else { - this.blueprintFields = []; - } - } - - @action - validateConnector() { - this.connector.validate(); - } - - get headerText() { - if (this.isEditing) { - return `Edit ${this.connector.name}`; - } else { - return this.connector.name ? this.connector.name : 'Name your connector'; - } - } - - get requiredFields() { - return this.blueprintFields.filterBy('isRequired', true); - } - - get optionalFields() { - return this.blueprintFields.filterBy('isRequired', false); - } - - get isShowingFields() { - return !!this.connector.plugin; - } - - get selectedConnectorPlugin() { - if (this.connector.plugin) { - return this.connector.plugin; - } else { - return this.connectorPluginDefault; - } - } - - get sourceConnectorPlugins() { - return this.args.connectorPlugins.filter((plugin) => { - return Object.keys(plugin.sourceParams).length > 0; - }); - } - - get destinationConnectorPlugins() { - return this.args.connectorPlugins.filter((plugin) => { - return Object.keys(plugin.destinationParams).length > 0; - }); - } - - get connectorPluginOptions() { - const isNewSource = this.connector.type === 'source'; - - const relevantPlugins = isNewSource - ? this.sourceConnectorPlugins - : this.destinationConnectorPlugins; - const defaultOption = this.connectorPluginDefault; - - return A([defaultOption, ...relevantPlugins]); - } - - get isEditing() { - return this.args.isEditing; - } - - @action - setConnectorName(changeset, event) { - changeset.set('name', event.target.value); - - if (changeset.get('error.name')) { - this.isConnectorNameValid = false; - } else { - this.isConnectorNameValid = true; - } - } - - @action - setConnectorType(typeOption) { - this.connector.data.plugin = ''; - this.connector.data.type = typeOption.value; - this.connector.validate(); - this.blueprintFields = []; - this.selectedConnectorType = typeOption; - } - - @action - setConnectorPlugin(plugin) { - if (plugin.id === '') { - this.connector.data.plugin = null; - this.connector.validate(); - this.blueprintFields = []; - } else { - this.connector.data.plugin = plugin; - this.connector.validate(); - this.blueprintFields = generateBlueprintFields( - plugin.getParams(this.connector.type), - this.connector, - ); - } - this.isShowingRequiredTab = true; - } - - @action - setConnectorConfig(fieldChangeset, event) { - fieldChangeset.value = event.target.value; - - if (fieldChangeset.isValid) { - this.connector.set( - `config.settings.${fieldChangeset.id}`, - fieldChangeset.value, - ); - } else { - this.connector.set(`config.settings.${fieldChangeset.id}`, undefined); - // this.connector.rollbackProperty(`config.${fieldChangeset.id}`); - } - } -} diff --git a/ui/app/components/pipeline-editor/connector-overview.hbs b/ui/app/components/pipeline-editor/connector-overview.hbs deleted file mode 100644 index f7ca16c4d..000000000 --- a/ui/app/components/pipeline-editor/connector-overview.hbs +++ /dev/null @@ -1,73 +0,0 @@ -
    - {{#each @sourceConnectors as |connector|}} - {{! template-lint-disable no-invalid-interactive }} -
  • - {{! template-lint-enable no-invalid-interactive }} -
    -
    - {{connector.name}} -
    -
    - {{connector.connectorPlugin.name}} -
    -
    -
    -
    - {{connector.processors.length}} - {{#if (eq connector.processors.length 1)}} - Transform - {{else}} - Transforms - {{/if}} -
    -
    -
  • - {{/each}} - {{#each @destinationConnectors as |connector|}} - {{! template-lint-disable no-invalid-interactive }} -
  • - {{! template-lint-enable no-invalid-interactive }} -
    -
    - {{connector.name}} -
    -
    - {{connector.connectorPlugin.name}} -
    -
    -
    -
    - {{connector.processors.length}} - {{#if (eq connector.processors.length 1)}} - Transform - {{else}} - Transforms - {{/if}} -
    -
    -
  • - {{/each}} - {{#if (and (not @sourceConnectors) (not @destinationConnectors))}} -
    - No connectors. Try adding some with the '+' above! -
    - {{/if}} -
diff --git a/ui/app/components/pipeline-editor/connector-slide-panel.hbs b/ui/app/components/pipeline-editor/connector-slide-panel.hbs deleted file mode 100644 index b306a0594..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel.hbs +++ /dev/null @@ -1,248 +0,0 @@ -{{! template-lint-disable no-action }} - -
-
-
- - {{@selectedNode.name}} - -
- {{#if @pipeline.isRunning}} -
- -
- You must pause the pipeline if you'd like to update it's connectors -
-
- - - -
- {{else}} - - - - - - - -
    - {{! template-lint-disable no-invalid-interactive }} -
  • - {{! template-lint-enable no-invalid-interactive }} - - - - Edit Connector -
  • - {{! template-lint-disable no-invalid-interactive }} -
  • - {{! template-lint-enable no-invalid-interactive }} - - - - Remove Connector -
  • -
-
-
- {{/if}} -
-
-
{{@selectedNode.plugin.id}}
-
- Inspect stream -
-
-
- Transforms - {{this.sortedTransforms.length}} -
-
-
-
-
- - Add transform - -
-
-
    - {{#each this.wrappedSortedTransforms as |connectorTransform idx|}} - {{#if @pipeline.isRunning}} -
  1. -
    -
    -
    - {{add-one idx}} -
    -
    -
    - {{connectorTransform.transform.label}} -
    -
    - {{connectorTransform.transform.name}} -
    -
    -
    -
    -
  2. - {{else}} -
  3. -
    -
    - - - - - -
    - {{add-one idx}} -
    -
    -
    - {{connectorTransform.transform.label}} -
    -
    - {{connectorTransform.transform.name}} -
    -
    -
    - {{! template-lint-disable no-invalid-interactive }} - - {{! template-lint-enable no-invalid-interactive }} - - -
    -
  4. - - {{/if}} - - {{else}} -
    - No transforms configured for this source -
    - {{/each}} -
- - {{#if @pipeline.isRunning}} -
You must pause the pipeline if you'd like to update it's connectors or transforms.
- {{/if}} -
-
-
-
- - {{#if this.isShowingAvailableTransforms}} -
- -
- {{/if}} -
- {{#if this.isShowingNewTransformPanel}} - - {{/if}} - {{#if this.isShowingEditTransformPanel}} - - {{/if}} -
-
-
diff --git a/ui/app/components/pipeline-editor/connector-slide-panel.js b/ui/app/components/pipeline-editor/connector-slide-panel.js deleted file mode 100644 index 34c29a411..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel.js +++ /dev/null @@ -1,164 +0,0 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { action } from '@ember/object'; -import { inject as service } from '@ember/service'; -import lookupValidator from 'ember-changeset-validations'; -import { Changeset } from 'ember-changeset'; -import { run } from '@ember/runloop'; - -import { validatePresence } from 'ember-changeset-validations/validators'; - -const ConnectorTransformValidations = { - name: validatePresence({ presence: true }), -}; - -export default class PipelineEditorConnectorSlidePanel extends Component { - @service - store; - - @tracked - isShowingAvailableTransforms = false; - - @tracked - isShowingNewTransformPanel = false; - - @tracked - isShowingEditTransformPanel = false; - - @tracked - selectedTransform = null; - - @tracked - draggingItem = null; - - get sortedTransforms() { - const processors = this.args.selectedNode.get('processors.content'); - return processors - ? this.args.selectedNode.get('processors').sortBy('ordinal') - : []; - } - - get wrappedSortedTransforms() { - return this.sortedTransforms.map((processor) => { - return Changeset( - processor, - lookupValidator(ConnectorTransformValidations), - ConnectorTransformValidations, - { - changesetKeys: ['type', 'config', 'parent'], - }, - ); - }); - } - - @action - showNewTransformPanel(transform) { - const newConnectorTransform = this.store.createRecord('processor', { - type: `${transform.id}${transform.onOptions.firstObject}`, - parent: { - type: 'TYPE_CONNECTOR', - id: this.args.selectedNode.id, - }, - config: { settings: {} }, - }); - - this.selectedTransform = Changeset( - newConnectorTransform, - lookupValidator(ConnectorTransformValidations), - ConnectorTransformValidations, - { - changesetKeys: ['type', 'config', 'parent', 'transform'], - }, - ); - - this.isShowingNewTransformPanel = true; - } - - @action - cancelNewTransformPanel() { - this.selectedTransform = null; - this.isShowingNewTransformPanel = false; - } - - @action - showEditTransformPanel(connectorTransform) { - this.selectedTransform = connectorTransform; - this.isShowingEditTransformPanel = true; - } - - @action - cancelEditTransformPanel() { - this.isShowingEditTransformPanel = false; - this.selectedTransform = null; - } - - @action - sortConnectorTransforms(connectorTransforms) { - run(() => { - connectorTransforms.forEach((connectorTransform, idx) => { - if (connectorTransform.ordinal !== idx) { - connectorTransform.data.hasPendingChanges = true; - } - connectorTransform.ordinal = idx; - }); - }); - - if (connectorTransforms.isAny('data.hasPendingChanges')) { - this.args.selectedNode.data.hasPendingChanges = true; - } - } - - @action - async addTransform(connectorTransform) { - await connectorTransform.save(); - this.args.selectedNode.processors.pushObject(connectorTransform.data); - this.isShowingNewTransformPanel = false; - this.isShowingAvailableTransforms = false; - } - - @action - async updateTransform(connectorTransform) { - await connectorTransform.save(); - this.isShowingEditTransformPanel = false; - } - - @action - duplicateTransform(connectorTransform) { - const duplicated = this.store.createRecord('processor', { - type: connectorTransform.type, - parent: connectorTransform.data.parent, - config: connectorTransform.data.config, - }); - - const changeset = Changeset( - duplicated, - lookupValidator(ConnectorTransformValidations), - ConnectorTransformValidations, - { - changesetKeys: ['type', 'config', 'parent', 'transform'], - }, - ); - - this.addTransform(changeset); - this.isShowingEditTransformPanel = false; - } - - @action - async removeTransform(connectorTransform) { - await connectorTransform.data.destroyRecord(); - this.selectedTransform = null; - - this.isShowingEditTransformPanel = false; - this.isShowingAvailableTransforms = false; - } - - @action - onDragStart(item) { - this.draggingItem = item; - } - - @action - onDragStop() { - this.draggingItem = null; - } -} diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/available-transforms-panel.hbs b/ui/app/components/pipeline-editor/connector-slide-panel/available-transforms-panel.hbs deleted file mode 100644 index eb4f9e62d..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/available-transforms-panel.hbs +++ /dev/null @@ -1,41 +0,0 @@ -
-
- - Select transform - - -
-
- -
- Built-in Transforms -
-
    - {{#each this.availableFilteredTransforms as |availableTransform|}} - {{!-- template-lint-disable no-invalid-interactive --}} -
  • - {{!-- template-lint-enable no-invalid-interactive --}} -
    -
    - {{availableTransform.label}} -
    -

    - {{availableTransform.description}} -

    -
    - - - -
  • - {{/each}} -
-
-
diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/available-transforms-panel.js b/ui/app/components/pipeline-editor/connector-slide-panel/available-transforms-panel.js deleted file mode 100644 index 6792a373a..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/available-transforms-panel.js +++ /dev/null @@ -1,27 +0,0 @@ -import Component from '@glimmer/component'; -import { action } from '@ember/object'; -import { tracked } from '@glimmer/tracking'; - -export default class ConnectorSlidePanelAvailableTransformsPanelComponent extends Component { - @tracked - fuzzyInput = ''; - - get availableFilteredTransforms() { - if (this.fuzzyInput) { - return this.args.availableTransforms.filter((transform) => { - return ( - transform.name - .toLowerCase() - .indexOf(this.fuzzyInput.toLowerCase()) !== -1 - ); - }); - } else { - return this.args.availableTransforms; - } - } - - @action - onFuzzyInput(event) { - this.fuzzyInput = event.target.value; - } -} diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/pause-button.hbs b/ui/app/components/pipeline-editor/connector-slide-panel/pause-button.hbs deleted file mode 100644 index e4dbdf296..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/pause-button.hbs +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/pause-button.js b/ui/app/components/pipeline-editor/connector-slide-panel/pause-button.js deleted file mode 100644 index 4bb8da894..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/pause-button.js +++ /dev/null @@ -1,21 +0,0 @@ -import Component from '@glimmer/component'; - -const pauseMap = { - running: 'text-gray-500', - degraded: 'text-gray-500', - paused: 'text-yellow-400', - pending: 'text-yellow-400', -}; - -export default class PipelineEditorConnectorSlidePanelPauseButtonComponent extends Component { - get textColorClass() { - return pauseMap[this.args.connectorStatus]; - } - - get isDisabled() { - return ( - this.args.connectorStatus === 'paused' || - this.args.connectorStatus === 'pending' - ); - } -} diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/play-button.hbs b/ui/app/components/pipeline-editor/connector-slide-panel/play-button.hbs deleted file mode 100644 index dbf74a2e8..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/play-button.hbs +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/play-button.js b/ui/app/components/pipeline-editor/connector-slide-panel/play-button.js deleted file mode 100644 index 63fd0ca78..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/play-button.js +++ /dev/null @@ -1,22 +0,0 @@ -import Component from '@glimmer/component'; - -const playMap = { - running: 'text-teal-600', - degraded: 'text-teal-600', - paused: 'text-gray-500', - pending: 'text-gray-500', -}; - -export default class PipelineEditorConnectorSlidePanelPlayButtonComponent extends Component { - get textColorClass() { - return playMap[this.args.connectorStatus]; - } - - get isDisabled() { - return ( - this.args.connectorStatus === 'running' || - this.args.connectorStatus === 'degraded' || - this.args.connectorStatus === 'pending' - ); - } -} diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/transform-panel.hbs b/ui/app/components/pipeline-editor/connector-slide-panel/transform-panel.hbs deleted file mode 100644 index 6d910dd8d..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/transform-panel.hbs +++ /dev/null @@ -1,92 +0,0 @@ -
-
- - {{#if @isEditing}} -
-
- - - - - - - - -
    - {{!-- template-lint-disable no-invalid-interactive --}} -
  • - {{!-- template-lint-enable no-invalid-interactive --}} - Duplicate -
  • - - {{!-- template-lint-disable no-invalid-interactive --}} -
  • - {{!-- template-lint-enable no-invalid-interactive --}} - Delete -
  • -
-
-
-
- {{/if}} -
- -
- {{this.connectorTransform.transform.label}} -

{{this.connectorTransform.transform.description}}

-
- -
-
- -
- - {{#each this.blueprintFields as |field|}} - -
- {{/each}} - -
- Cancel - - {{#if this.isEditing}} - - Update transform - - - {{else}} - - Add transform - - {{/if}} -
-
-
diff --git a/ui/app/components/pipeline-editor/connector-slide-panel/transform-panel.js b/ui/app/components/pipeline-editor/connector-slide-panel/transform-panel.js deleted file mode 100644 index 3b5f5705a..000000000 --- a/ui/app/components/pipeline-editor/connector-slide-panel/transform-panel.js +++ /dev/null @@ -1,78 +0,0 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { action } from '@ember/object'; -import generateBlueprintFields from 'conduit-ui/utils/blueprints/generate-blueprint-fields'; -import { capitalize } from '@ember/string'; - -export default class PipelineEditorConnectorSlidePanelTransformPanel extends Component { - @tracked - blueprintFields; - - @tracked - connectorTransform; - - @tracked - selectedTransformOnOption; - - constructor() { - super(...arguments); - this.connectorTransform = this.args.connectorTransform; - this.blueprintFields = generateBlueprintFields( - this.connectorTransform.data.transform.blueprint, - this.connectorTransform, - ); - - this.selectedTransformOnOption = this.transformOnOptions.findBy( - 'value', - this.connectorTransform.type, - ); - } - - get isValid() { - return ( - this.connectorTransform.isValid && this.blueprintFields.isEvery('isValid') - ); - } - - get isEditing() { - return !!this.args.isEditing; - } - - get transformOnOptions() { - return this.connectorTransform.transform.onOptions.map((option) => { - return { - name: capitalize(option), - value: `${this.connectorTransform.transform.id}${option}`, - }; - }); - } - - @action - setTransformOnOption(option) { - this.connectorTransform.type = option.value; - this.selectedTransformOnOption = this.transformOnOptions.findBy( - 'value', - option.value, - ); - } - - @action - setTransformConfig(fieldChangeset, event) { - fieldChangeset.value = event.target.value; - - if (fieldChangeset.isValid) { - this.connectorTransform.set( - `config.settings.${fieldChangeset.id}`, - fieldChangeset.value, - ); - } else { - this.connectorTransform.set(`config.${fieldChangeset.id}`, undefined); - } - } - - @action - addTransform() { - this.args.dismiss(); - this.args.addTransform(...arguments); - } -} diff --git a/ui/app/components/pipeline-editor/nodes/connector-node.hbs b/ui/app/components/pipeline-editor/nodes/connector-node.hbs deleted file mode 100644 index 68075df78..000000000 --- a/ui/app/components/pipeline-editor/nodes/connector-node.hbs +++ /dev/null @@ -1,52 +0,0 @@ -
-
-
-
- {{@connector.name}} -
-
- {{@connector.plugin.id}} -
-
-
-
- {{@connector.processors.length}} - {{#if (eq @connector.processors.length 1)}} - Transform - {{else}} - Transforms - {{/if}} -
-
-
-
-
diff --git a/ui/app/components/pipeline-editor/nodes/connector-node.js b/ui/app/components/pipeline-editor/nodes/connector-node.js deleted file mode 100644 index 41059542a..000000000 --- a/ui/app/components/pipeline-editor/nodes/connector-node.js +++ /dev/null @@ -1,42 +0,0 @@ -import Component from '@glimmer/component'; -import { inject as service } from '@ember/service'; - -export default class PipelineEditorNodesConnectorNodeComponent extends Component { - @service - pipelineNodeManager; - - @service - websockets; - - registerNode(element, [nodeType, pipelineNodeManager, model, websockets]) { - if (nodeType === 'source') { - pipelineNodeManager.registerSourceNode(element, model); - } - - if (nodeType === 'destination') { - pipelineNodeManager.registerDestinationNode(element, model); - } - websockets.connect(model.id, 'connectors'); - } - - unregisterNode(element, [nodeType, pipelineNodeManager, model, websockets]) { - if (nodeType === 'source') { - pipelineNodeManager.unregisterSourceNode(element); - } - - if (nodeType === 'destination') { - pipelineNodeManager.unregisterDestinationNode(element); - } - websockets.disconnect(model.id); - } - - get isSelected() { - const selectedNode = this.args.selectedNode; - if (!selectedNode) { - return false; - } - const connector = this.args.connector; - - return selectedNode === connector; - } -} diff --git a/ui/app/components/pipeline-editor/nodes/stream-node.hbs b/ui/app/components/pipeline-editor/nodes/stream-node.hbs deleted file mode 100644 index 72929bedd..000000000 --- a/ui/app/components/pipeline-editor/nodes/stream-node.hbs +++ /dev/null @@ -1,3 +0,0 @@ -
-
-
diff --git a/ui/app/components/pipeline-editor/nodes/stream-node.js b/ui/app/components/pipeline-editor/nodes/stream-node.js deleted file mode 100644 index 2d1e91bfa..000000000 --- a/ui/app/components/pipeline-editor/nodes/stream-node.js +++ /dev/null @@ -1,14 +0,0 @@ -import Component from '@glimmer/component'; -import { inject as service } from '@ember/service'; - -export default class PipelineEditorNodesStreamNodeComponent extends Component { - @service pipelineNodeManager; - - registerNode(element, [, pipelineNodeManager]) { - pipelineNodeManager.registerStreamNode(element); - } - - unregisterNode(element, [, pipelineNodeManager]) { - pipelineNodeManager.unregisterStreamNode(element); - } -} diff --git a/ui/app/components/pipeline-editor/status-badge.hbs b/ui/app/components/pipeline-editor/status-badge.hbs deleted file mode 100644 index 597d9ffda..000000000 --- a/ui/app/components/pipeline-editor/status-badge.hbs +++ /dev/null @@ -1 +0,0 @@ -{{@status}} diff --git a/ui/app/components/pipeline-editor/status-badge.js b/ui/app/components/pipeline-editor/status-badge.js deleted file mode 100644 index 41e329f62..000000000 --- a/ui/app/components/pipeline-editor/status-badge.js +++ /dev/null @@ -1,13 +0,0 @@ -import Component from '@glimmer/component'; - -const bgColorMap = { - running: 'bg-teal-600', - paused: 'bg-gray-500', - degraded: 'bg-orange-700', -}; - -export default class PipelineEditorStatusBadgeComponent extends Component { - get backgroundColorClass() { - return bgColorMap[this.args.status]; - } -} diff --git a/ui/app/components/pipeline-editor/stream-inspector-modal.hbs b/ui/app/components/pipeline-editor/stream-inspector-modal.hbs deleted file mode 100644 index 658743025..000000000 --- a/ui/app/components/pipeline-editor/stream-inspector-modal.hbs +++ /dev/null @@ -1,91 +0,0 @@ - -
-
- {{! template-lint-disable no-invalid-interactive }} -
- Stream -
-
- {{! template-lint-enable no-invalid-interactive }} - Single record -
-
- - {{#if this.isShowingSingleRecord}} -
-
{{if - this.lastRecord - this.lastRecord - "Waiting for data..." - }}
-
-
- Showing latest record in stream -
- {{else}} -
-
{{#each
-            this.inspector.records
-            as |record|
-          }}
{{record}}
{{else}}
Waiting for data...
{{/each}}
-
-
- Showing 10 latest records in stream -
- {{/if}} - -
- {{#if this.isShowingControls}} - {{#if this.isStreaming}} - - - - - Pause Inspector - - {{else}} - - - - - Resume Inspector - - {{/if}} - {{/if}} -
-
-
diff --git a/ui/app/components/pipeline-editor/stream-inspector-modal.js b/ui/app/components/pipeline-editor/stream-inspector-modal.js deleted file mode 100644 index 3dd55ee9a..000000000 --- a/ui/app/components/pipeline-editor/stream-inspector-modal.js +++ /dev/null @@ -1,38 +0,0 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { action } from '@ember/object'; -import { inject as service } from '@ember/service'; - -export default class StreamInspectorModal extends Component { - @service - websockets; - - @tracked - isShowingSingleRecord = false; - - get inspector() { - return this.websockets.getEntityInspection(this.args.entityId); - } - - get isStreaming() { - return this.inspector.isTrackingRecords; - } - - get isShowingControls() { - return this.inspector.hasRecords && this.args.pipeline.isRunning; - } - - get lastRecord() { - return this.inspector.records.at(-1); - } - - @action - pauseStream() { - this.inspector.trackRecords(false); - } - - @action - resumeStream() { - this.inspector.trackRecords(); - } -} diff --git a/ui/app/components/pipeline-editor/svg-layer.hbs b/ui/app/components/pipeline-editor/svg-layer.hbs deleted file mode 100644 index 821553788..000000000 --- a/ui/app/components/pipeline-editor/svg-layer.hbs +++ /dev/null @@ -1,14 +0,0 @@ -{{#if - (and - (gt this.pipelineNodeManager.sourceNodes.length 0) - (gt this.pipelineNodeManager.destinationNodes.length 0) - ) -}} - - - {{#each this.pipelineNodeManager.paths as |p|}} - - {{/each}} - - -{{/if}} diff --git a/ui/app/components/pipeline-editor/svg-layer.js b/ui/app/components/pipeline-editor/svg-layer.js deleted file mode 100644 index e6be50f8e..000000000 --- a/ui/app/components/pipeline-editor/svg-layer.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from '@glimmer/component'; -import { inject as service } from '@ember/service'; - -export default class SvgLayerComponent extends Component { - @service - pipelineNodeManager; -} diff --git a/ui/app/components/pipeline-editor/svg-line.hbs b/ui/app/components/pipeline-editor/svg-line.hbs deleted file mode 100644 index e562b1ceb..000000000 --- a/ui/app/components/pipeline-editor/svg-line.hbs +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/ui/app/components/pipeline-top-nav.hbs b/ui/app/components/pipeline-top-nav.hbs deleted file mode 100644 index c81b8a06e..000000000 --- a/ui/app/components/pipeline-top-nav.hbs +++ /dev/null @@ -1,32 +0,0 @@ -
- - - - Pipelines - - / - - {{#if @pipeline.name}} - - {{#if @pipeline.isNew}} - {{@pipeline.name}} - {{else}} - - {{@pipeline.name}} - - {{/if}} - - {{else}} - - Name your pipeline - - {{/if}} - -
diff --git a/ui/app/components/pipeline/form.hbs b/ui/app/components/pipeline/form.hbs deleted file mode 100644 index 594e28749..000000000 --- a/ui/app/components/pipeline/form.hbs +++ /dev/null @@ -1,58 +0,0 @@ -
- -
- {{@title}} -
- -
- - -
- - {{#if (not this.isPipelineNameValid)}} -
- {{@pipeline.error.name.validation}} -
- {{/if}} - -
-
- - - - {{or @pipeline.description.length 0}} - / 250 - -
-