From 90963c45953edfd323361817b7f63e8e0f613cdd Mon Sep 17 00:00:00 2001 From: titanventura Date: Mon, 9 Oct 2023 21:22:12 +0530 Subject: [PATCH 01/34] add. concurrent resource fetching code --- internal/internal.go | 34 +++++++++++++++++++--------------- providers/aws/aws.go | 34 ++++++++++++++++++---------------- providers/providers.go | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 31 deletions(-) diff --git a/internal/internal.go b/internal/internal.go index 1765a1171..48b966938 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -79,10 +79,14 @@ func Exec(address string, port int, configPath string, telemetry bool, a utils.A _, err = cron.Every(1).Hours().Do(func() { log.Info("Fetching resources workflow has started") - err = fetchResources(ctx, clients, regions, telemetry) + + numWorkers := 64 + wp := providers.NewWorkerPool(numWorkers) + err = fetchResources(ctx, clients, regions, telemetry, wp) if err != nil { log.Fatal(err) } + wp.Wait() }) if err != nil { @@ -209,7 +213,7 @@ func setupDBConnection(c *models.Config) error { return nil } -func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClient, provider string, telemetry bool, regions []string) { +func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClient, provider string, telemetry bool, regions []string, wp *providers.WorkerPool) { localHub := sentry.CurrentHub().Clone() defer func() { @@ -233,7 +237,7 @@ func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClien switch provider { case "AWS": - aws.FetchResources(ctx, client, regions, db, telemetry, analytics) + aws.FetchResources(ctx, client, regions, db, telemetry, analytics, wp) case "DigitalOcean": do.FetchResources(ctx, client, db, telemetry, analytics) case "OCI": @@ -257,30 +261,30 @@ func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClien } } -func fetchResources(ctx context.Context, clients []providers.ProviderClient, regions []string, telemetry bool) error { +func fetchResources(ctx context.Context, clients []providers.ProviderClient, regions []string, telemetry bool, wp *providers.WorkerPool) error { for _, client := range clients { if client.AWSClient != nil { - go triggerFetchingWorfklow(ctx, client, "AWS", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "AWS", telemetry, regions, wp) } else if client.DigitalOceanClient != nil { - go triggerFetchingWorfklow(ctx, client, "DigitalOcean", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "DigitalOcean", telemetry, regions, wp) } else if client.OciClient != nil { - go triggerFetchingWorfklow(ctx, client, "OCI", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "OCI", telemetry, regions, wp) } else if client.CivoClient != nil { - go triggerFetchingWorfklow(ctx, client, "Civo", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "Civo", telemetry, regions, wp) } else if client.K8sClient != nil { - go triggerFetchingWorfklow(ctx, client, "Kubernetes", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "Kubernetes", telemetry, regions, wp) } else if client.LinodeClient != nil { - go triggerFetchingWorfklow(ctx, client, "Linode", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "Linode", telemetry, regions, wp) } else if client.TencentClient != nil { - go triggerFetchingWorfklow(ctx, client, "Tencent", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "Tencent", telemetry, regions, wp) } else if client.AzureClient != nil { - go triggerFetchingWorfklow(ctx, client, "Azure", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "Azure", telemetry, regions, wp) } else if client.ScalewayClient != nil { - go triggerFetchingWorfklow(ctx, client, "Scaleway", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "Scaleway", telemetry, regions, wp) } else if client.MongoDBAtlasClient != nil { - go triggerFetchingWorfklow(ctx, client, "MongoDBAtlas", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "MongoDBAtlas", telemetry, regions, wp) } else if client.GCPClient != nil { - go triggerFetchingWorfklow(ctx, client, "GCP", telemetry, regions) + go triggerFetchingWorfklow(ctx, client, "GCP", telemetry, regions, wp) } } return nil diff --git a/providers/aws/aws.go b/providers/aws/aws.go index ecf1e862e..7b1cc8f4d 100644 --- a/providers/aws/aws.go +++ b/providers/aws/aws.go @@ -98,7 +98,7 @@ func listOfSupportedServices() []providers.FetchDataFunction { } } -func FetchResources(ctx context.Context, client providers.ProviderClient, regions []string, db *bun.DB, telemetry bool, analytics utils.Analytics) { +func FetchResources(ctx context.Context, client providers.ProviderClient, regions []string, db *bun.DB, telemetry bool, analytics utils.Analytics, wp *providers.WorkerPool) { listOfSupportedRegions := getRegions() if len(regions) > 0 { log.Infof("Komiser will fetch resources from the following regions: %s", strings.Join(regions, ",")) @@ -108,23 +108,25 @@ func FetchResources(ctx context.Context, client providers.ProviderClient, region for _, region := range listOfSupportedRegions { client.AWSClient.Region = region for _, fetchResources := range listOfSupportedServices() { - resources, err := fetchResources(ctx, client) - if err != nil { - log.Warnf("[%s][AWS] %s", client.Name, err) - } else { - for _, resource := range resources { - _, err = db.NewInsert().Model(&resource).On("CONFLICT (resource_id) DO UPDATE").Set("cost = EXCLUDED.cost, relations=EXCLUDED.relations").Exec(context.Background()) - if err != nil { - log.WithError(err).Errorf("db trigger failed") + wp.SubmitTask(func() { + resources, err := fetchResources(ctx, client) + if err != nil { + log.Warnf("[%s][AWS] %s", client.Name, err) + } else { + for _, resource := range resources { + _, err = db.NewInsert().Model(&resource).On("CONFLICT (resource_id) DO UPDATE").Set("cost = EXCLUDED.cost, relations=EXCLUDED.relations").Exec(context.Background()) + if err != nil { + log.WithError(err).Errorf("db trigger failed") + } + } + if telemetry { + analytics.TrackEvent("discovered_resources", map[string]interface{}{ + "provider": "AWS", + "resources": len(resources), + }) } } - if telemetry { - analytics.TrackEvent("discovered_resources", map[string]interface{}{ - "provider": "AWS", - "resources": len(resources), - }) - } - } + }) } } } diff --git a/providers/providers.go b/providers/providers.go index 138fa34da..9e2b1dc22 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -2,6 +2,7 @@ package providers import ( "context" + "sync" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/aws/aws-sdk-go-v2/aws" @@ -47,3 +48,39 @@ type K8sClient struct { Client *kubernetes.Clientset OpencostBaseUrl string } + +type WorkerPool struct { + numWorkers int + tasks chan func() + wg sync.WaitGroup +} + +func NewWorkerPool(numWorkers int) *WorkerPool { + return &WorkerPool{ + numWorkers: numWorkers, + tasks: make(chan func()), + } +} + +func (wp *WorkerPool) Start() { + for i := 0; i < wp.numWorkers; i++ { + wp.wg.Add(1) + go wp.worker() + } +} + +func (wp *WorkerPool) SubmitTask(task func()) { + wp.tasks <- task +} + +func (wp *WorkerPool) Wait() { + close(wp.tasks) + wp.wg.Wait() +} + +func (wp *WorkerPool) worker() { + defer wp.wg.Done() + for task := range wp.tasks { + task() + } +} From 3599f1f22e0dd30e5edd499c4752ea775b4ddc5a Mon Sep 17 00:00:00 2001 From: titanventura Date: Tue, 10 Oct 2023 00:35:10 +0530 Subject: [PATCH 02/34] feat(concurrency): fix - waiting and waitgroup logic --- internal/internal.go | 32 +++++++++++++++++++++----------- providers/providers.go | 8 ++++---- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/internal/internal.go b/internal/internal.go index 48b966938..2e3288c09 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -82,6 +82,7 @@ func Exec(address string, port int, configPath string, telemetry bool, a utils.A numWorkers := 64 wp := providers.NewWorkerPool(numWorkers) + wp.Start() err = fetchResources(ctx, clients, regions, telemetry, wp) if err != nil { log.Fatal(err) @@ -262,29 +263,38 @@ func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClien } func fetchResources(ctx context.Context, clients []providers.ProviderClient, regions []string, telemetry bool, wp *providers.WorkerPool) error { + + workflowTrigger := func(client providers.ProviderClient, provider string) { + wp.Wg.Add(1) + go func() { + defer wp.Wg.Done() + triggerFetchingWorfklow(ctx, client, provider, telemetry, regions, wp) + }() + } + for _, client := range clients { if client.AWSClient != nil { - go triggerFetchingWorfklow(ctx, client, "AWS", telemetry, regions, wp) + workflowTrigger(client, "AWS") } else if client.DigitalOceanClient != nil { - go triggerFetchingWorfklow(ctx, client, "DigitalOcean", telemetry, regions, wp) + workflowTrigger(client, "DigitalOcean") } else if client.OciClient != nil { - go triggerFetchingWorfklow(ctx, client, "OCI", telemetry, regions, wp) + workflowTrigger(client, "OCI") } else if client.CivoClient != nil { - go triggerFetchingWorfklow(ctx, client, "Civo", telemetry, regions, wp) + workflowTrigger(client, "Civo") } else if client.K8sClient != nil { - go triggerFetchingWorfklow(ctx, client, "Kubernetes", telemetry, regions, wp) + workflowTrigger(client, "Kubernetes") } else if client.LinodeClient != nil { - go triggerFetchingWorfklow(ctx, client, "Linode", telemetry, regions, wp) + workflowTrigger(client, "Linode") } else if client.TencentClient != nil { - go triggerFetchingWorfklow(ctx, client, "Tencent", telemetry, regions, wp) + workflowTrigger(client, "Tencent") } else if client.AzureClient != nil { - go triggerFetchingWorfklow(ctx, client, "Azure", telemetry, regions, wp) + workflowTrigger(client, "Azure") } else if client.ScalewayClient != nil { - go triggerFetchingWorfklow(ctx, client, "Scaleway", telemetry, regions, wp) + workflowTrigger(client, "Scaleway") } else if client.MongoDBAtlasClient != nil { - go triggerFetchingWorfklow(ctx, client, "MongoDBAtlas", telemetry, regions, wp) + workflowTrigger(client, "MongoDBAtlas") } else if client.GCPClient != nil { - go triggerFetchingWorfklow(ctx, client, "GCP", telemetry, regions, wp) + workflowTrigger(client, "GCP") } } return nil diff --git a/providers/providers.go b/providers/providers.go index 9e2b1dc22..81afb7b62 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -52,7 +52,7 @@ type K8sClient struct { type WorkerPool struct { numWorkers int tasks chan func() - wg sync.WaitGroup + Wg sync.WaitGroup } func NewWorkerPool(numWorkers int) *WorkerPool { @@ -64,23 +64,23 @@ func NewWorkerPool(numWorkers int) *WorkerPool { func (wp *WorkerPool) Start() { for i := 0; i < wp.numWorkers; i++ { - wp.wg.Add(1) go wp.worker() } } func (wp *WorkerPool) SubmitTask(task func()) { + wp.Wg.Add(1) wp.tasks <- task } func (wp *WorkerPool) Wait() { + wp.Wg.Wait() close(wp.tasks) - wp.wg.Wait() } func (wp *WorkerPool) worker() { - defer wp.wg.Done() for task := range wp.tasks { task() + wp.Wg.Done() } } From 493845ddeac6eab63f3a7f15dd7876937a725a16 Mon Sep 17 00:00:00 2001 From: Azanul Haque <42029519+Azanul@users.noreply.github.com> Date: Tue, 10 Oct 2023 06:30:56 +0000 Subject: [PATCH 03/34] using a separate WaitGroup Signed-off-by: Azanul Haque <42029519+Azanul@users.noreply.github.com> --- internal/internal.go | 10 +++++++--- providers/providers.go | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/internal/internal.go b/internal/internal.go index 2e3288c09..1c55b6de5 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -11,6 +11,7 @@ import ( "runtime" "strconv" "strings" + "sync" "time" "github.com/getsentry/sentry-go" @@ -54,7 +55,7 @@ var Arch = runtime.GOARCH var db *bun.DB var analytics utils.Analytics -func Exec(address string, port int, configPath string, telemetry bool, a utils.Analytics, regions []string, cmd *cobra.Command) error { +func Exec(address string, port int, configPath string, telemetry bool, a utils.Analytics, regions []string, _ *cobra.Command) error { analytics = a ctx := context.Background() @@ -264,10 +265,11 @@ func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClien func fetchResources(ctx context.Context, clients []providers.ProviderClient, regions []string, telemetry bool, wp *providers.WorkerPool) error { + var wwg sync.WaitGroup workflowTrigger := func(client providers.ProviderClient, provider string) { - wp.Wg.Add(1) + wwg.Add(1) go func() { - defer wp.Wg.Done() + defer wwg.Done() triggerFetchingWorfklow(ctx, client, provider, telemetry, regions, wp) }() } @@ -297,6 +299,8 @@ func fetchResources(ctx context.Context, clients []providers.ProviderClient, reg workflowTrigger(client, "GCP") } } + + wwg.Wait() return nil } diff --git a/providers/providers.go b/providers/providers.go index 81afb7b62..ef0198714 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -52,7 +52,7 @@ type K8sClient struct { type WorkerPool struct { numWorkers int tasks chan func() - Wg sync.WaitGroup + wg sync.WaitGroup } func NewWorkerPool(numWorkers int) *WorkerPool { @@ -69,18 +69,18 @@ func (wp *WorkerPool) Start() { } func (wp *WorkerPool) SubmitTask(task func()) { - wp.Wg.Add(1) + wp.wg.Add(1) wp.tasks <- task } func (wp *WorkerPool) Wait() { - wp.Wg.Wait() + wp.wg.Wait() close(wp.tasks) } func (wp *WorkerPool) worker() { for task := range wp.tasks { task() - wp.Wg.Done() + wp.wg.Done() } } From 49e3335f89ea6dac9e9a650c3c62db82492ec42e Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 12 Oct 2023 18:36:31 +0530 Subject: [PATCH 04/34] feat(devcontainer): devcontainer setup Signed-off-by: Azanul --- .devcontainer/devcontainer.json | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..94503ce34 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/go +{ + "name": "Go", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/go:1-1.21-bullseye", + "features": { + "ghcr.io/devcontainers-contrib/features/node-asdf:0": {}, + "ghcr.io/devcontainers-contrib/features/typescript:2": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "golang.go-nightly", + "bradlc.vscode-tailwindcss" + ] + } + } + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "go version", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} From afab697af02a94a3fa1dca1475b9bca6a5df9370 Mon Sep 17 00:00:00 2001 From: Azanul Date: Fri, 13 Oct 2023 23:01:34 +0530 Subject: [PATCH 05/34] feat(aws utils): util func extension Signed-off-by: Azanul --- providers/aws/lambda/functions.go | 2 +- providers/aws/utils/utils.go | 29 +++++++++++++++++++---- providers/aws/utils/utils_test.go | 38 ++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/providers/aws/lambda/functions.go b/providers/aws/lambda/functions.go index b7a345c6e..02a41e387 100644 --- a/providers/aws/lambda/functions.go +++ b/providers/aws/lambda/functions.go @@ -48,7 +48,7 @@ func Functions(ctx context.Context, client providers.ProviderClient) ([]models.R return resources, err } - priceMap, err := awsUtils.GetPriceMap(pricingOutput) + priceMap, err := awsUtils.GetPriceMap(pricingOutput, "group") if err != nil { log.Errorf("ERROR: Failed to calculate cost per month: %v", err) return resources, err diff --git a/providers/aws/utils/utils.go b/providers/aws/utils/utils.go index bc1708972..529c00bcb 100644 --- a/providers/aws/utils/utils.go +++ b/providers/aws/utils/utils.go @@ -11,8 +11,12 @@ import ( type ProductEntry struct { Product struct { Attributes struct { - Group string `json:"group"` - Operation string `json:"operation"` + Group string `json:"group"` + Operation string `json:"operation"` + GroupDescription string `json:"groupDescription"` + RequestDescription string `json:"requestDescription"` + InstanceType string `json:"instanceType"` + InstanceTypeFamily string `json:"instanceTypeFamily"` } `json:"attributes"` } `json:"product"` Terms struct { @@ -47,7 +51,7 @@ func GetCost(pds []PriceDimensions, v float64) float64 { return total } -func GetPriceMap(pricingOutput *pricing.GetProductsOutput) (map[string][]PriceDimensions, error) { +func GetPriceMap(pricingOutput *pricing.GetProductsOutput, field string) (map[string][]PriceDimensions, error) { priceMap := make(map[string][]PriceDimensions) if pricingOutput != nil && len(pricingOutput.PriceList) > 0 { @@ -58,7 +62,22 @@ func GetPriceMap(pricingOutput *pricing.GetProductsOutput) (map[string][]PriceDi return nil, fmt.Errorf("failed to unmarshal JSON: %w", err) } - group := price.Product.Attributes.Group + var key string + switch field { + case "group": + key = price.Product.Attributes.Group + case "operation": + key = price.Product.Attributes.Operation + case "groupDescription": + key = price.Product.Attributes.GroupDescription + case "requestDescription": + key = price.Product.Attributes.RequestDescription + case "instanceType": + key = price.Product.Attributes.InstanceType + case "instanceTypeFamily": + key = price.Product.Attributes.InstanceTypeFamily + } + unitPrices := []PriceDimensions{} for _, pd := range price.Terms.OnDemand { for _, p := range pd.PriceDimensions { @@ -66,7 +85,7 @@ func GetPriceMap(pricingOutput *pricing.GetProductsOutput) (map[string][]PriceDi } } - priceMap[group] = unitPrices + priceMap[key] = unitPrices } } diff --git a/providers/aws/utils/utils_test.go b/providers/aws/utils/utils_test.go index 1602fb242..bf2f6fb39 100644 --- a/providers/aws/utils/utils_test.go +++ b/providers/aws/utils/utils_test.go @@ -49,6 +49,7 @@ func TestGetCost(t *testing.T) { func TestGetPriceMap(t *testing.T) { testCases := []struct { inputPriceList []string + field string expectedNumProducts int expectedNumPriceDims map[string]int }{ @@ -77,6 +78,7 @@ func TestGetPriceMap(t *testing.T) { } } }`}, + field: "group", expectedNumProducts: 1, expectedNumPriceDims: map[string]int{"TestGroup": 1}, }, @@ -153,16 +155,46 @@ func TestGetPriceMap(t *testing.T) { } }`, }, + field: "group", expectedNumProducts: 2, expectedNumPriceDims: map[string]int{"TestGroup1": 2, "TestGroup2": 3}, }, + // Minimal valid JSON input with a single product, one price dimension & "instanceType" attribute + { + inputPriceList: []string{` + { + "product": { + "attributes": { + "instanceType": "TestInstanceType" + } + }, + "terms": { + "OnDemand": { + "test_term": { + "priceDimensions": { + "test_price_dimension": { + "beginRange": "0", + "endRange": "Inf", + "pricePerUnit": { + "USD": "0.1" + } + } + } + } + } + } + }`}, + field: "instanceType", + expectedNumProducts: 1, + expectedNumPriceDims: map[string]int{"TestInstanceType": 1}, + }, } for i, testCase := range testCases { t.Run(fmt.Sprintf("Test case %d", i+1), func(t *testing.T) { output := pricing.GetProductsOutput{ PriceList: testCase.inputPriceList, } - priceMap, err := GetPriceMap(&output) + priceMap, err := GetPriceMap(&output, "group") if err != nil { t.Errorf("Expected no error, but got: %v", err) } @@ -186,7 +218,7 @@ func TestGetPriceMap_InvalidJSON(t *testing.T) { output := pricing.GetProductsOutput{ PriceList: []string{invalidJSON}, } - _, err := GetPriceMap(&output) + _, err := GetPriceMap(&output, "group") if err == nil { t.Error("Expected an error, but got nil") } @@ -194,7 +226,7 @@ func TestGetPriceMap_InvalidJSON(t *testing.T) { func TestGetPriceMap_NoPricingOutput(t *testing.T) { // PricingOutput is nil - priceMap, err := GetPriceMap(nil) + priceMap, err := GetPriceMap(nil, "group") if err != nil { t.Errorf("Expected no error, but got: %v", err) } From a5a51a6fa8c8efb383d8da4f64d50fd9ebc85093 Mon Sep 17 00:00:00 2001 From: Azanul Date: Fri, 13 Oct 2023 23:02:48 +0530 Subject: [PATCH 06/34] feat(aws utils): util func extension s3 buckets Signed-off-by: Azanul --- providers/aws/s3/buckets.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/aws/s3/buckets.go b/providers/aws/s3/buckets.go index de60e6ed6..005f6104e 100644 --- a/providers/aws/s3/buckets.go +++ b/providers/aws/s3/buckets.go @@ -45,7 +45,7 @@ func Buckets(ctx context.Context, client ProviderClient) ([]Resource, error) { return resources, err } - priceMap, err := awsUtils.GetPriceMap(pricingOutput) + priceMap, err := awsUtils.GetPriceMap(pricingOutput, "group") if err != nil { log.Errorf("ERROR: Failed to calculate cost per month: %v", err) return resources, err From ce53d680bcce1708376ec475e6ae1992b6a83fb3 Mon Sep 17 00:00:00 2001 From: Azanul Date: Sun, 15 Oct 2023 22:55:34 +0530 Subject: [PATCH 07/34] refac(fetchResources): encapsulate Signed-off-by: Azanul --- internal/internal.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/internal/internal.go b/internal/internal.go index 1c55b6de5..29d8ea202 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -81,14 +81,7 @@ func Exec(address string, port int, configPath string, telemetry bool, a utils.A _, err = cron.Every(1).Hours().Do(func() { log.Info("Fetching resources workflow has started") - numWorkers := 64 - wp := providers.NewWorkerPool(numWorkers) - wp.Start() - err = fetchResources(ctx, clients, regions, telemetry, wp) - if err != nil { - log.Fatal(err) - } - wp.Wait() + fetchResources(ctx, clients, regions, telemetry) }) if err != nil { @@ -263,7 +256,10 @@ func triggerFetchingWorfklow(ctx context.Context, client providers.ProviderClien } } -func fetchResources(ctx context.Context, clients []providers.ProviderClient, regions []string, telemetry bool, wp *providers.WorkerPool) error { +func fetchResources(ctx context.Context, clients []providers.ProviderClient, regions []string, telemetry bool) { + numWorkers := 64 + wp := providers.NewWorkerPool(numWorkers) + wp.Start() var wwg sync.WaitGroup workflowTrigger := func(client providers.ProviderClient, provider string) { @@ -301,7 +297,7 @@ func fetchResources(ctx context.Context, clients []providers.ProviderClient, reg } wwg.Wait() - return nil + wp.Wait() } func checkUpgrade() { From 1d46d1dcaf166170532959644982b2dd03c49e47 Mon Sep 17 00:00:00 2001 From: Azanul Date: Sun, 15 Oct 2023 22:56:09 +0530 Subject: [PATCH 08/34] fear(fetchResources): benchmark test Signed-off-by: Azanul --- internal/internal_test.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 internal/internal_test.go diff --git a/internal/internal_test.go b/internal/internal_test.go new file mode 100644 index 000000000..f8bfc9ee9 --- /dev/null +++ b/internal/internal_test.go @@ -0,0 +1,37 @@ +package internal + +import ( + "context" + "io" + "testing" + + log "github.com/sirupsen/logrus" + + "github.com/tailwarden/komiser/internal/config" + "github.com/tailwarden/komiser/utils" +) + +// BenchmarkFactorial benchmarks the Factorial function. +func BenchmarkFetchResources(b *testing.B) { + // Setup + ctx := context.TODO() + log.SetOutput(io.Discard) + analytics.Init() + cfg, clients, accounts, err := config.Load("/workspaces/komiser/config.toml", false, analytics, db) + if err != nil { + b.Fatalf("Error during config setup: %v", err) + } + err = setupDBConnection(cfg) + if err != nil { + b.Fatalf("Error during DB setup: %v", err) + } + err = utils.SetupSchema(db, cfg, accounts) + if err != nil { + b.Fatalf("Error during schema setup: %v", err) + } + + // The benchmark function will run b.N times + for i := 0; i < b.N; i++ { + fetchResources(ctx, clients, []string{}, false) + } +} From 06b5c1ad181b78d7a5934dfa01df2fcdc0bc23d3 Mon Sep 17 00:00:00 2001 From: Saba Shavidze Date: Mon, 16 Oct 2023 13:50:42 +0400 Subject: [PATCH 09/34] feat: add empty state for empty page filters apllied on resource explorer --- .../components/empty-state/EmptyState.tsx | 3 +- .../components/explorer/DependencyGraph.tsx | 86 ++++++++++++------- dashboard/package.json | 1 + 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/dashboard/components/empty-state/EmptyState.tsx b/dashboard/components/empty-state/EmptyState.tsx index cd7883b32..74b65aabb 100644 --- a/dashboard/components/empty-state/EmptyState.tsx +++ b/dashboard/components/empty-state/EmptyState.tsx @@ -21,7 +21,8 @@ type Poses = | 'shirt' | 'whiteboard' | 'thinking' - | 'working'; + | 'working' + | 'tablet'; export type EmptyStateProps = { title: string; diff --git a/dashboard/components/explorer/DependencyGraph.tsx b/dashboard/components/explorer/DependencyGraph.tsx index 4c98ab025..14e33ed6b 100644 --- a/dashboard/components/explorer/DependencyGraph.tsx +++ b/dashboard/components/explorer/DependencyGraph.tsx @@ -1,5 +1,5 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import React, { useState, memo } from 'react'; +import React, { useState, memo, useEffect } from 'react'; import CytoscapeComponent from 'react-cytoscapejs'; import Cytoscape, { EventObject } from 'cytoscape'; import popper from 'cytoscape-popper'; @@ -12,6 +12,8 @@ import nodeHtmlLabel, { // @ts-ignore import COSEBilkent from 'cytoscape-cose-bilkent'; +import EmptyState from '@components/empty-state/EmptyState'; + import Tooltip from '@components/tooltip/Tooltip'; import WarningIcon from '@components/icons/WarningIcon'; import { ReactFlowData } from './hooks/useDependencyGraph'; @@ -36,6 +38,8 @@ Cytoscape.use(popper); const DependencyGraph = ({ data }: DependencyGraphProps) => { const [initDone, setInitDone] = useState(false); + const dataIsEmpty: boolean = data.nodes.length === 0; + // Type technically is Cytoscape.EdgeCollection but that throws an unexpected error const loopAnimation = (eles: any) => { const ani = eles.animation(edgeAnimationConfig[0], edgeAnimationConfig[1]); @@ -122,39 +126,55 @@ const DependencyGraph = ({ data }: DependencyGraphProps) => { return (
- cyActionHandlers(cy)} - /> -
+ {dataIsEmpty ? ( + <> +
+ +
+ + ) : ( + <> + cyActionHandlers(cy)} + /> + + )} +
{data?.nodes?.length} Resources -
- - - Only AWS resources are currently supported on the explorer. - -
+ {!dataIsEmpty && ( +
+ + + Only AWS resources are currently supported on the explorer. + +
+ )}
); diff --git a/dashboard/package.json b/dashboard/package.json index bce604520..0a9667039 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -7,6 +7,7 @@ "build": "next build && next export", "start": "next start -p 3002", "lint": "next lint", + "format": "prettier --write \"**/*.{ts,tsx,json,css,scss,md}\"", "prepare": "cd .. && husky install dashboard/.husky", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", From 96dba3af9825fa421d65517ed2fee2233e754279 Mon Sep 17 00:00:00 2001 From: Kavibritto Chalaman Date: Mon, 16 Oct 2023 11:24:58 +0000 Subject: [PATCH 10/34] #1089 added nil check on associated KeyPair --- providers/aws/ec2/instances.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/providers/aws/ec2/instances.go b/providers/aws/ec2/instances.go index b4997579a..32eb93c08 100644 --- a/providers/aws/ec2/instances.go +++ b/providers/aws/ec2/instances.go @@ -212,12 +212,14 @@ func getEC2Relations(inst *etype.Instance, resourceArn string) (rel []models.Lin }) // Get associated Keypair - rel = append(rel, models.Link{ - ResourceID: *inst.KeyName, - Name: *inst.KeyName, - Type: "Key Pair", - Relation: "USES", - }) + if inst.KeyName != nil { + rel = append(rel, models.Link{ + ResourceID: *inst.KeyName, + Name: *inst.KeyName, + Type: "Key Pair", + Relation: "USES", + }) + } // Get associated IAM roles if inst.IamInstanceProfile != nil { From 5ed06f6435b05fea1aee151a49ef2663a22411a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:42:09 +0200 Subject: [PATCH 11/34] fix: improve dashboard readme --- dashboard/README.md | 131 +++++++++++++++++---------- dashboard/tsconfig.json | 7 +- dashboard/utils/formatNumber.test.ts | 2 +- dashboard/utils/regex.test.ts | 2 +- 4 files changed, 91 insertions(+), 51 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index 514b43c94..f8340a486 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -1,12 +1,20 @@ +# ๐Ÿš€ Komiser Dashboard + Komiser dashboard is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). -Full frontend stack: `Next.js`, `Typescript`, `Tailwind`, `Storybook`, `Jest` & `React Testing Library.` +**Full frontend stack:** +- ๐Ÿ–ฅ `Next.js` +- ๐Ÿ“œ `Typescript` +- ๐ŸŽจ `Tailwind` +- ๐Ÿ“– `Storybook` +- ๐Ÿงช `Jest` +- ๐Ÿ“š `React Testing Library` -## Getting Started +## ๐Ÿš€ Getting Started First, run the development server: -```bash +\``` # From the Komiser root folder start the Komiser server, run: go run *.go start --config /path/to/config.toml @@ -15,56 +23,65 @@ NEXT_PUBLIC_API_URL=http://localhost:3000 npm run dev # Alternatively, you can create an .env file with it: NEXT_PUBLIC_API_URL=http://localhost:3000 -``` +\``` -Open [http://localhost:3002/](http://localhost:3002). If you see the dashboard, congrats! It's all up and running correctly. -image +Open [http://localhost:3002/](http://localhost:3002). If you see the dashboard, ๐ŸŽ‰ congrats! It's all up and running correctly. +![Dashboard Image](https://user-images.githubusercontent.com/13384559/224318056-3d2c68bc-aa56-49c8-841a-bb297e380dc9.png) -If you get an error page such as this, please refer to the logs and our [docs](https://docs.komiser.io/docs/introduction/getting-started). -image +โ— If you get an error page such as this, please refer to the logs and our [docs](https://docs.komiser.io/docs/introduction/getting-started). +![Error Image](https://user-images.githubusercontent.com/13384559/224320642-0bf6814b-d97a-4ad9-95a0-ca82e353c5d0.png) -## Components +## ๐Ÿงฉ Components Komiser components are documented under `/components` -Component convention: - -- Component folder: component name in `kebab-case` -- Component file: component name in `UpperCamelCase.*` -- Component story: component name in `UpperCamelCase.stories.*` -- Component story mock (if needed): component name in `UpperCamelCase.mocks.*` -- Component unit test: component name in `UpperCamelCase.test.*` -- Check `Card` example for more details: - -image - -Additional instructions: - -- To view this component on Storybook, run: `npm run storybook`, then pick `Card` - image - -- To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` - image - -## Testing +> ๐Ÿ’ก **Hint:** +> We have the following import aliases defined in `tsconfig.json` +\``` +{ +"@components/": "/dashboard/components/", +"@services/": "/dashboard/services/", +"@environments/": "/dashboard/environments/", +"@utils/": "/dashboard/utils/", +"@styles/": "/dashboard/styles/" +} +\``` + +**Component convention:** +- ๐Ÿ“ Component folder: component name in `kebab-case` +- ๐Ÿ“„ Component file: component name in `UpperCamelCase.*` +- ๐Ÿ“– Component story: component name in `UpperCamelCase.stories.*` +- ๐ŸŽญ Component story mock (if needed): component name in `UpperCamelCase.mocks.*` +- ๐Ÿงช Component unit test: component name in `UpperCamelCase.test.*` +- ๐Ÿง Check `Card` example for more details: +![Component Example](https://user-images.githubusercontent.com/13384559/224307211-2ce62245-de24-4ee7-a156-fb54d8d34b4f.png) + +**Additional instructions:** +- ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` +![Storybook Image](https://user-images.githubusercontent.com/13384559/224320112-e21d2ed4-1e22-4a33-adb3-6c236c4d4208.png) +- ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` +![Unit Test Image](https://user-images.githubusercontent.com/13384559/224320260-19b1359e-1bfb-4db5-8379-918dacd7da44.png) + +## ๐Ÿงช Testing We use Jest & React Testing Library for our unit tests. -Testing convention: - -- All tests should be wrapped in a `describe` -- If it's a unit test for a function: `describe('functionName outputs', () => { ... })` -- If it's a unit test for a component: `describe('Component Name', () => { ... })` -- A test should use 'it' for the test function: `it('should do something', () => { ... })` +**Testing convention:** +- โœ… All new Utils need to be tested. Existing ones when being changed +- โœ… All tests should be wrapped in a `describe` +- โœ… If it's a unit test for a function: `describe('[replace with function name]', () => { ... })` +- โœ… If it's a unit test for a util: `describe('[replace with util name] util', () => { ... })` +- โœ… If it's a unit test for a component: `describe('[replace with component name]', () => { ... })` +- โœ… A test should use 'it' for the test function: `it('should do something', () => { ... })` -Testing examples: +**Testing examples:** - Simple Jest unit test example (snippet from `/utils/formatNumber.test.ts`): -```Typescript +\``` import formatNumber from './formatNumber'; -describe('formatNumber outputs', () => { +describe('formatNumber util', () => { it('should format number (over a thousand) in short notation', () => { const result = formatNumber(12345); expect(result).toBe('12K'); @@ -73,11 +90,11 @@ describe('formatNumber outputs', () => { ... }); -``` +\``` - Jest & Testing library example (snippet from `/components/card/Card.test.tsx`): -```Typescript +\``` import { render, screen } from '@testing-library/react'; import RefreshIcon from '../icons/RefreshIcon'; import Card from './Card'; @@ -108,21 +125,39 @@ describe('Card', () => { ... }); -``` +\``` + +If you're looking for an example with event firing and state updates, have a look at `components/select-checkbox/SelectCheckbox.test.tsx`: +\``` +it('opens the dropdown when clicked', () => { + const { getByRole, getByText } = render( + {}} + /> + ); + + fireEvent.click(getByRole('button')); + + expect(getByText('Item 1')).toBeInTheDocument(); + expect(getByText('Item 2')).toBeInTheDocument(); + expect(getByText('Item 3')).toBeInTheDocument(); +}); +\``` -## Contributing +## ๐Ÿค Contributing We welcome all contributors to join us on the mission of improving Komiser, especially when it comes to writing tests and adding documentation. Not sure where to start? +- ๐Ÿ“– Read the [contributor guidelines](https://docs.komiser.io/docs/introduction/community) +- ๐Ÿ’ฌ [Join our Discord](https://discord.tailwarden.com/) and hang with us on #contributors channel. -- Read the [contributor guidelines](https://docs.komiser.io/docs/introduction/community) -- [Join our Discord](https://discord.tailwarden.com/) and hang with us on #contributors channel. - -## Learn More +## ๐Ÿ“š Learn More To learn more about our stack, take a look at the following resources: - - [Next.js documentation](https://nextjs.org/docs) - learn about Next.js features and API. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - [Tailwind documentation](https://tailwindcss.com/docs/) @@ -130,6 +165,6 @@ To learn more about our stack, take a look at the following resources: - [Jest documentation](https://jestjs.io/docs/getting-started) - [React testing library documentation](https://testing-library.com/docs/dom-testing-library/intro) -## Walkthrough video +## ๐ŸŽฅ Walkthrough video [![Watch the video](https://komiser-assets-cdn.s3.eu-central-1.amazonaws.com/images/dashboard-contrib-video-thumb.png)](https://www.youtube.com/watch?v=uwxj11-eRt8) diff --git a/dashboard/tsconfig.json b/dashboard/tsconfig.json index a5e48f892..15d7d31d3 100644 --- a/dashboard/tsconfig.json +++ b/dashboard/tsconfig.json @@ -21,7 +21,12 @@ "@environments/*": ["environments/*"], "@utils/*": ["utils/*"], "@styles/*": ["styles/*"] - } + }, + "plugins": [ + { + "name": "next" + } + ] }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] diff --git a/dashboard/utils/formatNumber.test.ts b/dashboard/utils/formatNumber.test.ts index 33bd449f6..ff7add422 100644 --- a/dashboard/utils/formatNumber.test.ts +++ b/dashboard/utils/formatNumber.test.ts @@ -1,6 +1,6 @@ import formatNumber from './formatNumber'; -describe('formatNumber outputs', () => { +describe('formatNumber util', () => { it('should format number (over a thousand) in short notation', () => { const result = formatNumber(12345); expect(result).toBe('12K'); diff --git a/dashboard/utils/regex.test.ts b/dashboard/utils/regex.test.ts index c6b279f1a..8466d9f6a 100644 --- a/dashboard/utils/regex.test.ts +++ b/dashboard/utils/regex.test.ts @@ -1,6 +1,6 @@ import regex, { required } from './regex'; -describe('regex outputs', () => { +describe('regex util', () => { it('should return the required regex', () => { const result = required; expect(result).toStrictEqual(/./); From b950b029117ea304e31310f7d7b40f82689f6a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:45:06 +0200 Subject: [PATCH 12/34] fix: fix code blocks --- dashboard/README.md | 76 ++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index f8340a486..c17f1c503 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -3,6 +3,7 @@ Komiser dashboard is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). **Full frontend stack:** + - ๐Ÿ–ฅ `Next.js` - ๐Ÿ“œ `Typescript` - ๐ŸŽจ `Tailwind` @@ -14,16 +15,20 @@ Komiser dashboard is a [Next.js](https://nextjs.org/) project bootstrapped with First, run the development server: -\``` +```shell + # From the Komiser root folder start the Komiser server, run: -go run *.go start --config /path/to/config.toml + +go run \*.go start --config /path/to/config.toml # In a different terminal tab in the dashboard folder, run: + NEXT_PUBLIC_API_URL=http://localhost:3000 npm run dev # Alternatively, you can create an .env file with it: + NEXT_PUBLIC_API_URL=http://localhost:3000 -\``` +``` Open [http://localhost:3002/](http://localhost:3002). If you see the dashboard, ๐ŸŽ‰ congrats! It's all up and running correctly. ![Dashboard Image](https://user-images.githubusercontent.com/13384559/224318056-3d2c68bc-aa56-49c8-841a-bb297e380dc9.png) @@ -37,36 +42,39 @@ Komiser components are documented under `/components` > ๐Ÿ’ก **Hint:** > We have the following import aliases defined in `tsconfig.json` -\``` -{ -"@components/": "/dashboard/components/", -"@services/": "/dashboard/services/", -"@environments/": "/dashboard/environments/", -"@utils/": "/dashboard/utils/", -"@styles/": "/dashboard/styles/" -} -\``` +> ```json +> { +> "@components/": "/dashboard/components/", +> "@services/": "/dashboard/services/", +> "@environments/": "/dashboard/environments/", +> "@utils/": "/dashboard/utils/", +> "@styles/": "/dashboard/styles/" +> } +> ``` **Component convention:** + - ๐Ÿ“ Component folder: component name in `kebab-case` - ๐Ÿ“„ Component file: component name in `UpperCamelCase.*` - ๐Ÿ“– Component story: component name in `UpperCamelCase.stories.*` - ๐ŸŽญ Component story mock (if needed): component name in `UpperCamelCase.mocks.*` - ๐Ÿงช Component unit test: component name in `UpperCamelCase.test.*` - ๐Ÿง Check `Card` example for more details: -![Component Example](https://user-images.githubusercontent.com/13384559/224307211-2ce62245-de24-4ee7-a156-fb54d8d34b4f.png) + ![Component Example](https://user-images.githubusercontent.com/13384559/224307211-2ce62245-de24-4ee7-a156-fb54d8d34b4f.png) **Additional instructions:** + - ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` -![Storybook Image](https://user-images.githubusercontent.com/13384559/224320112-e21d2ed4-1e22-4a33-adb3-6c236c4d4208.png) + ![Storybook Image](https://user-images.githubusercontent.com/13384559/224320112-e21d2ed4-1e22-4a33-adb3-6c236c4d4208.png) - ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` -![Unit Test Image](https://user-images.githubusercontent.com/13384559/224320260-19b1359e-1bfb-4db5-8379-918dacd7da44.png) + ![Unit Test Image](https://user-images.githubusercontent.com/13384559/224320260-19b1359e-1bfb-4db5-8379-918dacd7da44.png) ## ๐Ÿงช Testing We use Jest & React Testing Library for our unit tests. **Testing convention:** + - โœ… All new Utils need to be tested. Existing ones when being changed - โœ… All tests should be wrapped in a `describe` - โœ… If it's a unit test for a function: `describe('[replace with function name]', () => { ... })` @@ -78,7 +86,7 @@ We use Jest & React Testing Library for our unit tests. - Simple Jest unit test example (snippet from `/utils/formatNumber.test.ts`): -\``` +```typescript import formatNumber from './formatNumber'; describe('formatNumber util', () => { @@ -86,15 +94,13 @@ describe('formatNumber util', () => { const result = formatNumber(12345); expect(result).toBe('12K'); }); - ... - }); -\``` +``` - Jest & Testing library example (snippet from `/components/card/Card.test.tsx`): -\``` +```typescript import { render, screen } from '@testing-library/react'; import RefreshIcon from '../icons/RefreshIcon'; import Card from './Card'; @@ -103,9 +109,9 @@ describe('Card', () => { it('should render card component without crashing', () => { render( } + label="Test card" + value={500} + icon={} /> ); }); @@ -113,29 +119,27 @@ describe('Card', () => { it('should display the value formatted', () => { render( } + label="Test card" + value={5000} + icon={} /> ); const formattedNumber = screen.getByTestId('formattedNumber'); expect(formattedNumber).toHaveTextContent('5K'); }); - ... - }); -\``` +``` If you're looking for an example with event firing and state updates, have a look at `components/select-checkbox/SelectCheckbox.test.tsx`: -\``` +```typescript it('opens the dropdown when clicked', () => { const { getByRole, getByText } = render( {}} + label="Test Label" + query="provider" + exclude={[]} + setExclude={() => {}} /> ); @@ -145,19 +149,21 @@ it('opens the dropdown when clicked', () => { expect(getByText('Item 2')).toBeInTheDocument(); expect(getByText('Item 3')).toBeInTheDocument(); }); -\``` +``` ## ๐Ÿค Contributing We welcome all contributors to join us on the mission of improving Komiser, especially when it comes to writing tests and adding documentation. Not sure where to start? + - ๐Ÿ“– Read the [contributor guidelines](https://docs.komiser.io/docs/introduction/community) - ๐Ÿ’ฌ [Join our Discord](https://discord.tailwarden.com/) and hang with us on #contributors channel. ## ๐Ÿ“š Learn More To learn more about our stack, take a look at the following resources: + - [Next.js documentation](https://nextjs.org/docs) - learn about Next.js features and API. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - [Tailwind documentation](https://tailwindcss.com/docs/) From 314fbee352061ffd8feaa97e9a015de8f277bd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:03:04 +0200 Subject: [PATCH 13/34] fix: fix code blocks --- dashboard/README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index ec0690013..9bd70ba70 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -38,20 +38,20 @@ Open [http://localhost:3002/](http://localhost:3002). If you see the dashboard, โ— If you get an error page such as this, please refer to the logs and our [docs](https://docs.komiser.io/docs/introduction/getting-started). ![Error Image](https://user-images.githubusercontent.com/13384559/224320642-0bf6814b-d97a-4ad9-95a0-ca82e353c5d0.png) - ## ๐Ÿงฉ Components Komiser components are documented under `/components` > ๐Ÿ’ก **Hint:** > We have the following import aliases defined in `tsconfig.json` +> > ```json > { -> "@components/": "/dashboard/components/", -> "@services/": "/dashboard/services/", -> "@environments/": "/dashboard/environments/", -> "@utils/": "/dashboard/utils/", -> "@styles/": "/dashboard/styles/" +> "@components/": "/dashboard/components/", +> "@services/": "/dashboard/services/", +> "@environments/": "/dashboard/environments/", +> "@utils/": "/dashboard/utils/", +> "@styles/": "/dashboard/styles/" > } > ``` @@ -86,7 +86,6 @@ We use Jest & React Testing Library for our unit tests. - To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` image - **Testing convention:** - โœ… All new Utils need to be tested. Existing ones when being changed @@ -146,14 +145,15 @@ describe('Card', () => { ``` If you're looking for an example with event firing and state updates, have a look at `components/select-checkbox/SelectCheckbox.test.tsx`: + ```typescript it('opens the dropdown when clicked', () => { const { getByRole, getByText } = render( {}} + label="Test Label" + query="provider" + exclude={[]} + setExclude={() => {}} /> ); @@ -248,7 +248,6 @@ export default { > Remember: Storybook is not just a tool but also a way to document components. Ensure you provide meaningful names, descriptions, and use cases to help other developers understand the use and purpose of each component. - ## ๐Ÿค Contributing We welcome all contributors to join us on the mission of improving Komiser, especially when it comes to writing tests and adding documentation. From 5cffd04820fd4539857fcf03019cef60a1418db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:05:06 +0200 Subject: [PATCH 14/34] fix: remove doubles headlines --- dashboard/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index 9bd70ba70..7442804d5 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -58,8 +58,6 @@ Komiser components are documented under `/components` You can find all the shared Components also inside [Storybook](https://storybook.komiser.io/). If you're implementing a new Story, please check for existing or new components with Storybook. We will require a story for new shared components like icons, inputs or similar. -Component convention: - **Component convention:** - ๐Ÿ“ Component folder: component name in `kebab-case` From c35faf16c21bea68c7fc737d2f0ffc31db634012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 19:08:27 +0200 Subject: [PATCH 15/34] fix: adress review comments --- dashboard/README.md | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index 7442804d5..0c43f547b 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -15,28 +15,39 @@ Komiser dashboard is a [Next.js](https://nextjs.org/) project bootstrapped with Follow the [Contribution Guide](https://github.com/tailwarden/komiser/blob/develop/CONTRIBUTING.md#contributing-to-komiser-dashboard-ui) first if you haven't done so already. Then come back here and follow the next steps: -1. Run the development server: +#### 1. Run the development server: +From the Komiser root folder start the Komiser server by running: ```shell +go run \*.go start --config /path/to/config.toml +``` -# From the Komiser root folder start the Komiser server, run: +In a different terminal tab navigate to the `/dashboard` folder: +```shell +cd dashboard +``` -go run \*.go start --config /path/to/config.toml +and run: -# In a different terminal tab in the dashboard folder, run: +```shell +npm install NEXT_PUBLIC_API_URL=http://localhost:3000 npm run dev +``` -# Alternatively, you can create an .env file with it: - -NEXT_PUBLIC_API_URL=http://localhost:3000 +Alternatively, you can create an .env file with it, either manually or by running: +```shell +echo "NEXT_PUBLIC_API_URL=http://localhost:3000" > .env +``` +and simply run: +```shell +npm run dev ``` -Open [http://localhost:3002/](http://localhost:3002). If you see the dashboard, ๐ŸŽ‰ congrats! It's all up and running correctly. -![Dashboard Image](https://user-images.githubusercontent.com/13384559/224318056-3d2c68bc-aa56-49c8-841a-bb297e380dc9.png) +#### 2. Open [http://localhost:3002/](http://localhost:3002). If you see the dashboard, ๐ŸŽ‰ congrats! It's all up and running correctly. โ— If you get an error page such as this, please refer to the logs and our [docs](https://docs.komiser.io/docs/introduction/getting-started). -![Error Image](https://user-images.githubusercontent.com/13384559/224320642-0bf6814b-d97a-4ad9-95a0-ca82e353c5d0.png) +Error Image ## ๐Ÿงฉ Components @@ -67,22 +78,22 @@ We will require a story for new shared components like icons, inputs or similar. - ๐Ÿงช Component unit test: component name in `UpperCamelCase.test.*` - ๐Ÿง Check `Card` example for more details: - ![Component Example](https://user-images.githubusercontent.com/13384559/224307211-2ce62245-de24-4ee7-a156-fb54d8d34b4f.png) + Component Example **Additional instructions:** - ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` - ![Storybook Image](https://user-images.githubusercontent.com/13384559/224320112-e21d2ed4-1e22-4a33-adb3-6c236c4d4208.png) + Storybook Image - ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` - ![Unit Test Image](https://user-images.githubusercontent.com/13384559/224320260-19b1359e-1bfb-4db5-8379-918dacd7da44.png) + Unit Test Image ## ๐Ÿงช Testing We use Jest & React Testing Library for our unit tests. - To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` - image + image **Testing convention:** @@ -168,7 +179,7 @@ it('opens the dropdown when clicked', () => { [**Storybook**](https://storybook.komiser.io/) is a tool for UI development. It makes development faster by isolating components. This allows you to work on one component at a time. If you create a new shared component or want to visualize variations of an existing one, follow these steps: - To view this component on Storybook locally, run: `npm run storybook`, then pick an example (`Card`) or your new component story - image + image ### 1. **Create the Story**: From 402cfb4fd48a336682f2325edae4763b5ea78fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 19:13:00 +0200 Subject: [PATCH 16/34] fix: adress review comments --- dashboard/README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index 0c43f547b..b28d53070 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -18,11 +18,13 @@ Follow the [Contribution Guide](https://github.com/tailwarden/komiser/blob/devel #### 1. Run the development server: From the Komiser root folder start the Komiser server by running: + ```shell go run \*.go start --config /path/to/config.toml ``` In a different terminal tab navigate to the `/dashboard` folder: + ```shell cd dashboard ``` @@ -36,10 +38,13 @@ NEXT_PUBLIC_API_URL=http://localhost:3000 npm run dev ``` Alternatively, you can create an .env file with it, either manually or by running: + ```shell echo "NEXT_PUBLIC_API_URL=http://localhost:3000" > .env ``` + and simply run: + ```shell npm run dev ``` @@ -92,8 +97,7 @@ We will require a story for new shared components like icons, inputs or similar. We use Jest & React Testing Library for our unit tests. -- To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` - image +- To run the unit tests, run: `npm run test` **Testing convention:** From 5f654cc61ee083f70a8d4121caa5e52ac1cc4d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 19:28:36 +0200 Subject: [PATCH 17/34] fix: adress review comments --- dashboard/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/README.md b/dashboard/README.md index b28d53070..b62154269 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -88,9 +88,9 @@ We will require a story for new shared components like icons, inputs or similar. **Additional instructions:** - ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` + Storybook Image - ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` - Unit Test Image ## ๐Ÿงช Testing From 664a59ccac742b2eb8d7d58c02a82e53e8c06af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 20:02:46 +0200 Subject: [PATCH 18/34] fix: adress review comments --- dashboard/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dashboard/README.md b/dashboard/README.md index b62154269..e6a307ac8 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -88,7 +88,6 @@ We will require a story for new shared components like icons, inputs or similar. **Additional instructions:** - ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` - Storybook Image - ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` Unit Test Image @@ -183,7 +182,7 @@ it('opens the dropdown when clicked', () => { [**Storybook**](https://storybook.komiser.io/) is a tool for UI development. It makes development faster by isolating components. This allows you to work on one component at a time. If you create a new shared component or want to visualize variations of an existing one, follow these steps: - To view this component on Storybook locally, run: `npm run storybook`, then pick an example (`Card`) or your new component story - image +image ### 1. **Create the Story**: From 4648409fa4570460fe821a9b40b9fe425fd3c2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 20:03:53 +0200 Subject: [PATCH 19/34] fix: adress review comments --- dashboard/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dashboard/README.md b/dashboard/README.md index e6a307ac8..7af0d8de8 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -88,8 +88,10 @@ We will require a story for new shared components like icons, inputs or similar. **Additional instructions:** - ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` + Storybook Image - ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` + Unit Test Image ## ๐Ÿงช Testing @@ -182,7 +184,7 @@ it('opens the dropdown when clicked', () => { [**Storybook**](https://storybook.komiser.io/) is a tool for UI development. It makes development faster by isolating components. This allows you to work on one component at a time. If you create a new shared component or want to visualize variations of an existing one, follow these steps: - To view this component on Storybook locally, run: `npm run storybook`, then pick an example (`Card`) or your new component story -image + image ### 1. **Create the Story**: From 36055d3c83aa31d721c77468d09ff1fc571f7223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6sel?= <320272+Traxmaxx@users.noreply.github.com> Date: Mon, 16 Oct 2023 20:04:59 +0200 Subject: [PATCH 20/34] fix: adress review comments --- dashboard/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dashboard/README.md b/dashboard/README.md index 7af0d8de8..1b423fcb3 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -90,6 +90,7 @@ We will require a story for new shared components like icons, inputs or similar. - ๐Ÿ“– To view this component on Storybook, run: `npm run storybook`, then pick `Card` Storybook Image + - ๐Ÿงช To run the unit tests, run: `npm run test:watch`, hit `p`, then `card` Unit Test Image @@ -184,6 +185,7 @@ it('opens the dropdown when clicked', () => { [**Storybook**](https://storybook.komiser.io/) is a tool for UI development. It makes development faster by isolating components. This allows you to work on one component at a time. If you create a new shared component or want to visualize variations of an existing one, follow these steps: - To view this component on Storybook locally, run: `npm run storybook`, then pick an example (`Card`) or your new component story + image ### 1. **Create the Story**: From 3163755857951b90dfa16a108e05d3a9c540612c Mon Sep 17 00:00:00 2001 From: Azanul Date: Mon, 16 Oct 2023 23:46:57 +0530 Subject: [PATCH 21/34] fix: golangci lint Signed-off-by: Azanul --- .github/workflows/lint.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dffddfc31..c0213f7fd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,6 +1,5 @@ name: Lint -on: - push: +on: pull_request jobs: lint: @@ -8,10 +7,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - name: Setup go uses: actions/setup-go@v4 with: go-version-file: go.mod + - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: From 8a86970acf038e42f1a9e5146a36f8d08c93f54e Mon Sep 17 00:00:00 2001 From: Azanul Date: Tue, 17 Oct 2023 00:28:34 +0530 Subject: [PATCH 22/34] fix: golangci lint Signed-off-by: Azanul --- .github/workflows/lint.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c0213f7fd..b12288514 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,4 +17,5 @@ jobs: uses: golangci/golangci-lint-action@v3 with: args: --timeout=10m - version: v1.54.2 \ No newline at end of file + version: v1.54.2 + skip-pkg-cache: true \ No newline at end of file From a7caa3259ca0d3a95584600a6c5d142687086e58 Mon Sep 17 00:00:00 2001 From: jbleduigou Date: Mon, 16 Oct 2023 21:33:28 +0200 Subject: [PATCH 23/34] feat: retrieve tags of Kinesis Data Streams --- providers/aws/kinesis/streams.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/providers/aws/kinesis/streams.go b/providers/aws/kinesis/streams.go index de718e6d4..e7306e5cd 100644 --- a/providers/aws/kinesis/streams.go +++ b/providers/aws/kinesis/streams.go @@ -30,6 +30,18 @@ func Streams(ctx context.Context, client ProviderClient) ([]Resource, error) { } for _, stream := range output.StreamSummaries { + tags := make([]Tag, 0) + tagsResp, err := kinesisClient.ListTagsForStream(context.Background(), &kinesis.ListTagsForStreamInput{ + StreamARN: stream.StreamARN, + }) + if err == nil { + for _, t := range tagsResp.Tags { + tags = append(tags, Tag{ + Key: aws.ToString(t.Key), + Value: aws.ToString(t.Value), + }) + } + } resources = append(resources, Resource{ Provider: "AWS", Account: client.Name, @@ -40,6 +52,7 @@ func Streams(ctx context.Context, client ProviderClient) ([]Resource, error) { Cost: 0, CreatedAt: *stream.StreamCreationTimestamp, FetchedAt: time.Now(), + Tags: tags, Link: fmt.Sprintf("https://%s.console.aws.amazon.com/kinesis/home?region=%s#/streams/details/%s", client.AWSClient.Region, client.AWSClient.Region, *stream.StreamName), }) consumers, err := getStreamConsumers(ctx, kinesisClient, stream, client.Name, client.AWSClient.Region) From 37b1262444d611ab9298515e6cf061da499ac74e Mon Sep 17 00:00:00 2001 From: ShubhamPalriwala Date: Tue, 17 Oct 2023 09:46:07 +0530 Subject: [PATCH 24/34] feat: integrate formbricks in-app survey --- dashboard/package-lock.json | 246 ++++++++++++++++++------------------ dashboard/package.json | 1 + dashboard/pages/_app.tsx | 19 +++ 3 files changed, 146 insertions(+), 120 deletions(-) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index ce948cb7f..b91a54122 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -8,6 +8,7 @@ "name": "komiser-dashboard", "version": "3.1.0", "dependencies": { + "@formbricks/js": "^1.1.2", "@sentry/react": "^7.41.0", "@sentry/tracing": "^7.41.0", "@tippyjs/react": "^4.2.6", @@ -2934,6 +2935,11 @@ "integrity": "sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==", "dev": true }, + "node_modules/@formbricks/js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@formbricks/js/-/js-1.1.2.tgz", + "integrity": "sha512-1dz7pAFEykERzJXaAuqO0PkG7Fj+4Zbj3SNOxdorVRU/O6O3GtyCx56/LXT7DVX+dOEhZttDt56o+j/hDmGnyw==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -3575,6 +3581,126 @@ "node": ">= 10" } }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", + "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", + "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", + "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", + "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", + "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", + "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", + "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", + "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -23985,126 +24111,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", - "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", - "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", - "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", - "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", - "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", - "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", - "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", - "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } } } diff --git a/dashboard/package.json b/dashboard/package.json index bce604520..524ca343d 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -14,6 +14,7 @@ "test:watch": "jest --watch" }, "dependencies": { + "@formbricks/js": "^1.1.2", "@sentry/react": "^7.41.0", "@sentry/tracing": "^7.41.0", "@tippyjs/react": "^4.2.6", diff --git a/dashboard/pages/_app.tsx b/dashboard/pages/_app.tsx index c891d30d9..3ac787fa8 100644 --- a/dashboard/pages/_app.tsx +++ b/dashboard/pages/_app.tsx @@ -1,5 +1,8 @@ import '../styles/globals.css'; import type { AppProps } from 'next/app'; +import formbricks from '@formbricks/js'; +import { useRouter } from 'next/router'; +import { useEffect } from 'react'; import Layout from '../components/layout/Layout'; const printHiringMessage = () => { @@ -22,9 +25,25 @@ const printHiringMessage = () => { if (typeof window !== 'undefined') { printHiringMessage(); + formbricks.init({ + environmentId: 'clnmmpeg01ci3o50fu5wy89zn', + apiHost: 'https://app.formbricks.com', + debug: true // remove when in production + }); } export default function App({ Component, pageProps }: AppProps) { + const router = useRouter(); + + useEffect(() => { + // Connect next.js router to Formbricks + const handleRouteChange = formbricks?.registerRouteChange; + router.events.on('routeChangeComplete', handleRouteChange); + + return () => { + router.events.off('routeChangeComplete', handleRouteChange); + }; + }, []); return ( From 2a6c587da57c9478d2a095db0b5ffd4937c7ea3b Mon Sep 17 00:00:00 2001 From: Shubham Palriwala Date: Tue, 17 Oct 2023 09:52:28 +0530 Subject: [PATCH 25/34] fix: make formbricks debug false --- dashboard/pages/_app.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/pages/_app.tsx b/dashboard/pages/_app.tsx index 3ac787fa8..56a29b068 100644 --- a/dashboard/pages/_app.tsx +++ b/dashboard/pages/_app.tsx @@ -28,7 +28,7 @@ if (typeof window !== 'undefined') { formbricks.init({ environmentId: 'clnmmpeg01ci3o50fu5wy89zn', apiHost: 'https://app.formbricks.com', - debug: true // remove when in production + debug: false // remove when in production }); } From 25c9c28dd2fe2fd93c02c875d9173b0831bf71a7 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Le Duigou Date: Tue, 17 Oct 2023 07:33:58 +0200 Subject: [PATCH 26/34] fix: log message when failed to retrieve tags Co-authored-by: Azanul Haque <42029519+Azanul@users.noreply.github.com> --- providers/aws/kinesis/streams.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/providers/aws/kinesis/streams.go b/providers/aws/kinesis/streams.go index e7306e5cd..6052ba3ae 100644 --- a/providers/aws/kinesis/streams.go +++ b/providers/aws/kinesis/streams.go @@ -41,6 +41,8 @@ func Streams(ctx context.Context, client ProviderClient) ([]Resource, error) { Value: aws.ToString(t.Value), }) } + } else { + log.Warn("Failed to fetch tags for kinesis streams") } resources = append(resources, Resource{ Provider: "AWS", From 8ce39e9f87699c0e553f9f7389bfc12e0d728617 Mon Sep 17 00:00:00 2001 From: LABOUARDY Mohamed Date: Tue, 17 Oct 2023 09:27:14 +0200 Subject: [PATCH 27/34] include ph badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce3a84c85..39dcc3ed1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ --- -

Amp Logo

+

Amp Logo

Komiser is an open-source cloud-agnostic resource manager designed to analyze and manage cloud cost, usage, security, and governance all in one place. It integrates seamlessly with multiple cloud providers, including AWS, Azure, Civo, Digital Ocean, OCI, Linode, Tencent, Scaleway and [more](#supported-cloud-providers). Interested? read more about Komiser on our [website](https://komiser.io?utm_source=github&utm_medium=social). From 6b7b3d29c6c7fca22cf780536ba946c57e3d1f19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:24:42 +0000 Subject: [PATCH 28/34] chore(deps-dev): bump @storybook/addons in /dashboard Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/code/deprecated/addons) from 7.4.3 to 7.4.6. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v7.4.6/code/deprecated/addons) --- updated-dependencies: - dependency-name: "@storybook/addons" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dashboard/package-lock.json | 383 +++++++++++++++++++++++------------- dashboard/package.json | 2 +- 2 files changed, 244 insertions(+), 141 deletions(-) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index ce948cb7f..278859860 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -35,7 +35,7 @@ "@storybook/addon-essentials": "^7.4.6", "@storybook/addon-interactions": "^7.0.0-beta.52", "@storybook/addon-links": "^7.0.0-beta.52", - "@storybook/addons": "^7.0.0-beta.52", + "@storybook/addons": "^7.4.6", "@storybook/blocks": "^7.4.5", "@storybook/nextjs": "^7.0.0-alpha.41", "@storybook/preview-api": "^7.4.6", @@ -3575,6 +3575,126 @@ "node": ">= 10" } }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", + "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", + "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", + "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", + "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", + "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", + "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", + "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", + "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6252,14 +6372,14 @@ } }, "node_modules/@storybook/addons": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.4.3.tgz", - "integrity": "sha512-6XvXE3sRl78MceRDAnfPd6N6j9ltMCuTITjjqU2GU8iyAexJ4bYodfKcmUmAQmixuc+6UPbWmlrQKNmBDlp3rw==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.4.6.tgz", + "integrity": "sha512-c+4awrtwNlJayFdgLkEXa5H2Gj+KNlxuN+Z5oDAdZBLqXI8g0gn7eYO2F/eCSIDWdd/+zcU2uq57XPFKc8veHQ==", "dev": true, "dependencies": { - "@storybook/manager-api": "7.4.3", - "@storybook/preview-api": "7.4.3", - "@storybook/types": "7.4.3" + "@storybook/manager-api": "7.4.6", + "@storybook/preview-api": "7.4.6", + "@storybook/types": "7.4.6" }, "funding": { "type": "opencollective", @@ -6270,26 +6390,110 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@storybook/addons/node_modules/@storybook/preview-api": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.4.3.tgz", - "integrity": "sha512-qKwfH2+qN1Zpz2UX6dQLiTU5x2JH3o/+jOY4GYF6c3atTm5WAu1OvCYAJVb6MdXfAhZNuPwDKnJR8VmzWplWBg==", + "node_modules/@storybook/addons/node_modules/@storybook/channels": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.4.6.tgz", + "integrity": "sha512-yPv/sfo2c18fM3fvG0i1xse63vG8l33Al/OU0k/dtovltPu001/HVa1QgBgsb/QrEfZtvGjGhmtdVeYb39fv3A==", "dev": true, "dependencies": { - "@storybook/channels": "7.4.3", - "@storybook/client-logger": "7.4.3", - "@storybook/core-events": "7.4.3", + "@storybook/client-logger": "7.4.6", + "@storybook/core-events": "7.4.6", + "@storybook/global": "^5.0.0", + "qs": "^6.10.0", + "telejson": "^7.2.0", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addons/node_modules/@storybook/client-logger": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.4.6.tgz", + "integrity": "sha512-XDw31ZziU//86PKuMRnmc+L/G0VopaGKENQOGEpvAXCU9IZASwGKlKAtcyosjrpi+ZiUXlMgUXCpXM7x3b1Ehw==", + "dev": true, + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addons/node_modules/@storybook/core-events": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.4.6.tgz", + "integrity": "sha512-r5vrE+32lwrJh1NGFr1a0mWjvxo7q8FXYShylcwRWpacmL5NTtLkrXOoJSeGvJ4yKNYkvxQFtOPId4lzDxa32w==", + "dev": true, + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addons/node_modules/@storybook/manager-api": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.4.6.tgz", + "integrity": "sha512-inrm3DIbCp8wjXSN/wK6e6i2ysQ/IEmtC7IN0OJ7vdrp+USCooPT448SQTUmVctUGCFmOU3fxXByq8g77oIi7w==", + "dev": true, + "dependencies": { + "@storybook/channels": "7.4.6", + "@storybook/client-logger": "7.4.6", + "@storybook/core-events": "7.4.6", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/types": "7.4.3", - "@types/qs": "^6.9.5", + "@storybook/router": "7.4.6", + "@storybook/theming": "7.4.6", + "@storybook/types": "7.4.6", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "synchronous-promise": "^2.0.15", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" + "semver": "^7.3.7", + "store2": "^2.14.2", + "telejson": "^7.2.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addons/node_modules/@storybook/router": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.4.6.tgz", + "integrity": "sha512-Vl1esrHkcHxDKqc+HY7+6JQpBPW3zYvGk0cQ2rxVMhWdLZTAz1hss9DqzN9tFnPyfn0a1Q77EpMySkUrvWKKNQ==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "7.4.6", + "memoizerific": "^1.11.3", + "qs": "^6.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addons/node_modules/@storybook/types": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.4.6.tgz", + "integrity": "sha512-6QLXtMVsFZFpzPkdGWsu/iuc8na9dnS67AMOBKm5qCLPwtUJOYkwhMdFRSSeJthLRpzV7JLAL8Kwvl7MFP3QSw==", + "dev": true, + "dependencies": { + "@storybook/channels": "7.4.6", + "@types/babel__core": "^7.0.0", + "@types/express": "^4.7.0", + "file-system-cache": "2.3.0" }, "funding": { "type": "opencollective", @@ -6744,6 +6948,25 @@ } } }, + "node_modules/@storybook/builder-webpack5/node_modules/@storybook/addons": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.4.3.tgz", + "integrity": "sha512-6XvXE3sRl78MceRDAnfPd6N6j9ltMCuTITjjqU2GU8iyAexJ4bYodfKcmUmAQmixuc+6UPbWmlrQKNmBDlp3rw==", + "dev": true, + "dependencies": { + "@storybook/manager-api": "7.4.3", + "@storybook/preview-api": "7.4.3", + "@storybook/types": "7.4.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@storybook/builder-webpack5/node_modules/@storybook/preview-api": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.4.3.tgz", @@ -23985,126 +24208,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", - "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", - "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", - "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", - "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", - "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", - "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", - "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", - "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } } } diff --git a/dashboard/package.json b/dashboard/package.json index 0a9667039..107a7f2e6 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -42,7 +42,7 @@ "@storybook/addon-essentials": "^7.4.6", "@storybook/addon-interactions": "^7.0.0-beta.52", "@storybook/addon-links": "^7.0.0-beta.52", - "@storybook/addons": "^7.0.0-beta.52", + "@storybook/addons": "^7.4.6", "@storybook/blocks": "^7.4.5", "@storybook/nextjs": "^7.0.0-alpha.41", "@storybook/preview-api": "^7.4.6", From 49eb3a7ab950c848d0d09f19aea76dabfc66e5bc Mon Sep 17 00:00:00 2001 From: ShubhamPalriwala Date: Tue, 17 Oct 2023 17:58:29 +0530 Subject: [PATCH 29/34] fix: shift env id to environment file --- dashboard/environments/environment.ts | 3 ++- dashboard/pages/_app.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dashboard/environments/environment.ts b/dashboard/environments/environment.ts index 1e6515876..5b3eb666e 100644 --- a/dashboard/environments/environment.ts +++ b/dashboard/environments/environment.ts @@ -5,7 +5,8 @@ const environment = { : '', GA_TRACKING_ID: 'G-9HF3HT6S6W', SENTRY_URL: - 'https://b4b98ad60a89468284cf8aa5d66cf2cd@o1267000.ingest.sentry.io/4504797672701952' + 'https://b4b98ad60a89468284cf8aa5d66cf2cd@o1267000.ingest.sentry.io/4504797672701952', + FORMBRICKS_ENV_ID: 'clnmmpeg01ci3o50fu5wy89zn' }; export default environment; diff --git a/dashboard/pages/_app.tsx b/dashboard/pages/_app.tsx index 56a29b068..31306ed39 100644 --- a/dashboard/pages/_app.tsx +++ b/dashboard/pages/_app.tsx @@ -4,6 +4,7 @@ import formbricks from '@formbricks/js'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; import Layout from '../components/layout/Layout'; +import environment from '../environments/environment'; const printHiringMessage = () => { // eslint-disable-next-line no-console @@ -26,7 +27,7 @@ const printHiringMessage = () => { if (typeof window !== 'undefined') { printHiringMessage(); formbricks.init({ - environmentId: 'clnmmpeg01ci3o50fu5wy89zn', + environmentId: environment.FORMBRICKS_ENV_ID, apiHost: 'https://app.formbricks.com', debug: false // remove when in production }); From 1dfb814ff34eefa3f9659fa9e15888eef50d51fd Mon Sep 17 00:00:00 2001 From: Saba Shavidze Date: Wed, 18 Oct 2023 11:51:25 +0400 Subject: [PATCH 30/34] refactor: changed toast to have centrilized state management ans singleton approach --- .../feedback-widget/FeedbackWidget.tsx | 2 +- .../hooks/useInventory/useInventory.tsx | 2 +- dashboard/components/layout/Layout.tsx | 143 +++++++++--------- .../onboarding-wizard/ProviderContent.tsx | 2 +- dashboard/components/toast/Toast.tsx | 3 +- dashboard/components/toast/ToastProvider.tsx | 56 +++++++ dashboard/components/toast/hooks/useToast.tsx | 30 ---- dashboard/pages/cloud-accounts.tsx | 3 +- .../pages/onboarding/cloud-accounts/index.tsx | 3 +- .../pages/onboarding/database/postgres.tsx | 3 +- .../pages/onboarding/database/sqlite.tsx | 3 +- 11 files changed, 142 insertions(+), 108 deletions(-) create mode 100644 dashboard/components/toast/ToastProvider.tsx delete mode 100644 dashboard/components/toast/hooks/useToast.tsx diff --git a/dashboard/components/feedback-widget/FeedbackWidget.tsx b/dashboard/components/feedback-widget/FeedbackWidget.tsx index 51bf836d4..c36db5543 100644 --- a/dashboard/components/feedback-widget/FeedbackWidget.tsx +++ b/dashboard/components/feedback-widget/FeedbackWidget.tsx @@ -8,8 +8,8 @@ import Modal from '@components/modal/Modal'; import Input from '@components/input/Input'; import settingsService from '@services/settingsService'; import Button from '@components/button/Button'; -import useToast from '@components/toast/hooks/useToast'; import Toast from '@components/toast/Toast'; +import { useToast } from '@components/toast/ToastProvider'; // We define the placeholder here for convenience // It's difficult to read when passed inline diff --git a/dashboard/components/inventory/hooks/useInventory/useInventory.tsx b/dashboard/components/inventory/hooks/useInventory/useInventory.tsx index 37960eff8..2f2e12cd7 100644 --- a/dashboard/components/inventory/hooks/useInventory/useInventory.tsx +++ b/dashboard/components/inventory/hooks/useInventory/useInventory.tsx @@ -1,7 +1,7 @@ +import { useToast } from '@components/toast/ToastProvider'; import { useRouter } from 'next/router'; import { ChangeEvent, useEffect, useRef, useState } from 'react'; import settingsService from '../../../../services/settingsService'; -import useToast from '../../../toast/hooks/useToast'; import useIsVisible from '../useIsVisible/useIsVisible'; import getCustomViewInventoryListAndStats from './helpers/getCustomViewInventoryListAndStats'; import getInventoryListAndStats from './helpers/getInventoryListAndStats'; diff --git a/dashboard/components/layout/Layout.tsx b/dashboard/components/layout/Layout.tsx index b2b8f08b4..0ca6e3c3e 100644 --- a/dashboard/components/layout/Layout.tsx +++ b/dashboard/components/layout/Layout.tsx @@ -4,6 +4,7 @@ import { BrowserTracing } from '@sentry/tracing'; import { useRouter } from 'next/router'; import { ReactNode, useEffect } from 'react'; import settingsService from '@services/settingsService'; +import { ToastProvider } from '@components/toast/ToastProvider'; import environment from '../../environments/environment'; import Banner from '../banner/Banner'; import useGithubStarBanner from '../banner/hooks/useGithubStarBanner'; @@ -72,80 +73,82 @@ function Layout({ children }: LayoutProps) { betaFlagOnboardingWizard }} > - {isOnboarding && <>{children}} + + {isOnboarding && <>{children}} - {!isOnboarding && ( - <> - - -
- {canRender && children} + {!isOnboarding && ( + <> + + +
+ {canRender && children} - {hasNoAccounts && betaFlagOnboardingWizard && !isOnboarding && ( - { - router.push('/onboarding/choose-cloud'); - }} - actionLabel="Begin Onboarding" - secondaryAction={() => { - router.push( - 'https://github.com/tailwarden/komiser/issues/new/choose' - ); - }} - secondaryActionLabel="Report an issue" - mascotPose="greetings" - /> - )} + {hasNoAccounts && betaFlagOnboardingWizard && !isOnboarding && ( + { + router.push('/onboarding/choose-cloud'); + }} + actionLabel="Begin Onboarding" + secondaryAction={() => { + router.push( + 'https://github.com/tailwarden/komiser/issues/new/choose' + ); + }} + secondaryActionLabel="Report an issue" + mascotPose="greetings" + /> + )} - {/* This block would be removed when onboarding Wizard is stable leaving the block above */} - {hasNoAccounts && !betaFlagOnboardingWizard && ( - { - router.push( - 'https://docs.komiser.io/docs/introduction/getting-started?utm_source=komiser&utm_medium=referral&utm_campaign=static' - ); - }} - actionLabel="Guide to connect account" - secondaryAction={() => { - router.push( - 'https://github.com/tailwarden/komiser/issues/new/choose' - ); - }} - secondaryActionLabel="Report an issue" - mascotPose="thinking" - /> - )} - {/* This block would be removed when onboarding Wizard is stable leaving the block above */} + {/* This block would be removed when onboarding Wizard is stable leaving the block above */} + {hasNoAccounts && !betaFlagOnboardingWizard && ( + { + router.push( + 'https://docs.komiser.io/docs/introduction/getting-started?utm_source=komiser&utm_medium=referral&utm_campaign=static' + ); + }} + actionLabel="Guide to connect account" + secondaryAction={() => { + router.push( + 'https://github.com/tailwarden/komiser/issues/new/choose' + ); + }} + secondaryActionLabel="Report an issue" + mascotPose="thinking" + /> + )} + {/* This block would be removed when onboarding Wizard is stable leaving the block above */} - {error && ( - router.reload()} - > - Refresh the page - - } - /> - )} -
- - )} + {error && ( + router.reload()} + > + Refresh the page + + } + /> + )} +
+ + )} +
); } diff --git a/dashboard/components/onboarding-wizard/ProviderContent.tsx b/dashboard/components/onboarding-wizard/ProviderContent.tsx index f1d959b96..7c3dbf2ca 100644 --- a/dashboard/components/onboarding-wizard/ProviderContent.tsx +++ b/dashboard/components/onboarding-wizard/ProviderContent.tsx @@ -10,9 +10,9 @@ import OnboardingWizardLayout, { import PurplinCloud from '@components/onboarding-wizard/PurplinCloud'; import CredentialsButton from '@components/onboarding-wizard/CredentialsButton'; import Toast from '@components/toast/Toast'; -import useToast from '@components/toast/hooks/useToast'; import { Provider } from '@utils/providerHelper'; import { CloudAccountPayload } from '@components/cloud-account/hooks/useCloudAccounts/useCloudAccount'; +import { useToast } from '@components/toast/ToastProvider'; interface ChildProps { cloudAccountData?: CloudAccountPayload; diff --git a/dashboard/components/toast/Toast.tsx b/dashboard/components/toast/Toast.tsx index 6afe259f5..4d4207bb5 100644 --- a/dashboard/components/toast/Toast.tsx +++ b/dashboard/components/toast/Toast.tsx @@ -1,8 +1,9 @@ import classNames from 'classnames'; import Button from '../button/Button'; -import { ToastProps } from './hooks/useToast'; + import ErrorIcon from '../icons/ErrorIcon'; import CheckIcon from '../icons/CheckIcon'; +import { ToastProps } from './ToastProvider'; type ToastProp = ToastProps & { dismissToast: () => void; diff --git a/dashboard/components/toast/ToastProvider.tsx b/dashboard/components/toast/ToastProvider.tsx new file mode 100644 index 000000000..0a2188519 --- /dev/null +++ b/dashboard/components/toast/ToastProvider.tsx @@ -0,0 +1,56 @@ +import React, { + createContext, + useContext, + useState, + useEffect, + FC, + ReactNode, + Dispatch, + SetStateAction +} from 'react'; + +export type ToastProps = { + hasError: boolean; + title: string; + message: string; +}; + +type ToastContextType = { + setToast: Dispatch>; + dismissToast: () => void; + toast: ToastProps | null; +}; + +const ToastContext = createContext(undefined); + +export const ToastProvider: FC<{ children: ReactNode }> = ({ children }) => { + const [toast, setToast] = useState(null); + + const dismissToast = () => { + setToast(null); + }; + + useEffect(() => { + let timeout: any; + if (toast) { + timeout = setTimeout(dismissToast, 5000); + } + return () => clearTimeout(timeout); + }, [toast]); + + return ( + + {children} + + ); +}; + +export const useToast = () => { + const context = useContext(ToastContext); + + if (context === undefined) { + throw new Error('useToast must be used within a ToastProvider'); + } + + return context; +}; diff --git a/dashboard/components/toast/hooks/useToast.tsx b/dashboard/components/toast/hooks/useToast.tsx deleted file mode 100644 index 35f828355..000000000 --- a/dashboard/components/toast/hooks/useToast.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { useEffect, useState } from 'react'; - -export type ToastProps = { - hasError: boolean; - title: string; - message: string; -}; - -function useToast() { - const [toast, setToast] = useState(undefined); - - function dismissToast() { - setToast(undefined); - } - - useEffect(() => { - const timeout = setTimeout(dismissToast, 5000); - return () => { - clearTimeout(timeout); - }; - }, [toast]); - - return { - toast, - setToast, - dismissToast - }; -} - -export default useToast; diff --git a/dashboard/pages/cloud-accounts.tsx b/dashboard/pages/cloud-accounts.tsx index 8e94c263c..e5e771310 100644 --- a/dashboard/pages/cloud-accounts.tsx +++ b/dashboard/pages/cloud-accounts.tsx @@ -11,7 +11,8 @@ import CloudAccountsLayout from '@components/cloud-account/components/CloudAccou import useCloudAccount from '@components/cloud-account/hooks/useCloudAccounts/useCloudAccount'; import CloudAccountsSidePanel from '@components/cloud-account/components/CloudAccountsSidePanel'; import CloudAccountDeleteContents from '@components/cloud-account/components/CloudAccountDeleteContents'; -import useToast from '@components/toast/hooks/useToast'; +import { useToast } from '@components/toast/ToastProvider'; + import EmptyState from '@components/empty-state/EmptyState'; function CloudAccounts() { diff --git a/dashboard/pages/onboarding/cloud-accounts/index.tsx b/dashboard/pages/onboarding/cloud-accounts/index.tsx index 3959713e2..b8bad619e 100644 --- a/dashboard/pages/onboarding/cloud-accounts/index.tsx +++ b/dashboard/pages/onboarding/cloud-accounts/index.tsx @@ -13,9 +13,10 @@ import DeleteIcon from '@components/icons/DeleteIcon'; import Modal from '@components/modal/Modal'; import CloudAccountDeleteContents from '@components/cloud-account/components/CloudAccountDeleteContents'; import Toast from '@components/toast/Toast'; -import useToast from '@components/toast/hooks/useToast'; + import useCloudAccount from '@components/cloud-account/hooks/useCloudAccounts/useCloudAccount'; import Button from '@components/button/Button'; +import { useToast } from '@components/toast/ToastProvider'; export default function CloudAccounts() { const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); diff --git a/dashboard/pages/onboarding/database/postgres.tsx b/dashboard/pages/onboarding/database/postgres.tsx index ce7c342d0..54d453ee5 100644 --- a/dashboard/pages/onboarding/database/postgres.tsx +++ b/dashboard/pages/onboarding/database/postgres.tsx @@ -12,9 +12,10 @@ import LabelledInput from '@components/onboarding-wizard/LabelledInput'; import DatabasePurplin from '@components/onboarding-wizard/DatabasePurplin'; import CredentialsButton from '@components/onboarding-wizard/CredentialsButton'; import settingsService from '@services/settingsService'; -import useToast from '@components/toast/hooks/useToast'; + import Toast from '@components/toast/Toast'; import DatabaseErrorMessage from '@components/onboarding-wizard/DatabaseErrorMessage'; +import { useToast } from '@components/toast/ToastProvider'; export default function PostgreSQLCredentials() { const databaseProvider = allDBProviders.POSTGRES; diff --git a/dashboard/pages/onboarding/database/sqlite.tsx b/dashboard/pages/onboarding/database/sqlite.tsx index 5cdbb9b3f..ea013f2ee 100644 --- a/dashboard/pages/onboarding/database/sqlite.tsx +++ b/dashboard/pages/onboarding/database/sqlite.tsx @@ -13,9 +13,10 @@ import DatabasePurplin from '@components/onboarding-wizard/DatabasePurplin'; import InputFileSelect from '@components/onboarding-wizard/InputFileSelect'; import CredentialsButton from '@components/onboarding-wizard/CredentialsButton'; import settingsService from '@services/settingsService'; -import useToast from '@components/toast/hooks/useToast'; + import Toast from '@components/toast/Toast'; import DatabaseErrorMessage from '@components/onboarding-wizard/DatabaseErrorMessage'; +import { useToast } from '@components/toast/ToastProvider'; export default function SqliteCredentials() { const database = allDBProviders.SQLITE; From 2f528045c0e544107b13025b3006d5816153ce31 Mon Sep 17 00:00:00 2001 From: Saba Shavidze Date: Wed, 18 Oct 2023 12:03:54 +0400 Subject: [PATCH 31/34] refactor: updated imports for ToastProps --- .../cloud-account/components/CloudAccountDeleteContents.tsx | 2 +- .../cloud-account/components/CloudAccountsSidePanel.tsx | 2 +- dashboard/components/export-csv/ExportCSV.tsx | 2 +- .../components/inventory/components/InventorySearchBar.tsx | 2 +- dashboard/components/inventory/components/InventoryTable.tsx | 2 +- .../inventory/components/filter/InventoryFilterValue.tsx | 2 +- .../components/inventory/components/view/InventoryView.tsx | 2 +- .../inventory/components/view/InventoryViewHeader.tsx | 2 +- .../inventory/components/view/alerts/InventoryViewAlerts.tsx | 2 +- .../components/view/alerts/InventoryViewAlertsDeleteAlert.tsx | 2 +- .../components/view/alerts/InventoryViewAlertsEditAlert.tsx | 2 +- .../inventory/components/view/alerts/hooks/useEditAlerts.tsx | 2 +- .../components/inventory/components/view/hooks/useViews.tsx | 2 +- .../useInventory/helpers/getCustomViewInventoryListAndStats.ts | 2 +- .../hooks/useInventory/helpers/getInventoryListFromAFilter.ts | 2 +- .../hooks/useInventory/helpers/infiniteScrollCustomViewList.ts | 2 +- .../hooks/useInventory/helpers/infiniteScrollFilteredList.ts | 2 +- .../hooks/useInventory/helpers/infiniteScrollInventoryList.ts | 2 +- .../helpers/infiniteScrollSearchedAndFilteredList.ts | 2 +- .../helpers/infiniteScrollSearchedCustomViewList.ts | 2 +- .../hooks/useInventory/helpers/infiniteScrollSearchedList.ts | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx b/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx index 69398b196..f90639782 100644 --- a/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx +++ b/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx @@ -1,9 +1,9 @@ import { useState } from 'react'; +import { ToastProps } from '@components/toast/ToastProvider'; import AlertCircleIcon from '../../icons/AlertCircleIcon'; import Button from '../../button/Button'; import { CloudAccount } from '../hooks/useCloudAccounts/useCloudAccount'; import settingsService from '../../../services/settingsService'; -import { ToastProps } from '../../toast/hooks/useToast'; interface CloudAccountDeleteContentsProps { cloudAccount: CloudAccount; diff --git a/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx b/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx index a9dcb1d6e..21d0e1104 100644 --- a/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx +++ b/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx @@ -10,6 +10,7 @@ import MongoDbAtlasAccountDetails from '@components/account-details/MongoDBAtlas import OciAccountDetails from '@components/account-details/OciAccountDetails'; import ScalewayAccountDetails from '@components/account-details/ScalewayAccountDetails'; import { getPayloadFromForm } from '@utils/cloudAccountHelpers'; +import { ToastProps } from '@components/toast/ToastProvider'; import providers, { allProviders, Provider @@ -24,7 +25,6 @@ import { CloudAccount, CloudAccountsPage } from '../hooks/useCloudAccounts/useCloudAccount'; -import { ToastProps } from '../../toast/hooks/useToast'; import settingsService from '../../../services/settingsService'; interface CloudAccountsSidePanelProps { diff --git a/dashboard/components/export-csv/ExportCSV.tsx b/dashboard/components/export-csv/ExportCSV.tsx index fd17946c8..835cdbdaf 100644 --- a/dashboard/components/export-csv/ExportCSV.tsx +++ b/dashboard/components/export-csv/ExportCSV.tsx @@ -1,6 +1,6 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { useRouter } from 'next/router'; import settingsService from '../../services/settingsService'; -import { ToastProps } from '../toast/hooks/useToast'; import ExportCSVButton from './ExportCSVButton'; type ExportCSVProps = { diff --git a/dashboard/components/inventory/components/InventorySearchBar.tsx b/dashboard/components/inventory/components/InventorySearchBar.tsx index 2631e9d7d..13fd5b09d 100644 --- a/dashboard/components/inventory/components/InventorySearchBar.tsx +++ b/dashboard/components/inventory/components/InventorySearchBar.tsx @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import ExportCSV from '../../export-csv/ExportCSV'; import CloseIcon from '../../icons/CloseIcon'; import SearchIcon from '../../icons/SearchIcon'; -import { ToastProps } from '../../toast/hooks/useToast'; type InventorySearchBarProps = { query: string; diff --git a/dashboard/components/inventory/components/InventoryTable.tsx b/dashboard/components/inventory/components/InventoryTable.tsx index eb226295c..d25712411 100644 --- a/dashboard/components/inventory/components/InventoryTable.tsx +++ b/dashboard/components/inventory/components/InventoryTable.tsx @@ -1,10 +1,10 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { ChangeEvent } from 'react'; import formatNumber from '../../../utils/formatNumber'; import providers from '../../../utils/providerHelper'; import Checkbox from '../../checkbox/Checkbox'; import SkeletonInventory from '../../skeleton/SkeletonInventory'; -import { ToastProps } from '../../toast/hooks/useToast'; import { InventoryItem, InventoryStats diff --git a/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx b/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx index 0ed019754..e1acbc860 100644 --- a/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx +++ b/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx @@ -1,8 +1,8 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { ChangeEvent, useEffect, useState } from 'react'; import settingsService from '../../../../services/settingsService'; import Checkbox from '../../../checkbox/Checkbox'; import Input from '../../../input/Input'; -import { ToastProps } from '../../../toast/hooks/useToast'; import { InventoryFilterData } from '../../hooks/useInventory/types/useInventoryTypes'; import { CostBetween } from './hooks/useFilterWizard'; diff --git a/dashboard/components/inventory/components/view/InventoryView.tsx b/dashboard/components/inventory/components/view/InventoryView.tsx index 1cc5f0ed7..8f692e3ec 100644 --- a/dashboard/components/inventory/components/view/InventoryView.tsx +++ b/dashboard/components/inventory/components/view/InventoryView.tsx @@ -1,5 +1,6 @@ import Image from 'next/image'; import { NextRouter } from 'next/router'; +import { ToastProps } from '@components/toast/ToastProvider'; import formatNumber from '../../../../utils/formatNumber'; import providers, { Provider } from '../../../../utils/providerHelper'; import Button from '../../../button/Button'; @@ -10,7 +11,6 @@ import Sidepanel from '../../../sidepanel/Sidepanel'; import SidepanelHeader from '../../../sidepanel/SidepanelHeader'; import SidepanelPage from '../../../sidepanel/SidepanelPage'; import SidepanelTabs from '../../../sidepanel/SidepanelTabs'; -import { ToastProps } from '../../../toast/hooks/useToast'; import { HiddenResource, InventoryFilterData, diff --git a/dashboard/components/inventory/components/view/InventoryViewHeader.tsx b/dashboard/components/inventory/components/view/InventoryViewHeader.tsx index b51e18cdb..b0487caa8 100644 --- a/dashboard/components/inventory/components/view/InventoryViewHeader.tsx +++ b/dashboard/components/inventory/components/view/InventoryViewHeader.tsx @@ -1,3 +1,4 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { FormEvent, useState } from 'react'; import Button from '../../../button/Button'; @@ -10,7 +11,6 @@ import EditIcon from '../../../icons/EditIcon'; import LinkIcon from '../../../icons/LinkIcon'; import WarningIcon from '../../../icons/WarningIcon'; import Modal from '../../../modal/Modal'; -import { ToastProps } from '../../../toast/hooks/useToast'; import { InventoryFilterData, View diff --git a/dashboard/components/inventory/components/view/alerts/InventoryViewAlerts.tsx b/dashboard/components/inventory/components/view/alerts/InventoryViewAlerts.tsx index 8042fec6c..dbb3327f8 100644 --- a/dashboard/components/inventory/components/view/alerts/InventoryViewAlerts.tsx +++ b/dashboard/components/inventory/components/view/alerts/InventoryViewAlerts.tsx @@ -1,4 +1,4 @@ -import { ToastProps } from '../../../../toast/hooks/useToast'; +import { ToastProps } from '@components/toast/ToastProvider'; import useAlerts from './hooks/useAlerts'; import InventoryViewAlertsDeleteAlert from './InventoryViewAlertsDeleteAlert'; import InventoryViewAlertDisplayAlerts from './InventoryViewAlertsDisplay'; diff --git a/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsDeleteAlert.tsx b/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsDeleteAlert.tsx index db792db22..67f814da3 100644 --- a/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsDeleteAlert.tsx +++ b/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsDeleteAlert.tsx @@ -1,8 +1,8 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import Image from 'next/image'; import Button from '../../../../button/Button'; import { AlertMethod, Alert } from './hooks/useAlerts'; import useEditAlerts from './hooks/useEditAlerts'; -import { ToastProps } from '../../../../toast/hooks/useToast'; type InventoryViewAlertsDeleteAlertProps = { alertMethod: AlertMethod; diff --git a/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsEditAlert.tsx b/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsEditAlert.tsx index 589fa7fe8..a80b6c3c7 100644 --- a/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsEditAlert.tsx +++ b/dashboard/components/inventory/components/view/alerts/InventoryViewAlertsEditAlert.tsx @@ -1,11 +1,11 @@ import classNames from 'classnames'; import { useState } from 'react'; import Image from 'next/image'; +import { ToastProps } from '@components/toast/ToastProvider'; import Button from '../../../../button/Button'; import Grid from '../../../../grid/Grid'; import ArrowLeftIcon from '../../../../icons/ArrowLeftIcon'; import Input from '../../../../input/Input'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import useEditAlerts from './hooks/useEditAlerts'; import { AlertMethod, Alert } from './hooks/useAlerts'; import settingsService from '../../../../../services/settingsService'; diff --git a/dashboard/components/inventory/components/view/alerts/hooks/useEditAlerts.tsx b/dashboard/components/inventory/components/view/alerts/hooks/useEditAlerts.tsx index 9f1c72ec0..86a13c8f1 100644 --- a/dashboard/components/inventory/components/view/alerts/hooks/useEditAlerts.tsx +++ b/dashboard/components/inventory/components/view/alerts/hooks/useEditAlerts.tsx @@ -1,6 +1,6 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { FormEvent, useState } from 'react'; import settingsService from '../../../../../../services/settingsService'; -import { ToastProps } from '../../../../../toast/hooks/useToast'; import { AlertMethod, Alert } from './useAlerts'; type AlertType = 'BUDGET' | 'USAGE'; diff --git a/dashboard/components/inventory/components/view/hooks/useViews.tsx b/dashboard/components/inventory/components/view/hooks/useViews.tsx index 657ad9a91..b34a71d14 100644 --- a/dashboard/components/inventory/components/view/hooks/useViews.tsx +++ b/dashboard/components/inventory/components/view/hooks/useViews.tsx @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { ChangeEvent, FormEvent, useState } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { HiddenResource, InventoryFilterData, diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/getCustomViewInventoryListAndStats.ts b/dashboard/components/inventory/hooks/useInventory/helpers/getCustomViewInventoryListAndStats.ts index 6288037b0..acae4c110 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/getCustomViewInventoryListAndStats.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/getCustomViewInventoryListAndStats.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { HiddenResource, InventoryFilterData, diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/getInventoryListFromAFilter.ts b/dashboard/components/inventory/hooks/useInventory/helpers/getInventoryListFromAFilter.ts index 9858e31da..bdca50329 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/getInventoryListFromAFilter.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/getInventoryListFromAFilter.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryFilterData, InventoryItem, diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollCustomViewList.ts b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollCustomViewList.ts index 8e75df240..e9eeeaf90 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollCustomViewList.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollCustomViewList.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryItem, View } from '../types/useInventoryTypes'; type InfiniteScrollCustomViewListProps = { diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollFilteredList.ts b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollFilteredList.ts index 3a55f91b9..531289dd9 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollFilteredList.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollFilteredList.ts @@ -1,6 +1,6 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryFilterData, InventoryItem } from '../types/useInventoryTypes'; type InfiniteScrollFilteredListProps = { diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollInventoryList.ts b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollInventoryList.ts index 010b7d386..83d504328 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollInventoryList.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollInventoryList.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryFilterData, InventoryItem, diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedAndFilteredList.ts b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedAndFilteredList.ts index 8e671511d..9a199af8e 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedAndFilteredList.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedAndFilteredList.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryFilterData, InventoryItem } from '../types/useInventoryTypes'; type InfiniteScrollSearchedAndFilteredList = { diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedCustomViewList.ts b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedCustomViewList.ts index 546e83132..c9a9b282b 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedCustomViewList.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedCustomViewList.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryItem, View } from '../types/useInventoryTypes'; type InfiniteScrollSearchedCustomViewListProps = { diff --git a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedList.ts b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedList.ts index fcf38caba..4e19aaee6 100644 --- a/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedList.ts +++ b/dashboard/components/inventory/hooks/useInventory/helpers/infiniteScrollSearchedList.ts @@ -1,7 +1,7 @@ +import { ToastProps } from '@components/toast/ToastProvider'; import { NextRouter } from 'next/router'; import { SetStateAction } from 'react'; import settingsService from '../../../../../services/settingsService'; -import { ToastProps } from '../../../../toast/hooks/useToast'; import { InventoryItem } from '../types/useInventoryTypes'; type InfiniteScrollSearchedListProps = { From 5e44c2654228f6e939f8205cd64ba11bb3a40975 Mon Sep 17 00:00:00 2001 From: Saba Shavidze Date: Wed, 18 Oct 2023 12:33:47 +0400 Subject: [PATCH 32/34] refactor: updated imports for ToastProps --- .../components/CloudAccountDeleteContents.tsx | 8 ++-- .../components/CloudAccountsSidePanel.tsx | 10 ++--- .../filter/DependencyGraphFilterDropdown.tsx | 4 +- dashboard/components/export-csv/ExportCSV.tsx | 6 +-- .../feedback-widget/FeedbackWidget.tsx | 14 +++--- .../components/InventoryFilterDropdown.tsx | 4 +- .../components/InventorySearchBar.tsx | 6 +-- .../inventory/components/InventoryTable.tsx | 6 +-- .../filter/InventoryFilterValue.tsx | 12 ++--- .../components/view/InventoryView.tsx | 10 ++--- .../components/view/InventoryViewHeader.tsx | 8 ++-- .../view/alerts/InventoryViewAlerts.tsx | 10 ++--- .../alerts/InventoryViewAlertsDeleteAlert.tsx | 6 +-- .../alerts/InventoryViewAlertsEditAlert.tsx | 6 +-- .../view/alerts/hooks/useEditAlerts.tsx | 16 +++---- .../components/view/hooks/useViews.tsx | 28 ++++++------ .../getCustomViewInventoryListAndStats.ts | 8 ++-- .../helpers/getInventoryListFromAFilter.ts | 8 ++-- .../helpers/infiniteScrollCustomViewList.ts | 6 +-- .../helpers/infiniteScrollFilteredList.ts | 6 +-- .../helpers/infiniteScrollInventoryList.ts | 6 +-- .../infiniteScrollSearchedAndFilteredList.ts | 6 +-- .../infiniteScrollSearchedCustomViewList.ts | 6 +-- .../helpers/infiniteScrollSearchedList.ts | 6 +-- .../hooks/useInventory/useInventory.tsx | 44 +++++++++---------- .../onboarding-wizard/ProviderContent.tsx | 4 +- dashboard/components/toast/ToastProvider.tsx | 12 ++--- dashboard/pages/cloud-accounts.tsx | 6 +-- dashboard/pages/inventory.tsx | 6 +-- .../pages/onboarding/cloud-accounts/index.tsx | 4 +- .../pages/onboarding/database/postgres.tsx | 4 +- .../pages/onboarding/database/sqlite.tsx | 4 +- dashboard/utils/cloudAccountHelpers.ts | 28 ++++++------ 33 files changed, 160 insertions(+), 158 deletions(-) diff --git a/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx b/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx index f90639782..51b1c9c45 100644 --- a/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx +++ b/dashboard/components/cloud-account/components/CloudAccountDeleteContents.tsx @@ -9,14 +9,14 @@ interface CloudAccountDeleteContentsProps { cloudAccount: CloudAccount; onCancel: () => void; handleAfterDelete: (account: CloudAccount) => void; - setToast: (toast: ToastProps) => void; + showToast: (toast: ToastProps) => void; } function CloudAccountDeleteContents({ cloudAccount, onCancel, handleAfterDelete, - setToast + showToast }: CloudAccountDeleteContentsProps) { const [loading, setLoading] = useState(false); @@ -28,14 +28,14 @@ function CloudAccountDeleteContents({ settingsService.deleteCloudAccount(cloudAccount.id).then(res => { setLoading(false); if (res === Error) { - setToast({ + showToast({ hasError: true, title: 'Cloud account was not deleted', message: 'There was an error deleting this cloud account. Please try again.' }); } else { - setToast({ + showToast({ hasError: false, title: 'Cloud account deleted', message: `The cloud account was successfully deleted!` diff --git a/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx b/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx index 21d0e1104..0976ef508 100644 --- a/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx +++ b/dashboard/components/cloud-account/components/CloudAccountsSidePanel.tsx @@ -36,7 +36,7 @@ interface CloudAccountsSidePanelProps { handleAfterDelete: (account: CloudAccount) => void; page: CloudAccountsPage; goTo: (page: CloudAccountsPage) => void; - setToast: (toast: ToastProps) => void; + showToast: (toast: ToastProps) => void; } function AccountDetails({ @@ -81,7 +81,7 @@ function CloudAccountsSidePanel({ handleAfterDelete, page, goTo, - setToast + showToast }: CloudAccountsSidePanelProps) { const [isDeleteOpen, setIsDeleteOpen] = useState(false); const [loading, setLoading] = useState(false); @@ -101,7 +101,7 @@ function CloudAccountsSidePanel({ settingsService.editCloudAccount(id, payloadJson).then(res => { if (res === Error || res.error) { setLoading(false); - setToast({ + showToast({ hasError: true, title: 'Cloud account not edited', message: @@ -109,7 +109,7 @@ function CloudAccountsSidePanel({ }); } else { setLoading(false); - setToast({ + showToast({ hasError: false, title: 'Cloud account edited', message: `The cloud account was successfully edited!` @@ -182,7 +182,7 @@ function CloudAccountsSidePanel({ setIsDeleteOpen(false); closeModal(); }} - setToast={setToast} + showToast={showToast} />
) : ( diff --git a/dashboard/components/explorer/filter/DependencyGraphFilterDropdown.tsx b/dashboard/components/explorer/filter/DependencyGraphFilterDropdown.tsx index c2c927f1d..20e0e1b78 100644 --- a/dashboard/components/explorer/filter/DependencyGraphFilterDropdown.tsx +++ b/dashboard/components/explorer/filter/DependencyGraphFilterDropdown.tsx @@ -19,7 +19,7 @@ export default function InventoryFilterDropdown({ toggle, closeDropdownAfterAdd }: InventoryFilterDropdownProps) { - const { setSkippedSearch, router, setToast } = useInventory(); + const { setSkippedSearch, router, showToast } = useInventory(); const { // toggle, @@ -93,7 +93,7 @@ export default function InventoryFilterDropdown({ handleValueCheck={handleValueCheck} handleValueInput={handleValueInput} cleanValues={cleanValues} - setToast={setToast} + showToast={showToast} costBetween={costBetween} handleCostBetween={handleCostBetween} /> diff --git a/dashboard/components/export-csv/ExportCSV.tsx b/dashboard/components/export-csv/ExportCSV.tsx index 835cdbdaf..0029a4976 100644 --- a/dashboard/components/export-csv/ExportCSV.tsx +++ b/dashboard/components/export-csv/ExportCSV.tsx @@ -4,15 +4,15 @@ import settingsService from '../../services/settingsService'; import ExportCSVButton from './ExportCSVButton'; type ExportCSVProps = { - setToast: (toast: ToastProps | undefined) => void; + showToast: (toast: ToastProps) => void; }; -function ExportCSV({ setToast }: ExportCSVProps) { +function ExportCSV({ showToast }: ExportCSVProps) { const router = useRouter(); function exportCSV(id?: string) { settingsService.exportCSV(id); - setToast({ + showToast({ hasError: false, title: 'CSV exported', message: 'The download of the CSV file should begin shortly.' diff --git a/dashboard/components/feedback-widget/FeedbackWidget.tsx b/dashboard/components/feedback-widget/FeedbackWidget.tsx index c36db5543..9aa803604 100644 --- a/dashboard/components/feedback-widget/FeedbackWidget.tsx +++ b/dashboard/components/feedback-widget/FeedbackWidget.tsx @@ -54,7 +54,7 @@ const useFeedbackWidget = (defaultState: boolean = false) => { const [isTakingScreenCapture, setIsTakingScreenCapture] = useState(false); const [fileAttachement, setFileAttachement] = useState(null); const [isSendingFeedback, setIsSendingFeedback] = useState(false); - const { toast, setToast, dismissToast } = useToast(); + const { toast, showToast, dismissToast } = useToast(); async function takeScreenshot() { if ( @@ -85,7 +85,7 @@ const useFeedbackWidget = (defaultState: boolean = false) => { setFileAttachement(screenShotFile); } - setToast({ + showToast({ hasError: false, title: 'Screen capture', message: @@ -93,7 +93,7 @@ const useFeedbackWidget = (defaultState: boolean = false) => { }); }) .catch(err => { - setToast({ + showToast({ hasError: true, title: 'Screen capture failed', message: @@ -126,7 +126,7 @@ const useFeedbackWidget = (defaultState: boolean = false) => { settingsService .sendFeedback(formData) .then(result => { - setToast({ + showToast({ hasError: false, title: 'Feedback sent', message: @@ -136,7 +136,7 @@ const useFeedbackWidget = (defaultState: boolean = false) => { clearFeedbackForm(); }) .catch(error => { - setToast({ + showToast({ hasError: true, title: 'Feedback', message: 'An Error happened. Maybe try again please!' @@ -267,14 +267,14 @@ const useFeedbackWidget = (defaultState: boolean = false) => { hoverTitle="drop here" maxSize={MAX_FILE_SIZE_MB} onTypeError={(err: string) => - setToast({ + showToast({ hasError: true, title: 'File upload failed', message: err }) } onSizeError={(err: string) => - setToast({ + showToast({ hasError: true, title: 'File upload failed', message: err diff --git a/dashboard/components/inventory/components/InventoryFilterDropdown.tsx b/dashboard/components/inventory/components/InventoryFilterDropdown.tsx index 11f11dc69..118e74a4e 100644 --- a/dashboard/components/inventory/components/InventoryFilterDropdown.tsx +++ b/dashboard/components/inventory/components/InventoryFilterDropdown.tsx @@ -19,7 +19,7 @@ export default function InventoryFilterDropdown({ toggle, closeDropdownAfterAdd }: InventoryFilterDropdownProps) { - const { setSkippedSearch, router, setToast } = useInventory(); + const { setSkippedSearch, router, showToast } = useInventory(); const { // toggle, @@ -91,7 +91,7 @@ export default function InventoryFilterDropdown({ handleValueCheck={handleValueCheck} handleValueInput={handleValueInput} cleanValues={cleanValues} - setToast={setToast} + showToast={showToast} costBetween={costBetween} handleCostBetween={handleCostBetween} /> diff --git a/dashboard/components/inventory/components/InventorySearchBar.tsx b/dashboard/components/inventory/components/InventorySearchBar.tsx index 13fd5b09d..d6f3a1c75 100644 --- a/dashboard/components/inventory/components/InventorySearchBar.tsx +++ b/dashboard/components/inventory/components/InventorySearchBar.tsx @@ -7,14 +7,14 @@ type InventorySearchBarProps = { query: string; setQuery: (query: string) => void; error: boolean; - setToast: (toast: ToastProps | undefined) => void; + showToast: (toast: ToastProps) => void; }; function InventorySearchBar({ query, setQuery, error, - setToast + showToast }: InventorySearchBarProps) { return ( <> @@ -45,7 +45,7 @@ function InventorySearchBar({ maxLength={64} />
- +
)} diff --git a/dashboard/components/inventory/components/InventoryTable.tsx b/dashboard/components/inventory/components/InventoryTable.tsx index d25712411..de72272ae 100644 --- a/dashboard/components/inventory/components/InventoryTable.tsx +++ b/dashboard/components/inventory/components/InventoryTable.tsx @@ -32,7 +32,7 @@ type InventoryTableProps = { searchedLoading: boolean; hideResourceFromCustomView: () => void; hideResourcesLoading: boolean; - setToast: (toast: ToastProps | undefined) => void; + showToast: (toast: ToastProps) => void; }; function InventoryTable({ @@ -52,7 +52,7 @@ function InventoryTable({ searchedLoading, hideResourceFromCustomView, hideResourcesLoading, - setToast + showToast }: InventoryTableProps) { return ( <> @@ -63,7 +63,7 @@ function InventoryTable({ query={query} setQuery={setQuery} error={error} - setToast={setToast} + showToast={showToast} />
diff --git a/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx b/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx index e1acbc860..4462f0b9a 100644 --- a/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx +++ b/dashboard/components/inventory/components/filter/InventoryFilterValue.tsx @@ -14,7 +14,7 @@ type InventoryFilterValueProps = { ) => void; handleValueInput: (newValue: { values: string }) => void; cleanValues: () => void; - setToast: (toast: ToastProps | undefined) => void; + showToast: (toast: ToastProps) => void; costBetween: CostBetween; handleCostBetween: (newValue: Partial) => void; }; @@ -26,7 +26,7 @@ function InventoryFilterValue({ handleValueCheck, handleValueInput, cleanValues, - setToast, + showToast, costBetween, handleCostBetween }: InventoryFilterValueProps) { @@ -45,7 +45,7 @@ function InventoryFilterValue({ if (data.field === 'provider') { settingsService.getProviders().then(res => { if (res === Error) { - setToast({ + showToast({ hasError: true, title: `There was an error when fetching the cloud providers`, message: `Please refresh the page and try again.` @@ -59,7 +59,7 @@ function InventoryFilterValue({ if (data.field === 'account') { settingsService.getAccounts().then(res => { if (res === Error) { - setToast({ + showToast({ hasError: true, title: `There was an error when fetching the cloud accounts`, message: `Please refresh the page and try again.` @@ -73,7 +73,7 @@ function InventoryFilterValue({ if (data.field === 'region') { settingsService.getRegions().then(res => { if (res === Error) { - setToast({ + showToast({ hasError: true, title: `There was an error when fetching the cloud regions`, message: `Please refresh the page and try again.` @@ -87,7 +87,7 @@ function InventoryFilterValue({ if (data.field === 'service') { settingsService.getServices().then(res => { if (res === Error) { - setToast({ + showToast({ hasError: true, title: `There was an error when fetching the cloud services`, message: `Please refresh the page and try again.` diff --git a/dashboard/components/inventory/components/view/InventoryView.tsx b/dashboard/components/inventory/components/view/InventoryView.tsx index 8f692e3ec..0781f4faf 100644 --- a/dashboard/components/inventory/components/view/InventoryView.tsx +++ b/dashboard/components/inventory/components/view/InventoryView.tsx @@ -25,7 +25,7 @@ import useViews from './hooks/useViews'; type InventoryViewProps = { filters: InventoryFilterData[] | undefined; displayedFilters: InventoryFilterData[] | undefined; - setToast: (toast: ToastProps | undefined) => void; + showToast: (toast: ToastProps) => void; inventoryStats: InventoryStats | undefined; router: NextRouter; views: View[] | undefined; @@ -36,7 +36,7 @@ type InventoryViewProps = { function InventoryView({ filters, displayedFilters, - setToast, + showToast, inventoryStats, router, views, @@ -63,7 +63,7 @@ function InventoryView({ unhideResources, deleteLoading } = useViews({ - setToast, + showToast, views, router, getViews, @@ -78,7 +78,7 @@ function InventoryView({ views={views} router={router} saveView={saveView} - setToast={setToast} + showToast={showToast} loading={loading} deleteView={deleteView} deleteLoading={deleteLoading} @@ -173,7 +173,7 @@ function InventoryView({ - + diff --git a/dashboard/components/inventory/components/view/InventoryViewHeader.tsx b/dashboard/components/inventory/components/view/InventoryViewHeader.tsx index b0487caa8..79a4fbfc2 100644 --- a/dashboard/components/inventory/components/view/InventoryViewHeader.tsx +++ b/dashboard/components/inventory/components/view/InventoryViewHeader.tsx @@ -35,7 +35,7 @@ type InventoryViewHeaderProps = { dropdown?: boolean | undefined, viewToBeDeleted?: View | undefined ) => void; - setToast: (toast: ToastProps | undefined) => void; + showToast: (toast: ToastProps) => void; }; function InventoryViewHeader({ @@ -46,7 +46,7 @@ function InventoryViewHeader({ loading, deleteView, deleteLoading, - setToast + showToast }: InventoryViewHeaderProps) { const [dropdownIsOpen, setDropdownIsOpen] = useState(false); const [modalIsOpen, setModalIsOpen] = useState(false); @@ -134,7 +134,7 @@ function InventoryViewHeader({ transition={false} onClick={() => { navigator.clipboard.writeText(document.URL); - setToast({ + showToast({ hasError: false, title: 'Link copied!', message: `${document.URL} has been copied to your clipboard.` @@ -144,7 +144,7 @@ function InventoryViewHeader({ Copy view link - +