diff --git a/VERSION b/VERSION index 85e60ed180..7b52f5e517 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.34.0 +0.35.0 diff --git a/cli/go.sum b/cli/go.sum index 633adc3c15..d50293126d 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -5,6 +5,7 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM= cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= diff --git a/cli/integration/version_test.go b/cli/integration/version_test.go index 5fdbb14541..bb54c3cbfa 100644 --- a/cli/integration/version_test.go +++ b/cli/integration/version_test.go @@ -12,7 +12,7 @@ func TestVersion(t *testing.T) { } // https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string - validVersionString := regexp.MustCompile(`Version: (develop|(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?), GitCommit: [0-9a-f]{5,40}\n$`) + validVersionString := regexp.MustCompile(`CLI version: (develop|(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?), GitCommit: [0-9a-f]{5,40}\n`) if !validVersionString.MatchString(actual) { t.Errorf("expected %s to be a valid version but was not", actual) diff --git a/cli/pkg/cmd/BUILD b/cli/pkg/cmd/BUILD index 424b39d7bc..034ebe2dd5 100644 --- a/cli/pkg/cmd/BUILD +++ b/cli/pkg/cmd/BUILD @@ -17,6 +17,7 @@ go_library( "//cli/pkg/cmd/status", "//cli/pkg/cmd/ui", "//cli/pkg/cmd/upgrade", + "//cli/pkg/kube", "//cli/pkg/workspace", "@com_github_spf13_cobra//:cobra", "@com_github_spf13_viper//:viper", diff --git a/cli/pkg/cmd/config/config.go b/cli/pkg/cmd/config/config.go index 0dda760395..80e31b66b1 100644 --- a/cli/pkg/cmd/config/config.go +++ b/cli/pkg/cmd/config/config.go @@ -6,6 +6,7 @@ import ( "cli/pkg/workspace" "context" "fmt" + "os" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -30,7 +31,11 @@ func applyConfig(cmd *cobra.Command, args []string) { } func ApplyConfig(workspacePath string) { - dir := workspace.Init(workspacePath) + dir, err := workspace.Init(workspacePath) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } namespace := viper.GetString("namespace") conf, err := dir.LoadAiryYaml() if err != nil { diff --git a/cli/pkg/cmd/create/BUILD b/cli/pkg/cmd/create/BUILD index 38cc159ade..330066a3e6 100644 --- a/cli/pkg/cmd/create/BUILD +++ b/cli/pkg/cmd/create/BUILD @@ -3,9 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "create", - srcs = [ - "create.go", - ], + srcs = ["create.go"], importpath = "cli/pkg/cmd/create", visibility = ["//visibility:public"], x_defs = { @@ -22,12 +20,6 @@ go_library( "@com_github_spf13_viper//:viper", "@com_github_twinproduction_go_color//:go-color", "@in_gopkg_segmentio_analytics_go_v3//:analytics-go_v3", - "@io_k8s_api//batch/v1:go_default_library", - "@io_k8s_api//core/v1:go_default_library", - "@io_k8s_api//rbac/v1:go_default_library", - "@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library", - "@io_k8s_apimachinery//pkg/watch:go_default_library", - "@io_k8s_client_go//kubernetes:go_default_library", ], ) diff --git a/cli/pkg/cmd/root.go b/cli/pkg/cmd/root.go index e85caf7e56..4b369e23b9 100644 --- a/cli/pkg/cmd/root.go +++ b/cli/pkg/cmd/root.go @@ -7,6 +7,7 @@ import ( "cli/pkg/cmd/status" "cli/pkg/cmd/ui" "cli/pkg/cmd/upgrade" + "cli/pkg/kube" "cli/pkg/workspace" "fmt" "io/ioutil" @@ -35,7 +36,11 @@ var RootCmd = &cobra.Command{ TraverseChildren: true, PersistentPreRun: func(cmd *cobra.Command, args []string) { if cmd.Name() != "create" && cmd.Name() != "version" { - workspace.Init(cliConfigDir) + _, err := workspace.Init(cliConfigDir) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } } if !strings.Contains(Version, "alpha") { cliVersion() @@ -73,7 +78,30 @@ var versionCmd = &cobra.Command{ Short: "Prints version information", Long: ``, Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("Version: %s, GitCommit: %s\n", Version, CommitSHA1) + fmt.Printf("CLI version: %s, GitCommit: %s\n", Version, CommitSHA1) + + wsPath, _ := cmd.Flags().GetString("workspace") + dir, err := workspace.Init(wsPath) + if err != nil { + return + } else { + dir.LoadAiryYaml() + kubeCtx := kube.Load() + set, err := kubeCtx.GetClientSet() + if err != nil { + fmt.Println("Unable to retrieve the client set:", err.Error()) + return + } + + coreConfig, err := kube.GetCmData("core-config", viper.GetString("namespace"), set) + if err != nil { + fmt.Println("Unable to retrieve the kubernetes config map:", err.Error()) + } else if airyVersion, ok := coreConfig["APP_IMAGE_TAG"]; ok { + fmt.Println("Airy instance version: ", airyVersion) + } else { + fmt.Println("Warning: Unable to retrieve the version of the Airy Core instance from the config map.") + } + } }, } diff --git a/cli/pkg/cmd/status/status.go b/cli/pkg/cmd/status/status.go index b45835d7ff..5885e9b606 100644 --- a/cli/pkg/cmd/status/status.go +++ b/cli/pkg/cmd/status/status.go @@ -31,7 +31,7 @@ func status(cmd *cobra.Command, args []string) { if err != nil { console.Exit("Could not get kubernetes client", err) } - cm, _ := clientset.CoreV1().ConfigMaps(viper.GetString("namespace")).Get(context.TODO(), "api-config", v1.GetOptions{}) + cm, _ := clientset.CoreV1().ConfigMaps(viper.GetString("namespace")).Get(context.TODO(), "security", v1.GetOptions{}) c.Token = cm.Data["systemToken"] @@ -42,13 +42,19 @@ func status(cmd *cobra.Command, args []string) { } w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + fmt.Fprintf(w, "service\tenabled\thealthy\n") - for k, v := range res.Components { - if v["enabled"].(bool) { - fmt.Fprintf(w, "%s\t\u2713\n", k) - } else { - fmt.Fprintf(w, "%s\t\u2717\n", k) + for serviceName, service := range res.Services { + enabledStr := "❌" + if service.Enabled { + enabledStr = "βœ…" } + healthyStr := "❌" + if service.Healthy { + healthyStr = "βœ…" + } + + fmt.Fprintf(w, "%s\t%s\t%s\n", serviceName, enabledStr, healthyStr) } w.Flush() diff --git a/cli/pkg/cmd/upgrade/BUILD b/cli/pkg/cmd/upgrade/BUILD index 06b6d0432f..2e65e2047f 100644 --- a/cli/pkg/cmd/upgrade/BUILD +++ b/cli/pkg/cmd/upgrade/BUILD @@ -14,18 +14,10 @@ go_library( "//cli/pkg/console", "//cli/pkg/helm", "//cli/pkg/kube", - "//cli/pkg/providers", "//cli/pkg/workspace", "//infrastructure/lib/go/k8s/util", "@com_github_spf13_cobra//:cobra", "@com_github_spf13_viper//:viper", - "@com_github_twinproduction_go_color//:go-color", - "@io_k8s_api//batch/v1:go_default_library", - "@io_k8s_api//core/v1:go_default_library", - "@io_k8s_api//rbac/v1:go_default_library", - "@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library", - "@io_k8s_apimachinery//pkg/watch:go_default_library", - "@io_k8s_client_go//kubernetes:go_default_library", ], ) diff --git a/cli/pkg/cmd/upgrade/upgrade.go b/cli/pkg/cmd/upgrade/upgrade.go index 07c2eb9c0d..bb40b57334 100644 --- a/cli/pkg/cmd/upgrade/upgrade.go +++ b/cli/pkg/cmd/upgrade/upgrade.go @@ -7,6 +7,7 @@ import ( "cli/pkg/kube" "cli/pkg/workspace" "fmt" + "os" "github.com/airyhq/airy/infrastructure/lib/go/k8s/util" @@ -38,7 +39,11 @@ func upgrade(cmd *cobra.Command, args []string) { if err != nil { console.Exit("Unable to find suitable workspace :", err) } - dir := workspace.Init(workspacePath) + dir, err := workspace.Init(workspacePath) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } kubeCtx := kube.Load() clientset, err := kubeCtx.GetClientSet() namespace := viper.GetString("namespace") diff --git a/cli/pkg/console/output.go b/cli/pkg/console/output.go index 49c832737b..aeb837e14c 100644 --- a/cli/pkg/console/output.go +++ b/cli/pkg/console/output.go @@ -17,7 +17,6 @@ func GetMiddleware(f func(string) string) StdWriter { func (s StdWriter) Write(p []byte) (int, error) { _, err := fmt.Print(s.f(string(p))) if err != nil { - fmt.Print("HNA") Exit(err) } return len(p), err diff --git a/cli/pkg/helm/BUILD b/cli/pkg/helm/BUILD index 859cc9979a..2e1a495a22 100644 --- a/cli/pkg/helm/BUILD +++ b/cli/pkg/helm/BUILD @@ -6,7 +6,6 @@ go_library( importpath = "cli/pkg/helm", visibility = ["//visibility:public"], deps = [ - "//cli/pkg/kube", "//infrastructure/lib/go/k8s/util", "@io_k8s_api//batch/v1:go_default_library", "@io_k8s_api//core/v1:go_default_library", diff --git a/cli/pkg/helm/helm.go b/cli/pkg/helm/helm.go index e4a75d4682..8c0172c59f 100644 --- a/cli/pkg/helm/helm.go +++ b/cli/pkg/helm/helm.go @@ -79,7 +79,7 @@ func (h *Helm) Setup() error { } func (h *Helm) InstallCharts() error { - chartURL := "https://airy-core-helm-charts.s3.amazonaws.com/stable/airy-" + h.version + ".tgz" + chartURL := "https://airy-core-helm-charts.s3.amazonaws.com/stable/airy-0.33.0.tgz" return h.runHelm(append([]string{"install", "--values", "/apps/config/airy-config-map.yaml", "--namespace", h.namespace, diff --git a/cli/pkg/kube/BUILD b/cli/pkg/kube/BUILD index 1b69d84d82..f7ea35345e 100644 --- a/cli/pkg/kube/BUILD +++ b/cli/pkg/kube/BUILD @@ -9,12 +9,11 @@ go_library( importpath = "cli/pkg/kube", visibility = ["//visibility:public"], deps = [ - "//cli/pkg/workspace", "@com_github_spf13_viper//:viper", - "@in_gopkg_yaml_v2//:yaml_v2", "@io_k8s_api//core/v1:go_default_library", "@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library", "@io_k8s_client_go//kubernetes:go_default_library", + "@io_k8s_client_go//plugin/pkg/client/auth/gcp:go_default_library", "@io_k8s_client_go//tools/clientcmd:go_default_library", ], ) diff --git a/cli/pkg/kube/context.go b/cli/pkg/kube/context.go index 0c59c34c6b..b95ccdc5fc 100644 --- a/cli/pkg/kube/context.go +++ b/cli/pkg/kube/context.go @@ -2,8 +2,10 @@ package kube import ( "errors" + "github.com/spf13/viper" "k8s.io/client-go/kubernetes" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" "k8s.io/client-go/tools/clientcmd" ) diff --git a/cli/pkg/workspace/init.go b/cli/pkg/workspace/init.go index f22ff1a8dd..e6751f1345 100644 --- a/cli/pkg/workspace/init.go +++ b/cli/pkg/workspace/init.go @@ -3,34 +3,33 @@ package workspace import ( "cli/pkg/workspace/template" "fmt" - "github.com/spf13/viper" "os" "path/filepath" + + "github.com/spf13/viper" ) -func Init(path string) ConfigDir { +func Init(path string) (ConfigDir, error) { viper.AddConfigPath(getConfigPath(path)) viper.SetConfigType("yaml") viper.SetConfigName(cliConfigFileName) if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Println(err) - fmt.Println("the current directory is not an airy workspace directory") + err = fmt.Errorf("%w\nthe current directory is not an airy workspace directory", err) } else { - fmt.Println("invalid configuration: ", err) + err = fmt.Errorf("invalid configuration: %w", err) } - os.Exit(1) + return ConfigDir{}, err } dir := ConfigDir{Path: path} if _, err := os.Stat(dir.GetAiryYaml()); os.IsNotExist(err) { - fmt.Println("the current directory is not an airy workspace directory") - os.Exit(1) + return dir, fmt.Errorf("the current directory is not an airy workspace directory") } - return dir + return dir, nil } func getConfigPath(path string) string { @@ -57,7 +56,6 @@ func Create(path string, data template.Variables) (ConfigDir, error) { } } - if err := template.CopyToDir(path, data); err != nil { return ConfigDir{}, err } diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index f6945909be..4d160d770c 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -3,40 +3,88 @@ title: Changelog sidebar_label: πŸ“ Changelog --- -## 0.34.0 +## 0.35.0 #### Changes +- [[#2503](https://github.com/airyhq/airy/issues/2503)] Add capability for resource limits for components [[#2541](https://github.com/airyhq/airy/pull/2541)] + #### πŸš€ Features -- [[#2518](https://github.com/airyhq/airy/issues/2518)] Add fargate annotation [[#2540](https://github.com/airyhq/airy/pull/2540)] -- Add CLI outdated version warning [[#2529](https://github.com/airyhq/airy/pull/2529)] +- Custom message colors chatplugin + Documentation [[#2585](https://github.com/airyhq/airy/pull/2585)] +- [[#2108](https://github.com/airyhq/airy/issues/2108)] render attachments via whatsapp [[#2574](https://github.com/airyhq/airy/pull/2574)] +- [[#2518](https://github.com/airyhq/airy/issues/2518)] Add terraform code for core deployment [[#2555](https://github.com/airyhq/airy/pull/2555)] +- [[#2563](https://github.com/airyhq/airy/issues/2563)] Allow for disabling emojis in the chatplugin [[#2564](https://github.com/airyhq/airy/pull/2564)] +- [[#2560](https://github.com/airyhq/airy/issues/2560)] Dev\_cli.sh fails to apply the config [[#2561](https://github.com/airyhq/airy/pull/2561)] +- Print airy core version with version command [[#2537](https://github.com/airyhq/airy/pull/2537)] #### πŸ› Bug Fixes -- [[#2434](https://github.com/airyhq/airy/issues/2434)] Fix broken instagram Facebook inbox ingestion [[#2535](https://github.com/airyhq/airy/pull/2535)] -- [2457] Fix upgrade to same version [[#2538](https://github.com/airyhq/airy/pull/2538)] -- [[#2510](https://github.com/airyhq/airy/issues/2510)] Improve error logging for helm install [[#2522](https://github.com/airyhq/airy/pull/2522)] -- [[#2255](https://github.com/airyhq/airy/issues/2255)] Fix helm chart url [[#2525](https://github.com/airyhq/airy/pull/2525)] -- [[#2523](https://github.com/airyhq/airy/issues/2523)] Fix VERSION and add changelog [[#2524](https://github.com/airyhq/airy/pull/2524)] -- [[#2473](https://github.com/airyhq/airy/issues/2473)] fix failing cypress test [[#2507](https://github.com/airyhq/airy/pull/2507)] +- fixed input accept formatting [[#2584](https://github.com/airyhq/airy/pull/2584)] +- [[#2576](https://github.com/airyhq/airy/issues/2576)] Render Survey response Google Business Messages [[#2578](https://github.com/airyhq/airy/pull/2578)] +- [[#2544](https://github.com/airyhq/airy/issues/2544)] Include the analytics demo files in the jupyter hub [[#2545](https://github.com/airyhq/airy/pull/2545)] +- [[#2557](https://github.com/airyhq/airy/issues/2557)] Fix jumping conversationlist [[#2558](https://github.com/airyhq/airy/pull/2558)] +- [[#2548](https://github.com/airyhq/airy/issues/2548)] Use the cli with helm [[#2551](https://github.com/airyhq/airy/pull/2551)] +- [[#2511](https://github.com/airyhq/airy/issues/2511)] Fix Airy status command [[#2542](https://github.com/airyhq/airy/pull/2542)] + +#### πŸ“š Documentation + +- [[#2511](https://github.com/airyhq/airy/issues/2511)] Fix docs for helm upgrade [[#2547](https://github.com/airyhq/airy/pull/2547)] #### 🧰 Maintenance -- Bump react-redux from 7.2.5 to 7.2.6 [[#2539](https://github.com/airyhq/airy/pull/2539)] -- Bump reselect from 4.0.0 to 4.1.1 [[#2533](https://github.com/airyhq/airy/pull/2533)] -- Bump sass-loader from 12.1.0 to 12.3.0 [[#2534](https://github.com/airyhq/airy/pull/2534)] -- Bump @types/react-dom from 17.0.9 to 17.0.10 [[#2526](https://github.com/airyhq/airy/pull/2526)] -- Bump react-markdown from 7.0.1 to 7.1.0 [[#2527](https://github.com/airyhq/airy/pull/2527)] -- Bump webpack from 5.54.0 to 5.59.1 [[#2517](https://github.com/airyhq/airy/pull/2517)] +- Bump @types/react-dom from 17.0.10 to 17.0.11 [[#2572](https://github.com/airyhq/airy/pull/2572)] +- Bump style-loader from 3.3.0 to 3.3.1 [[#2573](https://github.com/airyhq/airy/pull/2573)] +- Bump cypress from 8.6.0 to 8.7.0 [[#2567](https://github.com/airyhq/airy/pull/2567)] +- Bump babel-loader from 8.2.2 to 8.2.3 [[#2568](https://github.com/airyhq/airy/pull/2568)] +- Bump @types/react from 17.0.20 to 17.0.34 [[#2553](https://github.com/airyhq/airy/pull/2553)] +- Bump sass from 1.43.2 to 1.43.4 [[#2565](https://github.com/airyhq/airy/pull/2565)] +- Bump node-fetch from 2.6.2 to 3.0.0 [[#2450](https://github.com/airyhq/airy/pull/2450)] +- Bump html-webpack-plugin from 5.3.2 to 5.5.0 [[#2552](https://github.com/airyhq/airy/pull/2552)] +- Bump prettier from 2.3.2 to 2.4.1 [[#2532](https://github.com/airyhq/airy/pull/2532)] #### Airy CLI You can download the Airy CLI for your operating system from the following links: -[MacOS](https://airy-core-binaries.s3.amazonaws.com/0.33.1/darwin/amd64/airy) -[Linux](https://airy-core-binaries.s3.amazonaws.com/0.33.1/linux/amd64/airy) -[Windows](https://airy-core-binaries.s3.amazonaws.com/0.33.1/windows/amd64/airy.exe) +[MacOS](https://airy-core-binaries.s3.amazonaws.com/0.34.1/darwin/amd64/airy) +[Linux](https://airy-core-binaries.s3.amazonaws.com/0.34.1/linux/amd64/airy) +[Windows](https://airy-core-binaries.s3.amazonaws.com/0.34.1/windows/amd64/airy.exe) + +## 0.34.0 + +#### Changes + +#### πŸš€ Features + +- [[#2518](https://github.com/airyhq/airy/issues/2518)] Add fargate annotation [[#2540](https://github.com/airyhq/airy/pull/2540)] +- [[#2305](https://github.com/airyhq/airy/issues/2305)] Add CLI outdated version warning [[#2529](https://github.com/airyhq/airy/pull/2529)] + +#### πŸ› Bug Fixes + +- [[#2434](https://github.com/airyhq/airy/issues/2434)] Fix broken instagram Facebook inbox ingestion [[#2535](https://github.com/airyhq/airy/pull/2535)] +- [[#2457](https://github.com/airyhq/airy/issues/2457)] Fix upgrade to same version [[#2538](https://github.com/airyhq/airy/pull/2538)] +- [[#2510](https://github.com/airyhq/airy/issues/2510)] Improve error logging for helm install [[#2522](https://github.com/airyhq/airy/pull/2522)] +- [[#2255](https://github.com/airyhq/airy/issues/2255)] Fix helm chart url [[#2525](https://github.com/airyhq/airy/pull/2525)] +- [[#2523](https://github.com/airyhq/airy/issues/2523)] Fix VERSION and add changelog [[#2524](https://github.com/airyhq/airy/pull/2524)] +- [[#2473](https://github.com/airyhq/airy/issues/2473)] fix failing cypress test [[#2507](https://github.com/airyhq/airy/pull/2507)] + +#### 🧰 Maintenance + +- Bump react-redux from 7.2.5 to 7.2.6 [[#2539](https://github.com/airyhq/airy/pull/2539)] +- Bump reselect from 4.0.0 to 4.1.1 [[#2533](https://github.com/airyhq/airy/pull/2533)] +- Bump sass-loader from 12.1.0 to 12.3.0 [[#2534](https://github.com/airyhq/airy/pull/2534)] +- Bump @types/react-dom from 17.0.9 to 17.0.10 [[#2526](https://github.com/airyhq/airy/pull/2526)] +- Bump react-markdown from 7.0.1 to 7.1.0 [[#2527](https://github.com/airyhq/airy/pull/2527)] +- Bump webpack from 5.54.0 to 5.59.1 [[#2517](https://github.com/airyhq/airy/pull/2517)] + +#### Airy CLI + +You can download the Airy CLI for your operating system from the following links: + +[MacOS](https://airy-core-binaries.s3.amazonaws.com/0.34.0/darwin/amd64/airy) +[Linux](https://airy-core-binaries.s3.amazonaws.com/0.34.0/linux/amd64/airy) +[Windows](https://airy-core-binaries.s3.amazonaws.com/0.34.0/windows/amd64/airy.exe) ## 0.33.0 @@ -1194,69 +1242,3 @@ You can download the Airy CLI for your operating system from the following links [Linux](https://airy-core-binaries.s3.amazonaws.com/0.13.0/linux/amd64/airy) [Windows](https://airy-core-binaries.s3.amazonaws.com/0.13.0/windows/amd64/airy.exe) -## 0.12.0 - -#### Changes - -- [[#1132](https://github.com/airyhq/airy/issues/1132)] Fix missing , in nginx [[#1133](https://github.com/airyhq/airy/pull/1133)] -- [[#1014](https://github.com/airyhq/airy/issues/1014)] Deploy the helm charts [[#1084](https://github.com/airyhq/airy/pull/1084)] -- [[#1124](https://github.com/airyhq/airy/issues/1124)] Template endpoints return 404 [[#1125](https://github.com/airyhq/airy/pull/1125)] - -#### πŸš€ Features - -- [[#1113](https://github.com/airyhq/airy/issues/1113)] Chat Plugin: keep text in input bar if… [[#1143](https://github.com/airyhq/airy/pull/1143)] -- [[#1000](https://github.com/airyhq/airy/issues/1000)] ConversationList scrolls over TopBar [[#1129](https://github.com/airyhq/airy/pull/1129)] -- [[#983](https://github.com/airyhq/airy/issues/983)] The login call should not send the auth… [[#1127](https://github.com/airyhq/airy/pull/1127)] -- [[#1126](https://github.com/airyhq/airy/issues/1126)] /templates.info And /templates.update are returning 404 [[#1128](https://github.com/airyhq/airy/pull/1128)] -- [[#660](https://github.com/airyhq/airy/issues/660)] Enable users to connect via Airy Live Chat [[#1078](https://github.com/airyhq/airy/pull/1078)] -- [[#1117](https://github.com/airyhq/airy/issues/1117)] Template docs are not accessible [[#1118](https://github.com/airyhq/airy/pull/1118)] - -#### πŸ› Bug Fixes - -- [[#1174](https://github.com/airyhq/airy/issues/1174)] Build the right cli version on develop [[#1177](https://github.com/airyhq/airy/pull/1177)] -- [[#1165](https://github.com/airyhq/airy/issues/1165)] Fix template endpoint content field [[#1166](https://github.com/airyhq/airy/pull/1166)] -- [[#1161](https://github.com/airyhq/airy/issues/1161)] Fix metadata 404 [[#1162](https://github.com/airyhq/airy/pull/1162)] -- [[#1152](https://github.com/airyhq/airy/issues/1152)] Fix conditional config apply [[#1153](https://github.com/airyhq/airy/pull/1153)] -- [[#1142](https://github.com/airyhq/airy/issues/1142)] Backbutton \& search aligned [[#1149](https://github.com/airyhq/airy/pull/1149)] -- [[#1034](https://github.com/airyhq/airy/issues/1034)] Tag empty state has strange scrolling… [[#1141](https://github.com/airyhq/airy/pull/1141)] -- [[#1112](https://github.com/airyhq/airy/issues/1112)] fixed highlight in inbox [[#1119](https://github.com/airyhq/airy/pull/1119)] -- [[#1120](https://github.com/airyhq/airy/issues/1120)] Fix Shellcheck [[#1121](https://github.com/airyhq/airy/pull/1121)] - -#### πŸ“š Documentation - -- [[#1094](https://github.com/airyhq/airy/issues/1094)] Minor UI improvements to the docs [[#1131](https://github.com/airyhq/airy/pull/1131)] - -#### 🧰 Maintenance - -- Revert "Bump webpack-dev-middleware from 3.7.2 to 4.1.0" [[#1172](https://github.com/airyhq/airy/pull/1172)] -- Bump elliptic from 6.5.3 to 6.5.4 in /docs [[#1170](https://github.com/airyhq/airy/pull/1170)] -- Bump elliptic from 6.5.3 to 6.5.4 [[#1171](https://github.com/airyhq/airy/pull/1171)] -- Bump terser-webpack-plugin from 2.3.6 to 4.2.3 [[#1169](https://github.com/airyhq/airy/pull/1169)] -- Bump html-webpack-plugin from 4.2.0 to 4.5.2 [[#1168](https://github.com/airyhq/airy/pull/1168)] -- Bump webpack-dev-middleware from 3.7.2 to 4.1.0 [[#1154](https://github.com/airyhq/airy/pull/1154)] -- Bump react from 16.12.0 to 16.14.0 [[#1167](https://github.com/airyhq/airy/pull/1167)] -- Restructure cli for building providers [[#1159](https://github.com/airyhq/airy/pull/1159)] -- Bump react-router-dom from 5.1.2 to 5.2.0 [[#1155](https://github.com/airyhq/airy/pull/1155)] -- Bump prettier from 1.19.1 to 2.2.1 [[#1147](https://github.com/airyhq/airy/pull/1147)] -- Bump lodash-es from 4.17.15 to 4.17.21 [[#1156](https://github.com/airyhq/airy/pull/1156)] -- Bump @types/react-router-dom from 5.1.3 to 5.1.7 [[#1157](https://github.com/airyhq/airy/pull/1157)] -- Restructure cli to prepare for providers [[#1151](https://github.com/airyhq/airy/pull/1151)] -- Bump eslint-plugin-react from 7.21.5 to 7.22.0 [[#1148](https://github.com/airyhq/airy/pull/1148)] -- Bump eslint from 7.16.0 to 7.21.0 [[#1144](https://github.com/airyhq/airy/pull/1144)] -- Bump file-loader from 6.0.0 to 6.2.0 [[#1145](https://github.com/airyhq/airy/pull/1145)] -- Bump @bazel/typescript from 3.2.0 to 3.2.1 [[#1146](https://github.com/airyhq/airy/pull/1146)] -- Bump react-hot-loader from 4.12.20 to 4.13.0 [[#1138](https://github.com/airyhq/airy/pull/1138)] -- Bump @types/react-redux from 7.1.3 to 7.1.16 [[#1136](https://github.com/airyhq/airy/pull/1136)] -- Bump @types/lodash-es from 4.17.3 to 4.17.4 [[#1137](https://github.com/airyhq/airy/pull/1137)] -- Bump preact from 10.5.7 to 10.5.12 [[#1139](https://github.com/airyhq/airy/pull/1139)] -- Bump react-redux from 7.1.3 to 7.2.2 [[#1140](https://github.com/airyhq/airy/pull/1140)] -- Add dependabot config [[#1135](https://github.com/airyhq/airy/pull/1135)] - -#### Airy CLI - -You can download the Airy CLI for your operating system from the following links: - -[MacOS](https://airy-core-binaries.s3.amazonaws.com/0.12.0/darwin/amd64/airy) -[Linux](https://airy-core-binaries.s3.amazonaws.com/0.12.0/linux/amd64/airy) -[Windows](https://airy-core-binaries.s3.amazonaws.com/0.12.0/windows/amd64/airy.exe) - diff --git a/docs/docs/getting-started/installation/configuration.md b/docs/docs/getting-started/installation/configuration.md index f14051783d..cc2a94b43a 100644 --- a/docs/docs/getting-started/installation/configuration.md +++ b/docs/docs/getting-started/installation/configuration.md @@ -22,6 +22,10 @@ Your Airy Core instance will start and stop components according to your configuration. For example, if you do not wish to start Facebook components, it is enough not to provide any Facebook specific configuration. +:::note +If you installed Airy with Helm, then you need to [setup your workspace directory](/getting-started/installation/helm#workspace-setup), before you can use the CLI. +::: + Now let's have a look at the different sections so you can make the changes you are looking for. diff --git a/docs/docs/getting-started/installation/helm.md b/docs/docs/getting-started/installation/helm.md index 68dc10c676..6f66a55688 100644 --- a/docs/docs/getting-started/installation/helm.md +++ b/docs/docs/getting-started/installation/helm.md @@ -28,13 +28,14 @@ You will also need the [Helm](https://helm.sh/docs/intro/quickstart/) and [Kubec Make sure that you can access the cluster running: ```sh -$ kubectl get pods +kubectl get pods No resources found in default namespace. -$ helm list + +helm list NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION ``` -## Deploy Airy Core +## Install Deploy Airy Core with the latest version. You can also configure a specific version @@ -65,12 +66,12 @@ ingress-controller: Run the following command to upgrade your Airy Core installation and setup Let's Encrypt: ```sh -$ helm upgrade airy https://airy-core-helm-charts.s3.amazonaws.com/testing/airy-${VERSION}.tgz --values ./airy.yaml +helm upgrade airy https://airy-core-helm-charts.s3.amazonaws.com/stable/airy-${VERSION}.tgz --values ./airy.yaml ``` After that you should be able to access your `Airy Core` instance through HTTPS, in this example on https://awesomechat.airy.co. -## Customization +## Customize Deploying `Airy Core` with Helm gives flexibility to customize your installation. @@ -154,6 +155,34 @@ VERSION=$(curl -L -s https://airy-core-binaries.s3.amazonaws.com/stable.txt) helm install airy https://airy-core-helm-charts.s3.amazonaws.com/stable/${VERSION}.tgz --timeout 10m --set global.containerRegistry=my-docker-registry ``` +## Workspace setup + +When installing with Helm, a workspace directory is not created and therefore you cannot use the `Airy CLI` with your `Airy Core` installation, without setting up your workspace directory first. The `Airy CLI` is needed to apply configuration, to get the status of the components and to interact with the API. + +In order for the CLI to recognize a workspace directory, you need to have two files there: + +- `cli.yaml` - Configuration on how the CLI can access the cluster. + + - `apihost` - The loadBalancer or the hostname on which the API can be reached. + - `kubeconfig` - The path to the Kubernetes config file. + - `contextname` - The context for the cluster, inside the kubeconfig file. + - `namespace` - The namespace where `Airy Core` is installed. + +- `airy.yaml` - Values you used for deploying the Helm chart. The file can also be empty, but it needs to exist. + +Example of the `cli.yaml` file. + +``` +apihost: https://my-airy-core-fqdn +contextname: gke_us-central1-c_awesomechat +kubeconfig: /home/user/.kube/config +namespace: default +``` + +## Upgrade + +For upgrading your `Airy Core` instance using helm, refer to our [upgrade document](/getting-started/upgrade#upgrade-using-helm). + ## Troubleshooting To view your existing Helm installation run `helm list`. diff --git a/docs/docs/getting-started/installation/introduction.md b/docs/docs/getting-started/installation/introduction.md index cd00050f09..d2a66ca926 100644 --- a/docs/docs/getting-started/installation/introduction.md +++ b/docs/docs/getting-started/installation/introduction.md @@ -7,6 +7,7 @@ import TLDR from "@site/src/components/TLDR"; import ButtonBoxList from "@site/src/components/ButtonBoxList"; import ButtonBox from "@site/src/components/ButtonBox"; import AwsSVG from "@site/static/icons/aws.svg"; +import TerraformSVG from "@site/static/icons/terraform.svg"; import Minikube from "@site/static/icons/minikube.svg"; import RocketSVG from "@site/static/icons/rocket.svg"; import HelmSVG from "@site/static/icons/helm.svg"; @@ -61,4 +62,10 @@ title='Production ready environment with AWS' description='Step by step guide to run Airy Core on AWS' link='getting-started/installation/aws' /> +} +title='Cloud deployment with Terraform' +description='Step by step guide to run Airy Core in the cloud managed by Terraform' +link='getting-started/installation/terraform' +/> diff --git a/docs/docs/getting-started/installation/minikube.md b/docs/docs/getting-started/installation/minikube.md index 87ee624b31..9f94ff837f 100644 --- a/docs/docs/getting-started/installation/minikube.md +++ b/docs/docs/getting-started/installation/minikube.md @@ -16,7 +16,7 @@ your local machine using [minikube](https://minikube.sigs.k8s.io/). ## Create a minikube cluster -First install minikube using [their documentation](https://kubernetes.io/de/docs/tasks/tools/install-minikube/). Currently supported versions are: v1.19.0, v1.20.0, v1.21.0 and v1.22.0. If you already have it installed make sure that your version is in line with the supported versions. +First install minikube using [their documentation](https://kubernetes.io/de/docs/tasks/tools/install-minikube/). Minikube version v1.19.0 or higher is required. Next you also need to install the [Airy CLI](cli/introduction.md). Now you can run this command, which will create a new minikube cluster on your system and install Airy core on it: diff --git a/docs/docs/getting-started/installation/terraform.md b/docs/docs/getting-started/installation/terraform.md new file mode 100644 index 0000000000..60cbd78f39 --- /dev/null +++ b/docs/docs/getting-started/installation/terraform.md @@ -0,0 +1,54 @@ +--- +title: Run Airy Core on AWS with Terraform +sidebar_label: Terraform +--- + +## Requirements + +- [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) v1.0.0+ +- [Airy CLI](https://airy.co/docs/core/cli/introduction) v0.34.0+ +- [SSH key](https://www.ssh.com/academy/ssh/keygen) in `~/.ssh/id_rsa.pub` +- [Kubectl](https://kubernetes.io/docs/tasks/tools/) (optional) + +## Create the Kubernetes cluster + +In case you already have a cluster running you can skip to the next section. + +### Amazon Web Services + +You need to provide Terraform with the AWS credentials for your IAM Role. If +you don't know how to create one, [follow these +instructions](https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/). +They have to be put into a `terraform.tfvars` file in `terraform/kubernetes` that looks contains: + +``` +aws_access_key = "" +aws_secret_key = "" +``` + +If you want to deploy the EKS cluster in your existing VPC you have to override the +`vpc_id`, `subnets` and `fargate_subnets` variables with the outputs from your +vpc and set `create_vpc=false` in the Airy Core module. + +``` +terraform init +terraform apply +``` + +## Install Airy Helm chart + +After the Kubernetes cluster has been created we can deploy the Airy Helm chart +to it. Change to the `terraform/main` directory and make sure the `.kubeconfig` +file is there. + +You can [configure](https://airy.co/docs/core/getting-started/installation/configuration) your instance by making changes to `infrastructure/terraform/main/files/values.yaml` + +If you want to deploy the stateless apps with AWS Fargate you can add +`workerType: fargate` to the `values.yaml` + +Finally, you need to initialize the Terraform workspace and run apply. + +``` +terraform init +terraform apply +``` diff --git a/docs/docs/getting-started/upgrade.md b/docs/docs/getting-started/upgrade.md index 4c1e0dd2ed..e38d1848ca 100644 --- a/docs/docs/getting-started/upgrade.md +++ b/docs/docs/getting-started/upgrade.md @@ -63,7 +63,16 @@ applied configuration for "security" Writing the new version into the configuration file. Copying the configuration file in the Airy Core K8s cluster. -βœ… Aity Core upgraded +βœ… Airy Core upgraded +``` + +## Upgrade using Helm + +If you used Helm to deploy `Airy Core`, you can upgrade with the `helm upgrade` command: + +```sh +VERSION=$(curl -L -s https://airy-core-binaries.s3.amazonaws.com/stable.txt) +helm upgrade airy https://airy-core-helm-charts.s3.amazonaws.com/stable/airy-${VERSION}.tgz --values ./airy.yaml ``` ## Cleanup the upgrade diff --git a/docs/docs/sources/chatplugin/customization.md b/docs/docs/sources/chatplugin/customization.md index 2d02e725cd..7a58653175 100644 --- a/docs/docs/sources/chatplugin/customization.md +++ b/docs/docs/sources/chatplugin/customization.md @@ -44,6 +44,10 @@ If you are happy with your customization, copy it and add this code inside the t | primaryColor | string | Set your primary color as the topbar, border of `textArea`, Start new Conversation button text and border color, or text color of `buttons` | | accentColor | string | Set your accent color as the `sendButton` | | backgroundColor | string | Set the background color of the entire Airy Chat Plugin | +| outboundMessageColor | string | Set the background color of the outbound messages in the Airy Chat Plugin | +| inboundMessageColor | string | Set the background color of the inbound messages in the Airy Chat Plugin | +| outboundMessageTextColor | string | Set the text color of the outbound messages in the Airy Chat Plugin | +| inboundMessageTextColor | string | Set the text color of the inbound messages in the Airy Chat Plugin | | height | number | Set the height of the entire Airy Chat Plugin | | width | number | Set the width of the entire Airy Chat Plugin | | bubbleIcon | URL | Set your company icon which appears on the button that opens and closes the Airy Chat Plugin | diff --git a/docs/src/components/ButtonBox/index.js b/docs/src/components/ButtonBox/index.js index 71029227a5..16aaa0a6e3 100644 --- a/docs/src/components/ButtonBox/index.js +++ b/docs/src/components/ButtonBox/index.js @@ -39,7 +39,8 @@ const ButtonBox = ({ + style={{backgroundColor: customizedBackgroundColor, boxShadow: `0px 0px 0px 4px ${customizedHoverColor}`}} + > {icon}

{title}

diff --git a/docs/src/components/TLDR/index.js b/docs/src/components/TLDR/index.js index 309e99b0d1..8063ff739b 100644 --- a/docs/src/components/TLDR/index.js +++ b/docs/src/components/TLDR/index.js @@ -12,7 +12,8 @@ const TLDR = ({children}) => { style={{ backgroundColor: color, borderLeft: `6px solid ${leftBarColor}`, - }}> + }} + > {children} ); diff --git a/docs/static/icons/terraform.svg b/docs/static/icons/terraform.svg new file mode 100644 index 0000000000..dc042195d1 --- /dev/null +++ b/docs/static/icons/terraform.svg @@ -0,0 +1 @@ +Terraform icon \ No newline at end of file diff --git a/frontend/chat-plugin/dev/config.ts b/frontend/chat-plugin/dev/config.ts index 72c836c59e..ca6c8921d7 100644 --- a/frontend/chat-plugin/dev/config.ts +++ b/frontend/chat-plugin/dev/config.ts @@ -29,4 +29,8 @@ export const config: Config = { }, }, showMode: false, + inboundMessageColor: '#B8E986', + inboundMessageTextColor: '#BD10E0', + outboundMessageColor: '#7ED321', + outboundMessageTextColor: '#F8E71C', }; diff --git a/frontend/chat-plugin/lib/BUILD b/frontend/chat-plugin/lib/BUILD index 324d75eaae..c9b34331c6 100644 --- a/frontend/chat-plugin/lib/BUILD +++ b/frontend/chat-plugin/lib/BUILD @@ -36,6 +36,7 @@ web_library( "library": "@airyhq/chat-plugin", "libraryTarget": "umd", "filename": "index.js", + "uniqueName": "airy-chat-plugin", }, ) diff --git a/frontend/chat-plugin/lib/src/AiryChatPlugin.tsx b/frontend/chat-plugin/lib/src/AiryChatPlugin.tsx index 5332ee5363..c17588dcbe 100644 --- a/frontend/chat-plugin/lib/src/AiryChatPlugin.tsx +++ b/frontend/chat-plugin/lib/src/AiryChatPlugin.tsx @@ -31,12 +31,25 @@ export const AiryChatPlugin = (props: AiryChatPluginProps) => { height: Math.min(config.config?.height ?? defaultHeight, windowHeight), ...(config.config?.primaryColor && { '--color-airy-blue': config.config?.primaryColor, + '--color-airy-message-outbound': config.config?.primaryColor, }), ...(config.config?.accentColor && { '--color-airy-accent': config.config?.accentColor, '--color-airy-blue-hover': config.config?.accentColor, '--color-airy-blue-pressed': config.config?.accentColor, }), + ...(config.config?.outboundMessageColor && { + '--color-airy-message-outbound': config.config?.outboundMessageColor, + }), + ...(config.config?.inboundMessageColor && { + '--color-airy-message-inbound': config.config?.inboundMessageColor, + }), + ...(config.config?.outboundMessageTextColor && { + '--color-airy-message-text-outbound': config.config?.outboundMessageTextColor, + }), + ...(config.config?.inboundMessageTextColor && { + '--color-airy-message-text-inbound': config.config?.inboundMessageTextColor, + }), }; return ( diff --git a/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.tsx b/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.tsx index d0ba0fcdeb..bd5a3ea7f3 100644 --- a/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.tsx +++ b/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.tsx @@ -47,7 +47,8 @@ const AiryBubble = (props: Props) => { transform="translate(1.000000, 1.000000)" fill="#ffffff" fillRule="nonzero" - stroke="#ffffff"> + stroke="#ffffff" + > { className={style.closeButton} onClick={props.toggleHideChat} title="End chat" - data-cy={cyChatPluginHeaderBarCloseButton}> + data-cy={cyChatPluginHeaderBarCloseButton} + >
@@ -57,7 +58,8 @@ const AiryHeaderBar = (props: AiryHeaderBarProps) => { className={style.closeButton} onClick={showModalOnClick} title="End chat" - data-cy={cyChatPluginHeaderBarCloseButton}> + data-cy={cyChatPluginHeaderBarCloseButton} + > diff --git a/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.tsx b/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.tsx index 447d0e0ec5..8022027af0 100644 --- a/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.tsx +++ b/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.tsx @@ -157,7 +157,8 @@ const AiryInputBar = (props: AiryInputBarProps) => { + rel="noreferrer" + > Powered by Airy diff --git a/frontend/chat-plugin/lib/src/components/chat/index.tsx b/frontend/chat-plugin/lib/src/components/chat/index.tsx index c8fe5e5edc..6030cbea9d 100644 --- a/frontend/chat-plugin/lib/src/components/chat/index.tsx +++ b/frontend/chat-plugin/lib/src/components/chat/index.tsx @@ -223,7 +223,8 @@ const Chat = ({config, ...props}: Props) => { {!isChatHidden && (
+ style={config.backgroundColor && {backgroundColor: config.backgroundColor}} + >
@@ -242,7 +243,8 @@ const Chat = ({config, ...props}: Props) => { + lastInGroup={lastInGroup} + > { diff --git a/frontend/chat-plugin/lib/src/components/newConversation/index.tsx b/frontend/chat-plugin/lib/src/components/newConversation/index.tsx index 45c4cafabf..8db2f77142 100644 --- a/frontend/chat-plugin/lib/src/components/newConversation/index.tsx +++ b/frontend/chat-plugin/lib/src/components/newConversation/index.tsx @@ -23,7 +23,8 @@ const NewConversation = (props: newConversationProps) => { href="" onClick={props.reAuthenticate} data-cy={cyChatPluginStartNewConversation} - className={style.newConversationLink}> + className={style.newConversationLink} + > {props.startNewConversationText || 'Start a new Conversation'} diff --git a/frontend/chat-plugin/lib/src/config.ts b/frontend/chat-plugin/lib/src/config.ts index 524da89d89..eaaadbcd2b 100644 --- a/frontend/chat-plugin/lib/src/config.ts +++ b/frontend/chat-plugin/lib/src/config.ts @@ -15,6 +15,10 @@ export type Config = { primaryColor?: string; accentColor?: string; bubbleIcon?: string; + outboundMessageColor?: string; + inboundMessageColor?: string; + outboundMessageTextColor?: string; + inboundMessageTextColor?: string; sendMessageIcon?: string; showMode?: boolean; height?: number; diff --git a/frontend/ui/src/assets/scss/colors.scss b/frontend/ui/src/assets/scss/colors.scss index 6f9690baae..f5cda7d157 100644 --- a/frontend/ui/src/assets/scss/colors.scss +++ b/frontend/ui/src/assets/scss/colors.scss @@ -26,4 +26,8 @@ --color-soft-green: #0da36b; --color-tag-green: #0e764f; --color-tag-purple: #730a80; + --color-airy-message-outbound: #1578d4; + --color-airy-message-inbound: #f1faff; + --color-airy-message-text-outbound: #ffffff; + --color-airy-message-text-inbound: #000000; } diff --git a/frontend/ui/src/components/Input.tsx b/frontend/ui/src/components/Input.tsx new file mode 100644 index 0000000000..df751ff2df --- /dev/null +++ b/frontend/ui/src/components/Input.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import {Picker} from 'emoji-mart'; +import {Input as LibInput} from 'components'; + +const renderPicker = onSelect => ( + +); + +export const Input = props => ; diff --git a/frontend/ui/src/components/Tag/index.tsx b/frontend/ui/src/components/Tag/index.tsx index 19a1da289a..8879512ec9 100644 --- a/frontend/ui/src/components/Tag/index.tsx +++ b/frontend/ui/src/components/Tag/index.tsx @@ -52,7 +52,8 @@ export const Tag = ({tag, expanded, variant, onClick, removeTag, settings}: TagP
+ style={tagStyle()} + > {tag.name} {removeTag && ( diff --git a/frontend/ui/src/pages/Channels/ConnectedChannelsBySourceCard/index.tsx b/frontend/ui/src/pages/Channels/ConnectedChannelsBySourceCard/index.tsx index 74e84128de..9ab90f2f27 100644 --- a/frontend/ui/src/pages/Channels/ConnectedChannelsBySourceCard/index.tsx +++ b/frontend/ui/src/pages/Channels/ConnectedChannelsBySourceCard/index.tsx @@ -29,7 +29,8 @@ const ConnectedChannelsBySourceCard = (props: ConnectedChannelsBySourceCardProps
props.history.push(sourceInfo.channelsListRoute)}> + onClick={() => props.history.push(sourceInfo.channelsListRoute)} + >
{channels.slice(0, sourceInfo.channelsToShow).map((channel: Channel) => { return ( @@ -65,7 +66,8 @@ const ConnectedChannelsBySourceCard = (props: ConnectedChannelsBySourceCardProps type="button" className={styles.addChannelButton} onClick={() => props.history.push(sourceInfo.newChannelRoute)} - data-cy={sourceInfo.dataCyAddChannelButton}> + data-cy={sourceInfo.dataCyAddChannelButton} + >
diff --git a/frontend/ui/src/pages/Channels/ConnectedChannelsList/ChannelListItem/index.tsx b/frontend/ui/src/pages/Channels/ConnectedChannelsList/ChannelListItem/index.tsx index e2b724dbbc..00348a2732 100644 --- a/frontend/ui/src/pages/Channels/ConnectedChannelsList/ChannelListItem/index.tsx +++ b/frontend/ui/src/pages/Channels/ConnectedChannelsList/ChannelListItem/index.tsx @@ -67,7 +67,8 @@ const ChannelListItem = (props: ChannelListItemProps) => { pathname: `/channels/${channel.source}/${channel.id}`, state: {channel: channel}, }) - }> + } + > Edit
diff --git a/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/ConnectNewChatPlugin.tsx b/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/ConnectNewChatPlugin.tsx index c2db89136c..783a5c1391 100644 --- a/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/ConnectNewChatPlugin.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/ConnectNewChatPlugin.tsx @@ -59,7 +59,8 @@ export const ConnectNewChatPlugin = ({createNewConnection}: ConnectNewChatPlugin onClick={(event: React.FormEvent) => { event.preventDefault(); createNewConnection(displayName, imageUrl); - }}> + }} + > Save diff --git a/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/CustomiseSection.tsx b/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/CustomiseSection.tsx index e435ac5b08..672eb02e81 100644 --- a/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/CustomiseSection.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/CustomiseSection.tsx @@ -40,8 +40,40 @@ export const CustomiseSection = ({channelId, host}: CustomiseSectionProps) => { const [showPrimaryColorPicker, setShowPrimaryColorPicker] = useLocalState('showPrimaryColorPicker', false); const [accentColor, setAccentColor] = useLocalState('accentColor', ''); const [showAccentColorPicker, setShowAccentColorPicker] = useLocalState('showAccentColorPicker', false); + const [backgroundColor, setBackgroundColor] = useLocalState('backgroundColor', ''); const [showBackgroundColorPicker, setShowBackgroundColorPicker] = useLocalState('showBackgroundColorPicker', false); + + const [inboundMessageBackgroundColor, setInboundMessageBackgroundColor] = useLocalState( + 'inboundMessageBackgroundColor', + '' + ); + const [showInboundMessageColorPicker, setShowInboundMessageColorPicker] = useLocalState( + 'showInboundMessageColorPicker', + false + ); + + const [inboundMessageTextColor, setInboundMessageTextColor] = useLocalState('inboundMessageTextColor', ''); + const [showInboundMessageTextColorPicker, setShowInboundMessageTextColorPicker] = useLocalState( + 'showInboundMessageTextColorPicker', + false + ); + + const [outboundMessageBackgroundColor, setOutboundMessageBackgroundColor] = useLocalState( + 'outboundMessageBackgroundColor', + '' + ); + const [showOutboundMessageColorPicker, setShowOutboundMessageColorPicker] = useLocalState( + 'showOutboundMessageColorPicker', + false + ); + + const [outboundMessageTextColor, setOutboundMessageTextColor] = useLocalState('outboundMessageTextColor', ''); + const [showOutboundMessageTextColorPicker, setShowOutboundMessageTextColorPicker] = useLocalState( + 'showOutboundMessageTextColorPicker', + false + ); + const [height, setHeight] = useLocalState('height', '700'); const [width, setWidth] = useLocalState('width', '350'); const [disableMobile, setDisableMobile] = useLocalState('disableMobile', false); @@ -72,6 +104,22 @@ export const CustomiseSection = ({channelId, host}: CustomiseSectionProps) => { setShowBackgroundColorPicker(!showBackgroundColorPicker); }; + const toggleShowInboundMessageColorPicker = () => { + setShowInboundMessageColorPicker(!showInboundMessageColorPicker); + }; + + const toggleShowInboundMessageTextColorPicker = () => { + setShowInboundMessageTextColorPicker(!showInboundMessageTextColorPicker); + }; + + const toggleShowOutboundMessageColorPicker = () => { + setShowOutboundMessageColorPicker(!showOutboundMessageColorPicker); + }; + + const toggleShowOutboundMessageTextColorPicker = () => { + setShowOutboundMessageTextColorPicker(!showOutboundMessageTextColorPicker); + }; + const getTemplateConfig = () => { const config = [ headerText && `headerText: '${headerText}'`, @@ -84,6 +132,10 @@ export const CustomiseSection = ({channelId, host}: CustomiseSectionProps) => { primaryColor && `primaryColor: '${primaryColor}'`, accentColor && `accentColor: '${accentColor}'`, backgroundColor && `backgroundColor: '${backgroundColor}'`, + inboundMessageBackgroundColor && `inboundMessageColor: '${inboundMessageBackgroundColor}'`, + inboundMessageTextColor && `inboundMessageTextColor: '${inboundMessageTextColor}'`, + outboundMessageBackgroundColor && `outboundMessageColor: '${outboundMessageBackgroundColor}'`, + outboundMessageTextColor && `outboundMessageTextColor: '${outboundMessageTextColor}'`, height && `height: '${height}'`, width && `width: '${width}'`, `closeMode: '${closingOption}'`, @@ -109,6 +161,10 @@ export const CustomiseSection = ({channelId, host}: CustomiseSectionProps) => { ...(primaryColor && {primaryColor}), ...(accentColor && {accentColor}), ...(backgroundColor && {backgroundColor}), + ...(outboundMessageBackgroundColor && {outboundMessageColor: outboundMessageBackgroundColor}), + ...(outboundMessageTextColor && {outboundMessageTextColor}), + ...(inboundMessageBackgroundColor && {inboundMessageColor: inboundMessageBackgroundColor}), + ...(inboundMessageTextColor && {inboundMessageTextColor}), ...(bubbleIconUrl && {bubbleIcon: bubbleIconUrl}), ...(sendMessageIconUrl && {sendMessageIcon: sendMessageIconUrl}), ...(width && {width: parseInt(width) < 200 ? 350 : parseInt(width)}), @@ -344,6 +400,170 @@ export const CustomiseSection = ({channelId, host}: CustomiseSectionProps) => { fontClass="font-base" />
+

Inbound Background Color

+
+ {showInboundMessageColorPicker && ( + + { + setInboundMessageBackgroundColor(color.hex.toUpperCase()); + }} + /> + + )} +
+ ) => { + setInboundMessageBackgroundColor(e.target.value); + }} + onBlur={(e: React.ChangeEvent) => { + const value = e.target.value; + if (value !== '') { + const newBackgroundColor = value.startsWith('#') ? value : '#' + value; + setInboundMessageBackgroundColor(newBackgroundColor.toUpperCase()); + } else { + setInboundMessageBackgroundColor(''); + } + }} + placeholder="#FFFFFF" + height={32} + fontClass="font-base" + /> +
+

Inbound Text Color

+
+ {showInboundMessageTextColorPicker && ( + + { + setInboundMessageTextColor(color.hex.toUpperCase()); + }} + /> + + )} +
+ ) => { + setInboundMessageTextColor(e.target.value); + }} + onBlur={(e: React.ChangeEvent) => { + const value = e.target.value; + if (value !== '') { + const newBackgroundColor = value.startsWith('#') ? value : '#' + value; + setInboundMessageTextColor(newBackgroundColor.toUpperCase()); + } else { + setInboundMessageTextColor(''); + } + }} + placeholder="#FFFFFF" + height={32} + fontClass="font-base" + /> +
+

Outbound Background Color

+
+ {showOutboundMessageColorPicker && ( + + { + setOutboundMessageBackgroundColor(color.hex.toUpperCase()); + }} + /> + + )} +
+ ) => { + setOutboundMessageBackgroundColor(e.target.value); + }} + onBlur={(e: React.ChangeEvent) => { + const value = e.target.value; + if (value !== '') { + const newBackgroundColor = value.startsWith('#') ? value : '#' + value; + setOutboundMessageBackgroundColor(newBackgroundColor.toUpperCase()); + } else { + setOutboundMessageBackgroundColor(''); + } + }} + placeholder="#FFFFFF" + height={32} + fontClass="font-base" + /> +
+

Outbound Text Color

+
+ {showOutboundMessageTextColorPicker && ( + + { + setOutboundMessageTextColor(color.hex.toUpperCase()); + }} + /> + + )} +
+ ) => { + setOutboundMessageTextColor(e.target.value); + }} + onBlur={(e: React.ChangeEvent) => { + const value = e.target.value; + if (value !== '') { + const newBackgroundColor = value.startsWith('#') ? value : '#' + value; + setOutboundMessageTextColor(newBackgroundColor.toUpperCase()); + } else { + setOutboundMessageTextColor(''); + } + }} + placeholder="#FFFFFF" + height={32} + fontClass="font-base" + /> +
{ }} />
-
- setDisableMobile(value)} - /> -
-
- setHideInputBar(value)} /> -
-
- setHideEmojis(value)} /> -
{ fontClass="font-base" showErrors={false} /> +
+ setDisableMobile(value)} + /> +
+
+ setHideInputBar(value)} /> +
+
+ setHideEmojis(value)} /> +
+ }} + >
diff --git a/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/EditChatPlugin.tsx b/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/EditChatPlugin.tsx index b6ce8f9183..12bfd8b009 100644 --- a/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/EditChatPlugin.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Airy/ChatPlugin/sections/EditChatPlugin.tsx @@ -45,7 +45,8 @@ export const EditChatPlugin = ({channel, host, updateConnection}: EditChatPlugin onSubmit={(event: React.FormEvent) => { event.preventDefault(); updateConnection(displayName, imageUrl); - }}> + }} + >
{ + color="grey" + > diff --git a/frontend/ui/src/pages/Channels/Providers/Google/GoogleConnect.tsx b/frontend/ui/src/pages/Channels/Providers/Google/GoogleConnect.tsx index 8e6b7dc55e..6bae51a486 100644 --- a/frontend/ui/src/pages/Channels/Providers/Google/GoogleConnect.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Google/GoogleConnect.tsx @@ -72,7 +72,8 @@ const GoogleConnect = (props: GoogleProps) => { + color="grey" + > diff --git a/frontend/ui/src/pages/Channels/Providers/Instagram/InstagramConnect.tsx b/frontend/ui/src/pages/Channels/Providers/Instagram/InstagramConnect.tsx index c7b62e76e1..ea40363ccf 100644 --- a/frontend/ui/src/pages/Channels/Providers/Instagram/InstagramConnect.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Instagram/InstagramConnect.tsx @@ -79,7 +79,8 @@ const InstagramConnect = (props: InstagramProps) => { + color="grey" + > diff --git a/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioConnect.tsx b/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioConnect.tsx index 30d7710efb..99a48705ea 100644 --- a/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioConnect.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioConnect.tsx @@ -118,7 +118,8 @@ const TwilioConnect = (props: TwilioConnectProps) => { type="submit" styleVariant="normal" disabled={numberInput.trim().length === 0} - onClick={(e: React.ChangeEvent) => connectTwilioChannel(e)}> + onClick={(e: React.ChangeEvent) => connectTwilioChannel(e)} + > {buttonText}
diff --git a/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioRequirementsDialog/index.tsx b/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioRequirementsDialog/index.tsx index e236bc2fad..f27e963c5a 100644 --- a/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioRequirementsDialog/index.tsx +++ b/frontend/ui/src/pages/Channels/Providers/Twilio/TwilioRequirementsDialog/index.tsx @@ -23,7 +23,8 @@ export const TwilioRequirementsDialog = (props: TwilioRequirementsDialogProps) = + rel="noreferrer" + > Twilio Auth Token {' '} to the{' '} @@ -31,7 +32,8 @@ export const TwilioRequirementsDialog = (props: TwilioRequirementsDialogProps) = className={styles.configMessage} href="https://airy.co/docs/core/getting-started/installation/configuration" target="_blank" - rel="noreferrer"> + rel="noreferrer" + > airy.yaml {' '} file. diff --git a/frontend/ui/src/pages/Channels/SourceDescriptionCard/index.tsx b/frontend/ui/src/pages/Channels/SourceDescriptionCard/index.tsx index dd18c20d30..bc64acb662 100644 --- a/frontend/ui/src/pages/Channels/SourceDescriptionCard/index.tsx +++ b/frontend/ui/src/pages/Channels/SourceDescriptionCard/index.tsx @@ -33,7 +33,8 @@ const SourceDescriptionCard = (props: SourceDescriptionCardProps) => { type="button" className={styles.addChannelButton} onClick={addChannelAction} - data-cy={sourceInfo.dataCyAddChannelButton}> + data-cy={sourceInfo.dataCyAddChannelButton} + >
diff --git a/frontend/ui/src/pages/Inbox/ConversationList/index.tsx b/frontend/ui/src/pages/Inbox/ConversationList/index.tsx index 438cfb96aa..6bbf0757e4 100644 --- a/frontend/ui/src/pages/Inbox/ConversationList/index.tsx +++ b/frontend/ui/src/pages/Inbox/ConversationList/index.tsx @@ -56,7 +56,11 @@ const ConversationList = (props: ConversationListProps) => { const isLoadingConversation = paginationData.loading; const hasPreviousMessages = () => { - return !!(conversationsPaginationData && conversationsPaginationData && conversationsPaginationData.nextCursor); + if (filteredPaginationData.previousCursor && filteredPaginationData.nextCursor === null) { + return false; + } else { + return !!(conversationsPaginationData && conversationsPaginationData && conversationsPaginationData.nextCursor); + } }; const debouncedListPreviousConversations = debounce(() => { diff --git a/frontend/ui/src/pages/Inbox/ConversationListHeader/index.tsx b/frontend/ui/src/pages/Inbox/ConversationListHeader/index.tsx index 3b5bc7330e..c7cec67fb8 100644 --- a/frontend/ui/src/pages/Inbox/ConversationListHeader/index.tsx +++ b/frontend/ui/src/pages/Inbox/ConversationListHeader/index.tsx @@ -107,7 +107,8 @@ const ConversationListHeader = (props: ConversationListHeaderProps) => { title="Filter" id="filterButton" className={`${isFilterActive() ? styles.activeFilters : styles.filterButton}`} - onClick={toggleFilter}> + onClick={toggleFilter} + > {isFilterOpen && ( diff --git a/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx b/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx index 2287a5f7ef..1d9b93069d 100644 --- a/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx +++ b/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx @@ -53,7 +53,8 @@ const ClosedStateButton = ({eventHandler}: StateButtonsProps) => {
@@ -98,7 +99,8 @@ const ConversationListItem = (props: ConversationListItemProps) => {
+ }`} + >
diff --git a/frontend/ui/src/pages/Inbox/MessageInput/InputOptions.tsx b/frontend/ui/src/pages/Inbox/MessageInput/InputOptions.tsx index 97f2f50088..3d2f3d77c9 100644 --- a/frontend/ui/src/pages/Inbox/MessageInput/InputOptions.tsx +++ b/frontend/ui/src/pages/Inbox/MessageInput/InputOptions.tsx @@ -1,4 +1,5 @@ import React, {useEffect, useRef, useState} from 'react'; +import {connect, ConnectedProps} from 'react-redux'; import {Picker} from 'emoji-mart'; import 'emoji-mart/css/emoji-mart.css'; import {ReactComponent as Smiley} from 'assets/images/icons/smiley.svg'; @@ -6,9 +7,9 @@ import {ReactComponent as TemplateAlt} from 'assets/images/icons/template-alt.sv import {ReactComponent as Paperclip} from 'assets/images/icons/paperclip.svg'; import TemplateSelector from '../TemplateSelector'; import {sendMessages} from '../../../actions/messages'; -import {connect, ConnectedProps} from 'react-redux'; import {Template, Source} from 'model'; import {ErrorPopUp} from 'components'; +import {getInputAcceptedFilesForSource} from '../../../services/types/attachmentsTypes'; import styles from './InputOptions.module.scss'; const mapDispatchToProps = {sendMessages}; @@ -52,6 +53,12 @@ export const InputOptions = (props: Props) => { const emojiDiv = useRef(null); const [isShowingEmojiDrawer, setIsShowingEmojiDrawer] = useState(false); const [isShowingTemplateModal, setIsShowingTemplateModal] = useState(false); + const [inputAcceptedFiles, setInputAcceptedFiles] = useState(''); + + useEffect(() => { + const inputAcceptValue = getInputAcceptedFilesForSource(source); + setInputAcceptedFiles(inputAcceptValue); + }, [source]); const toggleEmojiDrawer = () => { if (isShowingTemplateModal) { @@ -129,43 +136,51 @@ export const InputOptions = (props: Props) => { - {mediaResolverComponentsConfig.enabled && (source === 'facebook' || source === 'instagram') && ( - - )} + {mediaResolverComponentsConfig.enabled && + (source === 'facebook' || source === 'instagram' || source === 'google' || source === 'twilio.whatsapp') && ( + + )}
); }; diff --git a/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.module.scss b/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.module.scss index c6f15f3239..40579179e7 100644 --- a/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.module.scss +++ b/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.module.scss @@ -3,7 +3,17 @@ .container { max-width: 550px; position: relative; - margin: 0px 5px 0px 5px; + margin: 0px 0px 5px 10px; + animation: fadeIn 3s linear forwards; +} + +@keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } } .removeButton { diff --git a/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.tsx b/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.tsx index c5b769d6e5..c6064b62d0 100644 --- a/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.tsx +++ b/frontend/ui/src/pages/Inbox/MessageInput/InputSelector.tsx @@ -3,71 +3,75 @@ import styles from './InputSelector.module.scss'; import {ReactComponent as Close} from 'assets/images/icons/close.svg'; import {SourceMessage} from 'render'; import {Source, Message} from 'model'; -import {FileInfo} from './index'; type InputSelectorProps = { messageType: 'template' | 'suggestedReplies' | 'message'; message: Message; source: Source; - contentResizedHeight: number; - fileInfo: FileInfo | null; removeElementFromInput: () => void; + contentResizedHeight: number; }; +const textareaHeight = 40; +const minImageHeight = 50; + export const InputSelector = (props: InputSelectorProps) => { - const {source, message, messageType, removeElementFromInput, contentResizedHeight, fileInfo} = props; + const {source, message, messageType, removeElementFromInput, contentResizedHeight} = props; const [closeIconWidth, setCloseIconWidth] = useState(''); const [closeIconHeight, setCloseIconHeight] = useState(''); - const [closeButtonSelector, setCloseButtonSelector] = useState(false); + const [selectorPreviewCloseButton, setSelectorPreviewCloseButton] = useState(false); const fileSelectorDiv = useRef(null); const removeFileButton = useRef(null); - const scaleInputSelector = () => { - if (fileSelectorDiv?.current?.offsetHeight > contentResizedHeight) { - const contentSelectorDivHeight = fileSelectorDiv.current.offsetHeight; - const scaleRatio = Number(Math.min(contentResizedHeight / contentSelectorDivHeight).toFixed(2)); + const resizeObserver = new ResizeObserver(entries => { + for (const entry of entries) { + const fileSelectorHeight = entry.contentRect.height; + const fileSelectorWidth = entry.contentRect.width; + + if (fileSelectorHeight > contentResizedHeight) { + scaleDownInputSelector(fileSelectorHeight); + } else if (fileSelectorHeight >= textareaHeight && fileSelectorWidth > minImageHeight) { + setSelectorPreviewCloseButton(true); + } + } + }); - if (scaleRatio <= 0.9) { - const iconSize = scaleRatio > 0.3 ? '18px' : '30px'; - const buttonSize = scaleRatio > 0.3 ? '36px' : '60px'; + useEffect(() => { + resizeObserver.observe(fileSelectorDiv?.current); + }, [fileSelectorDiv?.current]); - setCloseIconHeight(iconSize); - setCloseIconWidth(iconSize); - setCloseButtonSelector(true); + const scaleDownInputSelector = (fileSelectorHeight: number) => { + const scaleRatio = Number(Math.min(contentResizedHeight / fileSelectorHeight).toFixed(2)); + let iconSize; + let buttonSize; - if (removeFileButton && removeFileButton.current) { - removeFileButton.current.style.width = buttonSize; - removeFileButton.current.style.height = buttonSize; - } + if (scaleRatio <= 0.9) { + if (scaleRatio < 0.5) { + iconSize = scaleRatio > 0.3 ? '36px' : '60px'; + buttonSize = scaleRatio > 0.3 ? '72px' : '120px'; } else { - setCloseButtonSelector(true); + iconSize = '18px'; + buttonSize = '36px'; } - fileSelectorDiv.current.style.transform = `scale(${scaleRatio})`; - fileSelectorDiv.current.style.transformOrigin = 'left'; - } else { - if (fileInfo && fileInfo?.size >= 1 && fileInfo?.type !== 'audio' && fileInfo?.type !== 'file') { - setTimeout(() => { - setCloseButtonSelector(true); - }, 1000); - } else if (fileInfo && fileInfo?.size < 1 && fileInfo?.type !== 'audio' && fileInfo?.type !== 'file') { - setTimeout(() => { - setCloseButtonSelector(true); - }, 500); - } else { - setCloseButtonSelector(true); + setCloseIconHeight(iconSize); + setCloseIconWidth(iconSize); + + if (removeFileButton && removeFileButton.current) { + removeFileButton.current.style.width = buttonSize; + removeFileButton.current.style.height = buttonSize; } } - }; - useEffect(() => { - scaleInputSelector(); - }, []); + fileSelectorDiv.current.style.transform = `scale(${scaleRatio})`; + fileSelectorDiv.current.style.transformOrigin = 'left'; + setSelectorPreviewCloseButton(true); + }; return (
- {closeButtonSelector && ( + {selectorPreviewCloseButton && (
diff --git a/frontend/ui/src/pages/Inbox/Messenger/ConversationStatus/index.tsx b/frontend/ui/src/pages/Inbox/Messenger/ConversationStatus/index.tsx index c049c3f3cc..4ffe7f8ff2 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/ConversationStatus/index.tsx +++ b/frontend/ui/src/pages/Inbox/Messenger/ConversationStatus/index.tsx @@ -5,6 +5,7 @@ import styles from './index.module.scss'; import {conversationState} from '../../../../actions/conversations'; import {StateModel} from '../../../../reducers'; import {cyConversationStatus} from 'handles'; +import {SimpleLoader} from 'components'; const mapStateToProps = (state: StateModel, ownProps) => { return { @@ -25,31 +26,44 @@ function ConversationStatus(props: Props) { const {currentConversationState, conversationState} = props; const [buttonStateEnabled, setButtonStateEnabled] = useState(true); + const [loading, setLoading] = useState(false); const toggleState = (id: string, state: string) => { - if (buttonStateEnabled) { + if (buttonStateEnabled && currentConversationState !== state) { + setLoading(true); setButtonStateEnabled(false); conversationState(id, state); setTimeout(() => { setButtonStateEnabled(true); - }, 2000); + setLoading(false); + }, 1000); } }; return (
-
-
toggleState(props.match.params.conversationId, 'CLOSED')}> - Closed -
-
-
-
toggleState(props.match.params.conversationId, 'OPEN')}> - Open -
-
+ data-cy={cyConversationStatus} + > + {loading ? ( + + ) : ( + <> +
+
toggleState(props.match.params.conversationId, 'CLOSED')} + > + Closed +
+
+
+
toggleState(props.match.params.conversationId, 'OPEN')}> + Open +
+
+ + )}
); } diff --git a/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.module.scss b/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.module.scss index 5fb94b6576..426bd19f73 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.module.scss +++ b/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.module.scss @@ -7,7 +7,6 @@ padding: 16px; height: 100%; overflow-y: scroll; - flex-grow: 1; overflow-x: hidden; } diff --git a/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx b/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx index 5a71bc2d67..1041953460 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx +++ b/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx @@ -173,7 +173,8 @@ const MessageList = (props: MessageListProps) => { sentAt={sentAt} lastInGroup={lastInGroup} isChatPlugin={false} - decoration={messageDecoration}> + decoration={messageDecoration} + > diff --git a/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.module.scss b/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.module.scss index 0ca61e7302..7e5a94ef51 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.module.scss +++ b/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.module.scss @@ -70,6 +70,7 @@ .dragOverlay { background-color: var(--color-template-highlight); opacity: 0.9; + border: 2px dashed var(--color-airy-blue); } .dragContainer h1 { diff --git a/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.tsx b/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.tsx index 90a8a6b68a..208f0b1495 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.tsx +++ b/frontend/ui/src/pages/Inbox/Messenger/MessengerContainer/index.tsx @@ -46,7 +46,7 @@ const MessengerContainer = ({ if (source && config) { if ( config?.components['media-resolver']?.enabled && - (source === 'instagram' || source === 'facebook') && + (source === 'instagram' || source === 'facebook' || source === 'google' || source === 'twilio.whatsapp') && !draggedAndDroppedFile ) { setDragAndDropDisabled(false); @@ -90,17 +90,17 @@ const MessengerContainer = ({ }; const handleDragOver = (event: React.DragEvent) => { - event.preventDefault(); event.stopPropagation(); + event.preventDefault(); if (dragAndDropDisabled) return; }; const handleDragEnter = (event: React.DragEvent) => { - if (dragAndDropDisabled) return; - - event.preventDefault(); event.stopPropagation(); + event.preventDefault(); + + if (dragAndDropDisabled) return; dragCounter++; @@ -108,10 +108,10 @@ const MessengerContainer = ({ }; const handleFileDrop = (event: React.DragEvent) => { - if (dragAndDropDisabled) return; - - event.preventDefault(); event.stopPropagation(); + event.preventDefault(); + + if (dragAndDropDisabled) return; dragCounter++; const file = event.dataTransfer.files[0]; @@ -120,9 +120,10 @@ const MessengerContainer = ({ }; const handleDragLeave = (event: React.DragEvent) => { - if (dragAndDropDisabled) return; - event.preventDefault(); event.stopPropagation(); + event.preventDefault(); + + if (dragAndDropDisabled) return; dragCounter--; if (dragCounter === 0) { @@ -139,7 +140,8 @@ const MessengerContainer = ({ onDrop={e => handleFileDrop(e)} onDragLeave={e => handleDragLeave(e)} onMouseOut={() => setIsFileDragged(false)} - onMouseLeave={() => setIsFileDragged(false)}> + onMouseLeave={() => setIsFileDragged(false)} + > {!dragAndDropDisabled && (

Drop Files Here

diff --git a/frontend/ui/src/pages/Inbox/QuickFilter/Popup.tsx b/frontend/ui/src/pages/Inbox/QuickFilter/Popup.tsx index 1eb8032bef..7fc95e3cd8 100644 --- a/frontend/ui/src/pages/Inbox/QuickFilter/Popup.tsx +++ b/frontend/ui/src/pages/Inbox/QuickFilter/Popup.tsx @@ -126,7 +126,8 @@ const PopUpFilter = (props: PopUpFilterProps) => { + coverStyle={{backgroundColor: 'rgba(247,247,247,0.7)'}} + >
@@ -135,12 +136,14 @@ const PopUpFilter = (props: PopUpFilterProps) => {
@@ -156,7 +159,8 @@ const PopUpFilter = (props: PopUpFilterProps) => { ? styles.filterButton : styles.filterButtonSelected } - onClick={(event: React.MouseEvent) => setState(event, true)}> + onClick={(event: React.MouseEvent) => setState(event, true)} + >
Open @@ -166,7 +170,8 @@ const PopUpFilter = (props: PopUpFilterProps) => { ? styles.filterButton : styles.filterButtonSelected } - onClick={(event: React.MouseEvent) => setState(event, false)}> + onClick={(event: React.MouseEvent) => setState(event, false)} + >
@@ -222,7 +227,8 @@ const PopUpFilter = (props: PopUpFilterProps) => { className={`${styles.sourceEntry} ${ isChannelSelected(filter.byChannels, channel) ? styles.sourceSelected : '' }`} - onClick={() => toggleChannel(channel.id)}> + onClick={() => toggleChannel(channel.id)} + > {isChannelSelected(filter.byChannels, channel) ? (
@@ -249,7 +255,8 @@ const PopUpFilter = (props: PopUpFilterProps) => { className={`${styles.sourceEntry} ${ isSourceSelected(filter.bySources, source) ? styles.sourceSelected : '' }`} - onClick={() => toggleSource(source)}> + onClick={() => toggleSource(source)} + > {isSourceSelected(filter.bySources, source) ? (
diff --git a/frontend/ui/src/pages/Inbox/QuickFilter/index.tsx b/frontend/ui/src/pages/Inbox/QuickFilter/index.tsx index a56d525835..b4cf3c2846 100644 --- a/frontend/ui/src/pages/Inbox/QuickFilter/index.tsx +++ b/frontend/ui/src/pages/Inbox/QuickFilter/index.tsx @@ -57,17 +57,20 @@ const QuickFilter = (props: ConversationsFilterProps) => {
diff --git a/frontend/ui/src/pages/Inbox/SuggestedReplySelector/index.tsx b/frontend/ui/src/pages/Inbox/SuggestedReplySelector/index.tsx index abb2e92cc2..12c2da4ef9 100644 --- a/frontend/ui/src/pages/Inbox/SuggestedReplySelector/index.tsx +++ b/frontend/ui/src/pages/Inbox/SuggestedReplySelector/index.tsx @@ -45,7 +45,8 @@ const SuggestedReplySelector = ({onClose, suggestions, selectSuggestedReply, sou key={id} onClick={() => { selectSuggestedReply(suggestion); - }}> + }} + >
{ selectTemplate(template); - }}> + }} + >
{template.name}
diff --git a/frontend/ui/src/pages/Tags/TableRow.tsx b/frontend/ui/src/pages/Tags/TableRow.tsx index dc341968b8..8b2720b2b5 100644 --- a/frontend/ui/src/pages/Tags/TableRow.tsx +++ b/frontend/ui/src/pages/Tags/TableRow.tsx @@ -145,7 +145,8 @@ const TableRowComponent = (props: TableRowProps) => { type="button" className={styles.actionButton} onClick={deleteClicked} - data-cy={cyTagsTableRowDisplayDeleteModal}> + data-cy={cyTagsTableRowDisplayDeleteModal} + >
diff --git a/frontend/ui/src/pages/Tags/index.tsx b/frontend/ui/src/pages/Tags/index.tsx index 114aaf6685..fc6fce503c 100644 --- a/frontend/ui/src/pages/Tags/index.tsx +++ b/frontend/ui/src/pages/Tags/index.tsx @@ -130,7 +130,8 @@ class Tags extends Component, typeof initialSta + close={this.closeModal} + >

You're about to permanently delete "{this.state.modal.tagName}" from your @@ -158,7 +159,8 @@ class Tags extends Component, typeof initialSta

diff --git a/frontend/ui/src/services/types/attachmentsTypes.ts b/frontend/ui/src/services/types/attachmentsTypes.ts new file mode 100644 index 0000000000..c7afe9b616 --- /dev/null +++ b/frontend/ui/src/services/types/attachmentsTypes.ts @@ -0,0 +1,42 @@ +import {attachmentsExtensions} from 'render'; + +export const getAllSupportedAttachmentsForSource = (source: string) => { + if (source === 'twilio.whatsapp') source = 'twilioWhatsapp'; + + const imageFiles = attachmentsExtensions[source + 'ImageExtensions']; + const videoFiles = attachmentsExtensions[source + 'VideoExtensions']; + const audioFiles = attachmentsExtensions[source + 'AudioExtensions']; + const docsFiles = attachmentsExtensions[source + 'FileExtensions']; + + const supportedDocsFiles = docsFiles ? docsFiles.join(', ') : ''; + const supportedAudioFiles = + audioFiles && docsFiles ? audioFiles.join(', ') + ',' : audioFiles ? audioFiles.join(', ') : ''; + const supportedVideoFiles = + videoFiles && audioFiles ? videoFiles.join(', ') + ',' : videoFiles ? videoFiles.join(', ') : ''; + const supportedImageFiles = + imageFiles && videoFiles ? imageFiles.join(', ') + ',' : imageFiles ? imageFiles.join(', ') : ''; + + return `${supportedImageFiles} ${supportedVideoFiles} ${supportedAudioFiles} ${supportedDocsFiles}`; +}; + +export const getInputAcceptedFilesForSource = (source: string) => { + if (source === 'twilio.whatsapp') source = 'twilioWhatsapp'; + + const imageFiles = attachmentsExtensions[source + 'ImageExtensions']; + const videoFiles = attachmentsExtensions[source + 'VideoExtensions']; + const audioFiles = attachmentsExtensions[source + 'AudioExtensions']; + const docsFiles = attachmentsExtensions[source + 'FileExtensions']; + + if (!imageFiles && !videoFiles && !audioFiles && !docsFiles) { + return null; + } + + const supportedDocsFiles = docsFiles ? '.' + docsFiles.join(', .') : ''; + const supportedAudioFiles = audioFiles ? '.' + audioFiles.join(', .') + ',' : ''; + const supportedVideoFiles = videoFiles ? '.' + videoFiles.join(', .') + ',' : ''; + const supportedImageFiles = imageFiles ? '.' + imageFiles.join(', .') + ',' : ''; + + const inputAcceptValue = `${supportedImageFiles} ${supportedVideoFiles} ${supportedAudioFiles} ${supportedDocsFiles}`; + + return inputAcceptValue; +}; diff --git a/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/communication/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/communication/deployment.yaml index 419bfc4806..86c0987e94 100644 --- a/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/communication/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/communication/deployment.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: api-communication + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -53,9 +54,11 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.communication.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/websocket/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/websocket/deployment.yaml index 24bafe4b74..57120161a5 100644 --- a/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/websocket/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/templates/websocket/deployment.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: api-websocket + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -53,9 +54,11 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.websocket.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/values.yaml b/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/values.yaml index 5de2cbd618..94594299c5 100644 --- a/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/api/charts/api-communication/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true communication: image: api/communication + resources: {} websocket: image: api/websocket + resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/templates/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/templates/deployment.yaml index 75c61ebf43..c6597c7166 100644 --- a/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/templates/deployment.yaml @@ -24,6 +24,7 @@ spec: metadata: labels: app: frontend-ui + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -45,6 +46,8 @@ spec: initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.resources | indent 10 }} volumes: - name: provisioning-scripts configMap: diff --git a/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/values.yaml b/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/values.yaml index 1c9bbf5e63..d5f4a70983 100644 --- a/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/frontend/charts/frontend-ui/values.yaml @@ -2,3 +2,4 @@ component: frontend-ui mandatory: false enabled: true image: frontend/ui +resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/Chart.yaml b/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/Chart.yaml index bf44496a95..a074f0edb0 100644 --- a/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/Chart.yaml +++ b/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for the Sources Chatplugin app -name: integration-source-api +name: source-api version: 0-develop diff --git a/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/templates/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/templates/deployment.yaml index 53b470b16c..33e6e3b398 100644 --- a/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/templates/deployment.yaml @@ -62,9 +62,11 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/values.yaml b/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/values.yaml index 68810eaa98..e73fd2f262 100644 --- a/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/integration/charts/source-api/values.yaml @@ -1,3 +1,4 @@ component: integration-source-api mandatory: false image: sources/api +resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/Chart.yaml b/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/Chart.yaml index 7a77d8744b..ccaa4034af 100644 --- a/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/Chart.yaml +++ b/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for the Webhook integration component -name: integration-webhook +name: webhook version: 0-develop diff --git a/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/templates/deployments.yaml b/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/templates/deployments.yaml index 336e59d2fb..94e58389d9 100644 --- a/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/templates/deployments.yaml +++ b/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/templates/deployments.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: webhook-consumer + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -65,7 +66,9 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 + resources: +{{ toYaml .Values.consumer.resources | indent 10 }} initContainers: - name: wait image: busybox @@ -114,6 +117,7 @@ spec: metadata: labels: app: webhook-publisher + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -159,7 +163,9 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 + resources: +{{ toYaml .Values.publisher.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/values.yaml b/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/values.yaml index 32796ac4f6..ce8d1a4226 100644 --- a/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/integration/charts/webhook/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true consumer: image: webhook/consumer + resources: {} publisher: - image: webhook/publisher \ No newline at end of file + image: webhook/publisher + resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/Chart.yaml b/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/Chart.yaml index b943f1e4e5..da92da72b8 100644 --- a/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/Chart.yaml +++ b/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for the Media Resolver app -name: media-resolver +name: resolver version: 0-develop diff --git a/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/templates/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/templates/deployment.yaml index 0a9425d88d..861a34ea58 100644 --- a/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/templates/deployment.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: media-resolver + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -55,12 +56,15 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.resources | indent 12 }} initContainers: - name: wait image: busybox + imagePullPolicy: IfNotPresent command: ["/bin/sh", "/opt/provisioning/wait-for-minimum-kafkas.sh"] env: - name: KAFKA_BROKERS diff --git a/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/values.yaml b/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/values.yaml index d473975913..34cdd62cdf 100644 --- a/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/media/charts/resolver/values.yaml @@ -2,3 +2,4 @@ component: media-resolver mandatory: false enabled: true image: media/resolver +resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/backend/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/backend/deployment.yaml index 90468c7312..43579183e7 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/backend/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/backend/deployment.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: sources-chatplugin + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -63,9 +64,11 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.backend.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/frontend/deployment.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/frontend/deployment.yaml index 17d2f0dc85..556b9a7c88 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/frontend/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/templates/frontend/deployment.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: frontend-chat-plugin + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -43,6 +44,8 @@ spec: initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.frontend.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/values.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/values.yaml index 53162c29af..f442ccc318 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/chatplugin/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true backend: image: sources/chat-plugin + resources: {} frontend: image: frontend/chat-plugin + resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/templates/deployments.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/templates/deployments.yaml index 74dee91ec8..5e673e5888 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/templates/deployments.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/templates/deployments.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: sources-facebook-connector + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -70,7 +71,9 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 + resources: +{{ toYaml .Values.connector.resources | indent 12 }} initContainers: - name: wait image: busybox @@ -119,6 +122,7 @@ spec: metadata: labels: app: sources-facebook-events-router + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -150,9 +154,11 @@ spec: livenessProbe: tcpSocket: port: 6000 - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.eventsRouter.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/values.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/values.yaml index b5f0d3e845..df9e87e6e8 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/facebook/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true connector: image: sources/facebook-connector + resources: {} eventsRouter: image: sources/facebook-events-router + resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/google/templates/deployments.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/google/templates/deployments.yaml index 1dc6598397..0fed5e8048 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/google/templates/deployments.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/google/templates/deployments.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: sources-google-connector + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -65,7 +66,9 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 + resources: +{{ toYaml .Values.connector.resources | indent 12 }} initContainers: - name: wait image: busybox @@ -114,6 +117,7 @@ spec: metadata: labels: app: sources-google-events-router + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -148,9 +152,11 @@ spec: livenessProbe: tcpSocket: port: 6000 - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.eventsRouter.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/google/values.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/google/values.yaml index 0ed77b47bd..f970cafe1f 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/google/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/google/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true connector: image: sources/google-connector + resources: {} eventsRouter: image: sources/google-events-router + resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/templates/deployments.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/templates/deployments.yaml index b467dadc1a..f3a998f91b 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/templates/deployments.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/templates/deployments.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: sources-twilio-connector + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -65,7 +66,9 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 + resources: +{{ toYaml .Values.connector.resources | indent 12 }} initContainers: - name: wait image: busybox @@ -116,6 +119,7 @@ spec: metadata: labels: app: sources-twilio-events-router + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -150,9 +154,11 @@ spec: livenessProbe: tcpSocket: port: 6000 - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.eventsRouter.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/values.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/values.yaml index 59eb0a71f3..f9768fdbbf 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/twilio/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true connector: image: sources/twilio-connector + resources: {} eventsRouter: image: sources/twilio-events-router + resources: {} diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/templates/deployments.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/templates/deployments.yaml index 8719ad5e36..cd9c59ee8e 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/templates/deployments.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/templates/deployments.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: sources-viber-connector + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -60,7 +61,9 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 + resources: +{{ toYaml .Values.connector.resources | indent 12 }} initContainers: - name: wait image: busybox @@ -111,6 +114,7 @@ spec: metadata: labels: app: sources-viber-events-router + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -145,9 +149,11 @@ spec: livenessProbe: tcpSocket: port: 6000 - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.eventsRouter.resources | indent 12 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/values.yaml b/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/values.yaml index cfc1d13514..8b944f790d 100644 --- a/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/values.yaml +++ b/infrastructure/helm-chart/charts/components/charts/sources/charts/viber/values.yaml @@ -3,5 +3,7 @@ mandatory: false enabled: true connector: image: sources/viber-connector + resources: {} eventsRouter: image: sources/viber-events-router + resources: {} diff --git a/infrastructure/helm-chart/charts/components/templates/api/admin/deployment.yaml b/infrastructure/helm-chart/charts/components/templates/api/admin/deployment.yaml index 7e0bc4c58c..b962f53dd5 100644 --- a/infrastructure/helm-chart/charts/components/templates/api/admin/deployment.yaml +++ b/infrastructure/helm-chart/charts/components/templates/api/admin/deployment.yaml @@ -22,6 +22,7 @@ spec: metadata: labels: app: api-admin + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app @@ -69,9 +70,11 @@ spec: httpHeaders: - name: Health-Check value: health-check - initialDelaySeconds: 60 + initialDelaySeconds: 120 periodSeconds: 10 failureThreshold: 3 + resources: +{{ toYaml .Values.api.admin.resources | indent 10 }} initContainers: - name: wait image: busybox diff --git a/infrastructure/helm-chart/charts/components/values.yaml b/infrastructure/helm-chart/charts/components/values.yaml index 19efbc5cb2..abfc886a88 100644 --- a/infrastructure/helm-chart/charts/components/values.yaml +++ b/infrastructure/helm-chart/charts/components/values.yaml @@ -4,3 +4,4 @@ api: image: api/admin mandatory: true enabled: true + resources: {} diff --git a/infrastructure/helm-chart/charts/ingress-controller/templates/service.yaml b/infrastructure/helm-chart/charts/ingress-controller/templates/service.yaml index 6e404336be..21f89b99e8 100644 --- a/infrastructure/helm-chart/charts/ingress-controller/templates/service.yaml +++ b/infrastructure/helm-chart/charts/ingress-controller/templates/service.yaml @@ -101,4 +101,4 @@ spec: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller -{{ end }} \ No newline at end of file +{{ end }} diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/statefulset.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/statefulset.yaml index e91720f5df..47a44ce114 100644 --- a/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/statefulset.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/statefulset.yaml @@ -23,8 +23,11 @@ spec: image: "{{ .Values.prometheusExporterImage }}:{{ .Values.prometheusExporterImageTag }}" resources: requests: + cpu: 50m + memory: 64Mi + limits: cpu: 100m - memory: 100Mi + memory: 256Mi ports: - containerPort: {{ .Values.prometheusExporterPort }} name: exporter diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml index f2899c415c..3eba2f9055 100644 --- a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml @@ -32,8 +32,8 @@ spec: - "--kafka.server={{ template "kafka.name" . }}:{{ .Values.port }}" resources: requests: - cpu: 100m - memory: 100Mi + cpu: 50m + memory: 64Mi imagePullPolicy: "{{ .Values.imagePullPolicy }}" ports: - containerPort: {{ .Values.prometheus.exporterPort }} diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml index 27c733e79f..8489e443be 100644 --- a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml @@ -20,6 +20,7 @@ spec: labels: app: schema-registry release: {{ .Release.Name }} + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: schema-registry-server diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml index 5a3eaab0dc..838b64bc68 100644 --- a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml @@ -7,3 +7,4 @@ servicePort: 8081 kafka: bootstrapServers: kafka-headless:9092 minBrokers: 1 +resources: {} diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/values.yaml index 8bdee23aea..ad682bb02b 100644 --- a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/values.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/values.yaml @@ -19,7 +19,7 @@ persistence: enabled: true dataDirSize: 5Gi dataLogDirSize: 5Gi -resources: {} +resources: {} podAnnotations: {} nodeSelector: {} tolerations: [] diff --git a/infrastructure/helm-chart/charts/tools/charts/akhq/templates/deployment.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/deployment.yaml index 02fbf6e711..c449fd5305 100644 --- a/infrastructure/helm-chart/charts/tools/charts/akhq/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/deployment.yaml @@ -21,6 +21,7 @@ spec: metadata: labels: app: akhq + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" spec: containers: - name: app diff --git a/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/deployment.yaml b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/deployment.yaml index 29c15ac60e..15a1bf66a3 100644 --- a/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/deployment.yaml @@ -22,6 +22,7 @@ spec: labels: app: {{ template "kafka-connect.name" . }} release: {{ .Release.Name }} + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" {{- if or .Values.podAnnotations .Values.prometheus.jmx.enabled }} annotations: {{- range $key, $value := .Values.podAnnotations }} diff --git a/infrastructure/helm-chart/templates/controller/deployment.yaml b/infrastructure/helm-chart/templates/controller/deployment.yaml index 21cb794eb3..e2436a88f1 100644 --- a/infrastructure/helm-chart/templates/controller/deployment.yaml +++ b/infrastructure/helm-chart/templates/controller/deployment.yaml @@ -18,6 +18,7 @@ spec: metadata: labels: app: airy-controller + WorkerType: "{{ default "NodeGroup" .Values.global.workerType }}" annotations: releaseTime: {{ (now) | toString | trunc 28 | quote }} spec: @@ -32,3 +33,10 @@ spec: value: "core.airy.co/managed=true" - name: NAMESPACE value: {{ .Release.Namespace }} + resources: + requests: + cpu: "50m" + memory: "32Mi" + limits: + cpu: "50m" + memory: "128Mi" diff --git a/infrastructure/helm-chart/templates/provisioning/job-wait.yaml b/infrastructure/helm-chart/templates/provisioning/job-wait.yaml index 1732d3bfa5..63ed7410fd 100644 --- a/infrastructure/helm-chart/templates/provisioning/job-wait.yaml +++ b/infrastructure/helm-chart/templates/provisioning/job-wait.yaml @@ -2,6 +2,7 @@ apiVersion: batch/v1 kind: Job metadata: name: wait-for-api-communication + namespace: {{ .Release.Namespace }} annotations: "helm.sh/hook": "post-install,post-upgrade" "helm.sh/hook-weight": "5" @@ -33,6 +34,7 @@ apiVersion: batch/v1 kind: Job metadata: name: wait-for-frontend-ui + namespace: {{ .Release.Namespace }} annotations: "helm.sh/hook": "post-install,post-upgrade" "helm.sh/hook-weight": "5" diff --git a/infrastructure/helm-chart/templates/provisioning/kafka-create-topics.yaml b/infrastructure/helm-chart/templates/provisioning/kafka-create-topics.yaml index 9776c5e05f..faa1aea685 100644 --- a/infrastructure/helm-chart/templates/provisioning/kafka-create-topics.yaml +++ b/infrastructure/helm-chart/templates/provisioning/kafka-create-topics.yaml @@ -5,6 +5,7 @@ metadata: annotations: "helm.sh/hook": "pre-install, pre-upgrade" "helm.sh/hook-weight": "2" + namespace: {{ .Release.Namespace }} data: create-topics.sh: | #!/bin/bash diff --git a/infrastructure/helm-chart/templates/provisioning/scripts.yaml b/infrastructure/helm-chart/templates/provisioning/scripts.yaml index a2122f5b49..5786ccc9dc 100644 --- a/infrastructure/helm-chart/templates/provisioning/scripts.yaml +++ b/infrastructure/helm-chart/templates/provisioning/scripts.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: provisioning-scripts + namespace: {{ .Release.Namespace }} data: wait-for-service.sh: | #!/bin/sh diff --git a/infrastructure/helm-chart/templates/resources/limitRange.yaml b/infrastructure/helm-chart/templates/resources/limitRange.yaml new file mode 100644 index 0000000000..257f8dba0d --- /dev/null +++ b/infrastructure/helm-chart/templates/resources/limitRange.yaml @@ -0,0 +1,15 @@ +{{ if .Values.limitRange }} +apiVersion: v1 +kind: LimitRange +metadata: + name: {{ .Release.Namespace }} +spec: + limits: + - default: + cpu: "50m" + memory: "128Mi" + defaultRequest: + cpu: "20m" + memory: "32Mi" + type: Container +{{ end }} diff --git a/infrastructure/helm-chart/templates/serviceaccount.yaml b/infrastructure/helm-chart/templates/serviceaccount.yaml index 49626235d8..62afa46f81 100644 --- a/infrastructure/helm-chart/templates/serviceaccount.yaml +++ b/infrastructure/helm-chart/templates/serviceaccount.yaml @@ -9,7 +9,7 @@ metadata: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: airy-admin + name: {{ .Release.Namespace }}-airy-admin annotations: "helm.sh/hook": "pre-install,pre-upgrade" "helm.sh/hook-weight": "-5" @@ -20,4 +20,4 @@ roleRef: subjects: - kind: ServiceAccount name: airy-admin - namespace: {{ .Release.Namespace }} \ No newline at end of file + namespace: {{ .Release.Namespace }} diff --git a/infrastructure/helm-chart/values.yaml b/infrastructure/helm-chart/values.yaml index 07492b6955..5730dcbfe2 100644 --- a/infrastructure/helm-chart/values.yaml +++ b/infrastructure/helm-chart/values.yaml @@ -19,3 +19,4 @@ tools: enabled: true serviceAccount: airy-admin apiHost: http://airy.core +limitRange: false diff --git a/infrastructure/terraform/demos/analytics/files/jupyter-config.yaml b/infrastructure/terraform/demos/analytics/files/jupyter-config.yaml index 18ca907dbc..b6f1c7177d 100644 --- a/infrastructure/terraform/demos/analytics/files/jupyter-config.yaml +++ b/infrastructure/terraform/demos/analytics/files/jupyter-config.yaml @@ -11,3 +11,6 @@ singleuser: - > cp -r /tmp/demo_data.ipynb /home/jovyan; cp -r /tmp/create_df_from_parquet.ipynb /home/jovyan + cp -r /tmp/movie_data_demo.ipynb /home/jovyan + cp -r /tmp/models.py /home/jovyan + cp -r /tmp/utils.py /home/jovyan diff --git a/infrastructure/terraform/kubernetes/main.tf b/infrastructure/terraform/kubernetes/main.tf new file mode 100644 index 0000000000..c1ee627fc1 --- /dev/null +++ b/infrastructure/terraform/kubernetes/main.tf @@ -0,0 +1,12 @@ +module "eks" { + source = "../modules/aws_eks" + + core_id = "core" + + + aws_access_key = var.aws_access_key + aws_secret_key = var.aws_secret_key + + fargate_profiles = var.fargate_profiles + +} diff --git a/infrastructure/terraform/kubernetes/outputs.tf b/infrastructure/terraform/kubernetes/outputs.tf new file mode 100644 index 0000000000..89778bbd55 --- /dev/null +++ b/infrastructure/terraform/kubernetes/outputs.tf @@ -0,0 +1,3 @@ +output "cluster_name" { + value = module.eks.cluster_name +} diff --git a/infrastructure/terraform/kubernetes/variables.tf b/infrastructure/terraform/kubernetes/variables.tf new file mode 100644 index 0000000000..ac26c8f1d7 --- /dev/null +++ b/infrastructure/terraform/kubernetes/variables.tf @@ -0,0 +1,14 @@ +variable "aws_access_key" { + description = "AWS Access Key" +} + +variable "aws_secret_key" { + description = "AWS Secret Key" +} + +variable "fargate_profiles" { + type = map + default = { + "name" = "default" + } +} diff --git a/infrastructure/terraform/main/main.tf b/infrastructure/terraform/main/main.tf new file mode 100644 index 0000000000..68dfbe500e --- /dev/null +++ b/infrastructure/terraform/main/main.tf @@ -0,0 +1,13 @@ +module "my-airy-core" { + source = "../modules/core" + values_yaml = data.template_file.airy_yaml.rendered +} + +data "template_file" "airy_yaml" { + template = file("${path.module}/files/airy.yaml") + + vars = { + host = var.host + hosted_zone = var.hosted_zone + } +} diff --git a/infrastructure/terraform/main/variables.tf b/infrastructure/terraform/main/variables.tf new file mode 100644 index 0000000000..09a9749fbf --- /dev/null +++ b/infrastructure/terraform/main/variables.tf @@ -0,0 +1,22 @@ +variable "aws_access_key" { + description = "AWS Access Key" +} + +variable "aws_secret_key" { + description = "AWS Secret Key" +} + +variable "core_id" { + default = "core" +} + +variable "kubeconfig_output_path" { + default = "./.kubeconfig" +} + +variable "host" { + +} +variable "hosted_zone" { + default = "airy.co" +} diff --git a/infrastructure/terraform/modules/aws_eks/main.tf b/infrastructure/terraform/modules/aws_eks/main.tf new file mode 100644 index 0000000000..f04912ddb0 --- /dev/null +++ b/infrastructure/terraform/modules/aws_eks/main.tf @@ -0,0 +1,113 @@ +provider "aws" { + region = var.region + profile = "airy-prod" + access_key = var.aws_access_key + secret_key = var.aws_secret_key +} + +locals { + create_vpc = var.vpc_id == null ? true : false +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + + create_vpc = local.create_vpc + + name = var.vpc_name + cidr = "10.0.0.0/16" + + azs = ["${var.region}a", "${var.region}b", "${var.region}c"] + private_subnets = var.private_subnets + public_subnets = var.public_subnets + + enable_nat_gateway = true + enable_vpn_gateway = true + + tags = { + Terraform = "true" + } +} + +locals { + vpc = ( + local.create_vpc ? + { + id = module.vpc.vpc_id + private_subnets = module.vpc.private_subnets + public_subnets = module.vpc.public_subnets + } : + { + id = var.vpc_id + private_subnets = var.private_subnets + public_subnets = var.public_subnets + } + ) +} + +module "eks" { + source = "terraform-aws-modules/eks/aws" + + + cluster_version = var.cluster_version + cluster_name = var.core_id + vpc_id = local.vpc.id + subnets = [local.vpc.private_subnets[0], local.vpc.public_subnets[1]] + fargate_subnets = [local.vpc.private_subnets[0]] + kubeconfig_output_path = var.kubeconfig_output_path + write_kubeconfig = true + + node_groups = { + default = { + desired_capacity = var.node_group_size + + instance_types = [var.instance_type] + update_config = { + max_unavailable_percentage = 50 + } + } + } + + fargate_profiles = { + + + default = { + name = "default" + selectors = [ + { + namespace = "kube-system" + labels = { + k8s-app = "kube-dns" + } + }, + { + namespace = var.namespace + labels = { + WorkerType = "fargate" + } + } + ] + } + } + manage_aws_auth = false + +} + +resource "aws_eks_fargate_profile" "example" { + + + cluster_name = module.eks.cluster_name + fargate_profile_name = "example" + pod_execution_role_arn = module.eks.cluster_iam_role_arn + subnet_ids = module.eks.subnet_ids + + dynamic "selector" { + for_each = var.fargate_profiles + content { + namespace = selector.value + labels = { + WorkerType = "fargate" + } + } + } +} diff --git a/infrastructure/terraform/modules/aws_eks/outputs.tf b/infrastructure/terraform/modules/aws_eks/outputs.tf new file mode 100644 index 0000000000..6c3e36bdb3 --- /dev/null +++ b/infrastructure/terraform/modules/aws_eks/outputs.tf @@ -0,0 +1,19 @@ +output "cluster_endpoint" { + value = module.eks.cluster_endpoint +} + +output "cluster_certificate_authority_data" { + value = module.eks.cluster_certificate_authority_data +} + +output "cluster_name" { + value = module.eks.cluster_id +} + +output "cluster_iam_role_arn" { + value = module.eks.fargate_iam_role_arn +} + +output "subnet_ids" { + value = module.vpc.private_subnets +} diff --git a/infrastructure/terraform/modules/aws_eks/variables.tf b/infrastructure/terraform/modules/aws_eks/variables.tf new file mode 100644 index 0000000000..67356a9160 --- /dev/null +++ b/infrastructure/terraform/modules/aws_eks/variables.tf @@ -0,0 +1,75 @@ +variable "region" { + description = "the AWS region in which resources are created, you must set the availability_zones variable as well if you define this value to something other than the default" + default = "eu-west-1" +} + +variable "aws_access_key" { + description = "AWS Access Key" +} + +variable "aws_secret_key" { + description = "AWS Secret Key" +} + +variable "ssh_key" { + description = "The name of the ssh key to use, e.g. \"airytf\"" + default = "~/.ssh/id_rsa" +} + +variable "profile" { + description = "AWS profile that is used for authentication" + default = "airy-prod" +} + +variable "vpc_id" { + type = string + default = null +} + +variable "vpc_name" { + default = "core_vpc" +} + +variable "private_subnets" { + description = "Subnet ids for the EKS cluster to be created in" + type = list(string) + default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] +} + +variable "public_subnets" { + default = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] + +} + +variable "instance_type" { + default = "t3.large" +} + +variable "node_group_size" { + default = 1 +} + +variable "cluster_version" { + default = "1.21" +} + +variable "core_id" { + default = "my-core" +} + +variable "namespace" { + default = "default" +} + +variable "kubeconfig_output_path" { + default = "../main/.kubeconfig" +} + +variable "fargate_namespaces" { + type = list(string) + default = [ "default" ] +} + +variable "fargate_profiles" { + +} \ No newline at end of file diff --git a/infrastructure/terraform/modules/core/main.tf b/infrastructure/terraform/modules/core/main.tf new file mode 100644 index 0000000000..8b05785109 --- /dev/null +++ b/infrastructure/terraform/modules/core/main.tf @@ -0,0 +1,47 @@ +provider "helm" { + kubernetes { + config_path = var.kubeconfig_output_path + } +} + +provider "kubernetes" { + config_path = var.kubeconfig_output_path +} + +resource "kubernetes_namespace" "core" { + metadata { + name = var.core_id + } +} + +data "http" "core_version" { + url = "https://airy-core-binaries.s3.amazonaws.com/stable.txt" + + request_headers = { + Accept = "application/json" + } +} + +resource "helm_release" "airy_core" { + name = "airy-release" + chart = "https://airy-core-helm-charts.s3.amazonaws.com/testing/airy-${trimspace(data.http.core_version.body)}.tgz" + + timeout = "600" + values = [ + var.values_yaml + ] + + + namespace = var.namespaced ? var.core_id : "default" + + set { + name = "global.appImageTag" + value = trimspace(data.http.core_version.body) + } + + depends_on = [ + kubernetes_namespace.core + ] + +} + diff --git a/infrastructure/terraform/modules/core/outputs.tf b/infrastructure/terraform/modules/core/outputs.tf new file mode 100644 index 0000000000..8c6077e8c2 --- /dev/null +++ b/infrastructure/terraform/modules/core/outputs.tf @@ -0,0 +1,3 @@ +output "core_id" { + value = var.core_id +} diff --git a/infrastructure/terraform/modules/core/variables.tf b/infrastructure/terraform/modules/core/variables.tf new file mode 100644 index 0000000000..d28bc29764 --- /dev/null +++ b/infrastructure/terraform/modules/core/variables.tf @@ -0,0 +1,19 @@ +variable "kubeconfig_output_path" { + default = "./.kubeconfig" +} + +variable "kubernetes_namespace" { + default = "default" +} + +variable "core_id" { + default = "airy-core" +} + +variable "namespaced" { + default = false +} + +variable "values_yaml" { + +} \ No newline at end of file diff --git a/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java b/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java index 5c4cd1aee7..7e815feb3a 100644 --- a/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java +++ b/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java @@ -27,6 +27,8 @@ public static void main(String[] args) { "\n" + " \"helm.sh/hook-weight\": \"2\"" + "\n" + + " namespace: {{ .Release.Namespace }}" + + "\n" + "data:" + "\n" + " create-topics.sh: |" + diff --git a/lib/go/httpclient/payloads/client_config_response_payload.go b/lib/go/httpclient/payloads/client_config_response_payload.go index 23ab1d77a6..a6664e1dcb 100644 --- a/lib/go/httpclient/payloads/client_config_response_payload.go +++ b/lib/go/httpclient/payloads/client_config_response_payload.go @@ -1,6 +1,12 @@ package payloads +type Service struct { + Enabled bool `json:"enabled"` + Healthy bool `json:"healthy"` + Component string `json:"component"` +} + type ClientConfigResponsePayload struct { - Components map[string]map[string]interface{} `json:"components"` - Features map[string]string `json:"features"` + Services map[string]Service `json:"services"` + UserProfile map[string]string `json:"user_profile"` } diff --git a/lib/typescript/assets/scss/colors.scss b/lib/typescript/assets/scss/colors.scss index b4b644c1e4..c4c9895bcf 100644 --- a/lib/typescript/assets/scss/colors.scss +++ b/lib/typescript/assets/scss/colors.scss @@ -26,4 +26,8 @@ --color-soft-green: #0da36b; --color-tag-green: #0e764f; --color-tag-purple: #730a80; + --color-airy-message-outbound: #1578d4; + --color-airy-message-inbound: #f1faff; + --color-airy-message-text-outbound: #ffffff; + --color-airy-message-text-inbound: #000000; } diff --git a/lib/typescript/components/BUILD b/lib/typescript/components/BUILD index d7053071f5..655011eabf 100644 --- a/lib/typescript/components/BUILD +++ b/lib/typescript/components/BUILD @@ -9,11 +9,8 @@ ts_web_library( deps = [ "//lib/typescript/model", "//lib/typescript/types", - "@npm//@crello/react-lottie", "@npm//@types/node", "@npm//@types/react", - "@npm//@types/resize-observer-browser", - "@npm//emoji-mart", "@npm//react", "@npm//react-autosize-textarea", "@npm//react-modal", diff --git a/lib/typescript/components/alerts/ErrorPopUp/style.module.scss b/lib/typescript/components/alerts/ErrorPopUp/style.module.scss index acabe9536f..0b771b1259 100644 --- a/lib/typescript/components/alerts/ErrorPopUp/style.module.scss +++ b/lib/typescript/components/alerts/ErrorPopUp/style.module.scss @@ -42,6 +42,7 @@ line-height: 1.5; padding: 0 6px; @include font-s; + white-space: pre-line; } } diff --git a/lib/typescript/components/alerts/SettingsModal/index.tsx b/lib/typescript/components/alerts/SettingsModal/index.tsx index 8bf085d537..837aa46359 100644 --- a/lib/typescript/components/alerts/SettingsModal/index.tsx +++ b/lib/typescript/components/alerts/SettingsModal/index.tsx @@ -13,7 +13,8 @@ export const SettingsModal = ({close, title, children, style}) => { contentLabel={title} isOpen={true} shouldCloseOnOverlayClick={true} - onRequestClose={close}> + onRequestClose={close} + >
diff --git a/lib/typescript/components/cta/Button/index.tsx b/lib/typescript/components/cta/Button/index.tsx index b9809a9f93..5740394ec1 100644 --- a/lib/typescript/components/cta/Button/index.tsx +++ b/lib/typescript/components/cta/Button/index.tsx @@ -40,7 +40,8 @@ export const Button = ({children, onClick, type, styleVariant, disabled, tabInde className={styleFor(styleVariant)} onClick={onClick} tabIndex={tabIndex} - data-cy={dataCy}> + data-cy={dataCy} + > {children} ); diff --git a/lib/typescript/components/cta/InfoButton/index.tsx b/lib/typescript/components/cta/InfoButton/index.tsx index 70d563743d..104a59067a 100644 --- a/lib/typescript/components/cta/InfoButton/index.tsx +++ b/lib/typescript/components/cta/InfoButton/index.tsx @@ -17,7 +17,8 @@ export const InfoButton = ({text, link, color, dataCy}: Props) => ( href={link} target="_blank" rel="noopener noreferrer" - className={`${styles.link} ${color === 'blue' ? styles.blueLink : styles.greyLink}`}> + className={`${styles.link} ${color === 'blue' ? styles.blueLink : styles.greyLink}`} + > {text} diff --git a/lib/typescript/components/inputs/Input/index.tsx b/lib/typescript/components/inputs/Input/index.tsx index 89314f1cdc..f2297fb186 100644 --- a/lib/typescript/components/inputs/Input/index.tsx +++ b/lib/typescript/components/inputs/Input/index.tsx @@ -1,5 +1,4 @@ import React, {Component, Fragment} from 'react'; -import {Picker} from 'emoji-mart'; import styles from './style.module.scss'; import {ReactComponent as CheckmarkIcon} from 'assets/images/icons/checkmark.svg'; @@ -238,18 +237,15 @@ class InputComponent extends Component { }; emojiDrawer = () => { + const Picker = () => this.props.renderEmojiPicker(this.addEmoji); return (
{ this.node = node; }} - className={styles.emojiDrawer}> - + className={styles.emojiDrawer} + > +
); }; @@ -362,14 +358,15 @@ class InputComponent extends Component { inputMode={inputmode} data-cy={dataCy} /> - {this.props.emoji ? ( + {this.props.renderEmojiPicker ? (
{this.state.isShowingEmojiDrawer && this.emojiDrawer()}
@@ -385,6 +382,9 @@ class InputComponent extends Component { } export interface InputProps { + /** Pass an emoji picker component to render have it rendered and work with the input */ + renderEmojiPicker?: (onSelect: (emoji: string) => void) => JSX.Element; + id?: string; /** The label above the input field */ label?: string; @@ -446,9 +446,6 @@ export interface InputProps { // If you want to enable browser suggestions on the input autoComplete?: string; - // set this to true if you want to have an emoji button - emoji?: boolean; - // set this to true if you want to display the length counter showCounter?: boolean; diff --git a/lib/typescript/components/loaders/AiryLoader/data.ts b/lib/typescript/components/loaders/AiryLoader/data.ts deleted file mode 100644 index 0688a1d63b..0000000000 --- a/lib/typescript/components/loaders/AiryLoader/data.ts +++ /dev/null @@ -1,1287 +0,0 @@ -export const AiryAnimationLoaderData = { - v: '5.5.2', - fr: 25, - ip: 0, - op: 150, - w: 800, - h: 600, - nm: 'main', - ddd: 0, - assets: [ - { - id: 'comp_0', - layers: [ - { - ddd: 0, - ind: 2, - ty: 0, - nm: 'A', - refId: 'comp_1', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: {a: 0, k: 0, ix: 10}, - p: {a: 0, k: [400, 300, 0], ix: 2}, - a: {a: 0, k: [400, 300, 0], ix: 1}, - s: {a: 0, k: [100, 100, 100], ix: 6}, - }, - ao: 0, - w: 800, - h: 600, - ip: 0, - op: 153, - st: 0, - bm: 0, - }, - { - ddd: 0, - ind: 3, - ty: 4, - nm: 'Background – logo 4', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: {a: 0, k: 0, ix: 10}, - p: {a: 0, k: [400.048, 297.666, 0], ix: 2}, - a: {a: 0, k: [156.707, 157.891, 0], ix: 1}, - s: {a: 0, k: [100, 100, 100], ix: 6}, - }, - ao: 0, - shapes: [ - { - ty: 'gr', - it: [ - { - ind: 0, - ty: 'sh', - ix: 1, - ks: { - a: 0, - k: { - i: [ - [89.013, -5.356], - [6.654, -75.723], - [-9.549, -22.526], - [0.638, -2.729], - [0, 0], - [-0.32, 0.014], - [0, 0], - [-2.067, -1.479], - [-34.314, 0.411], - [1.404, 85.166], - ], - o: [ - [-75.877, 4.565], - [-2.328, 26.501], - [1.094, 2.58], - [0, 0], - [-0.073, 0.311], - [0, 0], - [2.538, -0.114], - [25.853, 18.504], - [85.17, -1.02], - [-1.444, -87.511], - ], - v: [ - [-9.365, -154.619], - [-154.081, -13.896], - [-142.446, 60.358], - [-141.689, 68.508], - [-155.108, 128.497], - [-154.616, 129.089], - [-96.912, 123.898], - [-89.829, 126.045], - [2.113, 154.895], - [155.101, -2.606], - ], - c: true, - }, - ix: 2, - }, - nm: 'Path 1', - mn: 'ADBE Vector Shape - Group', - hd: false, - }, - { - ty: 'mm', - mm: 4, - nm: 'Merge Paths 1', - mn: 'ADBE Vector Filter - Merge', - hd: false, - }, - { - ty: 'fl', - c: { - a: 0, - k: [0.294000004787, 0.702000038297, 0.991999966491, 1], - ix: 4, - }, - o: { - a: 1, - k: [ - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 72, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 79, - s: [100], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 94, - s: [100], - }, - {t: 101, s: [0]}, - ], - ix: 5, - }, - r: 1, - bm: 0, - nm: 'Fill 1', - mn: 'ADBE Vector Graphic - Fill', - hd: false, - }, - { - ty: 'tr', - p: {a: 0, k: [156.659, 160.225], ix: 2}, - a: {a: 0, k: [0, 0], ix: 1}, - s: {a: 0, k: [100, 100], ix: 3}, - r: {a: 0, k: 0, ix: 6}, - o: {a: 0, k: 100, ix: 7}, - sk: {a: 0, k: 0, ix: 4}, - sa: {a: 0, k: 0, ix: 5}, - nm: 'Transform', - }, - ], - nm: 'Group 1', - np: 3, - cix: 2, - bm: 0, - ix: 1, - mn: 'ADBE Vector Group', - hd: false, - }, - { - ty: 'tm', - s: { - a: 1, - k: [ - { - i: {x: [0], y: [1]}, - o: {x: [0.333], y: [0]}, - t: 54, - s: [0], - }, - { - i: {x: [0], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 74, - s: [100], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 109, - s: [100], - }, - {t: 121, s: [0]}, - ], - ix: 1, - }, - e: {a: 0, k: 0, ix: 2}, - o: {a: 0, k: 0, ix: 3}, - m: 1, - ix: 2, - nm: 'Trim Paths 1', - mn: 'ADBE Vector Filter - Trim', - hd: false, - }, - { - ty: 'st', - c: { - a: 0, - k: [0.29411765933, 0.701960802078, 0.992156922817, 1], - ix: 3, - }, - o: {a: 0, k: 100, ix: 4}, - w: { - a: 1, - k: [ - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 49, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 66, - s: [2], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 76, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 94, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 104, - s: [2], - }, - {t: 121, s: [0]}, - ], - ix: 5, - }, - lc: 1, - lj: 1, - ml: 4, - bm: 0, - nm: 'Stroke 1', - mn: 'ADBE Vector Graphic - Stroke', - hd: false, - }, - ], - ip: 44, - op: 809, - st: 44, - bm: 0, - }, - ], - }, - { - id: 'comp_1', - layers: [ - { - ddd: 0, - ind: 1, - ty: 4, - nm: 'part 3', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: { - a: 1, - k: [ - { - i: {x: [0.667], y: [1]}, - o: {x: [0.167], y: [0.167]}, - t: 0, - s: [-33], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [0.167], y: [0.167]}, - t: 13, - s: [15], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 31, - s: [25], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [0.167], y: [0.167]}, - t: 39, - s: [25], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 49, - s: [0], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 110, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.333], y: [0]}, - t: 114.833, - s: [0], - }, - { - i: {x: [0.833], y: [1]}, - o: {x: [0.333], y: [0]}, - t: 123.167, - s: [25], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.333], y: [0]}, - t: 129.833, - s: [25], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.333], y: [0]}, - t: 140.667, - s: [15], - }, - {t: 151.5, s: [-33]}, - ], - ix: 10, - }, - p: { - a: 1, - k: [ - { - i: {x: 0, y: 1}, - o: {x: 0.167, y: 0.167}, - t: 37, - s: [400, 300, 0], - to: [-6.271, -5, 0], - ti: [6.271, 5, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 0.167, y: 0.167}, - t: 49, - s: [362.375, 270, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 0}, - o: {x: 0.167, y: 0.167}, - t: 110, - s: [362.375, 270, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 1, y: 0}, - t: 114, - s: [362.375, 270, 0], - to: [6.271, 5, 0], - ti: [-6.271, -5, 0], - }, - {t: 124, s: [400, 300, 0]}, - ], - ix: 2, - }, - a: {a: 0, k: [31.146, 43.689, 0], ix: 1}, - s: { - a: 1, - k: [ - { - i: {x: [0, 0, 0.667], y: [1, 1, 1]}, - o: {x: [0.333, 0.333, 0.333], y: [0, 0, 0]}, - t: 0, - s: [0, 0, 100], - }, - { - i: {x: [0.833, 0.833, 0.833], y: [0.833, 0.833, 0.833]}, - o: {x: [0.167, 0.167, 0.167], y: [0.167, 0.167, 0.167]}, - t: 16, - s: [100, 100, 100], - }, - { - i: {x: [0, 0, 0.667], y: [1, 1, 1]}, - o: {x: [0.167, 0.167, 0.167], y: [0, 0, 0]}, - t: 110, - s: [100, 100, 100], - }, - { - i: {x: [0.667, 0.667, 0.667], y: [1, 1, 1]}, - o: {x: [1, 1, 0.333], y: [0, 0, 0]}, - t: 137.333, - s: [100, 100, 100], - }, - {t: 150.6669921875, s: [0, 0, 100]}, - ], - ix: 6, - }, - }, - ao: 0, - shapes: [ - { - ty: 'gr', - it: [ - { - ind: 0, - ty: 'sh', - ix: 1, - ks: { - a: 0, - k: { - i: [ - [0, 0], - [0, 0], - [0, 0], - ], - o: [ - [0, 0], - [0, 0], - [0, 0], - ], - v: [ - [30.896, 18.648], - [-30.896, 43.439], - [5.988, -43.439], - ], - c: true, - }, - ix: 2, - }, - nm: 'Path 1', - mn: 'ADBE Vector Shape - Group', - hd: false, - }, - { - ty: 'fl', - c: {a: 0, k: [1, 1, 1, 1], ix: 4}, - o: { - a: 1, - k: [ - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 8, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 16, - s: [100], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 110, - s: [100], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 144, - s: [100], - }, - {t: 150.6669921875, s: [0]}, - ], - ix: 5, - }, - r: 1, - bm: 0, - nm: 'Fill 1', - mn: 'ADBE Vector Graphic - Fill', - hd: false, - }, - { - ty: 'tr', - p: {a: 0, k: [31.146, 43.689], ix: 2}, - a: {a: 0, k: [0, 0], ix: 1}, - s: {a: 0, k: [100, 100], ix: 3}, - r: {a: 0, k: 0, ix: 6}, - o: {a: 0, k: 100, ix: 7}, - sk: {a: 0, k: 0, ix: 4}, - sa: {a: 0, k: 0, ix: 5}, - nm: 'Transform', - }, - ], - nm: 'Group 1', - np: 2, - cix: 2, - bm: 0, - ix: 1, - mn: 'ADBE Vector Group', - hd: false, - }, - { - ty: 'tm', - s: { - a: 1, - k: [ - { - i: {x: [0], y: [1]}, - o: {x: [0.333], y: [0]}, - t: 0, - s: [100], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 20, - s: [0], - }, - { - i: {x: [0], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 110, - s: [0], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [1], y: [0]}, - t: 137.333, - s: [0], - }, - {t: 154, s: [100]}, - ], - ix: 1, - }, - e: {a: 0, k: 100, ix: 2}, - o: {a: 0, k: 0, ix: 3}, - m: 1, - ix: 2, - nm: 'Trim Paths 1', - mn: 'ADBE Vector Filter - Trim', - hd: false, - }, - { - ty: 'st', - c: { - a: 0, - k: [0.258823543787, 0.666666686535, 0.992156863213, 1], - ix: 3, - }, - o: {a: 0, k: 100, ix: 4}, - w: {a: 0, k: 4, ix: 5}, - lc: 1, - lj: 1, - ml: 4, - bm: 0, - nm: 'Stroke 1', - mn: 'ADBE Vector Graphic - Stroke', - hd: false, - }, - ], - ip: 0, - op: 765, - st: 0, - bm: 0, - }, - { - ddd: 0, - ind: 2, - ty: 4, - nm: 'part 4', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: { - a: 1, - k: [ - { - i: {x: [0], y: [1]}, - o: {x: [0.333], y: [0]}, - t: 23, - s: [-40], - }, - { - i: {x: [0.004], y: [1]}, - o: {x: [0.167], y: [0.167]}, - t: 39, - s: [-13], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 53, - s: [0], - }, - { - i: {x: [0.004], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 110, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.996], y: [0]}, - t: 117.333, - s: [0], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [1], y: [0]}, - t: 129, - s: [-13], - }, - {t: 142.3330078125, s: [-40]}, - ], - ix: 10, - }, - p: { - a: 1, - k: [ - { - i: {x: 0, y: 1}, - o: {x: 0.296, y: 0}, - t: 23, - s: [398.603, 302.839, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 1}, - o: {x: 0.428, y: 0.267}, - t: 34, - s: [307.546, 342.236, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 0.167, y: 0.167}, - t: 53, - s: [435.046, 291.736, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 0}, - o: {x: 0.167, y: 0.167}, - t: 110, - s: [435.046, 291.736, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.572, y: 0.733}, - o: {x: 1, y: 0}, - t: 117.333, - s: [435.046, 291.736, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.704, y: 1}, - o: {x: 1, y: 0}, - t: 133.167, - s: [307.546, 342.236, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - {t: 142.3330078125, s: [398.603, 302.839, 0]}, - ], - ix: 2, - }, - a: {a: 0, k: [61.591, 98.404, 0], ix: 1}, - s: { - a: 1, - k: [ - { - i: {x: [0, 0, 0.667], y: [1.063, 1.063, 1]}, - o: {x: [0.333, 0.333, 0.333], y: [0, 0, 0]}, - t: 20, - s: [0, 0, 100], - }, - { - i: {x: [0.833, 0.833, 0.833], y: [0.833, 0.833, 0.833]}, - o: {x: [0.167, 0.167, 0.167], y: [0.167, 0.167, 0.167]}, - t: 39, - s: [100, 100, 100], - }, - { - i: {x: [0, 0, 0.667], y: [3.067, 3.067, 1]}, - o: {x: [0.167, 0.167, 0.167], y: [0, 0, 0]}, - t: 123, - s: [100, 100, 100], - }, - { - i: {x: [0.667, 0.667, 0.667], y: [1, 1, 1]}, - o: {x: [1, 1, 0.333], y: [-0.063, -0.063, 0]}, - t: 128.167, - s: [100, 100, 100], - }, - {t: 144, s: [0, 0, 100]}, - ], - ix: 6, - }, - }, - ao: 0, - shapes: [ - { - ty: 'gr', - it: [ - { - ind: 0, - ty: 'sh', - ix: 1, - ks: { - a: 0, - k: { - i: [ - [0, 0], - [0, 0], - [0, 0], - [0, 0], - ], - o: [ - [0, 0], - [0, 0], - [0, 0], - [0, 0], - ], - v: [ - [61.342, 76.983], - [8.924, 98.153], - [-61.342, -76.985], - [-8.925, -98.153], - ], - c: true, - }, - ix: 2, - }, - nm: 'Path 1', - mn: 'ADBE Vector Shape - Group', - hd: false, - }, - { - ty: 'fl', - c: {a: 0, k: [1, 1, 1, 1], ix: 4}, - o: {a: 0, k: 100, ix: 5}, - r: 1, - bm: 0, - nm: 'Fill 1', - mn: 'ADBE Vector Graphic - Fill', - hd: false, - }, - { - ty: 'tr', - p: {a: 0, k: [61.591, 98.404], ix: 2}, - a: {a: 0, k: [0, 0], ix: 1}, - s: {a: 0, k: [100, 100], ix: 3}, - r: {a: 0, k: 0, ix: 6}, - o: {a: 0, k: 100, ix: 7}, - sk: {a: 0, k: 0, ix: 4}, - sa: {a: 0, k: 0, ix: 5}, - nm: 'Transform', - }, - ], - nm: 'Group 1', - np: 2, - cix: 2, - bm: 0, - ix: 1, - mn: 'ADBE Vector Group', - hd: false, - }, - { - ty: 'st', - c: { - a: 0, - k: [0.258823529412, 0.666666666667, 0.992156922583, 1], - ix: 3, - }, - o: {a: 0, k: 100, ix: 4}, - w: {a: 0, k: 4, ix: 5}, - lc: 1, - lj: 1, - ml: 4, - bm: 0, - nm: 'Stroke 1', - mn: 'ADBE Vector Graphic - Stroke', - hd: false, - }, - ], - ip: 20, - op: 785, - st: 20, - bm: 0, - }, - { - ddd: 0, - ind: 3, - ty: 4, - nm: 'Part 2', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: { - a: 1, - k: [ - { - i: {x: [0], y: [1]}, - o: {x: [0.333], y: [0]}, - t: 24, - s: [-65], - }, - { - i: {x: [0], y: [1]}, - o: {x: [0.167], y: [0.167]}, - t: 39, - s: [35], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 50, - s: [0], - }, - { - i: {x: [0], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 110, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [1], y: [0]}, - t: 119, - s: [0], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [1], y: [0]}, - t: 128.167, - s: [35], - }, - {t: 140.6669921875, s: [-65]}, - ], - ix: 10, - }, - p: { - a: 1, - k: [ - { - i: {x: 0, y: 1}, - o: {x: 0.333, y: 0}, - t: 24, - s: [399.08, 301.932, 0], - to: [-11.447, -17.333, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 1}, - o: {x: 0.167, y: 0.167}, - t: 40, - s: [330.401, 197.932, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 0.167, y: 0.167}, - t: 50, - s: [383.984, 345.641, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 0}, - o: {x: 0.167, y: 0.167}, - t: 110, - s: [383.984, 345.641, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 1, y: 0}, - t: 119, - s: [383.984, 345.641, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.667, y: 1}, - o: {x: 1, y: 0}, - t: 127.333, - s: [330.401, 197.932, 0], - to: [0, 0, 0], - ti: [-11.447, -17.333, 0], - }, - {t: 140.6669921875, s: [399.08, 301.932, 0]}, - ], - ix: 2, - }, - a: {a: 0, k: [50.694, 47.891, 0], ix: 1}, - s: { - a: 1, - k: [ - { - i: {x: [0, 0, 0.667], y: [1, 1, 1]}, - o: {x: [0.333, 0.333, 0.333], y: [0, 0, 0]}, - t: 19, - s: [0, 0, 100], - }, - { - i: {x: [0.833, 0.833, 0.833], y: [0.833, 0.833, 0.833]}, - o: {x: [0.167, 0.167, 0.167], y: [0.167, 0.167, 0.167]}, - t: 39, - s: [100, 100, 100], - }, - { - i: {x: [0, 0, 0.667], y: [1, 1, 1]}, - o: {x: [0.167, 0.167, 0.167], y: [0, 0, 0]}, - t: 110, - s: [100, 100, 100], - }, - { - i: {x: [0.667, 0.667, 0.667], y: [1, 1, 1]}, - o: {x: [1, 1, 0.333], y: [0, 0, 0]}, - t: 127.333, - s: [100, 100, 100], - }, - {t: 144, s: [0, 0, 100]}, - ], - ix: 6, - }, - }, - ao: 0, - shapes: [ - { - ty: 'gr', - it: [ - { - ind: 0, - ty: 'sh', - ix: 1, - ks: { - a: 0, - k: { - i: [ - [0, 0], - [0, 0], - [0, 0], - ], - o: [ - [0, 0], - [0, 0], - [0, 0], - ], - v: [ - [50.444, 47.641], - [-50.444, -22.526], - [12.218, -47.641], - ], - c: true, - }, - ix: 2, - }, - nm: 'Path 1', - mn: 'ADBE Vector Shape - Group', - hd: false, - }, - { - ty: 'fl', - c: {a: 0, k: [1, 1, 1, 1], ix: 4}, - o: {a: 0, k: 100, ix: 5}, - r: 1, - bm: 0, - nm: 'Fill 1', - mn: 'ADBE Vector Graphic - Fill', - hd: false, - }, - { - ty: 'tr', - p: {a: 0, k: [50.694, 47.891], ix: 2}, - a: {a: 0, k: [0, 0], ix: 1}, - s: {a: 0, k: [100, 100], ix: 3}, - r: {a: 0, k: 0, ix: 6}, - o: {a: 0, k: 100, ix: 7}, - sk: {a: 0, k: 0, ix: 4}, - sa: {a: 0, k: 0, ix: 5}, - nm: 'Transform', - }, - ], - nm: 'Group 1', - np: 2, - cix: 2, - bm: 0, - ix: 1, - mn: 'ADBE Vector Group', - hd: false, - }, - { - ty: 'st', - c: { - a: 0, - k: [0.258823529412, 0.666666666667, 0.992156922583, 1], - ix: 3, - }, - o: {a: 0, k: 100, ix: 4}, - w: {a: 0, k: 4, ix: 5}, - lc: 1, - lj: 1, - ml: 4, - bm: 0, - nm: 'Stroke 1', - mn: 'ADBE Vector Graphic - Stroke', - hd: false, - }, - ], - ip: 20, - op: 785, - st: 20, - bm: 0, - }, - { - ddd: 0, - ind: 4, - ty: 4, - nm: 'part 1', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: { - a: 1, - k: [ - { - i: {x: [0], y: [1]}, - o: {x: [0.333], y: [0]}, - t: 18, - s: [-48], - }, - { - i: {x: [0], y: [1]}, - o: {x: [0.167], y: [0.167]}, - t: 39, - s: [26], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [0.167], y: [0.167]}, - t: 53, - s: [0], - }, - { - i: {x: [0], y: [1]}, - o: {x: [0.167], y: [0]}, - t: 110, - s: [0], - }, - { - i: {x: [0.833], y: [0.833]}, - o: {x: [1], y: [0]}, - t: 114.833, - s: [0], - }, - { - i: {x: [0.667], y: [1]}, - o: {x: [1], y: [0]}, - t: 126.5, - s: [26], - }, - {t: 144, s: [-48]}, - ], - ix: 10, - }, - p: { - a: 1, - k: [ - { - i: {x: 0, y: 1}, - o: {x: 0.333, y: 0}, - t: 20, - s: [398.596, 301.788, 0], - to: [11.833, -5.798, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 1}, - o: {x: 0.167, y: 0.167}, - t: 36, - s: [469.596, 267, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 0.167, y: 0.167}, - t: 53, - s: [334.221, 354.625, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0, y: 0}, - o: {x: 0.167, y: 0.167}, - t: 110, - s: [334.221, 354.625, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.833, y: 0.833}, - o: {x: 1, y: 0}, - t: 116.5, - s: [334.221, 354.625, 0], - to: [0, 0, 0], - ti: [0, 0, 0], - }, - { - i: {x: 0.667, y: 1}, - o: {x: 1, y: 0}, - t: 130.667, - s: [469.596, 267, 0], - to: [0, 0, 0], - ti: [11.833, -5.798, 0], - }, - {t: 144, s: [398.596, 301.788, 0]}, - ], - ix: 2, - }, - a: {a: 0, k: [31.548, 25.807, 0], ix: 1}, - s: { - a: 1, - k: [ - { - i: {x: [0, 0, 0.667], y: [1, 1, 1]}, - o: {x: [0.333, 0.333, 0.333], y: [0, 0, 0]}, - t: 16, - s: [0, 0, 100], - }, - { - i: {x: [0.833, 0.833, 0.833], y: [0.833, 0.833, 0.833]}, - o: {x: [0.167, 0.167, 0.167], y: [0.167, 0.167, 0.167]}, - t: 39, - s: [100, 100, 100], - }, - { - i: {x: [0, 0, 0.667], y: [1, 1, 1]}, - o: {x: [0.167, 0.167, 0.167], y: [0, 0, 0]}, - t: 110, - s: [100, 100, 100], - }, - { - i: {x: [0.667, 0.667, 0.667], y: [1, 1, 1]}, - o: {x: [1, 1, 0.333], y: [0, 0, 0]}, - t: 126.5, - s: [100, 100, 100], - }, - {t: 145.6669921875, s: [0, 0, 100]}, - ], - ix: 6, - }, - }, - ao: 0, - shapes: [ - { - ty: 'gr', - it: [ - { - ind: 0, - ty: 'sh', - ix: 1, - ks: { - a: 0, - k: { - i: [ - [0, 0], - [0, 0], - [0, 0], - ], - o: [ - [0, 0], - [0, 0], - [0, 0], - ], - v: [ - [31.298, 1.327], - [-31.298, 25.557], - [-8.792, -25.557], - ], - c: true, - }, - ix: 2, - }, - nm: 'Path 1', - mn: 'ADBE Vector Shape - Group', - hd: false, - }, - { - ty: 'fl', - c: {a: 0, k: [1, 1, 1, 1], ix: 4}, - o: {a: 0, k: 100, ix: 5}, - r: 1, - bm: 0, - nm: 'Fill 1', - mn: 'ADBE Vector Graphic - Fill', - hd: false, - }, - { - ty: 'tr', - p: {a: 0, k: [31.548, 25.807], ix: 2}, - a: {a: 0, k: [0, 0], ix: 1}, - s: {a: 0, k: [100, 100], ix: 3}, - r: {a: 0, k: 0, ix: 6}, - o: {a: 0, k: 100, ix: 7}, - sk: {a: 0, k: 0, ix: 4}, - sa: {a: 0, k: 0, ix: 5}, - nm: 'Transform', - }, - ], - nm: 'Group 1', - np: 2, - cix: 2, - bm: 0, - ix: 1, - mn: 'ADBE Vector Group', - hd: false, - }, - { - ty: 'st', - c: { - a: 0, - k: [0.258823529412, 0.666666666667, 0.992156922583, 1], - ix: 3, - }, - o: {a: 0, k: 100, ix: 4}, - w: {a: 0, k: 4, ix: 5}, - lc: 1, - lj: 1, - ml: 4, - bm: 0, - nm: 'Stroke 1', - mn: 'ADBE Vector Graphic - Stroke', - hd: false, - }, - ], - ip: 17, - op: 782, - st: 17, - bm: 0, - }, - ], - }, - ], - layers: [ - { - ddd: 0, - ind: 1, - ty: 0, - nm: 'logo-loading', - refId: 'comp_0', - sr: 1, - ks: { - o: {a: 0, k: 100, ix: 11}, - r: {a: 0, k: 0, ix: 10}, - p: {a: 0, k: [400, 300, 0], ix: 2}, - a: {a: 0, k: [400, 300, 0], ix: 1}, - s: {a: 0, k: [100, 100, 100], ix: 6}, - }, - ao: 0, - w: 800, - h: 600, - ip: 0, - op: 765, - st: 0, - bm: 0, - }, - ], - markers: [], -}; diff --git a/lib/typescript/components/loaders/AiryLoader/index.tsx b/lib/typescript/components/loaders/AiryLoader/index.tsx deleted file mode 100644 index 64782b4f58..0000000000 --- a/lib/typescript/components/loaders/AiryLoader/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import {Lottie} from '@crello/react-lottie'; -import {AiryAnimationLoaderData} from './data'; -import styles from './style.module.scss'; - -export const AiryLoader = () => ( -
- -
-); diff --git a/lib/typescript/components/loaders/AiryLoader/style.module.scss b/lib/typescript/components/loaders/AiryLoader/style.module.scss deleted file mode 100644 index b472f95f23..0000000000 --- a/lib/typescript/components/loaders/AiryLoader/style.module.scss +++ /dev/null @@ -1,10 +0,0 @@ -.wrapper { - width: 100vw; - height: 100vh; - display: flex; - flex-flow: column; - justify-content: center; - align-items: center; - position: relative; - background-color: white; -} diff --git a/lib/typescript/components/loaders/index.ts b/lib/typescript/components/loaders/index.ts index e9d84c5e69..39d4fb6b4b 100644 --- a/lib/typescript/components/loaders/index.ts +++ b/lib/typescript/components/loaders/index.ts @@ -1,2 +1 @@ export * from './SimpleLoader'; -export * from './AiryLoader'; diff --git a/lib/typescript/components/message/MessageInfoWrapper/index.tsx b/lib/typescript/components/message/MessageInfoWrapper/index.tsx index 37c589d20e..cc86a8d9f2 100644 --- a/lib/typescript/components/message/MessageInfoWrapper/index.tsx +++ b/lib/typescript/components/message/MessageInfoWrapper/index.tsx @@ -35,7 +35,8 @@ export const MessageInfoWrapper = (props: MessageInfoWrapperProps) => { )}
+ style={lastInGroup === false && isChatPlugin === false ? {marginLeft: '48px'} : {}} + > {children}
{decoration} diff --git a/lib/typescript/httpclient/BUILD b/lib/typescript/httpclient/BUILD index f10f97dee8..4c393f4627 100644 --- a/lib/typescript/httpclient/BUILD +++ b/lib/typescript/httpclient/BUILD @@ -16,7 +16,7 @@ ts_web_library( deps = module_deps + [ "@npm//@types/node", "@npm//camelcase-keys", - "@npm//node-fetch", + "@npm//isomorphic-fetch", "@npm//form-data", ], ) @@ -40,7 +40,7 @@ web_library( entry = "lib/typescript/httpclient/src/index.js", externals = { "camelcase-keys": "camelcase-keys", - "node-fetch": "node-fetch", + "isomorphic-fetch": "isomorphic-fetch", "form-data": "form-data", }, module_deps = module_deps, diff --git a/lib/typescript/httpclient/src/client.ts b/lib/typescript/httpclient/src/client.ts index 3498052748..9fa660c6fb 100644 --- a/lib/typescript/httpclient/src/client.ts +++ b/lib/typescript/httpclient/src/client.ts @@ -51,7 +51,7 @@ import { updateContactDef, uploadFileDef, } from './endpoints'; -import fetch from 'node-fetch'; +import 'isomorphic-fetch'; import FormData from 'form-data'; function isString(object: any) { @@ -92,12 +92,12 @@ export class HttpClient { headers['Content-Type'] = 'application/json'; } - const response: Response = await fetch(`${this.apiUrl}/${url}`, { + const response = await fetch(`${this.apiUrl}/${url}`, { method: 'POST', headers: headers, mode: 'cors', credentials: 'include', - body: body as BodyInit, + body: body, }); return this.parseBody(response); diff --git a/lib/typescript/render/SourceMessagePreview.tsx b/lib/typescript/render/SourceMessagePreview.tsx index caa71bc621..84a290a741 100644 --- a/lib/typescript/render/SourceMessagePreview.tsx +++ b/lib/typescript/render/SourceMessagePreview.tsx @@ -5,7 +5,10 @@ import {ReactComponent as AttachmentVideo} from 'assets/images/icons/attachmentV import {ReactComponent as AttachmentAudio} from 'assets/images/icons/file-audio.svg'; import {ReactComponent as AttachmentFile} from 'assets/images/icons/file-download.svg'; import {ReactComponent as RichCardIcon} from 'assets/images/icons/richCardIcon.svg'; +import {decodeURIComponentMessage, getAttachmentType} from './services'; import {Conversation, Message} from 'model'; +import {Emoji} from 'components'; + interface SourceMessagePreviewProps { conversation: Conversation; } @@ -15,7 +18,7 @@ interface FormattedMessageProps { const FormattedMessage = ({message}: FormattedMessageProps) => { if (message?.content) { - return <>{message.content.message?.text || message.content.text}; + return <>{message.content.message?.text || message.content.text || message?.content?.Body}; } return
; }; @@ -35,77 +38,134 @@ export const SourceMessagePreview = (props: SourceMessagePreviewProps) => { const lastMessageIsText = (conversation: Conversation) => { const lastMessageContent = conversation.lastMessage.content; + const googleLiveAgentRequest = lastMessageContent?.userStatus?.requestedLiveAgent; + const googleSurveyResponse = lastMessageContent?.surveyResponse; + + if (googleLiveAgentRequest) { + return ( + <> + Live Agent request + + ); + } + + if (googleSurveyResponse) { + return ( + <> + Survey response + + ); + } if (typeof lastMessageContent === 'string') { + let text; + if (lastMessageContent.includes('&Body=' && '&FromCountry=')) { - const startText = lastMessageContent.search('&Body='); - const endText = lastMessageContent.search('&FromCountry='); - const textLength = endText - startText; - const enCodedText = lastMessageContent.substring(startText + 6, startText + textLength); - const replaced = enCodedText.split('+').join(' '); - const text = decodeURIComponent(replaced); - return text; + const contentStart = '&Body='; + const contentEnd = '&FromCountry='; + text = decodeURIComponentMessage(lastMessageContent, contentStart, contentEnd); } else if (lastMessageContent.includes('&Body=' && '&To=whatsapp')) { - const startText = lastMessageContent.search('&Body='); - const endText = lastMessageContent.search('&To=whatsapp'); - const textLength = endText - startText; - const enCodedText = lastMessageContent.substring(startText + 6, startText + textLength); - const replaced = enCodedText.split('+').join(' '); - const text = decodeURIComponent(replaced); - return text; + const contentStart = '&Body='; + const contentEnd = '&To=whatsapp'; + text = decodeURIComponentMessage(lastMessageContent, contentStart, contentEnd); } + + return text; } if ( - (lastMessageContent.text || lastMessageContent.message?.text) && + (lastMessageContent.text || + lastMessageContent.message?.text || + (lastMessageContent?.Body && typeof lastMessageContent?.Body === 'string')) && !isImageFromGoogleSource(lastMessageContent.message?.text) ) { return ; - } else if (lastMessageContent.suggestionResponse) { + } + + if (lastMessageContent.suggestionResponse) { return <>{conversation.lastMessage.content.suggestionResponse.text}; } }; const lastMessageIsIcon = (conversation: Conversation) => { const lastMessageContent = conversation.lastMessage.content; + const source = conversation.channel.source; + + const twilioWhatsAppOutboundMediaUrl = lastMessageContent?.MediaUrl; + + const twilioWhatsAppInboundImage = + typeof lastMessageContent === 'string' && lastMessageContent.includes('MediaContentType0=image'); + const twilioWhatsAppInboundFile = + typeof lastMessageContent === 'string' && + (lastMessageContent.includes('MediaContentType0=application%2Fpdf') || + lastMessageContent.includes('MediaContentType0=text%2Fvcard')); + const twilioWhatsAppInboundAudio = + typeof lastMessageContent === 'string' && lastMessageContent.includes('MediaContentType0=audio'); + const twilioWhatsAppInboundVideo = + typeof lastMessageContent === 'string' && lastMessageContent.includes('MediaContentType0=video'); + + if (twilioWhatsAppOutboundMediaUrl) { + const attachmentType = getAttachmentType(twilioWhatsAppOutboundMediaUrl, source); + + if (attachmentType === 'image') { + return ; + } + + if (attachmentType === 'video') { + return ; + } + + if (attachmentType === 'audio') { + return ; + } + + if (attachmentType === 'file') { + return ; + } + } if ( lastMessageContent.message?.attachments?.[0].type === 'image' || - isImageFromGoogleSource(lastMessageContent.message?.text) + lastMessageContent?.attachment?.type === 'image' || + isImageFromGoogleSource(lastMessageContent.message?.text) || + twilioWhatsAppInboundImage ) { return ; } if ( lastMessageContent.message?.attachments?.[0].type === 'video' || - lastMessageContent.attachment?.type === 'video' + lastMessageContent?.attachment?.type === 'video' || + twilioWhatsAppInboundVideo ) { return ; } if ( lastMessageContent.message?.attachments?.[0].type === 'audio' || - lastMessageContent.attachment?.type === 'audio' + lastMessageContent?.attachment?.type === 'audio' || + twilioWhatsAppInboundAudio ) { return ; } if ( lastMessageContent.message?.attachments?.[0].type === 'file' || - lastMessageContent.attachment?.type === 'file' + lastMessageContent?.attachment?.type === 'file' || + twilioWhatsAppInboundFile ) { return ; } - if (lastMessageContent.suggestionResponse) { + if (lastMessageContent?.suggestionResponse) { return <>{conversation.lastMessage.content.suggestionResponse.text}; } - if (lastMessageContent.image) { + if (lastMessageContent?.image) { return ; } - if (lastMessageContent.richCard) { + if (lastMessageContent?.richCard) { return ; } diff --git a/lib/typescript/render/attachments.ts b/lib/typescript/render/attachments.ts deleted file mode 100644 index bd69144b2c..0000000000 --- a/lib/typescript/render/attachments.ts +++ /dev/null @@ -1,62 +0,0 @@ -export const imageExtensions = ['jpeg', 'jpg', 'gif', 'png', 'tiff', 'tif']; -export const instagramImageExtensions = ['jpeg', 'jpg', 'png', 'ico', 'bmp', 'gif']; -export const videoExtensions = ['mp4', 'mov', 'wmv']; -export const audioExtensions = ['mp3', 'ogg', 'wav']; -export const fileExtensions = [ - 'pdf', - 'cvc', - 'doc', - 'docx', - 'rtf', - 'tex', - 'txt', - 'wpd', - 'psd', - 'svg', - 'ico', - 'json', - 'md', - 'mdx', - 'tsx', - 'jsx', - 'js', - 'ts', - 'css', - 'scss', - 'html', - 'bmp', -]; - -export const getAttachmentType = (url: string) => { - const urlArr = url.split('.'); - const extension = urlArr[urlArr.length - 1]; - - if (imageExtensions.includes(extension)) { - return 'image'; - } - - if (videoExtensions.includes(extension)) { - return 'video'; - } - - if (audioExtensions.includes(extension)) { - return 'audio'; - } - - if (fileExtensions.includes(extension)) { - return 'file'; - } -}; - -export const isSupportedByInstagramMessenger = (url: string) => { - const urlArr = url.split('.'); - const extension = urlArr[urlArr.length - 1]; - - return instagramImageExtensions.includes(extension) ? true : false; -}; - -export const getFileName = (fileUrl: string) => { - const fileUrlArr = fileUrl.split('/'); - - return fileUrlArr[fileUrlArr.length - 1].split('?')[0]; -}; diff --git a/lib/typescript/render/components/Audio/index.module.scss b/lib/typescript/render/components/Audio/index.module.scss index 0772a7654e..e726c93f2c 100644 --- a/lib/typescript/render/components/Audio/index.module.scss +++ b/lib/typescript/render/components/Audio/index.module.scss @@ -4,7 +4,7 @@ .wrapper { width: 250px; text-align: center; - margin: 5px 0; + margin-top: 5px; } .player { diff --git a/lib/typescript/render/components/File/index.module.scss b/lib/typescript/render/components/File/index.module.scss index 8c230038d3..307da6e5dc 100644 --- a/lib/typescript/render/components/File/index.module.scss +++ b/lib/typescript/render/components/File/index.module.scss @@ -6,7 +6,7 @@ display: flex; align-items: center; padding: 10px; - margin: 5px 0; + margin-top: 5px; background-color: var(--color-background-blue); border: 1px solid var(--color-light-gray); box-shadow: 0 1px 2px var(--color-light-gray); diff --git a/lib/typescript/render/components/File/index.tsx b/lib/typescript/render/components/File/index.tsx index 8f3f8af044..e8f681025c 100644 --- a/lib/typescript/render/components/File/index.tsx +++ b/lib/typescript/render/components/File/index.tsx @@ -1,23 +1,31 @@ import React from 'react'; import styles from './index.module.scss'; -import {getFileName} from '../../attachments'; +import {getFileName} from '../../services'; import {ReactComponent as FileDownloadIcon} from 'assets/images/icons/file-download.svg'; type FileRenderProps = { fileUrl: string; + fileType?: string; }; -export const File = ({fileUrl}: FileRenderProps) => { - const fileName = getFileName(fileUrl); +export const File = ({fileUrl, fileType}: FileRenderProps) => { + const maxFileNameLength = 30; + let fileName = getFileName(fileUrl); + + if (fileName.length >= maxFileNameLength) fileName = fileName.slice(-maxFileNameLength); + + if (fileType) fileName = `${fileName}.${fileType}`; return ( - + <> + + ); }; diff --git a/lib/typescript/render/components/Image/index.module.scss b/lib/typescript/render/components/Image/index.module.scss index eacbe7dd55..362d0c91a3 100644 --- a/lib/typescript/render/components/Image/index.module.scss +++ b/lib/typescript/render/components/Image/index.module.scss @@ -4,6 +4,10 @@ margin-top: 5px; } +.wrapper a { + display: flex; +} + .imagesContainer { display: flex; flex-direction: column; @@ -14,7 +18,9 @@ } .messageListItemImageBlock { - max-height: 200px; + max-height: 300px; + min-height: 50px; + min-width: 50px; max-width: 300px; border-radius: 8px; } diff --git a/lib/typescript/render/components/Image/index.tsx b/lib/typescript/render/components/Image/index.tsx index cb121eec6d..389a3c9dcd 100644 --- a/lib/typescript/render/components/Image/index.tsx +++ b/lib/typescript/render/components/Image/index.tsx @@ -1,28 +1,35 @@ import React from 'react'; import {ImageWithFallback} from '../ImageWithFallback'; import {ImageContent} from '../../providers/facebook/facebookModel'; +import {Text} from '../../components/Text'; import styles from './index.module.scss'; type ImageRenderProps = { imageUrl?: string; images?: ImageContent[]; altText?: string; + text?: string; + fromContact?: boolean; }; -export const Image = ({imageUrl, altText, images}: ImageRenderProps) => ( -
- {images ? ( -
- {images.map(image => ( - - ))} -
- ) : ( - - )} -
+export const Image = ({imageUrl, altText, images, text, fromContact}: ImageRenderProps) => ( + <> +
+ {images ? ( +
+ {images.map(image => ( + + ))} +
+ ) : ( + + )} +
+ + {text && } + ); diff --git a/lib/typescript/render/components/Text/index.module.scss b/lib/typescript/render/components/Text/index.module.scss index 646778373c..12f5447bb9 100644 --- a/lib/typescript/render/components/Text/index.module.scss +++ b/lib/typescript/render/components/Text/index.module.scss @@ -15,14 +15,14 @@ .contactContent { @extend .textMessage; - background: var(--color-background-blue); - color: var(--color-text-contrast); + background: var(--color-airy-message-inbound); + color: var(--color-airy-message-text-inbound); } .memberContent { @extend .textMessage; - background: var(--color-airy-blue); - color: white; + background: var(--color-airy-message-outbound); + color: var(--color-airy-message-text-outbound); } .messageLink { diff --git a/lib/typescript/render/components/Text/index.tsx b/lib/typescript/render/components/Text/index.tsx index c6b506c592..cbb37b5fff 100644 --- a/lib/typescript/render/components/Text/index.tsx +++ b/lib/typescript/render/components/Text/index.tsx @@ -14,7 +14,8 @@ export const Text = ({text, fromContact}: TextRenderProps) => ( options={{ defaultProtocol: 'https', className: `${styles.messageLink} ${fromContact ? styles.contactContent : styles.memberContent}`, - }}> + }} + > {text} ); diff --git a/lib/typescript/render/components/UnknownSourceText/index.module.scss b/lib/typescript/render/components/UnknownSourceText/index.module.scss index 8a90afd53b..93401f9d83 100644 --- a/lib/typescript/render/components/UnknownSourceText/index.module.scss +++ b/lib/typescript/render/components/UnknownSourceText/index.module.scss @@ -15,14 +15,14 @@ .contactContent { @extend .textMessage; - background: var(--color-background-blue); - color: var(--color-text-contrast); + background: var(--color-airy-message-inbound); + color: var(--color-airy-message-text-inbound); } .memberContent { @extend .textMessage; - background: var(--color-airy-blue); - color: white; + background: var(--color-airy-message-outbound); + color: var(--color-airy-message-text-outbound); } .messageLink { diff --git a/lib/typescript/render/components/UnknownSourceText/index.tsx b/lib/typescript/render/components/UnknownSourceText/index.tsx index 2e153b688d..e70e5a93c5 100644 --- a/lib/typescript/render/components/UnknownSourceText/index.tsx +++ b/lib/typescript/render/components/UnknownSourceText/index.tsx @@ -20,7 +20,8 @@ export const UnknownSourceText = ({text, fromContact, sourceName}: TextRenderPro options={{ defaultProtocol: 'https', className: `${styles.messageLink} ${fromContact ? styles.contactContent : styles.memberContent}`, - }}> + }} + > {text}
diff --git a/lib/typescript/render/components/Video/index.module.scss b/lib/typescript/render/components/Video/index.module.scss index 7ecf2e14e5..4ab8ccbb3f 100644 --- a/lib/typescript/render/components/Video/index.module.scss +++ b/lib/typescript/render/components/Video/index.module.scss @@ -7,6 +7,10 @@ margin-top: 5px; } +.wrapper a { + display: flex; +} + .item { display: flex; align-self: flex-end; @@ -49,6 +53,10 @@ } .video { - max-width: 100%; - max-height: 210px; + width: auto; + max-width: 300px; + max-height: 200px; + margin-bottom: 0; + border: 1px solid var(--color-light-gray); + border-radius: 8px; } diff --git a/lib/typescript/render/components/Video/index.tsx b/lib/typescript/render/components/Video/index.tsx index c631f514e3..3cec2afe44 100644 --- a/lib/typescript/render/components/Video/index.tsx +++ b/lib/typescript/render/components/Video/index.tsx @@ -1,8 +1,11 @@ import React, {useEffect, useState} from 'react'; +import {Text} from '../../components/Text'; import styles from './index.module.scss'; type VideoRenderProps = { videoUrl: string; + text?: string; + fromContact?: boolean; }; /** @@ -13,7 +16,7 @@ type VideoRenderProps = { */ const failedUrls = []; -export const Video = ({videoUrl}: VideoRenderProps) => { +export const Video = ({videoUrl, text, fromContact}: VideoRenderProps) => { const [isVideoFailed, setVideoFailed] = useState(failedUrls.includes(videoUrl)); useEffect(() => { @@ -26,19 +29,23 @@ export const Video = ({videoUrl}: VideoRenderProps) => { }; return ( -
-
- {isVideoFailed ? ( -
Loading of video failed
- ) : ( - - - - )} + <> +
+
+ {isVideoFailed ? ( +
Loading of video failed
+ ) : ( + + + + )} +
-
+ + {text && } + ); }; diff --git a/lib/typescript/render/index.ts b/lib/typescript/render/index.ts index 8b99a1ccec..f7841ac3b6 100644 --- a/lib/typescript/render/index.ts +++ b/lib/typescript/render/index.ts @@ -2,4 +2,4 @@ export * from './props'; export * from './SourceMessage'; export * from './SourceMessagePreview'; export * from './outbound'; -export * from './attachments'; +export * from './services'; diff --git a/lib/typescript/render/outbound/chatplugin.ts b/lib/typescript/render/outbound/chatplugin.ts index 0d90223f03..feaec32861 100644 --- a/lib/typescript/render/outbound/chatplugin.ts +++ b/lib/typescript/render/outbound/chatplugin.ts @@ -1,4 +1,5 @@ import {OutboundMapper} from './mapper'; +import {getAttachmentType} from '../services'; export class ChatpluginMapper extends OutboundMapper { getTextPayload(text: string): any { @@ -10,4 +11,17 @@ export class ChatpluginMapper extends OutboundMapper { isTextSupported(): boolean { return true; } + + getAttachmentPayload(mediaUrl: string): any { + const mediaType = getAttachmentType(mediaUrl, 'chatplugin'); + + return { + attachment: { + type: mediaType, + payload: { + url: mediaUrl, + }, + }, + }; + } } diff --git a/lib/typescript/render/outbound/facebook.ts b/lib/typescript/render/outbound/facebook.ts index df860dc67a..743e59ccf3 100644 --- a/lib/typescript/render/outbound/facebook.ts +++ b/lib/typescript/render/outbound/facebook.ts @@ -1,5 +1,5 @@ import {OutboundMapper} from './mapper'; -import {getAttachmentType} from '../attachments'; +import {getAttachmentType} from '../services'; export class FacebookMapper extends OutboundMapper { getTextPayload(text: string): any { @@ -13,7 +13,7 @@ export class FacebookMapper extends OutboundMapper { } getAttachmentPayload(mediaUrl: string): any { - const mediaType = getAttachmentType(mediaUrl); + const mediaType = getAttachmentType(mediaUrl, 'facebook'); return { attachment: { diff --git a/lib/typescript/render/outbound/google.ts b/lib/typescript/render/outbound/google.ts index 54ee08d548..185b9858c4 100644 --- a/lib/typescript/render/outbound/google.ts +++ b/lib/typescript/render/outbound/google.ts @@ -13,4 +13,19 @@ export class GoogleMapper extends OutboundMapper { isTextSupported(): boolean { return true; } + + getAttachmentPayload(mediaUrl: string): any { + return { + representative: { + representativeType: 'HUMAN', + }, + fallback: 'An image has been sent with Google Business Messages.', + image: { + contentInfo: { + altText: 'An image sent via Google Business Messages.', + fileUrl: mediaUrl, + }, + }, + }; + } } diff --git a/lib/typescript/render/outbound/twilio.ts b/lib/typescript/render/outbound/twilio.ts index 5f6c29994b..20f2c4dbad 100644 --- a/lib/typescript/render/outbound/twilio.ts +++ b/lib/typescript/render/outbound/twilio.ts @@ -10,4 +10,10 @@ export class TwilioMapper extends OutboundMapper { isTextSupported(): boolean { return true; } + + getAttachmentPayload(mediaUrl: string): any { + return { + MediaUrl: mediaUrl, + }; + } } diff --git a/lib/typescript/render/providers/chatplugin/components/RichCard/index.tsx b/lib/typescript/render/providers/chatplugin/components/RichCard/index.tsx index 3133f98a75..832b861453 100644 --- a/lib/typescript/render/providers/chatplugin/components/RichCard/index.tsx +++ b/lib/typescript/render/providers/chatplugin/components/RichCard/index.tsx @@ -54,7 +54,8 @@ export const RichCard = ({title, description, suggestions, media, cardWidth, com className={styles.suggestionButton} onClick={() => { clickSuggestion(suggestion); - }}> + }} + > {suggestion.reply ? suggestion.reply.text : suggestion.action.text} ))} diff --git a/lib/typescript/render/providers/facebook/components/ButtonTemplate/index.module.scss b/lib/typescript/render/providers/facebook/components/ButtonTemplate/index.module.scss index c9f5dbb033..a788b224b6 100644 --- a/lib/typescript/render/providers/facebook/components/ButtonTemplate/index.module.scss +++ b/lib/typescript/render/providers/facebook/components/ButtonTemplate/index.module.scss @@ -4,7 +4,7 @@ .wrapper { display: flex; flex-direction: column; - margin: 5px 0px; + margin-top: 5px; } .template { diff --git a/lib/typescript/render/providers/facebook/components/InstagramStoryMention/index.tsx b/lib/typescript/render/providers/facebook/components/InstagramStoryMention/index.tsx index 36e3115a4a..1a558aff84 100644 --- a/lib/typescript/render/providers/facebook/components/InstagramStoryMention/index.tsx +++ b/lib/typescript/render/providers/facebook/components/InstagramStoryMention/index.tsx @@ -20,7 +20,8 @@ export const StoryMention = ({url, sentAt, fromContact}: StoryMentionProps) => { className={`${fromContact ? styles.linkContactContent : styles.linkMemberContent}`} href={url} target="_blank" - rel="noopener noreferrer"> + rel="noopener noreferrer" + > mentioned in an active Instagram story{' '} diff --git a/lib/typescript/render/providers/facebook/components/InstagramStoryReplies/index.tsx b/lib/typescript/render/providers/facebook/components/InstagramStoryReplies/index.tsx index d2dcfe9c1b..63872cf557 100644 --- a/lib/typescript/render/providers/facebook/components/InstagramStoryReplies/index.tsx +++ b/lib/typescript/render/providers/facebook/components/InstagramStoryReplies/index.tsx @@ -33,7 +33,8 @@ export const StoryReplies = ({url, text, sentAt, fromContact}: InstagramRepliesP options={{ defaultProtocol: 'https', className: `${styles.messageLink} ${fromContact ? styles.contactContent : styles.memberContent}`, - }}> + }} + > {text}
diff --git a/lib/typescript/render/providers/facebook/components/MediaTemplate/index.module.scss b/lib/typescript/render/providers/facebook/components/MediaTemplate/index.module.scss index 437c5a2c26..0bd6110598 100644 --- a/lib/typescript/render/providers/facebook/components/MediaTemplate/index.module.scss +++ b/lib/typescript/render/providers/facebook/components/MediaTemplate/index.module.scss @@ -5,7 +5,7 @@ max-width: 500px; border-radius: 8px; border: 1px solid var(--color-light-gray); - margin: 5px 0px; + margin-top: 5px; } .media { diff --git a/lib/typescript/render/providers/google/GoogleRender.tsx b/lib/typescript/render/providers/google/GoogleRender.tsx index 44ab0b279e..a5cf9883c6 100644 --- a/lib/typescript/render/providers/google/GoogleRender.tsx +++ b/lib/typescript/render/providers/google/GoogleRender.tsx @@ -9,6 +9,7 @@ import {Suggestions} from './components/Suggestions'; import {RichCard} from './components/RichCard'; import {RichCardCarousel} from './components/RichCardCarousel'; import {RequestedLiveAgent} from './components/RequestedLiveAgent'; +import {SurveyResponse} from './components/SurveyResponse'; export const GoogleRender = (props: RenderPropsUnion) => { const message = props.message; @@ -24,6 +25,9 @@ function render(content: ContentUnion, props: RenderPropsUnion) { case 'requestedLiveAgent': return ; + case 'surveyResponse': + return ; + case 'image': return ; @@ -122,12 +126,21 @@ function googleInbound(message): ContentUnion { }; } - if (messageJson?.userStatus?.requestedLiveAgent === undefined) { + if (messageJson?.userStatus?.requestedLiveAgent) { return { type: 'requestedLiveAgent', }; } + if (messageJson?.surveyResponse) { + const userResponse = + messageJson?.surveyResponse?.questionResponsePostbackData ?? messageJson?.surveyResponse?.questionResponseText; + return { + type: 'surveyResponse', + rating: userResponse, + }; + } + return { type: 'text', text: 'Unsupported message type', @@ -135,10 +148,10 @@ function googleInbound(message): ContentUnion { } function googleOutbound(message): ContentUnion { - const messageJson = message.content.message ?? message.content; + const messageJson = message?.content?.message ?? message?.content ?? message; const maxNumberOfSuggestions = 13; - if (messageJson.richCard?.standaloneCard) { + if (messageJson?.richCard?.standaloneCard) { const { richCard: { standaloneCard: {cardContent}, diff --git a/lib/typescript/render/providers/google/components/RequestedLiveAgent/index.tsx b/lib/typescript/render/providers/google/components/RequestedLiveAgent/index.tsx index 146660b36c..bf5231e355 100644 --- a/lib/typescript/render/providers/google/components/RequestedLiveAgent/index.tsx +++ b/lib/typescript/render/providers/google/components/RequestedLiveAgent/index.tsx @@ -1,5 +1,4 @@ import React from 'react'; - import styles from './index.module.scss'; import {Emoji} from 'components'; diff --git a/lib/typescript/render/providers/google/components/RichCard/index.tsx b/lib/typescript/render/providers/google/components/RichCard/index.tsx index bca48af542..0f149c6c86 100644 --- a/lib/typescript/render/providers/google/components/RichCard/index.tsx +++ b/lib/typescript/render/providers/google/components/RichCard/index.tsx @@ -54,7 +54,8 @@ export const RichCard = ({title, description, suggestions, media, cardWidth, com className={styles.suggestionButton} onClick={() => { clickSuggestion(suggestion); - }}> + }} + > {suggestion.reply ? suggestion.reply.text : suggestion.action.text} ))} diff --git a/lib/typescript/render/providers/google/components/Suggestions/index.tsx b/lib/typescript/render/providers/google/components/Suggestions/index.tsx index e89cda5b16..a0ecd65f23 100644 --- a/lib/typescript/render/providers/google/components/Suggestions/index.tsx +++ b/lib/typescript/render/providers/google/components/Suggestions/index.tsx @@ -56,7 +56,8 @@ export const Suggestions = ({text, fallback, image, suggestions, fromContact}: S : `tel: ${elem.action.dialAction?.phoneNumber}` } target="_blank" - rel="noopener noreferrer"> + rel="noopener noreferrer" + > {elem.action.text} diff --git a/lib/typescript/render/providers/google/components/SurveyResponse/index.module.scss b/lib/typescript/render/providers/google/components/SurveyResponse/index.module.scss new file mode 100644 index 0000000000..7750980996 --- /dev/null +++ b/lib/typescript/render/providers/google/components/SurveyResponse/index.module.scss @@ -0,0 +1,10 @@ +.text { + display: inline-block; + max-width: 500px; + padding: 10px; + margin-top: 5px; + border-radius: 8px; + font-family: 'Lato', sans-serif; + background: var(--color-template-gray); + color: var(--color-text-contrast); +} diff --git a/lib/typescript/render/providers/google/components/SurveyResponse/index.tsx b/lib/typescript/render/providers/google/components/SurveyResponse/index.tsx new file mode 100644 index 0000000000..52b98baddb --- /dev/null +++ b/lib/typescript/render/providers/google/components/SurveyResponse/index.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +import styles from './index.module.scss'; +import {Emoji} from 'components'; + +export const SurveyResponse = ({rating}) => ( + + This user {rating === 'NO' ? 'negatively' : rating === 'YES' ? 'positively' : ''} rated the + experience with the response '{rating}'. + +); diff --git a/lib/typescript/render/providers/google/googleModel.ts b/lib/typescript/render/providers/google/googleModel.ts index 9ad2a739ea..fe3bbe7370 100644 --- a/lib/typescript/render/providers/google/googleModel.ts +++ b/lib/typescript/render/providers/google/googleModel.ts @@ -4,13 +4,18 @@ export enum MediaHeight { tall = 'TALL', } export interface Content { - type: 'text' | 'image' | 'suggestions' | 'richCard' | 'richCardCarousel' | 'requestedLiveAgent'; + type: 'text' | 'image' | 'suggestions' | 'richCard' | 'richCardCarousel' | 'requestedLiveAgent' | 'surveyResponse'; } export interface RequestedLiveAgent extends Content { type: 'requestedLiveAgent'; } +export interface SurveyResponse extends Content { + type: 'surveyResponse'; + rating: string; +} + export interface Text extends Content { type: 'text'; text: string; @@ -111,4 +116,11 @@ export interface Suggestions extends Content { suggestions: SuggestionsUnion[]; } -export type ContentUnion = Text | Image | Suggestions | RichCard | RichCardCarousel | RequestedLiveAgent; +export type ContentUnion = + | Text + | Image + | Suggestions + | RichCard + | RichCardCarousel + | RequestedLiveAgent + | SurveyResponse; diff --git a/lib/typescript/render/providers/twilio/TwilioRender.tsx b/lib/typescript/render/providers/twilio/TwilioRender.tsx index ed536002dc..3cdcbc0bb4 100644 --- a/lib/typescript/render/providers/twilio/TwilioRender.tsx +++ b/lib/typescript/render/providers/twilio/TwilioRender.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import {Text} from '../../components/Text'; +import {Text, Image, File, Video, Audio} from '../../components'; +import {CurrentLocation} from './components/CurrentLocation'; import {RenderPropsUnion} from '../../props'; import {ContentUnion} from './twilioModel'; +import {decodeURIComponentMessage, getAttachmentType} from '../../services'; export const TwilioRender = (props: RenderPropsUnion) => { const message = props.message; @@ -13,28 +15,205 @@ function render(content: ContentUnion, props: RenderPropsUnion) { switch (content.type) { case 'text': return ; + + case 'image': + return ( + + ); + + case 'video': + return ( +