diff --git a/gadb/models.go b/gadb/models.go
index a0e9a9f6ef..04af5ee126 100644
--- a/gadb/models.go
+++ b/gadb/models.go
@@ -945,10 +945,11 @@ type HeartbeatMonitor struct {
}
type IntegrationKey struct {
- ID uuid.UUID
- Name string
- ServiceID uuid.UUID
- Type EnumIntegrationKeysType
+ ExternalSystemName sql.NullString
+ ID uuid.UUID
+ Name string
+ ServiceID uuid.UUID
+ Type EnumIntegrationKeysType
}
type Keyring struct {
diff --git a/gadb/queries.sql.go b/gadb/queries.sql.go
index 53a7039e58..6bdb5cb4f6 100644
--- a/gadb/queries.sql.go
+++ b/gadb/queries.sql.go
@@ -1397,15 +1397,16 @@ func (q *Queries) FindOneCalSubForUpdate(ctx context.Context, id uuid.UUID) (Fin
}
const intKeyCreate = `-- name: IntKeyCreate :exec
-INSERT INTO integration_keys(id, name, type, service_id)
- VALUES ($1, $2, $3, $4)
+INSERT INTO integration_keys(id, name, type, service_id, external_system_name)
+ VALUES ($1, $2, $3, $4, $5)
`
type IntKeyCreateParams struct {
- ID uuid.UUID
- Name string
- Type EnumIntegrationKeysType
- ServiceID uuid.UUID
+ ID uuid.UUID
+ Name string
+ Type EnumIntegrationKeysType
+ ServiceID uuid.UUID
+ ExternalSystemName sql.NullString
}
func (q *Queries) IntKeyCreate(ctx context.Context, arg IntKeyCreateParams) error {
@@ -1414,6 +1415,7 @@ func (q *Queries) IntKeyCreate(ctx context.Context, arg IntKeyCreateParams) erro
arg.Name,
arg.Type,
arg.ServiceID,
+ arg.ExternalSystemName,
)
return err
}
@@ -1433,7 +1435,8 @@ SELECT
id,
name,
type,
- service_id
+ service_id,
+ external_system_name
FROM
integration_keys
WHERE
@@ -1441,10 +1444,11 @@ WHERE
`
type IntKeyFindByServiceRow struct {
- ID uuid.UUID
- Name string
- Type EnumIntegrationKeysType
- ServiceID uuid.UUID
+ ID uuid.UUID
+ Name string
+ Type EnumIntegrationKeysType
+ ServiceID uuid.UUID
+ ExternalSystemName sql.NullString
}
func (q *Queries) IntKeyFindByService(ctx context.Context, serviceID uuid.UUID) ([]IntKeyFindByServiceRow, error) {
@@ -1461,6 +1465,7 @@ func (q *Queries) IntKeyFindByService(ctx context.Context, serviceID uuid.UUID)
&i.Name,
&i.Type,
&i.ServiceID,
+ &i.ExternalSystemName,
); err != nil {
return nil, err
}
@@ -1480,7 +1485,8 @@ SELECT
id,
name,
type,
- service_id
+ service_id,
+ external_system_name
FROM
integration_keys
WHERE
@@ -1488,10 +1494,11 @@ WHERE
`
type IntKeyFindOneRow struct {
- ID uuid.UUID
- Name string
- Type EnumIntegrationKeysType
- ServiceID uuid.UUID
+ ID uuid.UUID
+ Name string
+ Type EnumIntegrationKeysType
+ ServiceID uuid.UUID
+ ExternalSystemName sql.NullString
}
func (q *Queries) IntKeyFindOne(ctx context.Context, id uuid.UUID) (IntKeyFindOneRow, error) {
@@ -1502,6 +1509,7 @@ func (q *Queries) IntKeyFindOne(ctx context.Context, id uuid.UUID) (IntKeyFindOn
&i.Name,
&i.Type,
&i.ServiceID,
+ &i.ExternalSystemName,
)
return i, err
}
diff --git a/go.mod b/go.mod
index 9b6cfdf0e1..81ae9fd24d 100644
--- a/go.mod
+++ b/go.mod
@@ -101,7 +101,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
- github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+ github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
github.com/jhump/protoreflect v1.15.3 // indirect
diff --git a/go.sum b/go.sum
index 0f5b703b8c..4cf4d52065 100644
--- a/go.sum
+++ b/go.sum
@@ -953,8 +953,9 @@ github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX
github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
+github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
diff --git a/graphql2/generated.go b/graphql2/generated.go
index 6d762b6a6e..7be8c43c28 100644
--- a/graphql2/generated.go
+++ b/graphql2/generated.go
@@ -344,11 +344,12 @@ type ComplexityRoot struct {
}
IntegrationKey struct {
- Href func(childComplexity int) int
- ID func(childComplexity int) int
- Name func(childComplexity int) int
- ServiceID func(childComplexity int) int
- Type func(childComplexity int) int
+ ExternalSystemName func(childComplexity int) int
+ Href func(childComplexity int) int
+ ID func(childComplexity int) int
+ Name func(childComplexity int) int
+ ServiceID func(childComplexity int) int
+ Type func(childComplexity int) int
}
IntegrationKeyConnection struct {
@@ -2112,6 +2113,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.HeartbeatMonitor.TimeoutMinutes(childComplexity), true
+ case "IntegrationKey.externalSystemName":
+ if e.complexity.IntegrationKey.ExternalSystemName == nil {
+ break
+ }
+
+ return e.complexity.IntegrationKey.ExternalSystemName(childComplexity), true
+
case "IntegrationKey.href":
if e.complexity.IntegrationKey.Href == nil {
break
@@ -13540,6 +13548,47 @@ func (ec *executionContext) fieldContext_IntegrationKey_href(ctx context.Context
return fc, nil
}
+func (ec *executionContext) _IntegrationKey_externalSystemName(ctx context.Context, field graphql.CollectedField, obj *integrationkey.IntegrationKey) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_IntegrationKey_externalSystemName(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.ExternalSystemName, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(string)
+ fc.Result = res
+ return ec.marshalOString2string(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_IntegrationKey_externalSystemName(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "IntegrationKey",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type String does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
func (ec *executionContext) _IntegrationKeyConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *IntegrationKeyConnection) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_IntegrationKeyConnection_nodes(ctx, field)
if err != nil {
@@ -13589,6 +13638,8 @@ func (ec *executionContext) fieldContext_IntegrationKeyConnection_nodes(ctx cont
return ec.fieldContext_IntegrationKey_name(ctx, field)
case "href":
return ec.fieldContext_IntegrationKey_href(ctx, field)
+ case "externalSystemName":
+ return ec.fieldContext_IntegrationKey_externalSystemName(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type IntegrationKey", field.Name)
},
@@ -16071,6 +16122,8 @@ func (ec *executionContext) fieldContext_Mutation_createIntegrationKey(ctx conte
return ec.fieldContext_IntegrationKey_name(ctx, field)
case "href":
return ec.fieldContext_IntegrationKey_href(ctx, field)
+ case "externalSystemName":
+ return ec.fieldContext_IntegrationKey_externalSystemName(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type IntegrationKey", field.Name)
},
@@ -19298,6 +19351,8 @@ func (ec *executionContext) fieldContext_Query_integrationKey(ctx context.Contex
return ec.fieldContext_IntegrationKey_name(ctx, field)
case "href":
return ec.fieldContext_IntegrationKey_href(ctx, field)
+ case "externalSystemName":
+ return ec.fieldContext_IntegrationKey_externalSystemName(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type IntegrationKey", field.Name)
},
@@ -24841,6 +24896,8 @@ func (ec *executionContext) fieldContext_Service_integrationKeys(ctx context.Con
return ec.fieldContext_IntegrationKey_name(ctx, field)
case "href":
return ec.fieldContext_IntegrationKey_href(ctx, field)
+ case "externalSystemName":
+ return ec.fieldContext_IntegrationKey_externalSystemName(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type IntegrationKey", field.Name)
},
@@ -31796,7 +31853,7 @@ func (ec *executionContext) unmarshalInputCreateIntegrationKeyInput(ctx context.
asMap[k] = v
}
- fieldsInOrder := [...]string{"serviceID", "type", "name"}
+ fieldsInOrder := [...]string{"serviceID", "type", "name", "externalSystemName"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -31824,6 +31881,13 @@ func (ec *executionContext) unmarshalInputCreateIntegrationKeyInput(ctx context.
return it, err
}
it.Name = data
+ case "externalSystemName":
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalSystemName"))
+ data, err := ec.unmarshalOString2ᚖstring(ctx, v)
+ if err != nil {
+ return it, err
+ }
+ it.ExternalSystemName = data
}
}
@@ -37727,6 +37791,8 @@ func (ec *executionContext) _IntegrationKey(ctx context.Context, sel ast.Selecti
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
+ case "externalSystemName":
+ out.Values[i] = ec._IntegrationKey_externalSystemName(ctx, field, obj)
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -47932,6 +47998,16 @@ func (ec *executionContext) unmarshalOSlackUserGroupSearchOptions2ᚖgithubᚗco
return &res, graphql.ErrorOnPath(ctx, err)
}
+func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) {
+ res, err := graphql.UnmarshalString(v)
+ return res, graphql.ErrorOnPath(ctx, err)
+}
+
+func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
+ res := graphql.MarshalString(v)
+ return res
+}
+
func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) {
if v == nil {
return nil, nil
diff --git a/graphql2/graphqlapp/integrationkey.go b/graphql2/graphqlapp/integrationkey.go
index e668fb3e70..2213569002 100644
--- a/graphql2/graphqlapp/integrationkey.go
+++ b/graphql2/graphqlapp/integrationkey.go
@@ -29,6 +29,9 @@ func (m *Mutation) CreateIntegrationKey(ctx context.Context, input graphql2.Crea
Name: input.Name,
Type: integrationkey.Type(input.Type),
}
+ if input.ExternalSystemName != nil {
+ key.ExternalSystemName = *input.ExternalSystemName
+ }
key, err = m.IntKeyStore.Create(ctx, tx, key)
return err
})
diff --git a/graphql2/models_gen.go b/graphql2/models_gen.go
index fa6fd02d02..ac2445f454 100644
--- a/graphql2/models_gen.go
+++ b/graphql2/models_gen.go
@@ -184,6 +184,8 @@ type CreateIntegrationKeyInput struct {
ServiceID *string `json:"serviceID,omitempty"`
Type IntegrationKeyType `json:"type"`
Name string `json:"name"`
+ // Name of the external system this key is managed by.
+ ExternalSystemName *string `json:"externalSystemName,omitempty"`
}
type CreateRotationInput struct {
diff --git a/graphql2/schema.graphql b/graphql2/schema.graphql
index 4d3816b11b..284f92fab7 100644
--- a/graphql2/schema.graphql
+++ b/graphql2/schema.graphql
@@ -1000,6 +1000,11 @@ input CreateIntegrationKeyInput {
serviceID: ID
type: IntegrationKeyType!
name: String!
+
+ """
+ Name of the external system this key is managed by.
+ """
+ externalSystemName: String
}
input CreateHeartbeatMonitorInput {
@@ -1044,6 +1049,11 @@ type IntegrationKey {
type: IntegrationKeyType!
name: String!
href: String!
+
+ """
+ Name of the external system this key is managed by.
+ """
+ externalSystemName: String
}
enum IntegrationKeyType {
diff --git a/integrationkey/integrationkey.go b/integrationkey/integrationkey.go
index 90590e1f89..13ea122788 100644
--- a/integrationkey/integrationkey.go
+++ b/integrationkey/integrationkey.go
@@ -9,6 +9,8 @@ type IntegrationKey struct {
Name string `json:"name"`
Type Type `json:"type"`
ServiceID string `json:"service_id"`
+
+ ExternalSystemName string
}
func (i IntegrationKey) Normalize() (*IntegrationKey, error) {
@@ -16,6 +18,7 @@ func (i IntegrationKey) Normalize() (*IntegrationKey, error) {
validate.IDName("Name", i.Name),
validate.UUID("ServiceID", i.ServiceID),
validate.OneOf("Type", i.Type, TypeGrafana, TypeSite24x7, TypePrometheusAlertmanager, TypeGeneric, TypeEmail),
+ validate.ASCII("ExternalSystemName", i.ExternalSystemName, 0, 255),
)
if err != nil {
return nil, err
diff --git a/integrationkey/queries.sql b/integrationkey/queries.sql
index 046443d702..e39cbe1e76 100644
--- a/integrationkey/queries.sql
+++ b/integrationkey/queries.sql
@@ -8,15 +8,16 @@ WHERE
AND type = $2;
-- name: IntKeyCreate :exec
-INSERT INTO integration_keys(id, name, type, service_id)
- VALUES ($1, $2, $3, $4);
+INSERT INTO integration_keys(id, name, type, service_id, external_system_name)
+ VALUES ($1, $2, $3, $4, $5);
-- name: IntKeyFindOne :one
SELECT
id,
name,
type,
- service_id
+ service_id,
+ external_system_name
FROM
integration_keys
WHERE
@@ -27,7 +28,8 @@ SELECT
id,
name,
type,
- service_id
+ service_id,
+ external_system_name
FROM
integration_keys
WHERE
diff --git a/integrationkey/store.go b/integrationkey/store.go
index 30bea03e8e..8ee2908d03 100644
--- a/integrationkey/store.go
+++ b/integrationkey/store.go
@@ -92,6 +92,8 @@ func (s *Store) Create(ctx context.Context, dbtx gadb.DBTX, i *IntegrationKey) (
Name: n.Name,
Type: gadb.EnumIntegrationKeysType(n.Type),
ServiceID: serviceUUID,
+
+ ExternalSystemName: sql.NullString{String: n.ExternalSystemName, Valid: n.ExternalSystemName != ""},
})
if err != nil {
return nil, err
@@ -142,6 +144,8 @@ func (s *Store) FindOne(ctx context.Context, id string) (*IntegrationKey, error)
Name: row.Name,
Type: Type(row.Type),
ServiceID: row.ServiceID.String(),
+
+ ExternalSystemName: row.ExternalSystemName.String,
}, nil
}
@@ -167,6 +171,8 @@ func (s *Store) FindAllByService(ctx context.Context, serviceID string) ([]Integ
Name: row.Name,
Type: Type(row.Type),
ServiceID: row.ServiceID.String(),
+
+ ExternalSystemName: row.ExternalSystemName.String,
}
}
return keys, nil
diff --git a/migrate/migrations/20240415143348-ext-int-keys.sql b/migrate/migrations/20240415143348-ext-int-keys.sql
new file mode 100644
index 0000000000..67b5b521e5
--- /dev/null
+++ b/migrate/migrations/20240415143348-ext-int-keys.sql
@@ -0,0 +1,23 @@
+-- +migrate Up
+ALTER TABLE integration_keys
+ ADD COLUMN external_system_name TEXT,
+ DROP CONSTRAINT integration_keys_name_service_id_key;
+
+DROP INDEX IF EXISTS integration_keys_name_service_id_key;
+
+DROP INDEX IF EXISTS integration_keys_name_service_id;
+
+CREATE UNIQUE INDEX idx_int_key_name_svc_ext ON public.integration_keys USING btree(lower(name), service_id, coalesce(external_system_name, ''));
+
+-- +migrate Down
+LOCK TABLE integration_keys;
+
+DELETE FROM integration_keys
+WHERE external_system_name IS NOT NULL;
+
+ALTER TABLE integration_keys
+ DROP COLUMN external_system_name,
+ ADD CONSTRAINT integration_keys_name_service_id_key UNIQUE (name, service_id);
+
+CREATE UNIQUE INDEX integration_keys_name_service_id ON public.integration_keys USING btree(lower(name), service_id);
+
diff --git a/migrate/schema.sql b/migrate/schema.sql
index 1d3f64d2b2..06c1c5dcd1 100644
--- a/migrate/schema.sql
+++ b/migrate/schema.sql
@@ -1,7 +1,7 @@
-- This file is auto-generated by "make db-schema"; DO NOT EDIT
--- DATA=80b70842c372137de893fdbeb2e15ff063e281350f99ac81b71965ba0b8ea167 -
--- DISK=d28a06c3676164b926f7998045b6ad7c986cab75cd3e8cdbd98d4991fdcce593 -
--- PSQL=d28a06c3676164b926f7998045b6ad7c986cab75cd3e8cdbd98d4991fdcce593 -
+-- DATA=75b49324476222eb037d3cba6e07d309090a82b93508ac3e72d9908279657a33 -
+-- DISK=e74e9237489fd549f592dca04bb8781e83c9923a5d594b24709b6496990b385a -
+-- PSQL=e74e9237489fd549f592dca04bb8781e83c9923a5d594b24709b6496990b385a -
--
-- pgdump-lite database dump
--
@@ -1675,18 +1675,17 @@ CREATE CONSTRAINT TRIGGER trg_enforce_heartbeat_monitor_limit AFTER INSERT ON pu
CREATE TABLE integration_keys (
+ external_system_name text,
id uuid DEFAULT gen_random_uuid() NOT NULL,
name text NOT NULL,
service_id uuid NOT NULL,
type enum_integration_keys_type NOT NULL,
- CONSTRAINT integration_keys_name_service_id_key UNIQUE (name, service_id),
CONSTRAINT integration_keys_pkey PRIMARY KEY (id),
CONSTRAINT integration_keys_services_id_fkey FOREIGN KEY (service_id) REFERENCES services(id) ON DELETE CASCADE
);
+CREATE UNIQUE INDEX idx_int_key_name_svc_ext ON public.integration_keys USING btree (lower(name), service_id, COALESCE(external_system_name, ''::text));
CREATE INDEX idx_integration_key_service ON public.integration_keys USING btree (service_id);
-CREATE UNIQUE INDEX integration_keys_name_service_id ON public.integration_keys USING btree (lower(name), service_id);
-CREATE UNIQUE INDEX integration_keys_name_service_id_key ON public.integration_keys USING btree (name, service_id);
CREATE UNIQUE INDEX integration_keys_pkey ON public.integration_keys USING btree (id);
CREATE CONSTRAINT TRIGGER trg_enforce_integration_key_limit AFTER INSERT ON public.integration_keys NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE FUNCTION fn_enforce_integration_key_limit();
diff --git a/package.json b/package.json
index 24aa349940..7aa5f69b32 100644
--- a/package.json
+++ b/package.json
@@ -43,8 +43,8 @@
"@material/material-color-utilities": "0.2.7",
"@mui/icons-material": "5.15.13",
"@mui/lab": "5.0.0-alpha.162",
- "@mui/material": "5.15.5",
- "@mui/styles": "5.15.5",
+ "@mui/material": "5.15.15",
+ "@mui/styles": "5.15.15",
"@mui/system": "5.15.6",
"@mui/x-data-grid": "6.19.6",
"@playwright/test": "1.41.2",
@@ -58,7 +58,7 @@
"@storybook/test": "8.0.8",
"@storybook/test-runner": "0.17.0",
"@storybook/types": "8.0.6",
- "@types/chance": "1.1.4",
+ "@types/chance": "1.1.6",
"@types/diff": "5.0.8",
"@types/glob": "8.1.0",
"@types/jest": "29.5.12",
@@ -71,7 +71,7 @@
"@types/react-dom": "18.2.22",
"@types/react-transition-group": "4.4.10",
"@types/react-virtualized-auto-sizer": "1.0.4",
- "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/eslint-plugin": "7.7.0",
"@typescript-eslint/parser": "6.21.0",
"@urql/exchange-retry": "1.2.1",
"bowser": "2.11.0",
@@ -125,7 +125,7 @@
"react-redux": "8.1.3",
"react-transition-group": "4.4.5",
"react-virtualized-auto-sizer": "1.0.20",
- "recharts": "2.8.0",
+ "recharts": "2.9.2",
"redux": "4.2.1",
"redux-devtools-extension": "2.13.9",
"redux-thunk": "2.4.2",
diff --git a/test/smoke/migrations_test.go b/test/smoke/migrations_test.go
index 5cfd10cb8f..c5c5ebefc9 100644
--- a/test/smoke/migrations_test.go
+++ b/test/smoke/migrations_test.go
@@ -1,16 +1,12 @@
package smoke
import (
- "bufio"
"bytes"
"context"
"database/sql"
"fmt"
"math/rand"
"os"
- "os/exec"
- "regexp"
- "sort"
"strings"
"testing"
"text/template"
@@ -18,20 +14,19 @@ import (
"github.com/google/uuid"
_ "github.com/jackc/pgx/v5/stdlib" // import db driver
+ "github.com/stretchr/testify/require"
"github.com/target/goalert/migrate"
"github.com/target/goalert/test/smoke/harness"
+ "github.com/target/goalert/test/smoke/migratetest"
"github.com/target/goalert/util/sqlutil"
)
-type ignoreRule struct {
- MigrationName string
- TableName string
- ColumnName string
- ExtraRows bool
- MissingRows bool
-}
+// DefaultSkipToMigration is the default migration to skip to when running the migration tests.
+//
+// It can be overriden by setting the SKIP_TO environment variable.
+const DefaultSkipToMigration = "switchover-mk2"
-var ignoreRules = []ignoreRule{
+var rules = migratetest.RuleSet{
// All migration timestamps will differ as they applied/re-applied
{TableName: "gorp_migrations", ColumnName: "applied_at"},
@@ -162,283 +157,6 @@ values
({{uuid "cb2"}}, {{uuid "ncy1"}}, 1, {{uuid "c2"}}, {{uuid "n2"}}, now());
`
-type pgDumpEntry struct {
- Name string
- Body string
-}
-
-var enumRx = regexp.MustCompile(`(?s)CREATE TYPE ([\w_.]+) AS ENUM \(\s*(.*)\s*\);`)
-
-// enumOK handles checking for safe enum differences. This case is that migrate
-// up can add, but migrate down will not remove new enum values.
-//
-// migrate down can't safely remove enum values, but it's safe for new ones
-// to exist. So we simply check that all original items exist.
-func enumOK(got, want string) bool {
- partsW := enumRx.FindStringSubmatch(want)
- if len(partsW) != 3 {
- return false
- }
- partsG := enumRx.FindStringSubmatch(got)
- if len(partsG) != 3 {
- return false
- }
- if partsW[1] != partsG[1] {
- return false
- }
-
- gotItems := strings.Split(partsG[2], ",\n")
- wantItems := strings.Split(partsW[2], ",\n")
-
- g := make(map[string]bool, len(gotItems))
- for _, v := range gotItems {
- g[strings.TrimSpace(v)] = true
- }
-
- for _, v := range wantItems {
- if !g[strings.TrimSpace(v)] {
- return false
- }
- }
-
- return true
-}
-
-func TestEnumOK(t *testing.T) {
- const got = `CREATE TYPE enum_alert_log_event AS ENUM (
-'created',
-'reopened',
-'status_changed',
-'assignment_changed',
-'escalated',
-'closed',
-'notification_sent',
-'response_received',
-'acknowledged',
-'policy_updated',
-'duplicate_suppressed',
-'escalation_request'
-);`
- const want = `CREATE TYPE enum_alert_log_event AS ENUM (
-'created',
-'reopened',
-'status_changed',
-'assignment_changed',
-'escalated',
-'closed',
-'notification_sent',
-'response_received'
-);`
-
- if !enumOK(got, want) {
- t.Errorf("got false; want true")
- }
-}
-
-func processIgnoreRules(ignoreRules []ignoreRule, name, body string) string {
- for _, r := range ignoreRules {
- if r.MigrationName != "" && r.MigrationName != name {
- continue
- }
- if !strings.HasPrefix(body, "COPY "+r.TableName+" ") && !strings.HasPrefix(body, "COPY public."+r.TableName+" ") {
- continue
- }
- lines := strings.Split(body, "\n")
- pref, cols, suf := getCols(lines[0])
- index := -1
- for i, v := range cols {
- if v == r.ColumnName {
- index = i
- }
- }
- if index == -1 {
- continue
- }
- newLen := len(cols) - 1
- copy(cols[index:], cols[index+1:])
- cols = cols[:newLen]
- lines[0] = pref + strings.Join(cols, ", ") + suf
-
- data := lines[1 : len(lines)-1]
- for i, l := range data {
- cols = strings.Split(l, "\t")
- copy(cols[index:], cols[index+1:])
- cols = cols[:newLen]
- data[i] = strings.Join(cols, "\t")
- }
- body = strings.Join(lines, "\n")
- }
- return body
-}
-
-func TestProcessIgnoreRules(t *testing.T) {
- t.Parallel()
- const input = `COPY public.my_table (foo, bar, baz) FROM stdin;
-1 2 3
-a b c
-\.`
- const expected = `COPY public.my_table (foo, baz) FROM stdin;
-1 3
-a c
-\.`
- rules := []ignoreRule{
- {MigrationName: "foo", TableName: "my_table", ColumnName: "bar"},
- }
- result := processIgnoreRules(rules, "foo", input)
- if result != expected {
- t.Errorf("got\n%s\n\nwant\n%s", result, expected)
- }
-}
-
-func getCols(line string) (prefix string, cols []string, suffix string) {
- cols = strings.SplitN(line, "(", 2)
-
- prefix = cols[0] + "("
- suffix = cols[1]
- cols = strings.SplitN(suffix, ")", 2)
- suffix = ")" + cols[1]
- cols = strings.Split(cols[0], ", ")
-
- return prefix, cols, suffix
-}
-
-func alphabetizeCopy(body string) string {
- lines := strings.Split(body, "\n")
- data := lines[1 : len(lines)-1]
-
- pref, cols, suf := getCols(lines[0])
-
- orig := make(map[string]int, len(cols))
- for i, c := range cols {
- orig[c] = i
- }
- sort.Strings(cols)
- lines[0] = pref + strings.Join(cols, ", ") + suf
-
- order := make(map[int]int, len(cols))
- for i, c := range cols {
- order[orig[c]] = i
- }
-
- for n, l := range data {
- cols = strings.Split(l, "\t")
- sorted := make([]string, len(cols))
- for i, v := range cols {
- sorted[order[i]] = v
- }
-
- data[n] = strings.Join(sorted, "\t")
- }
-
- sort.Strings(lines[1:])
- return strings.Join(lines, "\n")
-}
-
-func TestAlphabetizeCopy(t *testing.T) {
- t.Parallel()
- const input = `COPY foobar (a, e, f, b, c) FROM stdin;
-first second third fourth fifth
-\.`
- const expected = `COPY foobar (a, b, c, e, f) FROM stdin;
-\.
-first fourth fifth second third`
- result := alphabetizeCopy(input)
- if result != expected {
- t.Errorf("got\n%s\n\nwant\n%s", result, expected)
- }
-}
-
-func parsePGDump(data []byte, name string) []pgDumpEntry {
- rd := bufio.NewReader(bytes.NewReader(data))
-
- entries := make([]pgDumpEntry, 0, 10000)
- var entry pgDumpEntry
-
- addEntry := func() {
- if strings.Contains(entry.Body, "COPY notifications (user_id, started_at) FROM stdin") {
- // we ignore the (old) notifications table
- // since it's trigger based and always re-calculated
- //
- // which makes it near impossible to test migrations
- //
- // it also doesn't work properly anyhow, which is why it has been
- // replaced.
- return
- }
-
- entry.Body = strings.TrimSpace(entry.Body)
- entry.Name = strings.TrimSpace(entry.Name)
-
- if strings.HasPrefix(entry.Body, "COPY ") && strings.Contains(entry.Name, "Type: TABLE DATA") {
- // ignore column order, as long as the data matches
- entry.Body = processIgnoreRules(ignoreRules, name, entry.Body)
- entry.Body = alphabetizeCopy(entry.Body)
- }
- if strings.Contains(entry.Body, "REPLICA IDENTITY NOTHING") && strings.Contains(entry.Body, "ALTER TABLE ONLY") {
- // skip 'view' tables
- return
- }
-
- if strings.Contains(entry.Name, " _RETURN; Type: RULE") {
- // view return rule -> convert to view
- tname := strings.SplitN(entry.Name, " ", 2)[0]
- entry.Name = strings.Replace(entry.Name, " _RETURN; Type: RULE", "; Type: VIEW", 1)
- entry.Body = strings.Replace(entry.Body, "CREATE RULE \"_RETURN\" AS\n", "", 1)
- entry.Body = strings.Replace(entry.Body,
- "ON SELECT TO "+tname+" DO INSTEAD ",
- "CREATE VIEW "+tname+" AS\n",
- 1,
- )
- }
-
- if strings.HasPrefix(entry.Body, "CREATE TABLE") {
- // order args alphabetically
- lines := strings.Split(entry.Body, "\n")
- sort.Strings(lines[1 : len(lines)-1])
- for i := 1; i < len(lines)-1; i++ {
- if !strings.HasSuffix(lines[i], ",") {
- lines[i] += ","
- }
- }
- entry.Body = strings.Join(lines, "\n")
- }
-
- entries = append(entries, entry)
- }
-
- for {
- line, err := rd.ReadString('\n')
- if err != nil {
- break
- }
- if strings.HasPrefix(line, "-- Name: ") {
- entry.Name = strings.TrimSpace(strings.TrimPrefix(line, "-- Name: "))
- entry.Body = ""
- _, _ = rd.ReadString('\n') // skip next line
- continue
- } else if strings.HasPrefix(line, "-- Data for Name: ") {
- entry.Name = strings.TrimSpace(strings.TrimPrefix(line, "-- Data for Name: "))
- entry.Body = ""
- _, _ = rd.ReadString('\n') // skip next line
- continue
- } else if strings.HasPrefix(line, "--") {
- if entry.Name != "" {
- addEntry()
- }
- entry.Body = ""
- entry.Name = ""
- } else if entry.Name != "" && line != "" {
- entry.Body += strings.Trim(line, "\n ") + "\n"
- }
- }
-
- return entries
-}
-
-func indent(str string) string {
- return " " + strings.Replace(str, "\n", "\n ", -1)
-}
-
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
@@ -480,57 +198,6 @@ func renderQuery(t *testing.T, sql string) string {
return b.String()
}
-func (e pgDumpEntry) matchesBody(migrationName string, body string) bool {
- if e.Body == body {
- return true
- }
- if enumOK(body, e.Body) {
- return true
- }
-
- if !strings.HasPrefix(e.Body, "COPY ") {
- return false
- }
-
- // check for extra rows rule
- var extraRows, missingRows bool
- for _, r := range ignoreRules {
- if r.MigrationName != migrationName {
- continue
- }
- if !strings.HasPrefix(e.Name, r.TableName+";") {
- continue
- }
- extraRows = extraRows || r.ExtraRows
- missingRows = missingRows || r.MissingRows
- }
- if !extraRows && !missingRows {
- return false
- }
-
- e.Body = strings.TrimSuffix(e.Body, "\n\\.")
- body = strings.TrimSuffix(body, "\n\\.")
- if extraRows {
- rows := strings.Split(body, "\n")
- for i := range rows {
- if e.Body == strings.Join(rows[:len(rows)-i], "\n") {
- return true
- }
- }
- }
-
- if missingRows {
- rows := strings.Split(e.Body, "\n")
- for i := range rows {
- if body == strings.Join(rows[:len(rows)-i], "\n") {
- return true
- }
- }
- }
-
- return false
-}
-
func TestMigrations(t *testing.T) {
if testing.Short() {
t.Skip("skipping migrations tests for short mode")
@@ -546,20 +213,22 @@ func TestMigrations(t *testing.T) {
defer db.Close()
dbName := strings.Replace("migrations_smoketest_"+time.Now().Format("2006_01_02_03_04_05")+uuid.New().String(), "-", "", -1)
+ testURL := harness.DBURL(dbName)
+
_, err = db.Exec("create database " + sqlutil.QuoteID(dbName))
if err != nil {
t.Fatal("failed to create db:", err)
}
defer func() { _, _ = db.Exec("drop database " + sqlutil.QuoteID(dbName)) }()
- n, err := migrate.Up(context.Background(), harness.DBURL(dbName), start)
+ n, err := migrate.Up(context.Background(), testURL, start)
if err != nil {
t.Fatal("failed to apply initial migrations:", err)
}
initSQL := renderQuery(t, migrateInitData)
- err = harness.ExecSQLBatch(context.Background(), harness.DBURL(dbName), initSQL)
+ err = harness.ExecSQLBatch(context.Background(), testURL, initSQL)
if err != nil {
t.Fatalf("failed to init db %v", err)
}
@@ -571,7 +240,7 @@ func TestMigrations(t *testing.T) {
start = env
skipTo = true
} else {
- start = "switchover-mk2" // default skip_to
+ start = DefaultSkipToMigration
skipTo = true
}
var idx int
@@ -583,7 +252,7 @@ func TestMigrations(t *testing.T) {
names = names[idx:]
if skipTo {
- n, err := migrate.Up(context.Background(), harness.DBURL(dbName), start)
+ n, err := migrate.Up(context.Background(), testURL, start)
if err != nil {
t.Fatal("failed to apply skip migrations:", err)
}
@@ -593,92 +262,60 @@ func TestMigrations(t *testing.T) {
t.Logf("Skipping to %s", start)
}
- snapshot := func(t *testing.T, name string) []pgDumpEntry {
- data, err := exec.Command("pg_dump",
- "-d", harness.DBURL(dbName),
- "-O",
- ).Output()
- if err != nil {
- t.Fatal("failed to dump db:", err)
- }
- return parsePGDump(data, name)
- }
- mm := 0
- checkDiff := func(t *testing.T, typ, migrationName string, a, b []pgDumpEntry) bool {
- m1 := make(map[string]string)
- m2 := make(map[string]string)
- for _, e := range a {
- m1[e.Name] = e.Body
- }
- for _, e := range b {
- m2[e.Name] = e.Body
- }
- var mismatch bool
- for _, e := range a {
- body, ok := m2[e.Name]
- if !ok {
- mismatch = true
- t.Errorf("%s missing\n%s\n%s", typ, e.Name, indent(e.Body))
- continue
- }
- if !e.matchesBody(migrationName, body) {
- mismatch = true
- t.Errorf("%s mismatch\n%s\ngot\n%s\nwant\n%s", typ, e.Name, indent(body), indent(e.Body))
- continue
- }
- }
- for _, e := range b {
- _, ok := m1[e.Name]
- if !ok {
- mismatch = true
- t.Errorf("%s leftover\n%s\n%s", typ, e.Name, indent(e.Body))
- }
- }
+ snapshot := func(t *testing.T, name string) *migratetest.Snapshot {
+ t.Helper()
- mm++
- return mismatch
+ snap, err := migratetest.NewSnapshotURL(context.Background(), testURL)
+ require.NoErrorf(t, err, "failed to create snapshot for %s", name)
+ return snap
}
+
names = names[1:]
for i, migrationName := range names[1:] {
lastMigrationName := names[i]
- var applied bool
+ var beforeUpSnap *migratetest.Snapshot
pass := t.Run(migrationName, func(t *testing.T) {
ctx := context.Background()
- orig := snapshot(t, migrationName)
- n, err = migrate.Up(ctx, harness.DBURL(dbName), migrationName)
- if err != nil {
- t.Fatalf("failed to apply UP migration: %v", err)
+
+ if beforeUpSnap == nil {
+ beforeUpSnap = snapshot(t, migrationName)
}
+
+ n, err = migrate.Up(ctx, testURL, migrationName)
+ require.NoError(t, err, "failed to apply UP migration")
if n == 0 {
+ // no more migrations are left, so end the test
return
}
- applied = true
- upSnap := snapshot(t, migrationName)
- _, err = migrate.Down(ctx, harness.DBURL(dbName), lastMigrationName)
- if err != nil {
- t.Fatalf("failed to apply DOWN migration: %v", err)
- }
- applied = false
- s := snapshot(t, migrationName)
- if checkDiff(t, "DOWN", migrationName, orig, s) {
- t.Fatalf("DOWN migration did not restore previous schema")
- }
- _, err = migrate.Up(ctx, harness.DBURL(dbName), migrationName)
- if err != nil {
- t.Fatalf("failed to apply UP migration (2nd time): %v", err)
+ afterUpSnap1 := snapshot(t, migrationName)
+
+ _, err = migrate.Down(ctx, testURL, lastMigrationName)
+ require.NoError(t, err, "failed to apply DOWN migration")
+
+ afterDownSnap := snapshot(t, migrationName)
+ pass := t.Run("Down", func(t *testing.T) {
+ rules.RequireEqualDown(t, beforeUpSnap, afterDownSnap)
+ })
+ if !pass {
+ return
}
- applied = true
- s = snapshot(t, migrationName)
- if checkDiff(t, "UP", migrationName, upSnap, s) {
- t.Fatalf("UP migration did not restore previous schema")
+
+ _, err = migrate.Up(ctx, testURL, migrationName)
+ require.NoError(t, err, "failed to apply UP migration (2nd time)")
+
+ afterUpSnap2 := snapshot(t, migrationName)
+ pass = t.Run("Up", func(t *testing.T) {
+ rules.RequireEqualUp(t, afterUpSnap1, afterUpSnap2)
+ })
+ if !pass {
+ return
}
+
+ beforeUpSnap = afterUpSnap2 // save for next iteration
})
- if !pass && !applied {
- n, err = migrate.Up(context.Background(), harness.DBURL(dbName), migrationName)
- if err != nil || n == 0 {
- t.Fatalf("failed to apply UP migration; abort")
- }
+ if !pass {
+ return
}
}
}
diff --git a/util/errutil/maperror.go b/util/errutil/maperror.go
index 9d7cec01b3..eb0bcaee8c 100644
--- a/util/errutil/maperror.go
+++ b/util/errutil/maperror.go
@@ -43,6 +43,9 @@ func MapDBError(err error) error {
return validation.NewFieldError("UserID", "user does not exist")
}
case "23505": // unique constraint
+ if dbErr.ConstraintName == "idx_int_key_name_svc_ext" {
+ return validation.NewFieldError("Name", "already in use")
+ }
if dbErr.ConstraintName == "auth_basic_users_username_key" {
return validation.NewFieldError("Username", "already in use")
}
diff --git a/web/src/app/services/IntegrationKeyDeleteDialog.tsx b/web/src/app/services/IntegrationKeyDeleteDialog.tsx
index d87faa0d2a..ec7d193f4b 100644
--- a/web/src/app/services/IntegrationKeyDeleteDialog.tsx
+++ b/web/src/app/services/IntegrationKeyDeleteDialog.tsx
@@ -2,9 +2,14 @@ import React from 'react'
import { gql, useQuery, useMutation } from 'urql'
import { nonFieldErrors } from '../util/errutil'
-import Spinner from '../loading/components/Spinner'
import { GenericError } from '../error-pages'
import FormDialog from '../dialogs/FormDialog'
+import {
+ Checkbox,
+ FormControl,
+ FormControlLabel,
+ FormHelperText,
+} from '@mui/material'
const query = gql`
query ($id: ID!) {
@@ -12,6 +17,7 @@ const query = gql`
id
name
serviceID
+ externalSystemName
}
}
`
@@ -26,17 +32,19 @@ export default function IntegrationKeyDeleteDialog(props: {
integrationKeyID: string
onClose: () => void
}): JSX.Element {
- const [{ fetching, error, data }] = useQuery({
+ const [{ error, data }] = useQuery({
query,
variables: { id: props.integrationKeyID },
})
+ const extSystemName = data?.integrationKey?.externalSystemName || ''
+ const [confirmed, setConfirmed] = React.useState(!extSystemName) // only require confirmation if external system name is present
+ const [confirmError, setConfirmError] = React.useState(false)
const [deleteKeyStatus, deleteKey] = useMutation(mutation)
- if (fetching && !data) return
if (error) return
- if (!fetching && !deleteKeyStatus.fetching && data?.integrationKey === null) {
+ if (!data?.integrationKey) {
return (
+ {
+ setConfirmed(e.target.checked)
+ setConfirmError(false)
+ }}
+ />
+ }
+ label='I understand the consequences of deleting this key'
+ />
+
+ {confirmError ? (
+ 'Please confirm'
+ ) : (
+
+ Deleting this key may break integrations with
+ {extSystemName}
+
+ )}
+
+
+ )
+ }
+
return (
{
+ if (!confirmed) {
+ setConfirmError(true)
+ return
+ }
+ setConfirmError(false)
+
const input = [
{
type: 'integrationKey',
diff --git a/web/src/app/services/IntegrationKeyList.tsx b/web/src/app/services/IntegrationKeyList.tsx
index 8bcaf6ba41..fa97a27247 100644
--- a/web/src/app/services/IntegrationKeyList.tsx
+++ b/web/src/app/services/IntegrationKeyList.tsx
@@ -13,12 +13,20 @@ import IntegrationKeyDeleteDialog from './IntegrationKeyDeleteDialog'
import CopyText from '../util/CopyText'
import AppLink from '../util/AppLink'
import { useIsWidthDown } from '../util/useWidth'
-import { Add } from '@mui/icons-material'
+import { Add, ArrowDownward } from '@mui/icons-material'
import makeStyles from '@mui/styles/makeStyles'
import Spinner from '../loading/components/Spinner'
import { GenericError } from '../error-pages'
import { IntegrationKey } from '../../schema'
import { useFeatures } from '../util/RequireConfig'
+import {
+ Accordion,
+ AccordionDetails,
+ AccordionSummary,
+ Chip,
+ Divider,
+ Typography,
+} from '@mui/material'
const query = gql`
query ($serviceID: ID!) {
@@ -29,6 +37,7 @@ const query = gql`
type
name
href
+ externalSystemName
}
}
}
@@ -50,6 +59,12 @@ const useStyles = makeStyles({
})
const sortItems = (a: IntegrationKey, b: IntegrationKey): number => {
+ const extA = a.externalSystemName || ''
+ const extB = b.externalSystemName || ''
+ if (extA.toLowerCase() < extB.toLowerCase()) return -1
+ if (extA.toLowerCase() > extB.toLowerCase()) return 1
+ if (extA < extB) return -1
+ if (extA > extB) return 1
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1
if (a.name < b.name) return -1
@@ -101,6 +116,7 @@ export default function IntegrationKeyList(props: {
const items = (data.service.integrationKeys || [])
.slice()
.sort(sortItems)
+ .filter((key: IntegrationKey) => !key.externalSystemName)
.map(
(key: IntegrationKey): FlatListListItem => ({
title: key.name,
@@ -123,6 +139,25 @@ export default function IntegrationKeyList(props: {
}),
)
+ const extItems = (data.service.integrationKeys || [])
+ .slice()
+ .sort(sortItems)
+ .filter((key: IntegrationKey) => !!key.externalSystemName)
+ .map(
+ (key: IntegrationKey): FlatListListItem => ({
+ title: key.name,
+ subText: ,
+ secondaryAction: (
+ setDeleteDialog(key.id)}
+ size='large'
+ >
+
+
+ ),
+ }),
+ )
+
return (
@@ -151,6 +186,22 @@ export default function IntegrationKeyList(props: {
)
}
/>
+ {!!extItems.length && (
+
+
+
+ }>
+ Externally Managed Keys
+
+
+
+
+
+
+ )}
diff --git a/web/src/app/worker/worker.ts b/web/src/app/worker/worker.ts
index 15692936fd..bb5a4c4871 100644
--- a/web/src/app/worker/worker.ts
+++ b/web/src/app/worker/worker.ts
@@ -1,7 +1,19 @@
import methods from './methods'
self.onmessage = (e) => {
- const method = e.data.method as keyof typeof methods
- const result = methods[method](e.data.arg)
+ const methodName = e.data.method as keyof typeof methods
+
+ if (!(methodName in methods)) {
+ // Shouldn't happen, but ensures that we can't unknowingly
+ // call a method that doesn't exist, or is on the prototype.
+ throw new Error('Invalid method')
+ }
+
+ const method = methods[methodName]
+ if (typeof method !== 'function') {
+ throw new Error('Method is not a function')
+ }
+
+ const result = method(e.data.arg)
self.postMessage(result)
}
diff --git a/web/src/schema.d.ts b/web/src/schema.d.ts
index cf76ef5f1d..44b6bd664f 100644
--- a/web/src/schema.d.ts
+++ b/web/src/schema.d.ts
@@ -220,6 +220,7 @@ export interface CreateHeartbeatMonitorInput {
}
export interface CreateIntegrationKeyInput {
+ externalSystemName?: null | string
name: string
serviceID?: null | string
type: IntegrationKeyType
@@ -534,6 +535,7 @@ export type InlineDisplayInfo =
export type Int = string
export interface IntegrationKey {
+ externalSystemName?: null | string
href: string
id: string
name: string
diff --git a/yarn.lock b/yarn.lock
index 173b23a5d1..5bcca3bf88 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1500,7 +1500,16 @@ __metadata:
languageName: node
linkType: hard
-"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
+"@babel/runtime@npm:^7.1.2":
+ version: 7.24.4
+ resolution: "@babel/runtime@npm:7.24.4"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3
+ languageName: node
+ linkType: hard
+
+"@babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
version: 7.23.9
resolution: "@babel/runtime@npm:7.23.9"
dependencies:
@@ -2586,7 +2595,7 @@ __metadata:
languageName: node
linkType: hard
-"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.0, @eslint-community/regexpp@npm:^4.6.1":
+"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.0, @eslint-community/regexpp@npm:^4.6.1":
version: 4.10.0
resolution: "@eslint-community/regexpp@npm:4.10.0"
checksum: 2a6e345429ea8382aaaf3a61f865cae16ed44d31ca917910033c02dc00d505d939f10b81e079fa14d43b51499c640138e153b7e40743c4c094d9df97d4e56f7b
@@ -2643,7 +2652,7 @@ __metadata:
languageName: node
linkType: hard
-"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.5, @floating-ui/react-dom@npm:^2.0.6":
+"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.6, @floating-ui/react-dom@npm:^2.0.8":
version: 2.0.8
resolution: "@floating-ui/react-dom@npm:2.0.8"
dependencies:
@@ -3262,14 +3271,14 @@ __metadata:
languageName: node
linkType: hard
-"@mui/base@npm:5.0.0-beta.32":
- version: 5.0.0-beta.32
- resolution: "@mui/base@npm:5.0.0-beta.32"
+"@mui/base@npm:5.0.0-beta.33":
+ version: 5.0.0-beta.33
+ resolution: "@mui/base@npm:5.0.0-beta.33"
dependencies:
"@babel/runtime": ^7.23.8
- "@floating-ui/react-dom": ^2.0.5
+ "@floating-ui/react-dom": ^2.0.6
"@mui/types": ^7.2.13
- "@mui/utils": ^5.15.5
+ "@mui/utils": ^5.15.6
"@popperjs/core": ^2.11.8
clsx: ^2.1.0
prop-types: ^15.8.1
@@ -3280,18 +3289,18 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
- checksum: 5f27be8914c072ffcbe6720de9aa6129180e68927657e8bcbc03a6f322d1ee6c6740a199d72ed0b490a7b29b79cc0c59d1e05a427089b17f4cbc9cc756e67506
+ checksum: 5724b2ad6971254944cada34ed06e7bda90c719d01ff5491af71f58e9a1cb6d804dda03bfc16fe5220f817acea18b178ef6b16475e99551ab89348e1e3057bd2
languageName: node
linkType: hard
-"@mui/base@npm:5.0.0-beta.33":
- version: 5.0.0-beta.33
- resolution: "@mui/base@npm:5.0.0-beta.33"
+"@mui/base@npm:5.0.0-beta.40":
+ version: 5.0.0-beta.40
+ resolution: "@mui/base@npm:5.0.0-beta.40"
dependencies:
- "@babel/runtime": ^7.23.8
- "@floating-ui/react-dom": ^2.0.6
- "@mui/types": ^7.2.13
- "@mui/utils": ^5.15.6
+ "@babel/runtime": ^7.23.9
+ "@floating-ui/react-dom": ^2.0.8
+ "@mui/types": ^7.2.14
+ "@mui/utils": ^5.15.14
"@popperjs/core": ^2.11.8
clsx: ^2.1.0
prop-types: ^15.8.1
@@ -3302,14 +3311,14 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
- checksum: 5724b2ad6971254944cada34ed06e7bda90c719d01ff5491af71f58e9a1cb6d804dda03bfc16fe5220f817acea18b178ef6b16475e99551ab89348e1e3057bd2
+ checksum: 9c084ee67de372411a71af5eca9a5367db9f5bce57bb43973629c522760fe64fa2a43d2934dccd24d6dcbcd0ed399c5fc5c461226c86104f5767de1c9b8deba2
languageName: node
linkType: hard
-"@mui/core-downloads-tracker@npm:^5.15.5":
- version: 5.15.7
- resolution: "@mui/core-downloads-tracker@npm:5.15.7"
- checksum: cdaea04222020086fd68e25bdf0f4dfdfc9a3b58a558297ef0a247f02cce8ea7671f9a31c07c5b53cfe553d24110baed2b03b701b1bea60f5c2b2e3ba56ba6fc
+"@mui/core-downloads-tracker@npm:^5.15.15":
+ version: 5.15.15
+ resolution: "@mui/core-downloads-tracker@npm:5.15.15"
+ checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc
languageName: node
linkType: hard
@@ -3358,19 +3367,19 @@ __metadata:
languageName: node
linkType: hard
-"@mui/material@npm:5.15.5":
- version: 5.15.5
- resolution: "@mui/material@npm:5.15.5"
+"@mui/material@npm:5.15.15":
+ version: 5.15.15
+ resolution: "@mui/material@npm:5.15.15"
dependencies:
- "@babel/runtime": ^7.23.8
- "@mui/base": 5.0.0-beta.32
- "@mui/core-downloads-tracker": ^5.15.5
- "@mui/system": ^5.15.5
- "@mui/types": ^7.2.13
- "@mui/utils": ^5.15.5
+ "@babel/runtime": ^7.23.9
+ "@mui/base": 5.0.0-beta.40
+ "@mui/core-downloads-tracker": ^5.15.15
+ "@mui/system": ^5.15.15
+ "@mui/types": ^7.2.14
+ "@mui/utils": ^5.15.14
"@types/react-transition-group": ^4.4.10
clsx: ^2.1.0
- csstype: ^3.1.2
+ csstype: ^3.1.3
prop-types: ^15.8.1
react-is: ^18.2.0
react-transition-group: ^4.4.5
@@ -3387,11 +3396,28 @@ __metadata:
optional: true
"@types/react":
optional: true
- checksum: dbfcb31810c674d9ab3b9145752433de3917d9c0d1b491bdff84c44b8f1124e8fe8ab04fa09b974b497983b7bd3011b86fb441ad365f979f971d3ddb46712060
+ checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7
languageName: node
linkType: hard
-"@mui/private-theming@npm:^5.15.5, @mui/private-theming@npm:^5.15.6, @mui/private-theming@npm:^5.15.7":
+"@mui/private-theming@npm:^5.15.14":
+ version: 5.15.14
+ resolution: "@mui/private-theming@npm:5.15.14"
+ dependencies:
+ "@babel/runtime": ^7.23.9
+ "@mui/utils": ^5.15.14
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@types/react": ^17.0.0 || ^18.0.0
+ react: ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c
+ languageName: node
+ linkType: hard
+
+"@mui/private-theming@npm:^5.15.6":
version: 5.15.7
resolution: "@mui/private-theming@npm:5.15.7"
dependencies:
@@ -3408,13 +3434,13 @@ __metadata:
languageName: node
linkType: hard
-"@mui/styled-engine@npm:^5.15.6, @mui/styled-engine@npm:^5.15.7":
- version: 5.15.7
- resolution: "@mui/styled-engine@npm:5.15.7"
+"@mui/styled-engine@npm:^5.15.14, @mui/styled-engine@npm:^5.15.6":
+ version: 5.15.14
+ resolution: "@mui/styled-engine@npm:5.15.14"
dependencies:
"@babel/runtime": ^7.23.9
"@emotion/cache": ^11.11.0
- csstype: ^3.1.2
+ csstype: ^3.1.3
prop-types: ^15.8.1
peerDependencies:
"@emotion/react": ^11.4.1
@@ -3425,21 +3451,21 @@ __metadata:
optional: true
"@emotion/styled":
optional: true
- checksum: 270901d08bf662bf652d3cb18684ea9c90658b1fec7a8bc3300e87414c70acbe8defe79745bda85ac6fd015bf9d77ce7878386944de9b3ad087072ac7161343b
+ checksum: 23b45c859a4f0d2b10933d06a6082c0ff093f7b6d8d32a2bfe3a6e515fe46d7a38ca9e7150d45c025a2e98d963bae9a5991d131cf4748b62670075ef0fa321ed
languageName: node
linkType: hard
-"@mui/styles@npm:5.15.5":
- version: 5.15.5
- resolution: "@mui/styles@npm:5.15.5"
+"@mui/styles@npm:5.15.15":
+ version: 5.15.15
+ resolution: "@mui/styles@npm:5.15.15"
dependencies:
- "@babel/runtime": ^7.23.8
+ "@babel/runtime": ^7.23.9
"@emotion/hash": ^0.9.1
- "@mui/private-theming": ^5.15.5
- "@mui/types": ^7.2.13
- "@mui/utils": ^5.15.5
+ "@mui/private-theming": ^5.15.14
+ "@mui/types": ^7.2.14
+ "@mui/utils": ^5.15.14
clsx: ^2.1.0
- csstype: ^3.1.2
+ csstype: ^3.1.3
hoist-non-react-statics: ^3.3.2
jss: ^10.10.0
jss-plugin-camel-case: ^10.10.0
@@ -3456,7 +3482,7 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
- checksum: dc131c0e7763f7ac4fd96a1db3dd85abf59de5429a73f7cf9ed15d423fb9bb5883835c1951d36e8804da9ab2ed13d603ed349f12e7cd15885f8279d90d13511b
+ checksum: 5e436a8a22ae9a2e6fcb63ead3a6eff2092cc9731fce0b22d04ab9c67639a173a0e27fb617628e7720592862118a32248be458bedfabaf1de5448543a97b0307
languageName: node
linkType: hard
@@ -3488,17 +3514,17 @@ __metadata:
languageName: node
linkType: hard
-"@mui/system@npm:^5.15.5, @mui/system@npm:^5.15.6":
- version: 5.15.7
- resolution: "@mui/system@npm:5.15.7"
+"@mui/system@npm:^5.15.15, @mui/system@npm:^5.15.6":
+ version: 5.15.15
+ resolution: "@mui/system@npm:5.15.15"
dependencies:
"@babel/runtime": ^7.23.9
- "@mui/private-theming": ^5.15.7
- "@mui/styled-engine": ^5.15.7
- "@mui/types": ^7.2.13
- "@mui/utils": ^5.15.7
+ "@mui/private-theming": ^5.15.14
+ "@mui/styled-engine": ^5.15.14
+ "@mui/types": ^7.2.14
+ "@mui/utils": ^5.15.14
clsx: ^2.1.0
- csstype: ^3.1.2
+ csstype: ^3.1.3
prop-types: ^15.8.1
peerDependencies:
"@emotion/react": ^11.5.0
@@ -3512,23 +3538,23 @@ __metadata:
optional: true
"@types/react":
optional: true
- checksum: 346ae540b511b3d5baee544b8a8304fd9bbf87c076faa1abec973f4e9a3c412ec8d8762138902229f91112c2826924c67e8b24b5273a4f6476e7c5b361e581b5
+ checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f
languageName: node
linkType: hard
-"@mui/types@npm:^7.2.13":
- version: 7.2.13
- resolution: "@mui/types@npm:7.2.13"
+"@mui/types@npm:^7.2.13, @mui/types@npm:^7.2.14":
+ version: 7.2.14
+ resolution: "@mui/types@npm:7.2.14"
peerDependencies:
"@types/react": ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
- checksum: 58dfc96f9654288519ff01d6b54e6a242f05cadad51210deb85710a81be4fa1501a116c8968e2614b16c748fc1f407dc23beeeeae70fa37fceb6c6de876ff70d
+ checksum: 615c9f9110933157f5d3c4fee69d6e70b98fc0d9ebc3b63079b6a1e23e6b389748687a25ab4ac15b56166fc228885da87c3929503b41fa322cfdee0f6d411206
languageName: node
linkType: hard
-"@mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.5, @mui/utils@npm:^5.15.6, @mui/utils@npm:^5.15.7":
+"@mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.6, @mui/utils@npm:^5.15.7":
version: 5.15.7
resolution: "@mui/utils@npm:5.15.7"
dependencies:
@@ -3546,6 +3572,24 @@ __metadata:
languageName: node
linkType: hard
+"@mui/utils@npm:^5.15.14":
+ version: 5.15.14
+ resolution: "@mui/utils@npm:5.15.14"
+ dependencies:
+ "@babel/runtime": ^7.23.9
+ "@types/prop-types": ^15.7.11
+ prop-types: ^15.8.1
+ react-is: ^18.2.0
+ peerDependencies:
+ "@types/react": ^17.0.0 || ^18.0.0
+ react: ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893
+ languageName: node
+ linkType: hard
+
"@mui/x-data-grid@npm:6.19.6":
version: 6.19.6
resolution: "@mui/x-data-grid@npm:6.19.6"
@@ -6280,10 +6324,10 @@ __metadata:
languageName: node
linkType: hard
-"@types/chance@npm:1.1.4":
- version: 1.1.4
- resolution: "@types/chance@npm:1.1.4"
- checksum: 0ce6a654e6702237800b01ae7889209a98752ed4792d810b5007c27c046972988ac6fcc36063bdc7ede37d3ab1d0fd0a7bb3e405d4566c80debd9e663a90bbb0
+"@types/chance@npm:1.1.6":
+ version: 1.1.6
+ resolution: "@types/chance@npm:1.1.6"
+ checksum: a1845ff0a70989d581b8f7628aaef1807276c0ae22d0c038013ebcac4f4bd57e6a765319377994cc3cae2122838638fdb2afe5232ee6b987b3f7ea2cddecbead
languageName: node
linkType: hard
@@ -6615,7 +6659,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.9":
+"@types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9":
version: 7.0.15
resolution: "@types/json-schema@npm:7.0.15"
checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98
@@ -6858,13 +6902,20 @@ __metadata:
languageName: node
linkType: hard
-"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4, @types/semver@npm:^7.5.0":
+"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4":
version: 7.5.6
resolution: "@types/semver@npm:7.5.6"
checksum: 563a0120ec0efcc326567db2ed920d5d98346f3638b6324ea6b50222b96f02a8add3c51a916b6897b51523aad8ac227d21d3dcf8913559f1bfc6c15b14d23037
languageName: node
linkType: hard
+"@types/semver@npm:^7.5.8":
+ version: 7.5.8
+ resolution: "@types/semver@npm:7.5.8"
+ checksum: ea6f5276f5b84c55921785a3a27a3cd37afee0111dfe2bcb3e03c31819c197c782598f17f0b150a69d453c9584cd14c4c4d7b9a55d2c5e6cacd4d66fdb3b3663
+ languageName: node
+ linkType: hard
+
"@types/send@npm:*":
version: 0.17.4
resolution: "@types/send@npm:0.17.4"
@@ -7010,28 +7061,28 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/eslint-plugin@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/eslint-plugin@npm:7.1.0"
+"@typescript-eslint/eslint-plugin@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/eslint-plugin@npm:7.7.0"
dependencies:
- "@eslint-community/regexpp": ^4.5.1
- "@typescript-eslint/scope-manager": 7.1.0
- "@typescript-eslint/type-utils": 7.1.0
- "@typescript-eslint/utils": 7.1.0
- "@typescript-eslint/visitor-keys": 7.1.0
+ "@eslint-community/regexpp": ^4.10.0
+ "@typescript-eslint/scope-manager": 7.7.0
+ "@typescript-eslint/type-utils": 7.7.0
+ "@typescript-eslint/utils": 7.7.0
+ "@typescript-eslint/visitor-keys": 7.7.0
debug: ^4.3.4
graphemer: ^1.4.0
- ignore: ^5.2.4
+ ignore: ^5.3.1
natural-compare: ^1.4.0
- semver: ^7.5.4
- ts-api-utils: ^1.0.1
+ semver: ^7.6.0
+ ts-api-utils: ^1.3.0
peerDependencies:
"@typescript-eslint/parser": ^7.0.0
eslint: ^8.56.0
peerDependenciesMeta:
typescript:
optional: true
- checksum: 01d56d92560980fa8daaef2cb5b1e9b5231a766d6aa02697a87d079575399c90f3864e5d6032f889672329cece885faecf696683e380ce23a094fc6ef409572d
+ checksum: f97348425d114282407f4f524cdc618199d0d6d86e4e556709063b07611192068872cbd7f612cbd670617d958ee4519b25eeca0bccbac1b08433ce41511d3825
languageName: node
linkType: hard
@@ -7073,30 +7124,30 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/scope-manager@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/scope-manager@npm:7.1.0"
+"@typescript-eslint/scope-manager@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/scope-manager@npm:7.7.0"
dependencies:
- "@typescript-eslint/types": 7.1.0
- "@typescript-eslint/visitor-keys": 7.1.0
- checksum: 737c010cb60eedb2824038995150146a2099b09d0194ee0e7a2b730f29603775eba54b5260731a26e1056c4cdcc1847b5ea505228e9c240b6e31e3ed4b7a1d75
+ "@typescript-eslint/types": 7.7.0
+ "@typescript-eslint/visitor-keys": 7.7.0
+ checksum: cb280d4aa64cdefee362ef97b6fde3ae86a376fccff7f012e4e635ffe544dd90be37b340c7099784d0fbebb37b925aab6b53195825b41cee38e2382d0b552871
languageName: node
linkType: hard
-"@typescript-eslint/type-utils@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/type-utils@npm:7.1.0"
+"@typescript-eslint/type-utils@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/type-utils@npm:7.7.0"
dependencies:
- "@typescript-eslint/typescript-estree": 7.1.0
- "@typescript-eslint/utils": 7.1.0
+ "@typescript-eslint/typescript-estree": 7.7.0
+ "@typescript-eslint/utils": 7.7.0
debug: ^4.3.4
- ts-api-utils: ^1.0.1
+ ts-api-utils: ^1.3.0
peerDependencies:
eslint: ^8.56.0
peerDependenciesMeta:
typescript:
optional: true
- checksum: 07c4261da12ac57a7f03064192e20bdc473074839057deb7a2d289ceb5f205f419fb5c753d81a2ed13493ae3cfe60d371348489a326474d9c4cb810c3dd96523
+ checksum: 74c07e4fcc8e6ee7870a161596d25ecfa22624947d94ca9af7147590caa13b6388f0e55101961ab02f77e7e6cffdaf19895575d7329dda50fa18fc71bf15f6b7
languageName: node
linkType: hard
@@ -7114,10 +7165,10 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/types@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/types@npm:7.1.0"
- checksum: ad1e95ee83e9af7569c61260e62e4f4a42c8b82c57c33880c24dba44d1ab6792f5063e71ddf5176a1846b97158caba456805271787785250a937bba0e3df06d0
+"@typescript-eslint/types@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/types@npm:7.7.0"
+ checksum: c47aae2c1474b85fab012e0518c57685c595f11775b615b6a6749f943aa7a98554d9eb7054114850679f46699578049998408a492e0c1abd3bded2aee8e261a5
languageName: node
linkType: hard
@@ -7158,39 +7209,39 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/typescript-estree@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/typescript-estree@npm:7.1.0"
+"@typescript-eslint/typescript-estree@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/typescript-estree@npm:7.7.0"
dependencies:
- "@typescript-eslint/types": 7.1.0
- "@typescript-eslint/visitor-keys": 7.1.0
+ "@typescript-eslint/types": 7.7.0
+ "@typescript-eslint/visitor-keys": 7.7.0
debug: ^4.3.4
globby: ^11.1.0
is-glob: ^4.0.3
- minimatch: 9.0.3
- semver: ^7.5.4
- ts-api-utils: ^1.0.1
+ minimatch: ^9.0.4
+ semver: ^7.6.0
+ ts-api-utils: ^1.3.0
peerDependenciesMeta:
typescript:
optional: true
- checksum: a4db9f2b5094f3fdeaa09ca93ffefe23a7cfab3924c870b7277d36d1f9e3e9e0bd4fb10d9a4bae75d4ce5c0d1a0193888742f080e7f43a9f1b6d105f05f570c0
+ checksum: 54d16b2a083bff3c6d38fbee56465403bbcba411bf25e94f2d8bbbbd8b4b35c151c7845997e5141224f8dba5bc1f34964762713035d49113700efd7381246d02
languageName: node
linkType: hard
-"@typescript-eslint/utils@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/utils@npm:7.1.0"
+"@typescript-eslint/utils@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/utils@npm:7.7.0"
dependencies:
"@eslint-community/eslint-utils": ^4.4.0
- "@types/json-schema": ^7.0.12
- "@types/semver": ^7.5.0
- "@typescript-eslint/scope-manager": 7.1.0
- "@typescript-eslint/types": 7.1.0
- "@typescript-eslint/typescript-estree": 7.1.0
- semver: ^7.5.4
+ "@types/json-schema": ^7.0.15
+ "@types/semver": ^7.5.8
+ "@typescript-eslint/scope-manager": 7.7.0
+ "@typescript-eslint/types": 7.7.0
+ "@typescript-eslint/typescript-estree": 7.7.0
+ semver: ^7.6.0
peerDependencies:
eslint: ^8.56.0
- checksum: 9bf1be1fe7fad71412f5150d6ab74085b50da0f495e15a26f02239c9198a84b9376a827cbaa5ac0372ea914a5731168ac2e8a33190f0bbb84114aed27761959b
+ checksum: 830ff3af96538083d7513c211e39f07375b7e973c135a2b9bbae1ad7509bd4dce33a144a22d896a2ff4c18e9fcccd423535b6f9bb8adafe36e800f16bc53378c
languageName: node
linkType: hard
@@ -7232,13 +7283,13 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/visitor-keys@npm:7.1.0":
- version: 7.1.0
- resolution: "@typescript-eslint/visitor-keys@npm:7.1.0"
+"@typescript-eslint/visitor-keys@npm:7.7.0":
+ version: 7.7.0
+ resolution: "@typescript-eslint/visitor-keys@npm:7.7.0"
dependencies:
- "@typescript-eslint/types": 7.1.0
- eslint-visitor-keys: ^3.4.1
- checksum: 7ddac02dde4e16960ca87f0c05e5c5176fef6203bbf39d217ae15f8db498c262677a5799a258960a8d6bbcbc2ffbb799841e32276d2867f1e2f88bd988606092
+ "@typescript-eslint/types": 7.7.0
+ eslint-visitor-keys: ^3.4.3
+ checksum: 16d0b63b9d98ea1d3d20bd6f9dc3cbd2674055845ad493d98118669d54792b1c167f57ae25beaae2c1107ed07012ac3c3093cca978b2ab49833dc491bc302b33
languageName: node
linkType: hard
@@ -9358,13 +9409,6 @@ __metadata:
languageName: node
linkType: hard
-"css-unit-converter@npm:^1.1.1":
- version: 1.1.2
- resolution: "css-unit-converter@npm:1.1.2"
- checksum: 07888033346a5128f34dbe2f72884c966d24e9f29db24416dcde92860242490617ef9a178ac193a92f730834bbeea026cdc7027701d92ba9bbbe59db7a37eb2a
- languageName: node
- linkType: hard
-
"css-vendor@npm:^2.0.8":
version: 2.0.8
resolution: "css-vendor@npm:2.0.8"
@@ -9391,7 +9435,7 @@ __metadata:
languageName: node
linkType: hard
-"csstype@npm:^3.0.2, csstype@npm:^3.1.2":
+"csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3":
version: 3.1.3
resolution: "csstype@npm:3.1.3"
checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7
@@ -13122,7 +13166,7 @@ __metadata:
languageName: node
linkType: hard
-"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.0":
+"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.0, ignore@npm:^5.3.1":
version: 5.3.1
resolution: "ignore@npm:5.3.1"
checksum: 71d7bb4c1dbe020f915fd881108cbe85a0db3d636a0ea3ba911393c53946711d13a9b1143c7e70db06d571a5822c0a324a6bcde5c9904e7ca5047f01f1bf8cd3
@@ -16166,6 +16210,15 @@ __metadata:
languageName: node
linkType: hard
+"minimatch@npm:^9.0.4":
+ version: 9.0.4
+ resolution: "minimatch@npm:9.0.4"
+ dependencies:
+ brace-expansion: ^2.0.1
+ checksum: cf717f597ec3eed7dabc33153482a2e8d49f4fd3c26e58fd9c71a94c5029a0838728841b93f46bf1263b65a8010e2ee800d0dc9b004ab8ba8b6d1ec07cc115b5
+ languageName: node
+ linkType: hard
+
"minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
@@ -17345,13 +17398,6 @@ __metadata:
languageName: node
linkType: hard
-"postcss-value-parser@npm:^3.3.0":
- version: 3.3.1
- resolution: "postcss-value-parser@npm:3.3.1"
- checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16
- languageName: node
- linkType: hard
-
"postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
@@ -17979,7 +18025,7 @@ __metadata:
languageName: node
linkType: hard
-"react-smooth@npm:^2.0.2":
+"react-smooth@npm:^2.0.4":
version: 2.0.5
resolution: "react-smooth@npm:2.0.5"
dependencies:
@@ -18152,24 +18198,24 @@ __metadata:
languageName: node
linkType: hard
-"recharts@npm:2.8.0":
- version: 2.8.0
- resolution: "recharts@npm:2.8.0"
+"recharts@npm:2.9.2":
+ version: 2.9.2
+ resolution: "recharts@npm:2.9.2"
dependencies:
classnames: ^2.2.5
eventemitter3: ^4.0.1
lodash: ^4.17.19
react-is: ^16.10.2
react-resize-detector: ^8.0.4
- react-smooth: ^2.0.2
+ react-smooth: ^2.0.4
recharts-scale: ^0.4.4
- reduce-css-calc: ^2.1.8
+ tiny-invariant: ^1.3.1
victory-vendor: ^36.6.8
peerDependencies:
prop-types: ^15.6.0
react: ^16.0.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
- checksum: 4638bd5c6c2af8f5c79de5e13cce0e38f06e0bbb0a3c4df27a9b12632fd72c0a0604c8246f55e830f323dfa84a3da7cb2634c2243bb9c775d899fd71f9d4c87a
+ checksum: 77a87e3d91229ac5400240409568e3345ded50fc117e70e43e61a135b44bbc3164048704393aa988201ea2989278e1c4e96ce350f6a2f87044d1f0a48f290e84
languageName: node
linkType: hard
@@ -18183,16 +18229,6 @@ __metadata:
languageName: node
linkType: hard
-"reduce-css-calc@npm:^2.1.8":
- version: 2.1.8
- resolution: "reduce-css-calc@npm:2.1.8"
- dependencies:
- css-unit-converter: ^1.1.1
- postcss-value-parser: ^3.3.0
- checksum: 8fd27c06c4b443b84749a69a8b97d10e6ec7d142b625b41923a8807abb22b9e37e44df14e26cc606a802957be07bdce5e8ee2976a6952a7b438a7727007101e9
- languageName: node
- linkType: hard
-
"redux-devtools-extension@npm:2.13.9":
version: 2.13.9
resolution: "redux-devtools-extension@npm:2.13.9"
@@ -18779,8 +18815,8 @@ __metadata:
"@material/material-color-utilities": 0.2.7
"@mui/icons-material": 5.15.13
"@mui/lab": 5.0.0-alpha.162
- "@mui/material": 5.15.5
- "@mui/styles": 5.15.5
+ "@mui/material": 5.15.15
+ "@mui/styles": 5.15.15
"@mui/system": 5.15.6
"@mui/x-data-grid": 6.19.6
"@playwright/test": 1.41.2
@@ -18794,7 +18830,7 @@ __metadata:
"@storybook/test": 8.0.8
"@storybook/test-runner": 0.17.0
"@storybook/types": 8.0.6
- "@types/chance": 1.1.4
+ "@types/chance": 1.1.6
"@types/diff": 5.0.8
"@types/glob": 8.1.0
"@types/jest": 29.5.12
@@ -18807,7 +18843,7 @@ __metadata:
"@types/react-dom": 18.2.22
"@types/react-transition-group": 4.4.10
"@types/react-virtualized-auto-sizer": 1.0.4
- "@typescript-eslint/eslint-plugin": 7.1.0
+ "@typescript-eslint/eslint-plugin": 7.7.0
"@typescript-eslint/parser": 6.21.0
"@urql/exchange-retry": 1.2.1
bowser: 2.11.0
@@ -18861,7 +18897,7 @@ __metadata:
react-redux: 8.1.3
react-transition-group: 4.4.5
react-virtualized-auto-sizer: 1.0.20
- recharts: 2.8.0
+ recharts: 2.9.2
redux: 4.2.1
redux-devtools-extension: 2.13.9
redux-thunk: 2.4.2
@@ -19037,7 +19073,7 @@ __metadata:
languageName: node
linkType: hard
-"semver@npm:7.6.0":
+"semver@npm:7.6.0, semver@npm:^7.6.0":
version: 7.6.0
resolution: "semver@npm:7.6.0"
dependencies:
@@ -20373,6 +20409,15 @@ __metadata:
languageName: node
linkType: hard
+"ts-api-utils@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "ts-api-utils@npm:1.3.0"
+ peerDependencies:
+ typescript: ">=4.2.0"
+ checksum: c746ddabfdffbf16cb0b0db32bb287236a19e583057f8649ee7c49995bb776e1d3ef384685181c11a1a480369e022ca97512cb08c517b2d2bd82c83754c97012
+ languageName: node
+ linkType: hard
+
"ts-dedent@npm:^2.0.0, ts-dedent@npm:^2.2.0":
version: 2.2.0
resolution: "ts-dedent@npm:2.2.0"