Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions ipaas/src/api/apim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,25 +139,24 @@ export interface DeploySettingsV2Payload {
environmentId: string;
buildId: string;
comment?: string;
apiSettings: Record<string, {
accessMode: string;
settings: {
corsConfiguration?: CorsConfiguration & { corsOverrideEnabled?: boolean };
throttlingLimit: { requestCount: number; unit: string } | null;
operations?: { verb: string; target: string; throttlingLimit: { requestCount: number; unit: string } }[];
resiliency?: number;
};
revisionId?: string;
isAsyncAPI?: boolean;
multiGatewayDeployment?: boolean;
}>;
apiSettings: Record<
string,
{
accessMode: string;
settings: {
corsConfiguration?: CorsConfiguration & { corsOverrideEnabled?: boolean };
throttlingLimit: { requestCount: number; unit: string } | null;
operations?: { verb: string; target: string; throttlingLimit: { requestCount: number; unit: string } }[];
resiliency?: number;
};
revisionId?: string;
isAsyncAPI?: boolean;
multiGatewayDeployment?: boolean;
}
>;
}

export async function deploySettingsV2(
componentId: string,
versionId: string,
payload: DeploySettingsV2Payload,
): Promise<void> {
export async function deploySettingsV2(componentId: string, versionId: string, payload: DeploySettingsV2Payload): Promise<void> {
const base = getProxyDeployerBaseUrl();
const url = `${base}/components/${encodeURIComponent(componentId)}/versions/${encodeURIComponent(versionId)}/deploy-settings-v2`;
let res: Response;
Expand Down
34 changes: 31 additions & 3 deletions ipaas/src/api/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { gql } from './graphql';
import { authenticatedFetch, refreshAccessToken } from '../auth/tokenManager';
import type { GqlArtifact, GqlComponent, GqlEnvironment, GqlProject, GqlEnvEndpoint, SchemaConfigItem } from './queries';
import type { GqlArtifact, GqlComponent, GqlEnvironment, GqlProject, GqlEnvEndpoint, SchemaConfigItem, CertMapping } from './queries';
import { toBackendArtifactType } from './artifactToggleMutations';
import type { DeployComponentInput, UpdateBuildpackConfigsInput } from '../types/build';

Expand Down Expand Up @@ -489,7 +489,7 @@ export interface DeployDeploymentTrackInput {
id: string;
imageId: string;
environmentId: string;
deploymentPipelineId: string;
deploymentPipelineId?: string;
cronTimezone?: string;
cron?: string;
jobTimeoutSeconds?: number;
Expand Down Expand Up @@ -808,7 +808,10 @@ export function useSaveSchemaConfig() {
}
return res.json().catch(() => ({}));
},
onSuccess: (_, vars) => {
onSuccess: (data, vars) => {
if (data && data.configurations) {
qc.setQueryData(['schemaConfig', vars.projectId, vars.componentId, vars.envId, vars.deploymentTrackId, vars.commitHash], data);
}
qc.invalidateQueries({ queryKey: ['schemaConfig', vars.projectId, vars.componentId, vars.envId, vars.deploymentTrackId] });
},
});
Expand Down Expand Up @@ -970,6 +973,31 @@ export function useObtainGithubToken() {
});
}

// Certificate mappings

export function usePostCertificateMappings() {
const qc = useQueryClient();
return useMutation({
mutationFn: async (data: CertMapping) => {
const base = new URL(window.API_CONFIG.graphqlUrl).origin;
const url = `${base}/config-mapping-svc/v1.0/configs/mappings`;
const res = await authenticatedFetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(text || `HTTP ${res.status}`);
}
return res.json().catch(() => ({}));
},
onSuccess: (_, vars) => {
qc.invalidateQueries({ queryKey: ['certMappings', vars.projectId, vars.componentId, vars.envTemplateId, vars.deploymentTrackId] });
},
});
}

// ── Generate component endpoints (deploys endpoints for a release) ──

const GENERATE_COMPONENT_ENDPOINTS = `
Expand Down
98 changes: 90 additions & 8 deletions ipaas/src/api/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ export const DeploymentStatus = {
NotDeployed: 'NotDeployed',
} as const;

export type DeploymentStatus = typeof DeploymentStatus[keyof typeof DeploymentStatus];
export type DeploymentStatus = (typeof DeploymentStatus)[keyof typeof DeploymentStatus];

export interface GqlReleaseMgtDeploymentRef {
releaseMgtReleaseId: string;
Expand Down Expand Up @@ -983,13 +983,7 @@ export interface GqlReleaseMgtDeployment {

const esc = (s: string) => s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');

export function useReleaseMgtDeployments(
orgUuid: string,
projectId: string,
componentId: string,
versionId: string,
environmentId: string,
) {
export function useReleaseMgtDeployments(orgUuid: string, projectId: string, componentId: string, versionId: string, environmentId: string) {
return useQuery({
queryKey: ['releaseMgtDeployments', orgUuid, projectId, componentId, versionId, environmentId],
queryFn: () => {
Expand Down Expand Up @@ -1137,10 +1131,14 @@ export interface SchemaConfigValue {

export interface SchemaConfigItem {
key: string;
keyId?: string;
values: SchemaConfigValue[];
valueType?: string;
isRequired?: boolean;
isSensitive?: boolean;
configGroupId?: string;
configKeyId?: string;
isDynamic?: boolean;
}

export interface SchemaConfigData {
Expand All @@ -1149,6 +1147,90 @@ export interface SchemaConfigData {
configurations: SchemaConfigItem[];
}

// ── Certificate groups & mappings ──

export interface CertGroupKey {
keyUuid: string;
key: string;
isSensitive: boolean;
isFile: boolean;
}

export interface CertGroup {
groupUuid: string;
groupName: string;
groupDisplayName?: string;
configurations: CertGroupKey[];
}

export function useCertificateGroups(projectId: string, componentId: string, enabled: boolean) {
return useQuery({
queryKey: ['certGroups', projectId, componentId],
queryFn: async (): Promise<CertGroup[]> => {
const base = new URL(window.API_CONFIG.graphqlUrl).origin;
const params = new URLSearchParams({ projectId, componentId, nested_search: 'true' });
const res = await authenticatedFetch(`${base}/config-svc/v1.0/configs/groups?${params}`);
if (!res.ok) return [];
const data: CertGroup[] = await res.json();
return data.filter((g) => g.groupName.startsWith('certificates-'));
},
enabled: enabled && !!projectId && !!componentId,
retry: false,
});
}

export function useConfigGroups(projectId: string, componentId: string, enabled: boolean) {
return useQuery({
queryKey: ['configGroups', projectId, componentId],
queryFn: async (): Promise<CertGroup[]> => {
const base = new URL(window.API_CONFIG.graphqlUrl).origin;
const params = new URLSearchParams({ projectId, componentId, nested_search: 'true' });
const res = await authenticatedFetch(`${base}/config-svc/v1.0/configs/groups?${params}`);
if (!res.ok) return [];
return res.json();
},
enabled: enabled && !!projectId && !!componentId,
retry: false,
});
}

export interface CertMappingConfig {
key: string;
isDynamic: boolean;
configGroupId?: string;
configKeyId?: string;
configGroupName?: string;
configKeyName?: string;
isFile?: boolean;
isSensitive?: boolean;
keyId?: string;
values?: { value: string; environmentUuid: string }[];
}

export interface CertMapping {
projectId: string;
componentId: string;
envTemplateId: string;
deploymentTrackId: string;
configurations: CertMappingConfig[];
mappingId?: string;
}

export function useCertificateMappings(projectId: string, componentId: string, envId: string, deploymentTrackId: string, enabled: boolean) {
return useQuery({
queryKey: ['certMappings', projectId, componentId, envId, deploymentTrackId],
queryFn: async (): Promise<CertMapping | null> => {
const base = new URL(window.API_CONFIG.graphqlUrl).origin;
const params = new URLSearchParams({ projectId, componentId, envTemplateId: envId, deploymentTrackId });
const res = await authenticatedFetch(`${base}/config-mapping-svc/v1.0/configs/mappings?${params}`);
if (!res.ok) return null;
return res.json();
},
enabled: enabled && !!projectId && !!componentId && !!envId && !!deploymentTrackId,
retry: false,
});
}

export function useSchemaConfig(projectId: string, componentId: string, envId: string, deploymentTrackId: string, commitHash?: string) {
return useQuery({
queryKey: ['schemaConfig', projectId, componentId, envId, deploymentTrackId, commitHash],
Expand Down
8 changes: 6 additions & 2 deletions ipaas/src/components/AutomationExecutions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* under the License.
*/

import { Button, CircularProgress, IconButton, ListingTable, TablePagination, Typography } from '@wso2/oxygen-ui';
import { Box, Button, CircularProgress, IconButton, ListingTable, TablePagination, Typography } from '@wso2/oxygen-ui';
import { CheckCircle2, ChevronRight, XCircle } from '@wso2/oxygen-ui-icons-react';
import { Fragment, useEffect, useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
Expand Down Expand Up @@ -164,7 +164,11 @@ export default function AutomationExecutions({
const paged = allExecutions.slice(safePage * rowsPerPage, safePage * rowsPerPage + rowsPerPage);

if (isLoading) {
return <CircularProgress size={24} sx={{ display: 'block', mx: 'auto', py: 4 }} />;
return (
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', py: 4 }}>
<CircularProgress size={24} color="primary" />
</Box>
);
}

if (allExecutions.length === 0) {
Expand Down
Loading