From 2246a8713fc12c1c9e49fa339706a4dc200991a7 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Fri, 5 Jan 2024 02:34:27 +0530 Subject: [PATCH 01/29] :art: Cli queries updated --- src/apps/auth/server/gql/cli-queries.ts | 43 +++++++++++-------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/apps/auth/server/gql/cli-queries.ts b/src/apps/auth/server/gql/cli-queries.ts index 34772ae44..728589df6 100644 --- a/src/apps/auth/server/gql/cli-queries.ts +++ b/src/apps/auth/server/gql/cli-queries.ts @@ -33,7 +33,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.infra_updateVPNDevicePorts, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), cli_getSecret: executor( @@ -59,7 +59,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_getSecret, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), cli_getConfig: executor( @@ -85,7 +85,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_getConfig, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), @@ -243,7 +243,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_listApps, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), cli_listConfigs: executor( @@ -266,7 +266,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_listConfigs, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), cli_listSecrets: executor( @@ -274,13 +274,11 @@ export const cliQueries = (executor: IExecutor) => ({ query Core_listSecrets( $projectName: String! $envName: String! - $search: SearchSecrets $pq: CursorPaginationIn ) { core_listSecrets( projectName: $projectName envName: $envName - search: $search pq: $pq ) { edges { @@ -300,7 +298,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_listSecrets, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), cli_updateDevice: executor( @@ -335,7 +333,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.infra_updateVPNDevice, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), cli_listDevices: executor( @@ -377,7 +375,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.infra_listVPNDevices, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), @@ -418,7 +416,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.infra_getVPNDevice, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), @@ -426,14 +424,9 @@ export const cliQueries = (executor: IExecutor) => ({ gql` query Core_listEnvironments( $projectName: String! - $search: SearchEnvironments $pq: CursorPaginationIn ) { - core_listEnvironments( - projectName: $projectName - search: $search - pq: $pq - ) { + core_listEnvironments(projectName: $projectName, pq: $pq) { edges { cursor node { @@ -467,7 +460,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_listEnvironments, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), @@ -496,7 +489,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: any) => data.core_listProjects, - vars: (_: any) => { }, + vars: (_: any) => {}, } ), @@ -516,7 +509,7 @@ export const cliQueries = (executor: IExecutor) => ({ `, { transformer: (data: AuthCli_GetKubeConfigQuery) => data.infra_getCluster, - vars(_: AuthCli_GetKubeConfigQueryVariables) { }, + vars(_: AuthCli_GetKubeConfigQueryVariables) {}, } ), cli_listClusters: executor( @@ -541,7 +534,7 @@ export const cliQueries = (executor: IExecutor) => ({ transformer(data: AuthCli_ListClustersQuery) { return data.infra_listClusters; }, - vars(_: AuthCli_ListClustersQueryVariables) { }, + vars(_: AuthCli_ListClustersQueryVariables) {}, } ), cli_listAccounts: executor( @@ -559,7 +552,7 @@ export const cliQueries = (executor: IExecutor) => ({ transformer(data: AuthCli_ListAccountsQuery) { return data.accounts_listAccounts; }, - vars(_: AuthCli_ListAccountsQueryVariables) { }, + vars(_: AuthCli_ListAccountsQueryVariables) {}, } ), cli_getCurrentUser: executor( @@ -576,7 +569,7 @@ export const cliQueries = (executor: IExecutor) => ({ transformer(data: AuthCli_GetCurrentUserQuery) { return data.auth_me; }, - vars(_: AuthCli_GetCurrentUserQueryVariables) { }, + vars(_: AuthCli_GetCurrentUserQueryVariables) {}, } ), @@ -589,7 +582,7 @@ export const cliQueries = (executor: IExecutor) => ({ { transformer: (data: AuthCli_CreateRemoteLoginMutation) => data.auth_createRemoteLogin, - vars(_: AuthCli_CreateRemoteLoginMutationVariables) { }, + vars(_: AuthCli_CreateRemoteLoginMutationVariables) {}, } ), @@ -605,7 +598,7 @@ export const cliQueries = (executor: IExecutor) => ({ { transformer: (data: AuthCli_GetRemoteLoginQuery) => data.auth_getRemoteLogin, - vars(_: AuthCli_GetRemoteLoginQueryVariables) { }, + vars(_: AuthCli_GetRemoteLoginQueryVariables) {}, } ), }); From 7470ce359712eb5aa2868acbe3ffc979fd063836 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Fri, 5 Jan 2024 05:09:37 +0530 Subject: [PATCH 02/29] :art: Cli queries updated --- gql-queries-generator/doc/queries.graphql | 29 ++++++---- src/apps/auth/server/gql/cli-queries.ts | 34 ++++++++++++ src/generated/gql/sdl.graphql | 60 +++++++++++++++++++++ src/generated/gql/server.ts | 64 ++++++++++++++++++----- 4 files changed, 164 insertions(+), 23 deletions(-) diff --git a/gql-queries-generator/doc/queries.graphql b/gql-queries-generator/doc/queries.graphql index 791c20c14..27fce6092 100644 --- a/gql-queries-generator/doc/queries.graphql +++ b/gql-queries-generator/doc/queries.graphql @@ -2540,6 +2540,22 @@ mutation consoleDeleteHelmChart($clusterName: String!, $releaseName: String!) { infra_deleteHelmRelease(clusterName: $clusterName, releaseName: $releaseName) } +query authCli_getEnvironment($projectName: String!, $name: String!) { + core_getEnvironment(projectName: $projectName, name: $name) { + spec { + targetNamespace + } + } +} + +mutation authCli_updateDeviceNs($clusterName: String!, $deviceName: String!, $namespace: String!) { + infra_updateVPNDeviceNs( + clusterName: $clusterName + deviceName: $deviceName + namespace: $namespace + ) +} + mutation authCli_updateDevicePort($clusterName: String!, $deviceName: String!, $ports: [PortIn!]!) { infra_updateVPNDevicePorts( clusterName: $clusterName @@ -2736,13 +2752,8 @@ query authCli_listConfigs($projectName: String!, $envName: String!) { } } -query authCli_listSecrets($projectName: String!, $envName: String!, $search: SearchSecrets, $pq: CursorPaginationIn) { - core_listSecrets( - projectName: $projectName - envName: $envName - search: $search - pq: $pq - ) { +query authCli_listSecrets($projectName: String!, $envName: String!, $pq: CursorPaginationIn) { + core_listSecrets(projectName: $projectName, envName: $envName, pq: $pq) { edges { cursor node { @@ -2848,8 +2859,8 @@ query authCli_getDevice($clusterName: String!, $name: String!) { } } -query authCli_listEnvironments($projectName: String!, $search: SearchEnvironments, $pq: CursorPaginationIn) { - core_listEnvironments(projectName: $projectName, search: $search, pq: $pq) { +query authCli_listEnvironments($projectName: String!, $pq: CursorPaginationIn) { + core_listEnvironments(projectName: $projectName, pq: $pq) { edges { cursor node { diff --git a/src/apps/auth/server/gql/cli-queries.ts b/src/apps/auth/server/gql/cli-queries.ts index 728589df6..632307315 100644 --- a/src/apps/auth/server/gql/cli-queries.ts +++ b/src/apps/auth/server/gql/cli-queries.ts @@ -17,6 +17,40 @@ import { } from '~/root/src/generated/gql/server'; export const cliQueries = (executor: IExecutor) => ({ + cli_getEnvironment: executor( + gql` + query Core_getEnvironment($projectName: String!, $name: String!) { + core_getEnvironment(projectName: $projectName, name: $name) { + spec { + targetNamespace + } + } + } + `, + { + transformer: (data: any) => data.core_getEnvironment, + vars: (_: any) => {}, + } + ), + cli_updateDeviceNs: executor( + gql` + mutation Infra_updateVPNDeviceNs( + $clusterName: String! + $deviceName: String! + $namespace: String! + ) { + infra_updateVPNDeviceNs( + clusterName: $clusterName + deviceName: $deviceName + namespace: $namespace + ) + } + `, + { + transformer: (data: any) => data.infra_updateVPNDeviceNs, + vars: (_: any) => {}, + } + ), cli_updateDevicePort: executor( gql` mutation Mutation( diff --git a/src/generated/gql/sdl.graphql b/src/generated/gql/sdl.graphql index f6b5be65f..59f40c97f 100644 --- a/src/generated/gql/sdl.graphql +++ b/src/generated/gql/sdl.graphql @@ -1322,6 +1322,16 @@ input Github__com___kloudlite___operator___apis___crds___v1__ProbeIn { type: String! } +type Github__com___kloudlite___operator___apis___crds___v1__ProjectManagedServiceSpec { + msvcSpec: Github__com___kloudlite___operator___apis___crds___v1__ManagedServiceSpec! + targetNamespace: String! +} + +input Github__com___kloudlite___operator___apis___crds___v1__ProjectManagedServiceSpecIn { + msvcSpec: Github__com___kloudlite___operator___apis___crds___v1__ManagedServiceSpecIn! + targetNamespace: String! +} + type Github__com___kloudlite___operator___apis___crds___v1__ProjectSpec { accountName: String! clusterName: String! @@ -2756,6 +2766,7 @@ type Mutation { core_createImagePullSecret(envName: String!, imagePullSecretIn: ImagePullSecretIn!, projectName: String!): ImagePullSecret core_createManagedResource(envName: String!, mres: ManagedResourceIn!, projectName: String!): ManagedResource core_createProject(project: ProjectIn!): Project + core_createProjectManagedService(pmsvc: ProjectManagedServiceIn!, projectName: String!): ProjectManagedService core_createRouter(envName: String!, projectName: String!, router: RouterIn!): Router core_createSecret(envName: String!, projectName: String!, secret: SecretIn!): Secret core_deleteApp(appName: String!, envName: String!, projectName: String!): Boolean! @@ -2764,6 +2775,7 @@ type Mutation { core_deleteImagePullSecret(envName: String!, projectName: String!, secretName: String!): Boolean! core_deleteManagedResource(envName: String!, mresName: String!, projectName: String!): Boolean! core_deleteProject(name: String!): Boolean! + core_deleteProjectManagedService(pmsvcName: String!, projectName: String!): Boolean! core_deleteRouter(envName: String!, projectName: String!, routerName: String!): Boolean! core_deleteSecret(envName: String!, projectName: String!, secretName: String!): Boolean! core_updateApp(app: AppIn!, envName: String!, projectName: String!): App @@ -2771,6 +2783,7 @@ type Mutation { core_updateEnvironment(env: EnvironmentIn!, projectName: String!): Environment core_updateManagedResource(envName: String!, mres: ManagedResourceIn!, projectName: String!): ManagedResource core_updateProject(project: ProjectIn!): Project + core_updateProjectManagedService(pmsvc: ProjectManagedServiceIn!, projectName: String!): ProjectManagedService core_updateRouter(envName: String!, projectName: String!, router: RouterIn!): Router core_updateSecret(envName: String!, projectName: String!, secret: SecretIn!): Secret cr_addBuild(build: BuildIn!): Build @@ -2807,6 +2820,7 @@ type Mutation { infra_updateNodePool(clusterName: String!, pool: NodePoolIn!): NodePool infra_updateProviderSecret(secret: CloudProviderSecretIn!): CloudProviderSecret infra_updateVPNDevice(clusterName: String!, vpnDevice: VPNDeviceIn!): VPNDevice + infra_updateVPNDeviceNs(clusterName: String!, deviceName: String!, namespace: String!): Boolean! infra_updateVPNDevicePorts(clusterName: String!, deviceName: String!, ports: [PortIn!]!): Boolean! oAuth_addLogin(code: String!, provider: String!, state: String!): Boolean! oAuth_login(code: String!, provider: String!, state: String): Session! @@ -3041,6 +3055,42 @@ input ProjectIn { spec: Github__com___kloudlite___operator___apis___crds___v1__ProjectSpecIn! } +type ProjectManagedService { + accountName: String! + apiVersion: String! + createdBy: Github__com___kloudlite___api___common__CreatedOrUpdatedBy! + creationTime: Date! + displayName: String! + id: String! + kind: String! + lastUpdatedBy: Github__com___kloudlite___api___common__CreatedOrUpdatedBy! + markedForDeletion: Boolean + metadata: Metadata + projectName: String! + recordVersion: Int! + spec: Github__com___kloudlite___operator___apis___crds___v1__ProjectManagedServiceSpec + status: Github__com___kloudlite___operator___pkg___operator__Status + syncStatus: Github__com___kloudlite___api___pkg___types__SyncStatus! + updateTime: Date! +} + +type ProjectManagedServiceEdge { + cursor: String! + node: ProjectManagedService! +} + +input ProjectManagedServiceIn { + displayName: String! + metadata: MetadataIn + spec: Github__com___kloudlite___operator___apis___crds___v1__ProjectManagedServiceSpecIn +} + +type ProjectManagedServicePaginatedRecords { + edges: [ProjectManagedServiceEdge!]! + pageInfo: PageInfo! + totalCount: Int! +} + type ProjectPaginatedRecords { edges: [ProjectEdge!]! pageInfo: PageInfo! @@ -3072,6 +3122,7 @@ type Query { core_getImagePullSecret(envName: String!, name: String!, projectName: String!): ImagePullSecret core_getManagedResource(envName: String!, name: String!, projectName: String!): ManagedResource core_getProject(name: String!): Project + core_getProjectManagedService(name: String!, projectName: String!): ProjectManagedService core_getRouter(envName: String!, name: String!, projectName: String!): Router core_getSecret(envName: String!, name: String!, projectName: String!): Secret core_getSecretValues(queries: [SecretValuesIn!]): [SecretValuesOut!] @@ -3080,6 +3131,7 @@ type Query { core_listEnvironments(pq: CursorPaginationIn, projectName: String!, search: SearchEnvironments): EnvironmentPaginatedRecords core_listImagePullSecrets(envName: String!, pq: CursorPaginationIn, projectName: String!, search: SearchImagePullSecrets): ImagePullSecretPaginatedRecords core_listManagedResources(envName: String!, pq: CursorPaginationIn, projectName: String!, search: SearchManagedResources): ManagedResourcePaginatedRecords + core_listProjectManagedServices(pq: CursorPaginationIn, projectName: String!, search: SearchProjectManagedService): ProjectManagedServicePaginatedRecords core_listProjects(clusterName: String, pq: CursorPaginationIn, search: SearchProjects): ProjectPaginatedRecords core_listRouters(envName: String!, pq: CursorPaginationIn, projectName: String!, search: SearchRouters): RouterPaginatedRecords core_listSecrets(envName: String!, pq: CursorPaginationIn, projectName: String!, search: SearchSecrets): SecretPaginatedRecords @@ -3089,6 +3141,7 @@ type Query { core_resyncImagePullSecret(envName: String!, name: String!, projectName: String!): Boolean! core_resyncManagedResource(envName: String!, name: String!, projectName: String!): Boolean! core_resyncProject(name: String!): Boolean! + core_resyncProjectManagedService(name: String!, projectName: String!): Boolean! core_resyncRouter(envName: String!, name: String!, projectName: String!): Boolean! core_resyncSecret(envName: String!, name: String!, projectName: String!): Boolean! cr_checkUserNameAvailability(name: String!): CRCheckNameAvailabilityOutput! @@ -3302,6 +3355,13 @@ input SearchPersistentVolumes { text: MatchFilterIn } +input SearchProjectManagedService { + isReady: MatchFilterIn + managedServiceName: MatchFilterIn + markedForDeletion: MatchFilterIn + text: MatchFilterIn +} + input SearchProjects { isReady: MatchFilterIn markedForDeletion: MatchFilterIn diff --git a/src/generated/gql/server.ts b/src/generated/gql/server.ts index 6a516b524..3544c80c9 100644 --- a/src/generated/gql/server.ts +++ b/src/generated/gql/server.ts @@ -150,6 +150,13 @@ export type SearchManagedResources = { text?: InputMaybe; }; +export type SearchProjectManagedService = { + isReady?: InputMaybe; + managedServiceName?: InputMaybe; + markedForDeletion?: InputMaybe; + text?: InputMaybe; +}; + export type SearchProjects = { isReady?: InputMaybe; markedForDeletion?: InputMaybe; @@ -557,6 +564,30 @@ export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ProjectSpecIn targetNamespace: Scalars['String']['input']; }; +export type ProjectManagedServiceIn = { + displayName: Scalars['String']['input']; + metadata?: InputMaybe; + spec?: InputMaybe; +}; + +export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ProjectManagedServiceSpecIn = + { + msvcSpec: Github__Com___Kloudlite___Operator___Apis___Crds___V1__ManagedServiceSpecIn; + targetNamespace: Scalars['String']['input']; + }; + +export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ManagedServiceSpecIn = + { + serviceTemplate: Github__Com___Kloudlite___Operator___Apis___Crds___V1__ServiceTemplateIn; + }; + +export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ServiceTemplateIn = + { + apiVersion: Scalars['String']['input']; + kind: Scalars['String']['input']; + spec: Scalars['Map']['input']; + }; + export type RouterIn = { displayName: Scalars['String']['input']; enabled?: InputMaybe; @@ -740,18 +771,6 @@ export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ClusterManage namespace: Scalars['String']['input']; }; -export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ManagedServiceSpecIn = - { - serviceTemplate: Github__Com___Kloudlite___Operator___Apis___Crds___V1__ServiceTemplateIn; - }; - -export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__ServiceTemplateIn = - { - apiVersion: Scalars['String']['input']; - kind: Scalars['String']['input']; - spec: Scalars['Map']['input']; - }; - export type DomainEntryIn = { clusterName: Scalars['String']['input']; displayName: Scalars['String']['input']; @@ -3869,6 +3888,25 @@ export type ConsoleDeleteHelmChartMutation = { infra_deleteHelmRelease: boolean; }; +export type AuthCli_GetEnvironmentQueryVariables = Exact<{ + projectName: Scalars['String']['input']; + name: Scalars['String']['input']; +}>; + +export type AuthCli_GetEnvironmentQuery = { + core_getEnvironment?: { spec?: { targetNamespace?: string } }; +}; + +export type AuthCli_UpdateDeviceNsMutationVariables = Exact<{ + clusterName: Scalars['String']['input']; + deviceName: Scalars['String']['input']; + namespace: Scalars['String']['input']; +}>; + +export type AuthCli_UpdateDeviceNsMutation = { + infra_updateVPNDeviceNs: boolean; +}; + export type AuthCli_UpdateDevicePortMutationVariables = Exact<{ clusterName: Scalars['String']['input']; deviceName: Scalars['String']['input']; @@ -4053,7 +4091,6 @@ export type AuthCli_ListConfigsQuery = { export type AuthCli_ListSecretsQueryVariables = Exact<{ projectName: Scalars['String']['input']; envName: Scalars['String']['input']; - search?: InputMaybe; pq?: InputMaybe; }>; @@ -4134,7 +4171,6 @@ export type AuthCli_GetDeviceQuery = { export type AuthCli_ListEnvironmentsQueryVariables = Exact<{ projectName: Scalars['String']['input']; - search?: InputMaybe; pq?: InputMaybe; }>; From 49a272c903415aeef8994c4c9787960ad47488df Mon Sep 17 00:00:00 2001 From: Bikash Date: Mon, 8 Jan 2024 08:31:55 +0530 Subject: [PATCH 03/29] fixed issue with react-select dep --- package.json | 2 +- pnpm-lock.yaml | 39 +++++++++---------- .../packages+/repos/repo-resources.tsx | 4 +- .../$account+/packages+/repos/route.tsx | 2 +- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 416f599ad..4a48d7ed0 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@codemirror/legacy-modes": "^6.3.3", "@jengaicons/react": "^1.3.0", "@mdx-js/react": "^2.3.0", - "@oshq/react-select": "file:/Users/bikash/Documents/bikash/select/oshq-react-select-1.2.0.tgz", + "@oshq/react-select": "^1.2.0", "@radix-ui/primitive": "^1.0.1", "@radix-ui/react-alert-dialog": "1.0.4", "@radix-ui/react-checkbox": "^1.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69cf50537..5c566f6f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ dependencies: specifier: ^2.3.0 version: 2.3.0(react@18.2.0) '@oshq/react-select': - specifier: file:/Users/bikash/Documents/bikash/select/oshq-react-select-1.2.0.tgz - version: file:../../bikash/select/oshq-react-select-1.2.0.tgz(@radix-ui/react-portal@1.0.4)(classnames@2.5.1)(framer-motion@10.17.8)(rc-virtual-list@3.11.3)(react@18.2.0) + specifier: ^1.2.0 + version: 1.2.0(@radix-ui/react-portal@1.0.4)(classnames@2.5.1)(framer-motion@10.17.8)(rc-virtual-list@3.11.3)(react@18.2.0) '@radix-ui/primitive': specifier: ^1.0.1 version: 1.0.1 @@ -2607,6 +2607,22 @@ packages: json-parse-even-better-errors: 2.3.1 dev: true + /@oshq/react-select@1.2.0(@radix-ui/react-portal@1.0.4)(classnames@2.5.1)(framer-motion@10.17.8)(rc-virtual-list@3.11.3)(react@18.2.0): + resolution: {integrity: sha512-QhuR6D0tbfce1cqWjsHTzJVdJSSJA6rbNzMRXaBoDaxpd94m6SOpCSvhG1vvdCbaL/k1JqVW6bXzu8N7wTtygQ==} + peerDependencies: + '@radix-ui/react-portal': ^1.0.4 + classnames: ^2.3.2 + framer-motion: ^10.16.4 + rc-virtual-list: ^3.11.2 + react: ^18.2.0 || ^17.0.0 || ^16.0.0 + dependencies: + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + classnames: 2.5.1 + framer-motion: 10.17.8(react-dom@18.2.0)(react@18.2.0) + rc-virtual-list: 3.11.3(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + dev: false + /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -10964,22 +10980,3 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: true - - file:../../bikash/select/oshq-react-select-1.2.0.tgz(@radix-ui/react-portal@1.0.4)(classnames@2.5.1)(framer-motion@10.17.8)(rc-virtual-list@3.11.3)(react@18.2.0): - resolution: {integrity: sha512-Vc4MiN1HyjcjqTHEmidK/wc9fTmsdA1d+vtLvzssmn0JPvQIDmvOYrLLKmv2jSN62cptW64gOjvjD2kqRonSXw==, tarball: file:../../bikash/select/oshq-react-select-1.2.0.tgz} - id: file:../../bikash/select/oshq-react-select-1.2.0.tgz - name: '@oshq/react-select' - version: 1.2.0 - peerDependencies: - '@radix-ui/react-portal': ^1.0.4 - classnames: ^2.3.2 - framer-motion: ^10.16.4 - rc-virtual-list: ^3.11.2 - react: ^18.2.0 || ^17.0.0 || ^16.0.0 - dependencies: - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) - classnames: 2.5.1 - framer-motion: 10.17.8(react-dom@18.2.0)(react@18.2.0) - rc-virtual-list: 3.11.3(react-dom@18.2.0)(react@18.2.0) - react: 18.2.0 - dev: false diff --git a/src/apps/console/routes/_main+/$account+/packages+/repos/repo-resources.tsx b/src/apps/console/routes/_main+/$account+/packages+/repos/repo-resources.tsx index eade643bc..efa8275c0 100644 --- a/src/apps/console/routes/_main+/$account+/packages+/repos/repo-resources.tsx +++ b/src/apps/console/routes/_main+/$account+/packages+/repos/repo-resources.tsx @@ -22,7 +22,7 @@ import { } from '~/console/server/r-utils/common'; import { useReload } from '~/root/lib/client/helpers/reloader'; import useClipboard from '~/root/lib/client/hooks/use-clipboard'; -import { gatewayUrl } from '~/root/lib/configs/base-url.cjs'; +import { registryHost } from '~/root/lib/configs/base-url.cjs'; import { handleError } from '~/root/lib/utils/common'; type BaseType = ExtractNodeType; @@ -63,7 +63,7 @@ const RepoUrlView = ({ name }: { name: string }) => { toast.success('Registry url copied successfully.'); }, }); - const url = `${gatewayUrl}/${account}/${name}`; + const url = `${registryHost}/${account}/${name}`; return ( Date: Tue, 9 Jan 2024 04:24:52 +0530 Subject: [PATCH 04/29] :art: Added cli queries --- gql-queries-generator/doc/queries.graphql | 50 +++++++++ .../helpers/execute-query-with-context.ts | 9 +- src/apps/auth/routes/_main+/api.tsx | 8 +- src/apps/auth/server/gql/cli-queries.ts | 106 ++++++++++++++++++ src/generated/gql/sdl.graphql | 77 ++++++++++--- src/generated/gql/server.ts | 75 ++++++++++++- 6 files changed, 295 insertions(+), 30 deletions(-) diff --git a/gql-queries-generator/doc/queries.graphql b/gql-queries-generator/doc/queries.graphql index 27fce6092..a53c85e48 100644 --- a/gql-queries-generator/doc/queries.graphql +++ b/gql-queries-generator/doc/queries.graphql @@ -2540,6 +2540,56 @@ mutation consoleDeleteHelmChart($clusterName: String!, $releaseName: String!) { infra_deleteHelmRelease(clusterName: $clusterName, releaseName: $releaseName) } +query authCli_infraCheckNameAvailability($resType: ResType!, $name: String!, $clusterName: String) { + infra_checkNameAvailability( + resType: $resType + name: $name + clusterName: $clusterName + ) { + result + suggestedNames + } +} + +mutation authCli_createDevice($clusterName: String!, $vpnDevice: VPNDeviceIn!) { + infra_createVPNDevice(clusterName: $clusterName, vpnDevice: $vpnDevice) { + metadata { + name + } + } +} + +query authCli_getConfigSecretMap($projectName: String!, $envName: String!, $configQueries: [ConfigKeyRefIn], $secretQueries: [SecretKeyRefIn!]) { + configs: core_getConfigValues( + projectName: $projectName + envName: $envName + queries: $configQueries + ) { + configName + key + value + } + secrets: core_getSecretValues( + projectName: $projectName + envName: $envName + queries: $secretQueries + ) { + key + secretName + value + } +} + +mutation authCli_interceptApp($projectName: String!, $envName: String!, $appname: String!, $deviceName: String!, $intercept: Boolean!) { + core_interceptApp( + projectName: $projectName + envName: $envName + appname: $appname + deviceName: $deviceName + intercept: $intercept + ) +} + query authCli_getEnvironment($projectName: String!, $name: String!) { core_getEnvironment(projectName: $projectName, name: $name) { spec { diff --git a/lib/server/helpers/execute-query-with-context.ts b/lib/server/helpers/execute-query-with-context.ts index c95d26047..5f9766e29 100644 --- a/lib/server/helpers/execute-query-with-context.ts +++ b/lib/server/helpers/execute-query-with-context.ts @@ -113,18 +113,13 @@ export const ExecuteQueryWithContext = ( } catch (err) { if ((err as AxiosError).response) { console.trace('ErrorIn:', apiName, (err as Error).name); + return (err as AxiosError).response?.data; } console.trace('ErrorIn:', apiName, (err as Error).message); - return { - errors: [ - { - message: (err as Error).message, - }, - ], - }; + throw err; } finally { console.timeEnd(apiName); } diff --git a/src/apps/auth/routes/_main+/api.tsx b/src/apps/auth/routes/_main+/api.tsx index 6fe2e80d2..1ef9c8d0b 100644 --- a/src/apps/auth/routes/_main+/api.tsx +++ b/src/apps/auth/routes/_main+/api.tsx @@ -8,6 +8,12 @@ export const action = async (ctx: IRemixCtx) => { const res = await RootAPIAction(GQLServerHandler)(ctx); return res; } catch (err) { - return json({ errors: [(err as Error).message] }, 500); + return json({ + errors: [ + { + message: (err as Error).message, + }, + ], + }); } }; diff --git a/src/apps/auth/server/gql/cli-queries.ts b/src/apps/auth/server/gql/cli-queries.ts index 632307315..ed8181a58 100644 --- a/src/apps/auth/server/gql/cli-queries.ts +++ b/src/apps/auth/server/gql/cli-queries.ts @@ -17,6 +17,112 @@ import { } from '~/root/src/generated/gql/server'; export const cliQueries = (executor: IExecutor) => ({ + cli_infraCheckNameAvailability: executor( + gql` + query Infra_checkNameAvailability( + $resType: ResType! + $name: String! + $clusterName: String + ) { + infra_checkNameAvailability( + resType: $resType + name: $name + clusterName: $clusterName + ) { + result + suggestedNames + } + } + `, + { + transformer: (data: any) => data.infra_checkNameAvailability, + vars: (_: any) => {}, + } + ), + cli_createDevice: executor( + gql` + mutation Infra_createVPNDevice( + $clusterName: String! + $vpnDevice: VPNDeviceIn! + ) { + infra_createVPNDevice( + clusterName: $clusterName + vpnDevice: $vpnDevice + ) { + metadata { + name + } + } + } + `, + { + transformer: (data: any) => data.infra_createVPNDevice, + vars: (_: any) => {}, + } + ), + + cli_getConfigSecretMap: executor( + gql` + query Core_getConfigValues( + $projectName: String! + $envName: String! + $configQueries: [ConfigKeyRefIn] + $secretQueries: [SecretKeyRefIn!] + ) { + configs: core_getConfigValues( + projectName: $projectName + envName: $envName + queries: $configQueries + ) { + configName + key + value + } + secrets: core_getSecretValues( + projectName: $projectName + envName: $envName + queries: $secretQueries + ) { + key + secretName + value + } + } + `, + { + transformer: (data: any) => { + return { + configs: data.configs, + secrets: data.secrets, + }; + }, + + vars: (_: any) => {}, + } + ), + cli_interceptApp: executor( + gql` + mutation Core_interceptApp( + $projectName: String! + $envName: String! + $appname: String! + $deviceName: String! + $intercept: Boolean! + ) { + core_interceptApp( + projectName: $projectName + envName: $envName + appname: $appname + deviceName: $deviceName + intercept: $intercept + ) + } + `, + { + transformer: (data: any) => data.core_interceptApp, + vars: (_: any) => {}, + } + ), cli_getEnvironment: executor( gql` query Core_getEnvironment($projectName: String!, $name: String!) { diff --git a/src/generated/gql/sdl.graphql b/src/generated/gql/sdl.graphql index 59f40c97f..ae0242e85 100644 --- a/src/generated/gql/sdl.graphql +++ b/src/generated/gql/sdl.graphql @@ -336,23 +336,34 @@ input ConfigIn { metadata: MetadataIn } -type ConfigPaginatedRecords { - edges: [ConfigEdge!]! - pageInfo: PageInfo! - totalCount: Int! +type ConfigKeyRef { + configName: String! + key: String! } -input ConfigValuesIn { - configmapName: String! +input ConfigKeyRefIn { + configName: String! key: String! } -type ConfigValuesOut { - configmapName: String! +type ConfigKeyValueRef { + configName: String! key: String! value: String! } +input ConfigKeyValueRefIn { + configName: String! + key: String! + value: String! +} + +type ConfigPaginatedRecords { + edges: [ConfigEdge!]! + pageInfo: PageInfo! + totalCount: Int! +} + type ConsoleCheckNameAvailabilityOutput { result: Boolean! suggestedNames: [String!] @@ -1153,13 +1164,30 @@ input Github__com___kloudlite___operator___apis___crds___v1__EnvFromIn { type: Github__com___kloudlite___operator___apis___crds___v1__ConfigOrSecret! } +type Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRouting { + mode: Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRoutingMode + privateIngressClass: String + publicIngressClass: String +} + +input Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRoutingIn { + mode: Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRoutingMode +} + +enum Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRoutingMode { + private + public +} + type Github__com___kloudlite___operator___apis___crds___v1__EnvironmentSpec { projectName: String! + routing: Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRouting targetNamespace: String } input Github__com___kloudlite___operator___apis___crds___v1__EnvironmentSpecIn { projectName: String! + routing: Github__com___kloudlite___operator___apis___crds___v1__EnvironmentRoutingIn targetNamespace: String } @@ -1227,11 +1255,13 @@ input Github__com___kloudlite___operator___apis___crds___v1__HttpGetProbeIn { } type Github__com___kloudlite___operator___apis___crds___v1__Https { + clusterIssuer: String enabled: Boolean! forceRedirect: Boolean } input Github__com___kloudlite___operator___apis___crds___v1__HttpsIn { + clusterIssuer: String enabled: Boolean! forceRedirect: Boolean } @@ -1385,7 +1415,6 @@ type Github__com___kloudlite___operator___apis___crds___v1__RouterSpec { ingressClass: String maxBodySizeInMB: Int rateLimit: Github__com___kloudlite___operator___apis___crds___v1__RateLimit - region: String routes: [Github__com___kloudlite___operator___apis___crds___v1__Route!] } @@ -1398,7 +1427,6 @@ input Github__com___kloudlite___operator___apis___crds___v1__RouterSpecIn { ingressClass: String maxBodySizeInMB: Int rateLimit: Github__com___kloudlite___operator___apis___crds___v1__RateLimitIn - region: String routes: [Github__com___kloudlite___operator___apis___crds___v1__RouteIn!] } @@ -2760,6 +2788,7 @@ type Mutation { auth_setRemoteAuthHeader(authHeader: String, loginId: String!): Boolean! auth_signup(email: String!, name: String!, password: String!): Session auth_verifyEmail(token: String!): Session! + core_cloneEnvironment(envName: String!, projectName: String!, sourceEnvName: String!): Environment core_createApp(app: AppIn!, envName: String!, projectName: String!): App core_createConfig(config: ConfigIn!, envName: String!, projectName: String!): Config core_createEnvironment(env: EnvironmentIn!, projectName: String!): Environment @@ -2778,6 +2807,7 @@ type Mutation { core_deleteProjectManagedService(pmsvcName: String!, projectName: String!): Boolean! core_deleteRouter(envName: String!, projectName: String!, routerName: String!): Boolean! core_deleteSecret(envName: String!, projectName: String!, secretName: String!): Boolean! + core_interceptApp(appname: String!, deviceName: String!, envName: String!, intercept: Boolean!, projectName: String!): Boolean! core_updateApp(app: AppIn!, envName: String!, projectName: String!): App core_updateConfig(config: ConfigIn!, envName: String!, projectName: String!): Config core_updateEnvironment(env: EnvironmentIn!, projectName: String!): Environment @@ -3117,7 +3147,7 @@ type Query { core_checkNameAvailability(name: String!, namespace: String, resType: ConsoleResType!): ConsoleCheckNameAvailabilityOutput! core_getApp(envName: String!, name: String!, projectName: String!): App core_getConfig(envName: String!, name: String!, projectName: String!): Config - core_getConfigValues(queries: [ConfigValuesIn!]): [ConfigValuesOut!] + core_getConfigValues(envName: String!, projectName: String!, queries: [ConfigKeyRefIn]): [ConfigKeyValueRef!] core_getEnvironment(name: String!, projectName: String!): Environment core_getImagePullSecret(envName: String!, name: String!, projectName: String!): ImagePullSecret core_getManagedResource(envName: String!, name: String!, projectName: String!): ManagedResource @@ -3125,7 +3155,7 @@ type Query { core_getProjectManagedService(name: String!, projectName: String!): ProjectManagedService core_getRouter(envName: String!, name: String!, projectName: String!): Router core_getSecret(envName: String!, name: String!, projectName: String!): Secret - core_getSecretValues(queries: [SecretValuesIn!]): [SecretValuesOut!] + core_getSecretValues(envName: String!, projectName: String!, queries: [SecretKeyRefIn!]): [SecretKeyValueRef!] core_listApps(envName: String!, pq: CursorPaginationIn, projectName: String!, search: SearchApps): AppPaginatedRecords core_listConfigs(envName: String!, pq: CursorPaginationIn, projectName: String!, search: SearchConfigs): ConfigPaginatedRecords core_listEnvironments(pq: CursorPaginationIn, projectName: String!, search: SearchEnvironments): EnvironmentPaginatedRecords @@ -3435,23 +3465,34 @@ input SecretIn { type: K8s__io___api___core___v1__SecretType } -type SecretPaginatedRecords { - edges: [SecretEdge!]! - pageInfo: PageInfo! - totalCount: Int! +type SecretKeyRef { + key: String! + secretName: String! +} + +input SecretKeyRefIn { + key: String! + secretName: String! } -input SecretValuesIn { +type SecretKeyValueRef { key: String! secretName: String! + value: String! } -type SecretValuesOut { +input SecretKeyValueRefIn { key: String! secretName: String! value: String! } +type SecretPaginatedRecords { + edges: [SecretEdge!]! + pageInfo: PageInfo! + totalCount: Int! +} + type Session { id: ID! loginMethod: String! diff --git a/src/generated/gql/server.ts b/src/generated/gql/server.ts index 3544c80c9..47b217f0c 100644 --- a/src/generated/gql/server.ts +++ b/src/generated/gql/server.ts @@ -75,11 +75,14 @@ export type Github__Com___Kloudlite___Api___Pkg___Types__SyncState = | 'RECEIVED_UPDATE_FROM_AGENT' | 'UPDATED_AT_AGENT'; -export type ConfigValuesIn = { - configmapName: Scalars['String']['input']; +export type ConfigKeyRefIn = { + configName: Scalars['String']['input']; key: Scalars['String']['input']; }; +export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__EnvironmentRoutingMode = + 'private' | 'public'; + export type Github__Com___Kloudlite___Api___Apps___Console___Internal___Entities__ImagePullSecretFormat = 'dockerConfigJson' | 'params'; @@ -93,7 +96,7 @@ export type K8s__Io___Api___Core___V1__SecretType = | 'kubernetes__io___tls' | 'Opaque'; -export type SecretValuesIn = { +export type SecretKeyRefIn = { key: Scalars['String']['input']; secretName: Scalars['String']['input']; }; @@ -512,9 +515,15 @@ export type EnvironmentIn = { export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__EnvironmentSpecIn = { projectName: Scalars['String']['input']; + routing?: InputMaybe; targetNamespace?: InputMaybe; }; +export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__EnvironmentRoutingIn = + { + mode?: InputMaybe; + }; + export type ImagePullSecretIn = { displayName: Scalars['String']['input']; dockerConfigJson?: InputMaybe; @@ -605,7 +614,6 @@ export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__RouterSpecIn ingressClass?: InputMaybe; maxBodySizeInMB?: InputMaybe; rateLimit?: InputMaybe; - region?: InputMaybe; routes?: InputMaybe< Array >; @@ -625,6 +633,7 @@ export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__CorsIn = { }; export type Github__Com___Kloudlite___Operator___Apis___Crds___V1__HttpsIn = { + clusterIssuer?: InputMaybe; enabled: Scalars['Boolean']['input']; forceRedirect?: InputMaybe; }; @@ -1002,6 +1011,12 @@ export type AccountMembershipIn = { userId: Scalars['String']['input']; }; +export type ConfigKeyValueRefIn = { + configName: Scalars['String']['input']; + key: Scalars['String']['input']; + value: Scalars['String']['input']; +}; + export type Github__Com___Kloudlite___Api___Apps___Container____Registry___Internal___Domain___Entities__GithubUserAccountIn = { avatarUrl?: InputMaybe; @@ -1406,6 +1421,12 @@ export type PersistentVolumeIn = { status?: InputMaybe; }; +export type SecretKeyValueRefIn = { + key: Scalars['String']['input']; + secretName: Scalars['String']['input']; + value: Scalars['String']['input']; +}; + export type VolumeAttachmentIn = { metadata?: InputMaybe; spec: K8s__Io___Api___Storage___V1__VolumeAttachmentSpecIn; @@ -3888,6 +3909,52 @@ export type ConsoleDeleteHelmChartMutation = { infra_deleteHelmRelease: boolean; }; +export type AuthCli_InfraCheckNameAvailabilityQueryVariables = Exact<{ + resType: ResType; + name: Scalars['String']['input']; + clusterName?: InputMaybe; +}>; + +export type AuthCli_InfraCheckNameAvailabilityQuery = { + infra_checkNameAvailability: { + result: boolean; + suggestedNames: Array; + }; +}; + +export type AuthCli_CreateDeviceMutationVariables = Exact<{ + clusterName: Scalars['String']['input']; + vpnDevice: VpnDeviceIn; +}>; + +export type AuthCli_CreateDeviceMutation = { + infra_createVPNDevice?: { metadata?: { name: string } }; +}; + +export type AuthCli_GetConfigSecretMapQueryVariables = Exact<{ + projectName: Scalars['String']['input']; + envName: Scalars['String']['input']; + configQueries?: InputMaybe< + Array> | InputMaybe + >; + secretQueries?: InputMaybe | SecretKeyRefIn>; +}>; + +export type AuthCli_GetConfigSecretMapQuery = { + configs?: Array<{ configName: string; key: string; value: string }>; + secrets?: Array<{ key: string; secretName: string; value: string }>; +}; + +export type AuthCli_InterceptAppMutationVariables = Exact<{ + projectName: Scalars['String']['input']; + envName: Scalars['String']['input']; + appname: Scalars['String']['input']; + deviceName: Scalars['String']['input']; + intercept: Scalars['Boolean']['input']; +}>; + +export type AuthCli_InterceptAppMutation = { core_interceptApp: boolean }; + export type AuthCli_GetEnvironmentQueryVariables = Exact<{ projectName: Scalars['String']['input']; name: Scalars['String']['input']; From 106d169abf8eacf56a7ffbf318f708283cb48cc4 Mon Sep 17 00:00:00 2001 From: Bikash Date: Tue, 9 Jan 2024 12:06:01 +0530 Subject: [PATCH 05/29] UI refactoring --- .gitignore | 1 - gql-queries-generator/doc/queries.graphql | 360 ++++++++++++++- lib/client/hooks/use-unsaved-changes.tsx | 73 +++- .../components/console-list-components.tsx | 2 +- src/apps/console/components/menu-select.tsx | 8 + src/apps/console/components/name-id-view.tsx | 190 ++++++++ .../console/components/sidebar-layout.tsx | 3 +- .../console/page-components/app-states.tsx | 2 +- .../console/page-components/new-project.tsx | 130 +++--- .../console/page-components/new-scope.tsx | 49 +-- .../$project+/$environment+/_layout.tsx | 137 ++---- .../$environment+/app+/$app+/logs/route.tsx | 7 + .../$environment+/app+/$app+/route.tsx | 101 +---- .../app+/$app+/settings+/_layout.tsx | 155 ++++++- .../app+/$app+/settings+/advance/route.tsx | 164 ++++--- .../app+/$app+/settings+/compute/route.tsx | 327 +++++++++++--- .../$app+/settings+/environment/route.tsx | 61 ++- .../app+/$app+/settings+/general/route.tsx | 92 ++-- .../app+/$app+/settings+/network/route.tsx | 41 +- .../$environment+/new-app/app-compute.tsx | 33 +- .../$environment+/new-app/app-detail.tsx | 6 +- .../new-app/app-environment-mounts.tsx | 22 +- .../new-app/app-environment-variables.tsx | 38 +- .../$environment+/new-app/app-network.tsx | 18 +- .../$environment+/router+/$router+/_index.tsx | 7 + .../router+/$router+/_layout.tsx | 87 ++++ .../router+/$router+/routes/_index.tsx | 61 +++ .../router+/$router+/routes/handle-route.tsx | 180 ++++++++ .../$router+/routes/route-resources.tsx | 218 ++++++++++ .../router+/$router+/routes/tools.tsx | 29 ++ .../router+/$router+/settings/_index.tsx | 6 + .../router+/$router+/settings/_layout.tsx | 17 + .../$router+/settings/general/route.tsx | 164 +++++++ .../$environment+/routers/_index.tsx | 95 ++++ .../$environment+/routers/handle-router.tsx | 163 +++++++ .../$project+/$environment+/routers/route.tsx | 85 ---- .../routers/router-resources.tsx | 224 ++++++++++ .../$environment+/settings+/general/route.tsx | 48 +- .../_main+/$account+/$project+/_index.tsx | 4 +- .../_main+/$account+/$project+/_layout.tsx | 161 +++---- .../$project+/environments/resources.tsx | 38 +- .../backend-services-resources.tsx | 13 +- .../handle-backend-service.tsx | 22 +- .../$project+/managed-services/route.tsx | 6 +- .../$project+/settings+/general/route.tsx | 3 +- .../routes/_main+/$account+/_layout.tsx | 73 +--- .../helm-charts/handle-helm-chart.tsx | 22 +- .../infra+/clusters/cluster-resources.tsx | 4 +- .../packages+/repos/repo-resources.tsx | 4 +- .../$account+/projects/project-resources.tsx | 4 + .../$account+/repo+/$repo+/builds/_index.tsx | 8 + .../_main+/$account+/settings+/general.tsx | 7 +- .../console/server/gql/queries/app-queries.ts | 95 +++- .../server/gql/queries/environment-queries.ts | 19 +- .../project-managed-services-queries.ts | 229 ++++++++++ .../server/gql/queries/router-queries.ts | 191 ++++++++ src/apps/console/server/gql/saved-queries.ts | 2 + .../console/server/r-utils/key-constants.js | 1 + src/apps/console/utils/commons.tsx | 1 + src/design-system/components/atoms/button.tsx | 1 + src/design-system/components/atoms/input.tsx | 14 +- .../components/atoms/option-list.tsx | 10 +- src/design-system/components/atoms/tabs.tsx | 43 +- src/design-system/index.css | 11 +- src/generated/gql/sdl.graphql | 139 +++++- src/generated/gql/server.ts | 411 ++++++++++++++++-- 66 files changed, 3990 insertions(+), 950 deletions(-) create mode 100644 src/apps/console/components/name-id-view.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/logs/route.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/_index.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/_layout.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/routes/_index.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/routes/handle-route.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/routes/route-resources.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/routes/tools.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/settings/_index.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/settings/_layout.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/router+/$router+/settings/general/route.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/_index.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/handle-router.tsx delete mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/route.tsx create mode 100644 src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/router-resources.tsx create mode 100644 src/apps/console/server/gql/queries/project-managed-services-queries.ts diff --git a/.gitignore b/.gitignore index c8afaf902..40619e960 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ # Logs -logs *.log npm-debug.log* yarn-debug.log* diff --git a/gql-queries-generator/doc/queries.graphql b/gql-queries-generator/doc/queries.graphql index 791c20c14..5c9ff4547 100644 --- a/gql-queries-generator/doc/queries.graphql +++ b/gql-queries-generator/doc/queries.graphql @@ -782,6 +782,10 @@ mutation consoleUpdateEnvironment($projectName: String!, $env: EnvironmentIn!) { } } +mutation consoleDeleteEnvironment($projectName: String!, $envName: String!) { + core_deleteEnvironment(projectName: $projectName, envName: $envName) +} + query consoleListEnvironments($projectName: String!, $search: SearchEnvironments, $pq: CursorPaginationIn) { core_listEnvironments(projectName: $projectName, search: $search, pq: $pq) { edges { @@ -877,10 +881,6 @@ query consoleGetApp($projectName: String!, $envName: String!, $name: String!) { markedForDeletion metadata { annotations - creationTimestamp - deletionTimestamp - generation - labels name namespace } @@ -1023,17 +1023,100 @@ query consoleListApps($projectName: String!, $envName: String!, $search: SearchA markedForDeletion metadata { annotations - creationTimestamp - deletionTimestamp - generation - labels name namespace } projectName spec { + containers { + args + command + env { + key + optional + refKey + refName + type + value + } + envFrom { + refName + type + } + image + imagePullPolicy + livenessProbe { + failureThreshold + httpGet { + httpHeaders + path + port + } + initialDelay + interval + shell { + command + } + tcp { + port + } + type + } + name + readinessProbe { + failureThreshold + initialDelay + interval + type + } + resourceCpu { + max + min + } + resourceMemory { + max + min + } + volumes { + items { + fileName + key + } + mountPath + refName + type + } + } displayName freeze + hpa { + enabled + maxReplicas + minReplicas + thresholdCpu + thresholdMemory + } + intercept { + enabled + toDevice + } + nodeSelector + region + replicas + serviceAccount + services { + name + port + targetPort + type + } + tolerations { + effect + key + operator + tolerationSeconds + value + } } status { checks @@ -1063,6 +1146,26 @@ query consoleListApps($projectName: String!, $envName: String!, $search: SearchA } } +mutation consoleCreateRouter($projectName: String!, $envName: String!, $router: RouterIn!) { + core_createRouter(projectName: $projectName, envName: $envName, router: $router) { + id + } +} + +mutation consoleUpdateRouter($projectName: String!, $envName: String!, $router: RouterIn!) { + core_updateRouter(projectName: $projectName, envName: $envName, router: $router) { + id + } +} + +mutation consoleDeleteRouter($projectName: String!, $envName: String!, $routerName: String!) { + core_deleteRouter( + projectName: $projectName + envName: $envName + routerName: $routerName + ) +} + query consoleListRouters($projectName: String!, $envName: String!, $search: SearchRouters, $pq: CursorPaginationIn) { core_listRouters( projectName: $projectName @@ -1099,6 +1202,31 @@ query consoleListRouters($projectName: String!, $envName: String!, $search: Sear } projectName spec { + backendProtocol + basicAuth { + enabled + secretName + username + } + cors { + allowCredentials + enabled + origins + } + domains + https { + enabled + forceRedirect + } + ingressClass + maxBodySizeInMB + rateLimit { + connections + enabled + rpm + rps + } + region routes { app lambda @@ -1135,6 +1263,81 @@ query consoleListRouters($projectName: String!, $envName: String!, $search: Sear } } +query consoleGetRouter($projectName: String!, $envName: String!, $name: String!) { + core_getRouter(projectName: $projectName, envName: $envName, name: $name) { + createdBy { + userEmail + userId + userName + } + creationTime + displayName + enabled + environmentName + lastUpdatedBy { + userEmail + userId + userName + } + markedForDeletion + metadata { + name + namespace + } + projectName + spec { + backendProtocol + basicAuth { + enabled + secretName + username + } + cors { + allowCredentials + enabled + origins + } + domains + https { + enabled + forceRedirect + } + ingressClass + maxBodySizeInMB + rateLimit { + connections + enabled + rpm + rps + } + region + routes { + app + lambda + path + port + rewrite + } + } + status { + checks + isReady + lastReadyGeneration + lastReconcileTime + message { + RawMessage + } + resources { + apiVersion + kind + name + namespace + } + } + updateTime + } +} + mutation consoleUpdateConfig($projectName: String!, $envName: String!, $config: ConfigIn!) { core_updateConfig(projectName: $projectName, envName: $envName, config: $config) { id @@ -2351,6 +2554,147 @@ mutation consoleDeleteClusterMSv($clusterName: String!, $serviceName: String!) { ) } +query consoleGetProjectMSv($projectName: String!, $name: String!) { + core_getProjectManagedService(projectName: $projectName, name: $name) { + createdBy { + userEmail + userId + userName + } + creationTime + displayName + lastUpdatedBy { + userEmail + userId + userName + } + markedForDeletion + metadata { + annotations + creationTimestamp + deletionTimestamp + generation + labels + name + namespace + } + spec { + msvcSpec { + serviceTemplate { + apiVersion + kind + spec + } + } + targetNamespace + } + status { + checks + isReady + lastReadyGeneration + lastReconcileTime + message { + RawMessage + } + resources { + apiVersion + kind + name + namespace + } + } + updateTime + } +} + +mutation consoleCreateProjectMSv($projectName: String!, $pmsvc: ProjectManagedServiceIn!) { + core_createProjectManagedService(projectName: $projectName, pmsvc: $pmsvc) { + id + } +} + +mutation consoleUpdateProjectMSv($projectName: String!, $pmsvc: ProjectManagedServiceIn!) { + core_updateProjectManagedService(projectName: $projectName, pmsvc: $pmsvc) { + id + } +} + +query consoleListProjectMSvs($projectName: String!, $search: SearchProjectManagedService, $pq: CursorPaginationIn) { + core_listProjectManagedServices( + projectName: $projectName + search: $search + pq: $pq + ) { + edges { + cursor + node { + createdBy { + userEmail + userId + userName + } + creationTime + displayName + lastUpdatedBy { + userEmail + userId + userName + } + markedForDeletion + metadata { + annotations + creationTimestamp + deletionTimestamp + generation + labels + name + namespace + } + spec { + msvcSpec { + serviceTemplate { + apiVersion + kind + spec + } + } + targetNamespace + } + status { + checks + isReady + lastReadyGeneration + lastReconcileTime + message { + RawMessage + } + resources { + apiVersion + kind + name + namespace + } + } + updateTime + } + } + pageInfo { + endCursor + hasNextPage + hasPreviousPage + startCursor + } + totalCount + } +} + +mutation consoleDeleteProjectMSv($projectName: String!, $pmsvcName: String!) { + core_deleteProjectManagedService( + projectName: $projectName + pmsvcName: $pmsvcName + ) +} + query consoleGetMSvTemplate($category: String!, $name: String!) { infra_getManagedServiceTemplate(category: $category, name: $name) { active diff --git a/lib/client/hooks/use-unsaved-changes.tsx b/lib/client/hooks/use-unsaved-changes.tsx index 7822ae1cc..b411bbfe3 100644 --- a/lib/client/hooks/use-unsaved-changes.tsx +++ b/lib/client/hooks/use-unsaved-changes.tsx @@ -13,6 +13,7 @@ import { useState, } from 'react'; import { ChildrenProps } from '~/components/types'; +import Popup from '~/components/molecule/popup'; import { useReload } from '../helpers/reloader'; const UnsavedChanges = createContext<{ @@ -22,6 +23,11 @@ const UnsavedChanges = createContext<{ proceed: (() => void) | undefined; reset: (() => void) | undefined; resetAndReload: () => void; + setIgnorePaths: (path: string[]) => void; + performAction: string; + setPerformAction: (action: string) => void; + loading: boolean; + setLoading: (loading: boolean) => void; }>({ hasChanges: false, setHasChanges() {}, @@ -29,12 +35,27 @@ const UnsavedChanges = createContext<{ proceed() {}, reset() {}, resetAndReload() {}, + setIgnorePaths() {}, + performAction: '', + setPerformAction() {}, + loading: false, + setLoading() {}, }); export const UnsavedChangesProvider = ({ children }: ChildrenProps) => { const [hasChanges, setHasChanges] = useState(false); const [reload, setReload] = useState(false); - const { state, proceed, reset } = unstable_useBlocker(hasChanges); + const [ignorePaths, setIgnorePaths] = useState([]); + const [performAction, setPerformAction] = useState(''); + const [loading, setLoading] = useState(false); + const location = useLocation(); + const { state, proceed, reset } = unstable_useBlocker(({ nextLocation }) => { + if (hasChanges && !ignorePaths.includes(nextLocation.pathname)) { + return true; + } + return false; + }); + useBeforeUnload( useCallback( (e) => { @@ -46,10 +67,17 @@ export const UnsavedChangesProvider = ({ children }: ChildrenProps) => { [hasChanges] ) ); - const location = useLocation(); useEffect(() => { - setHasChanges(false); + if ( + !( + ignorePaths && + ignorePaths.length > 0 && + ignorePaths.includes(location.pathname) + ) + ) { + setHasChanges(false); + } }, [location]); const refresh = useReload(); @@ -76,11 +104,48 @@ export const UnsavedChangesProvider = ({ children }: ChildrenProps) => { proceed, reset, resetAndReload, + setIgnorePaths, + setPerformAction, + performAction, + loading, + setLoading, }), - [hasChanges, setHasChanges, state] + [ + hasChanges, + setHasChanges, + state, + ignorePaths, + performAction, + setPerformAction, + loading, + setLoading, + ] )} > {children} + { + reset?.(); + }} + > + Unsaved changes + + Are you sure you want to discard the changes? + + + reset?.()} + /> + proceed?.()} + /> + + ); }; diff --git a/src/apps/console/components/console-list-components.tsx b/src/apps/console/components/console-list-components.tsx index b00e0e80a..3d8c30b96 100644 --- a/src/apps/console/components/console-list-components.tsx +++ b/src/apps/console/components/console-list-components.tsx @@ -68,7 +68,7 @@ const ListTitle = ({ }) => { return (
-
+
{avatar}
{title && ( diff --git a/src/apps/console/components/menu-select.tsx b/src/apps/console/components/menu-select.tsx index dbdae0a2d..0804b8a3b 100644 --- a/src/apps/console/components/menu-select.tsx +++ b/src/apps/console/components/menu-select.tsx @@ -2,6 +2,7 @@ import React, { ReactNode, useState } from 'react'; import * as Select from '@radix-ui/react-select'; import { cn } from '~/components/utils'; import { AnimatePresence, motion } from 'framer-motion'; +import { ChevronDown, ChevronUp } from '@jengaicons/react'; interface ISelectItem { children: ReactNode; @@ -48,6 +49,7 @@ const MenuSelect = ({ onChange, }: IMenuSelect) => { const [open, setOpen] = useState(false); + const scrollButtonSize = 12; return ( + + + { console.log(e); @@ -90,6 +95,9 @@ const MenuSelect = ({
))} + + + diff --git a/src/apps/console/components/name-id-view.tsx b/src/apps/console/components/name-id-view.tsx new file mode 100644 index 000000000..a5fa16792 --- /dev/null +++ b/src/apps/console/components/name-id-view.tsx @@ -0,0 +1,190 @@ +/* eslint-disable no-nested-ternary */ +import { CircleNotch } from '@jengaicons/react'; +import { ReactNode, useState } from 'react'; +import { TextInput } from '~/components/atoms/input'; +import { useAPIClient } from '~/root/lib/client/hooks/api-provider'; +import useDebounce from '~/root/lib/client/hooks/use-debounce'; +import { NonNullableString } from '~/root/lib/types/common'; +import { handleError } from '~/root/lib/utils/common'; +import { ConsoleResType, ResType } from '~/root/src/generated/gql/server'; +import { useOutletContext, useParams } from '@remix-run/react'; +import { + ensureAccountClientSide, + ensureClusterClientSide, +} from '../server/utils/auth-utils'; +import { useConsoleApi } from '../server/gql/api-provider'; +import { IEnvironmentContext } from '../routes/_main+/$account+/$project+/$environment+/_layout'; + +interface INameIdView { + name: string; + displayName: string; + resType: + | ConsoleResType + | ResType + | 'account' + | 'username' + | NonNullableString; + onChange?: ({ name, id }: { name: string; id: string }) => void; + prefix?: ReactNode; + errors?: string; + label?: ReactNode; +} + +export const NameIdView = ({ + name, + onChange = (_) => {}, + resType, + errors, + prefix, + label, + displayName, +}: INameIdView) => { + const [nameValid, setNameValid] = useState(false); + const [nameLoading, setNameLoading] = useState(false); + + const api = useConsoleApi(); + const params = useParams(); + + const checkApi = () => { + switch (resType) { + case 'app': + case 'project': + case 'config': + case 'environment': + case 'managed_service': + case 'managed_resource': + case 'helm_release': + case 'router': + case 'secret': + ensureAccountClientSide(params); + ensureClusterClientSide(params); + return api.coreCheckNameAvailability; + + case 'cluster': + case 'providersecret': + ensureAccountClientSide(params); + return api.infraCheckNameAvailability; + case 'vpn_device': + ensureClusterClientSide(params); + ensureAccountClientSide(params); + return api.infraCheckNameAvailability; + case 'nodepool': + ensureAccountClientSide(params); + ensureClusterClientSide(params); + return api.infraCheckNameAvailability; + + case 'account': + return api.accountCheckNameAvailability; + + case 'username': + return api.crCheckNameAvailability; + + default: + return api.coreCheckNameAvailability; + } + }; + + const checkNameAvailable = () => { + if (errors) { + return errors; + } + if (!name) { + return null; + } + if (nameLoading) { + return ( +
+ + + + Checking availability +
+ ); + } + if (nameValid) { + return ( + + {name} is available. + + ); + } + return 'This name is not available. Please try different.'; + }; + + const { environment, project } = useOutletContext(); + const { cluster } = params; + useDebounce( + async () => { + if (displayName) { + try { + // @ts-ignore + const { data, errors } = await checkApi()({ + resType, + name: `${name}`, + ...(resType === 'environment' + ? { + namespace: project.spec?.targetNamespace, + } + : environment + ? { + namespace: environment.spec?.targetNamespace, + } + : {}), + ...(resType === 'nodepool' || resType === 'vpn_device' + ? { + clusterName: cluster, + } + : {}), + ...(resType === 'managed_resource' + ? { + namespace: '', + } + : {}), + }); + + if (errors) { + throw errors[0]; + } + if (data.result) { + setNameValid(true); + } else { + setNameValid(false); + } + } catch (err) { + handleError(err); + } finally { + setNameLoading(false); + } + } else { + setNameLoading(false); + } + }, + 500, + [displayName, name] + ); + + return ( + { + const v = e.target.value; + onChange?.({ + name: v, + id: v.toLowerCase().replace(' ', '-'), + }); + if (v) { + setNameLoading(true); + } else { + setNameLoading(false); + } + }} + size="lg" + error={!nameValid && !!name && !nameLoading} + message={checkNameAvailable()} + prefix={ + prefix && {prefix} / + } + /> + ); +}; diff --git a/src/apps/console/components/sidebar-layout.tsx b/src/apps/console/components/sidebar-layout.tsx index 17b02ab28..26ef418e8 100644 --- a/src/apps/console/components/sidebar-layout.tsx +++ b/src/apps/console/components/sidebar-layout.tsx @@ -77,7 +77,8 @@ const SidebarLayout = ({
-
+ {/* If overflow problem occurs in error page look here */} +
{children}
diff --git a/src/apps/console/page-components/app-states.tsx b/src/apps/console/page-components/app-states.tsx index 4deb1b1c4..3a0b9fee3 100644 --- a/src/apps/console/page-components/app-states.tsx +++ b/src/apps/console/page-components/app-states.tsx @@ -208,7 +208,7 @@ export const useAppState = () => { setState, getContainer, setContainer, - activeContIndex, + activeContIndex: activeContIndex || 0, services: app.spec.services || [], setServices, }; diff --git a/src/apps/console/page-components/new-project.tsx b/src/apps/console/page-components/new-project.tsx index 13606a0b1..240198b60 100644 --- a/src/apps/console/page-components/new-project.tsx +++ b/src/apps/console/page-components/new-project.tsx @@ -19,6 +19,7 @@ import { import { INewProjectFromAccountLoader } from '../routes/_a+/$a+/new-project'; import ProgressWrapper from '../components/progress-wrapper'; import { useConsoleApi } from '../server/gql/api-provider'; +import { NameIdView } from '../components/name-id-view'; const NewProject = () => { const { cluster: clusterName } = useParams(); @@ -83,64 +84,64 @@ const NewProject = () => { }, }); - const [nameValid, setNameValid] = useState(false); - const [nameLoading, setNameLoading] = useState(false); - useDebounce( - async () => { - if (values.name) { - try { - ensureAccountClientSide(params); - ensureClusterClientSide(params); - const { data, errors } = await api.coreCheckNameAvailability({ - resType: 'project', - name: `${values.name}`, - }); + // const [nameValid, setNameValid] = useState(false); + // const [nameLoading, setNameLoading] = useState(false); + // useDebounce( + // async () => { + // if (values.name) { + // try { + // ensureAccountClientSide(params); + // ensureClusterClientSide(params); + // const { data, errors } = await api.coreCheckNameAvailability({ + // resType: 'project', + // name: `${values.name}`, + // }); - if (errors) { - throw errors[0]; - } - if (data.result) { - setNameValid(true); - } else { - setNameValid(false); - } - } catch (err) { - handleError(err); - } finally { - setNameLoading(false); - } - } - }, - 500, - [values.name] - ); + // if (errors) { + // throw errors[0]; + // } + // if (data.result) { + // setNameValid(true); + // } else { + // setNameValid(false); + // } + // } catch (err) { + // handleError(err); + // } finally { + // setNameLoading(false); + // } + // } + // }, + // 500, + // [values.name] + // ); - const checkNameAvailable = () => { - if (errors.name) { - return errors.name; - } - if (!values.name) { - return null; - } - if (nameLoading) { - return ( -
- - - - Checking availability -
- ); - } - if (nameValid) { - return ( - - {values.name} is available. - - ); - } - return 'This name is not available. Please try different.'; - }; + // const checkNameAvailable = () => { + // if (errors.name) { + // return errors.name; + // } + // if (!values.name) { + // return null; + // } + // if (nameLoading) { + // return ( + //
+ // + // + // + // Checking availability + //
+ // ); + // } + // if (nameValid) { + // return ( + // + // {values.name} is available. + // + // ); + // } + // return 'This name is not available. Please try different.'; + // }; const getView = () => { return ( @@ -148,7 +149,7 @@ const NewProject = () => {
Create your project under production effortlessly.
-
+ {/*
{ {accountName} / } /> -
+
*/} + + { + handleChange('displayName')(dummyEvent(name)); + handleChange('name')(dummyEvent(id)); + }} + /> {!isOnboarding && ( [ + ...Object.entries(plans).map(([_, vs]) => ({ + label: vs.label, + options: vs.options.map((op) => ({ + ...op, + render: () => ( +
+
{op.label}
+
{op.memoryPerCpu}GB/vCPU
+
+ ), + })), + })), + ]} + valueRender={valueRender} + onChange={(v) => { + handleChange('selectedPlan')(dummyEvent(v.value)); + handleChange('memPerCpu')(dummyEvent(v.memoryPerCpu)); + handleChange('cpuMode')( + dummyEvent(v.isShared ? 'shared' : 'dedicated') + ); + }} + /> +
+
+
+ Select CPU +
+ + {((values.cpu || 1) / 1000).toFixed(2)}vCPU &{' '} + {( + ((values.cpu || 1) * parseValue(values.memPerCpu, 4)) / + 1000 + ).toFixed(2)} + GB Memory + +
+ { + handleChange('cpu')(dummyEvent(value)); + }} + /> +
+ + ) : ( +
+
+
+
+ + 1000m = 1VCPU + + } + /> +
+
+ + 1000m = 1VCPU + + } + size="lg" + suffix="m" + /> +
+
+
+
+
+
+ +
+
+ +
+
+
+
+ )} + + {/*
Select CPU
@@ -228,8 +442,9 @@ const SettingCompute = () => { handleChange('cpu')(dummyEvent(value)); }} /> -
- +
*/} + + ); }; export default SettingCompute; diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/environment/route.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/environment/route.tsx index 607af6f55..e84509468 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/environment/route.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/environment/route.tsx @@ -4,11 +4,12 @@ import { createAppEnvPage, useAppState, } from '~/console/page-components/app-states'; -import { FadeIn } from '~/console/page-components/util'; +import Wrapper from '~/console/components/wrapper'; +import { useUnsavedChanges } from '~/root/lib/client/hooks/use-unsaved-changes'; +import { Button } from '~/components/atoms/button'; import { EnvironmentVariables } from '../../../../new-app/app-environment-variables'; import { ConfigMounts } from '../../../../new-app/app-environment-mounts'; - export interface IAppDialogValue { refKey: string; refName: string; @@ -17,6 +18,7 @@ export interface IAppDialogValue { const SettingEnvironment = () => { const { envPage, setEnvPage } = useAppState(); + const { setPerformAction, hasChanges, loading } = useUnsavedChanges(); const items: { label: string; value: createAppEnvPage; @@ -32,29 +34,48 @@ const SettingEnvironment = () => { ]; return ( - -
-
Environment
+
+ +
+ ), + }} + > -
- - - {envPage === 'environment_variables' && } - {envPage === 'config_mounts' && } - - -
+ + + {envPage === 'environment_variables' && } + {envPage === 'config_mounts' && } + + + + ); }; diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/general/route.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/general/route.tsx index 0c77fda92..9776635af 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/general/route.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/general/route.tsx @@ -1,5 +1,4 @@ import { CopySimple } from '@jengaicons/react'; -import { useOutletContext } from '@remix-run/react'; import { useEffect } from 'react'; import { TextInput } from '~/components/atoms/input'; import { Box } from '~/console/components/common-console-components'; @@ -8,13 +7,15 @@ import { keyconstants } from '~/console/server/r-utils/key-constants'; import useForm from '~/root/lib/client/hooks/use-form'; import Yup from '~/root/lib/server/helpers/yup'; import { parseName } from '~/console/server/r-utils/common'; -import { IAppContext } from '../../route'; +import Wrapper from '~/console/components/wrapper'; +import { Button } from '~/components/atoms/button'; +import { useUnsavedChanges } from '~/root/lib/client/hooks/use-unsaved-changes'; const SettingGeneral = () => { const { app, setApp } = useAppState(); - const { environment } = useOutletContext(); + const { setPerformAction, hasChanges, loading } = useUnsavedChanges(); - const { values, errors, handleChange, submit } = useForm({ + const { values, errors, handleChange, submit, resetValues } = useForm({ initialValues: { name: parseName(app), displayName: app.displayName, @@ -33,7 +34,6 @@ const SettingGeneral = () => { metadata: { ...a.metadata, name: val.name, - namespace: environment.spec?.targetNamespace, annotations: { ...(a.metadata?.annotations || {}), [keyconstants.description]: val.description, @@ -49,35 +49,65 @@ const SettingGeneral = () => { submit(); }, [values]); + useEffect(() => { + if (!hasChanges) { + resetValues(); + } + }, [hasChanges]); + return ( - -
-
- -
-
+
+ +
+ ), + }} + > + +
+
+ +
+
+ } + disabled + /> +
+
} - disabled + label="Description" + error={!!errors.description} + message={errors.description} + value={values.description} + onChange={handleChange('description')} /> -
-
- -
+ + + ); }; export default SettingGeneral; diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/network/route.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/network/route.tsx index 0fe159dce..eba8b9fca 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/network/route.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/app+/$app+/settings+/network/route.tsx @@ -1,18 +1,37 @@ -import { TitleBox } from '~/console/components/raw-wrapper'; -import { FadeIn } from '~/console/page-components/util'; +import Wrapper from '~/console/components/wrapper'; +import { Button } from '~/components/atoms/button'; +import { useUnsavedChanges } from '~/root/lib/client/hooks/use-unsaved-changes'; import { ExposedPorts } from '../../../../new-app/app-network'; - - const AppNetwork = () => { + const { setPerformAction, hasChanges, loading } = useUnsavedChanges(); + return ( - - - - +
+ +
+ ), + }} + > + + + ); }; diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-compute.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-compute.tsx index 2249364dc..8d775f13c 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-compute.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-compute.tsx @@ -42,13 +42,15 @@ const AppCompute = () => { imageUrl: app.spec.containers[activeContIndex]?.image || '', pullSecret: 'TODO', cpuMode: app.metadata?.annotations?.[keyconstants.cpuMode] || 'shared', - selectedPlan: app.metadata?.annotations?.[keyconstants.selectedPlan] || 1, + memPerCpu: app.metadata?.annotations?.[keyconstants.memPerCpu] || '1', cpu: parseValue( app.spec.containers[activeContIndex]?.resourceCpu?.max, 250 ), + selectedPlan: + app.metadata?.annotations[keyconstants.selectedPlan] || 'shared-1', selectionMode: app.metadata?.annotations[keyconstants.selectionModeKey] || 'quick', manualCpuMin: parseValue( @@ -81,9 +83,11 @@ const AppCompute = () => { metadata: { ...s.metadata!, annotations: { + ...(s.metadata?.annotations || {}), [keyconstants.cpuMode]: val.cpuMode, - [keyconstants.selectedPlan]: val.selectedPlan, + [keyconstants.memPerCpu]: val.memPerCpu, [keyconstants.selectionModeKey]: val.selectionMode, + [keyconstants.selectedPlan]: val.selectedPlan, }, }, spec: { @@ -107,7 +111,7 @@ const AppCompute = () => { val.selectionMode === 'quick' ? { max: `${( - (values.cpu || 1) * parseValue(values.selectedPlan, 4) + (values.cpu || 1) * parseValue(values.memPerCpu, 4) ).toFixed(2)}Mi`, min: `${val.cpu}Mi`, } @@ -201,7 +205,8 @@ const AppCompute = () => { ]} valueRender={valueRender} onChange={(v) => { - handleChange('selectedPlan')(dummyEvent(v.memoryPerCpu)); + handleChange('selectedPlan')(dummyEvent(v.value)); + handleChange('memPerCpu')(dummyEvent(v.memoryPerCpu)); handleChange('cpuMode')( dummyEvent(v.isShared ? 'shared' : 'dedicated') ); @@ -215,7 +220,7 @@ const AppCompute = () => { {((values.cpu || 1) / 1000).toFixed(2)}vCPU &{' '} {( - ((values.cpu || 1) * parseValue(values.selectedPlan, 4)) / + ((values.cpu || 1) * parseValue(values.memPerCpu, 4)) / 1000 ).toFixed(2)} GB Memory @@ -242,7 +247,12 @@ const AppCompute = () => { onChange={handleChange('manualCpuMin')} label="CPU request" size="lg" - suffix="VCPU" + suffix="m" + extra={ + + 1000m = 1VCPU + + } />
@@ -250,8 +260,13 @@ const AppCompute = () => { value={values.manualCpuMax} onChange={handleChange('manualCpuMax')} label="CPU limit" + extra={ + + 1000m = 1VCPU + + } size="lg" - suffix="VCPU" + suffix="m" />
@@ -264,7 +279,7 @@ const AppCompute = () => { onChange={handleChange('manualMemMin')} label="Memory request" size="lg" - suffix="GB" + suffix="MB" />
@@ -273,7 +288,7 @@ const AppCompute = () => { onChange={handleChange('manualMemMax')} label="Memory limit" size="lg" - suffix="GB" + suffix="MB" />
diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-detail.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-detail.tsx index 2501e926c..f80e1fbcb 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-detail.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-detail.tsx @@ -2,14 +2,12 @@ import { ArrowRight } from '@jengaicons/react'; import { Button } from '~/components/atoms/button'; import { TextInput } from '~/components/atoms/input'; import { IdSelector } from '~/console/components/id-selector'; -import { TitleBox } from '~/console/components/raw-wrapper'; import { useAppState } from '~/console/page-components/app-states'; import { keyconstants } from '~/console/server/r-utils/key-constants'; import useForm, { dummyEvent } from '~/root/lib/client/hooks/use-form'; import Yup from '~/root/lib/server/helpers/yup'; import { parseName } from '~/console/server/r-utils/common'; import { FadeIn } from '~/console/page-components/util'; -import ProgressWrapper from '~/console/components/progress-wrapper'; const AppDetail = () => { const { app, setApp, setPage, markPageAsCompleted } = useAppState(); @@ -32,6 +30,10 @@ const AppDetail = () => { ...a, metadata: { ...a.metadata, + annotations: { + ...(a.metadata?.annotations || {}), + [keyconstants.description]: val.description || '', + }, name: val.name, }, displayName: val.displayName, diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-mounts.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-mounts.tsx index 4ed69f53d..1f8ad97eb 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-mounts.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-mounts.tsx @@ -25,6 +25,7 @@ import { } from '~/console/server/r-utils/common'; import useDebounce from '~/root/lib/client/hooks/use-debounce'; import useForm from '~/root/lib/client/hooks/use-form'; +import { useUnsavedChanges } from '~/root/lib/client/hooks/use-unsaved-changes'; import Yup from '~/root/lib/server/helpers/yup'; import { NonNullableString } from '~/root/lib/types/common'; import { handleError } from '~/root/lib/utils/common'; @@ -157,7 +158,6 @@ const ConfigMountsList = ({ configMounts, onDelete }: IConfigMountList) => { export const ConfigMounts = () => { const api = useConsoleApi(); - const [isloading, setIsloading] = useState(true); const { environment, project } = useParams(); const [configs, setConfigs] = useState[]>([]); @@ -192,8 +192,11 @@ export const ConfigMounts = () => { const { getContainer, setContainer } = useAppState(); const { volumes } = getContainer(); - const { setValues, submit, values } = useForm({ - initialValues: volumes || [], + // for updating + const { hasChanges } = useUnsavedChanges(); + + const { setValues, submit, values, resetValues } = useForm({ + initialValues: volumes, validationSchema: Yup.array( Yup.object({ mountPath: Yup.string().required(), @@ -218,7 +221,7 @@ export const ConfigMounts = () => { const addEntry = (val: Ientry) => { setValues((v) => { return [ - ...v, + ...(v || []), { type: 'config', mountPath: val.mountPath, @@ -230,7 +233,7 @@ export const ConfigMounts = () => { const deleteEntry = (val: { mountPath: string }) => { setValues((v) => { - return v.filter((v) => v.mountPath !== val.mountPath); + return v?.filter((v) => v.mountPath !== val.mountPath); }); }; @@ -244,13 +247,20 @@ export const ConfigMounts = () => { setEntryError(''); }, [mountPath]); + // for updating + useEffect(() => { + if (!hasChanges) { + resetValues(); + } + }, [hasChanges]); + return ( <>
{ e.preventDefault(); - if (values.find((k) => k.mountPath === mountPath)) { + if (values?.find((k) => k.mountPath === mountPath)) { setEntryError('path already present'); return; } diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-variables.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-variables.tsx index 07f972848..ae5ee85bf 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-variables.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-app/app-environment-variables.tsx @@ -21,6 +21,7 @@ import { useAppState } from '~/console/page-components/app-states'; import useForm from '~/root/lib/client/hooks/use-form'; import Yup from '~/root/lib/server/helpers/yup'; import { NonNullableString } from '~/root/lib/types/common'; +import { useUnsavedChanges } from '~/root/lib/client/hooks/use-unsaved-changes'; import AppDialog from './app-dialogs'; interface IEnvVariable { @@ -48,17 +49,17 @@ const EnvironmentVariablesList = ({ }: IEnvVariablesList) => { const { page, hasNext, hasPrevious, onNext, onPrev, setItems } = usePagination({ - items: envVariables, + items: envVariables || [], itemsPerPage: 5, }); useEffect(() => { - setItems(envVariables); + setItems(envVariables || []); }, [envVariables]); return (
- {envVariables.length > 0 && ( + {envVariables?.length > 0 && ( )} - {envVariables.length === 0 && ( + {envVariables?.length === 0 && (
{ const [showCSDialog, setShowCSDialog] = useState(null); + // for updating + const { hasChanges } = useUnsavedChanges(); + const entry = Yup.object({ type: Yup.string().oneOf(['config', 'secret']).notRequired(), key: Yup.string().required(), @@ -203,8 +207,13 @@ export const EnvironmentVariables = () => { .notRequired(), }); - const { values, setValues, submit } = useForm({ - initialValues: getContainer().env || [], + const { + values, + setValues, + submit, + resetValues: resetAppValue, + } = useForm({ + initialValues: getContainer().env, validationSchema: Yup.array(entry), onSubmit: (val) => { setContainer((c) => ({ @@ -217,15 +226,27 @@ export const EnvironmentVariables = () => { submit(); }, [values]); + // for updating + useEffect(() => { + if (!hasChanges) { + resetAppValue(); + } + }, [hasChanges]); + const addEntry = (val: IEnvVariable) => { setValues((v) => { - v?.push({ + const data = { key: val.key, type: val.type, refName: val.refName || '', refKey: val.refKey || '', value: val.value || '', - }); + }; + if (v) { + v?.push(data); + } else { + return [data]; + } return v; }); }; @@ -346,6 +367,7 @@ export const EnvironmentVariables = () => { {eValues.value.refName}
+
+ } + disabled + /> + + + + + { + setDeleteRouter(true); + }} + > + Permanently remove your router and all of its contents from the “ + {router.displayName}” router. This action is not reversible, so please + continue with caution. + + { + try { + const { errors } = await api.deleteRouter({ + envName: parseName(environment), + projectName: parseName(project), + routerName: parseName(router), + }); + + if (errors) { + throw errors[0]; + } + reload(); + toast.success(`Router deleted successfully`); + setDeleteRouter(false); + navigate( + `/${account}/${parseName(project)}/${parseName( + environment + )}/routers/` + ); + } catch (err) { + handleError(err); + } + }} + /> + + + ); +}; +export default ProjectSettingGeneral; diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/_index.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/_index.tsx new file mode 100644 index 000000000..44911940a --- /dev/null +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/routers/_index.tsx @@ -0,0 +1,95 @@ +import { Plus, PlusFill } from '@jengaicons/react'; +import { defer } from '@remix-run/node'; +import { Link, useLoaderData } from '@remix-run/react'; +import { Button } from '~/components/atoms/button.jsx'; +import { LoadingComp, pWrapper } from '~/console/components/loading-component'; +import Wrapper from '~/console/components/wrapper'; +import { GQLServerHandler } from '~/console/server/gql/saved-queries'; +import { parseNodes } from '~/console/server/r-utils/common'; +import { + ensureAccountSet, + ensureClusterSet, +} from '~/console/server/utils/auth-utils'; +import { getPagination, getSearch } from '~/console/server/utils/common'; +import { IRemixCtx } from '~/root/lib/types/common'; +import { useState } from 'react'; +import Tools from './tools'; +import HandleRouter from './handle-router'; +import RouterResources from './router-resources'; + +export const loader = async (ctx: IRemixCtx) => { + ensureAccountSet(ctx); + ensureClusterSet(ctx); + const { project, environment } = ctx.params; + + const promise = pWrapper(async () => { + const { data, errors } = await GQLServerHandler(ctx.request).listRouters({ + envName: environment, + projectName: project, + pq: getPagination(ctx), + search: getSearch(ctx), + }); + if (errors) { + throw errors[0]; + } + return { routersData: data }; + }); + + return defer({ promise }); +}; + +const Routers = () => { + const { promise } = useLoaderData(); + const [visible, setVisible] = useState(false); + + return ( + <> + + {({ routersData }) => { + const routers = parseNodes(routersData); + if (!routers) { + return null; + } + return ( + 0 && ( + {children} diff --git a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-managed-resource/_index.tsx b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-managed-resource/_index.tsx index d3a755650..662f7929f 100644 --- a/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-managed-resource/_index.tsx +++ b/src/apps/console/routes/_main+/$account+/$project+/$environment+/new-managed-resource/_index.tsx @@ -14,21 +14,12 @@ import ProgressWrapper from '~/console/components/progress-wrapper'; import { useConsoleApi } from '~/console/server/gql/api-provider'; import useForm, { dummyEvent } from '~/root/lib/client/hooks/use-form'; import Yup from '~/root/lib/server/helpers/yup'; -import { - Dispatch, - FormEventHandler, - SetStateAction, - useEffect, - useState, -} from 'react'; -import { - IMSvTemplate, - IMSvTemplates, -} from '~/console/server/gql/queries/managed-templates-queries'; +import { FormEventHandler, useEffect, useState } from 'react'; +import { IMSvTemplate } from '~/console/server/gql/queries/managed-templates-queries'; import { Switch } from '~/components/atoms/switch'; import { NumberInput, TextInput } from '~/components/atoms/input'; import { handleError } from '~/root/lib/utils/common'; -import { titleCase, useMapper } from '~/components/utils'; +import { useMapper } from '~/components/utils'; import { IRemixCtx } from '~/root/lib/types/common'; import { LoadingComp, pWrapper } from '~/console/components/loading-component'; import { GQLServerHandler } from '~/console/server/gql/saved-queries'; @@ -38,7 +29,6 @@ import { parseName, parseNodes, } from '~/console/server/r-utils/common'; -import DataSetter from '~/console/components/data-setter'; import { IProjectMSvs } from '~/console/server/gql/queries/project-managed-services-queries'; import { getManagedTemplate } from '~/console/utils/commons'; import { ReviewComponent } from '../new-app/app-review'; @@ -61,18 +51,7 @@ export const loader = (ctx: IRemixCtx) => { return defer({ promise }); }; -const valueRender = ({ label, icon }: { label: string; icon: string }) => { - return ( -
- - {label} - -
{label}
-
- ); -}; - -type steps = 'Select template' | 'Configure managed service' | 'Review'; +type steps = 'Select service' | 'Configure resource' | 'Review'; const hasResource = (res: any) => (!!res && res?.resource?.fields.length > 0) || !res; @@ -268,12 +247,11 @@ const TemplateView = ({ resources, isLoading, }: ITemplateView) => { - const [hasCheckNameError, setHasCheckNameError] = useState(false); return (
{ - if (!hasCheckNameError) { + if (!values.isNameCheckError) { handleSubmit(e); } else { e.preventDefault(); @@ -293,7 +271,7 @@ const TemplateView = ({ handleChange('displayName')(dummyEvent(name)); handleChange('name')(dummyEvent(id)); }} - onCheckError={setHasCheckNameError} + onCheckError={(v) => handleChange('isNameCheckError')(dummyEvent(v))} /> { handleChange('selectedTemplate')(dummyEvent(item)); }} @@ -293,7 +289,7 @@ const TemplateView = ({ - - } - disabled - /> - - -
-
- {' '} - - mapper(awsRegions, (v) => { - return { - value: v.Name, - label: v.Name, - region: v, - }; - }) - } - /> + const defaultRegion = awsRegions.find( + (r) => r.Name === cluster.spec?.aws?.region + ); + return ( + +
+ ), + }} + > +
+ +
+
+ +
+
+ +
-
-
- - { - setDeleteCluster(true); + } + disabled + /> +
+
+
+
+ {' '} + - Permanently remove your Cluster and all of its contents from the - Kloudlite platform. This action is not reversible — please - continue with caution. - + options={async () => + mapper(awsRegions, (v) => { + return { + value: v.Name, + label: v.Name, + region: v, + }; + }) + } + />
- ); - }} - +
+ + + { + setDeleteCluster(true); + }} + > + Permanently remove your Cluster and all of its contents from the + Kloudlite platform. This action is not reversible — please continue + with caution. + + { } }} /> - + + ); +}; + +const SettingGeneral = () => { + const { promise } = useLoaderData(); + return ( + + {({ providerSecrets }) => { + const providerSecretsOptions = parseNodes(providerSecrets).map( + (provider) => ({ + value: parseName(provider), + label: provider.displayName, + render: () => ( +
+
{provider.displayName}
+
+ {parseName(provider)} +
+
+ ), + provider, + }) + ); + return ; + }} +
); }; export default SettingGeneral; diff --git a/src/apps/console/routes/_main+/$account+/infra+/clusters/cluster-resources.tsx b/src/apps/console/routes/_main+/$account+/infra+/clusters/cluster-resources.tsx index 40bcf4f57..7d08fa3cb 100644 --- a/src/apps/console/routes/_main+/$account+/infra+/clusters/cluster-resources.tsx +++ b/src/apps/console/routes/_main+/$account+/infra+/clusters/cluster-resources.tsx @@ -12,6 +12,7 @@ import Grid from '~/console/components/grid'; import List from '~/console/components/list'; import ListGridView from '~/console/components/list-grid-view'; import ResourceExtraAction from '~/console/components/resource-extra-action'; +import { listStatus } from '~/console/components/sync-status'; import { IClusters } from '~/console/server/gql/queries/cluster-queries'; import { ExtractNodeType, @@ -153,6 +154,12 @@ const ListView = ({ items }: { items: ExtractNodeType[] }) => { className: 'min-w-[80px] mx-[25px] basis-full text-center', }); + const tempStatus = listStatus({ + key: keyPrefix, + item, + className: 'basis-full text-center', + }); + return ( [] }) => { columns={[ { key: generateKey(keyPrefix, name + id), - className: 'max-w-[180px]', + className: 'max-w-[180px] min-w-[180px] w-[180px]', render: () => ( [] }) => { /> ), }, - statusRender, + tempStatus, { key: generateKey(keyPrefix, `${provider}`), className: 'min-w-[150px] text-start', diff --git a/src/apps/console/routes/_main+/$account+/repo+/$repo+/builds/_index.tsx b/src/apps/console/routes/_main+/$account+/repo+/$repo+/builds/_index.tsx index 97d4b7c98..56ec43e7a 100644 --- a/src/apps/console/routes/_main+/$account+/repo+/$repo+/builds/_index.tsx +++ b/src/apps/console/routes/_main+/$account+/repo+/$repo+/builds/_index.tsx @@ -1,7 +1,6 @@ import { defer } from '@remix-run/node'; import { useLoaderData } from '@remix-run/react'; import { useState } from 'react'; -import { Button } from '~/components/atoms/button'; import { LoadingComp, pWrapper } from '~/console/components/loading-component'; import Wrapper from '~/console/components/wrapper'; import { GQLServerHandler } from '~/console/server/gql/saved-queries'; @@ -9,7 +8,6 @@ import { ensureAccountSet } from '~/console/server/utils/auth-utils'; import { getPagination, getSearch } from '~/console/server/utils/common'; import logger from '~/root/lib/client/helpers/log'; import { IRemixCtx } from '~/root/lib/types/common'; -import SecondarySubHeader from '~/console/components/secondary-sub-header'; import { Plus } from '@jengaicons/react'; import BuildResources from './build-resources'; import HandleBuild from './handle-builds'; @@ -40,6 +38,7 @@ export const loader = async (ctx: IRemixCtx) => { const Builds = () => { const [visible, setVisible] = useState(false); const { promise } = useLoaderData(); + return ( <> diff --git a/src/apps/console/routes/_main+/$account+/settings+/cloud-providers/handle-provider.tsx b/src/apps/console/routes/_main+/$account+/settings+/cloud-providers/handle-provider.tsx index 1038c988e..0809d3c53 100644 --- a/src/apps/console/routes/_main+/$account+/settings+/cloud-providers/handle-provider.tsx +++ b/src/apps/console/routes/_main+/$account+/settings+/cloud-providers/handle-provider.tsx @@ -6,6 +6,7 @@ import Select from '~/components/atoms/select'; import Popup from '~/components/molecule/popup'; import { toast } from '~/components/molecule/toast'; import { IdSelector } from '~/console/components/id-selector'; +import { NameIdView } from '~/console/components/name-id-view'; import { IDialogBase } from '~/console/components/types.d'; import { useConsoleApi } from '~/console/server/gql/api-provider'; import { IProviderSecrets } from '~/console/server/gql/queries/provider-secret-queries'; @@ -67,12 +68,14 @@ const Root = (props: IDialog) => { (p) => p.value === props.data.cloudProviderName ), awsAccountId: '', + isNameError: false, } : { displayName: '', name: '', provider: providers[0], awsAccountId: '', + isNameError: false, }, validationSchema: isUpdate ? Yup.object({ @@ -86,6 +89,20 @@ const Root = (props: IDialog) => { label: Yup.string().required(), value: Yup.string().required(), }).required(), + awsAccountId: Yup.string().test( + 'provider', + 'Account id is required', + function (item) { + return ( + // @ts-ignores + // eslint-disable-next-line react/no-this-in-sfc + this.parent.provider && + // eslint-disable-next-line react/no-this-in-sfc + this.parent.provider.value === 'aws' && + item + ); + } + ), }), onSubmit: async (val) => { @@ -191,7 +208,7 @@ const Root = (props: IDialog) => {
- {isUpdate && ( + {/* {isUpdate && ( { type: 'BASIC', }} /> - )} + )} */} - { handleChange('name')({ target: { value: id } }); }} /> - )} + )} */} + { + handleChange('displayName')(dummyEvent(name)); + if (!isUpdate) { + handleChange('name')(dummyEvent(id)); + } + }} + onCheckError={(check) => { + handleChange('isNameError')(dummyEvent(check)); + }} + isUpdate={isUpdate} + /> {!isUpdate && ( {