console: Schema Registry new pagination logic

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/10251
Co-authored-by: Aaysha <109507451+aayshasura@users.noreply.github.com>
GitOrigin-RevId: 1750e9ea4fa27d054d0e4bf6f58c1fdf170badfe
This commit is contained in:
ojas 2023-09-12 16:29:44 +05:30 committed by hasura-bot
parent c916a3fdc2
commit 967bbe4c63
17 changed files with 774 additions and 418 deletions

View File

@ -1,5 +1,5 @@
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = {
[K in keyof T]: T[K];
};
@ -1037,7 +1037,9 @@ export type Alert_Service_Type_Updates = {
/** Alert type enum for alert configuration */
export type Alert_Type = {
__typename?: 'alert_type';
always_enabled: Scalars['Boolean'];
description: Scalars['String'];
hidden: Scalars['Boolean'];
id: Scalars['String'];
name: Scalars['String'];
template?: Maybe<Scalars['String']>;
@ -1069,7 +1071,9 @@ export type Alert_Type_Bool_Exp = {
_and?: Maybe<Array<Alert_Type_Bool_Exp>>;
_not?: Maybe<Alert_Type_Bool_Exp>;
_or?: Maybe<Array<Alert_Type_Bool_Exp>>;
always_enabled?: Maybe<Boolean_Comparison_Exp>;
description?: Maybe<String_Comparison_Exp>;
hidden?: Maybe<Boolean_Comparison_Exp>;
id?: Maybe<String_Comparison_Exp>;
name?: Maybe<String_Comparison_Exp>;
template?: Maybe<String_Comparison_Exp>;
@ -1083,7 +1087,9 @@ export enum Alert_Type_Constraint {
/** input type for inserting data into table "alert_type" */
export type Alert_Type_Insert_Input = {
always_enabled?: Maybe<Scalars['Boolean']>;
description?: Maybe<Scalars['String']>;
hidden?: Maybe<Scalars['Boolean']>;
id?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
template?: Maybe<Scalars['String']>;
@ -1132,7 +1138,9 @@ export type Alert_Type_On_Conflict = {
/** Ordering options when selecting data from "alert_type". */
export type Alert_Type_Order_By = {
always_enabled?: Maybe<Order_By>;
description?: Maybe<Order_By>;
hidden?: Maybe<Order_By>;
id?: Maybe<Order_By>;
name?: Maybe<Order_By>;
template?: Maybe<Order_By>;
@ -1145,9 +1153,13 @@ export type Alert_Type_Pk_Columns_Input = {
/** select columns of table "alert_type" */
export enum Alert_Type_Select_Column {
/** column name */
AlwaysEnabled = 'always_enabled',
/** column name */
Description = 'description',
/** column name */
Hidden = 'hidden',
/** column name */
Id = 'id',
/** column name */
Name = 'name',
@ -1157,7 +1169,9 @@ export enum Alert_Type_Select_Column {
/** input type for updating data in table "alert_type" */
export type Alert_Type_Set_Input = {
always_enabled?: Maybe<Scalars['Boolean']>;
description?: Maybe<Scalars['String']>;
hidden?: Maybe<Scalars['Boolean']>;
id?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
template?: Maybe<Scalars['String']>;
@ -1173,7 +1187,9 @@ export type Alert_Type_Stream_Cursor_Input = {
/** Initial value of the column from where the streaming should start */
export type Alert_Type_Stream_Cursor_Value_Input = {
always_enabled?: Maybe<Scalars['Boolean']>;
description?: Maybe<Scalars['String']>;
hidden?: Maybe<Scalars['Boolean']>;
id?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
template?: Maybe<Scalars['String']>;
@ -1181,9 +1197,13 @@ export type Alert_Type_Stream_Cursor_Value_Input = {
/** update columns of table "alert_type" */
export enum Alert_Type_Update_Column {
/** column name */
AlwaysEnabled = 'always_enabled',
/** column name */
Description = 'description',
/** column name */
Hidden = 'hidden',
/** column name */
Id = 'id',
/** column name */
Name = 'name',
@ -6608,11 +6628,6 @@ export type CreateTenantResponse = {
tenant?: Maybe<Tenant>;
};
export type CreateTunnelOutput = {
__typename?: 'CreateTunnelOutput';
tunnel?: Maybe<DdnTunnel>;
};
/** ordering argument of a cursor */
export enum Cursor_Ordering {
/** ascending ordering of the cursor */
@ -11529,44 +11544,6 @@ export type Ddn_Tunnel_Variance_Order_By = {
reserved_port?: Maybe<Order_By>;
};
export type DdnApplyMetadataOutput = {
__typename?: 'DDNApplyMetadataOutput';
build?: Maybe<Ddn_Build>;
build_id?: Maybe<Scalars['String']>;
graphql_api_endpoint: Scalars['String'];
};
export type DdnCreateBuildOutput = {
__typename?: 'ddnCreateBuildOutput';
build?: Maybe<Ddn_Build>;
build_id: Scalars['String'];
build_version: Scalars['String'];
graphql_api_endpoint: Scalars['String'];
};
export type DdnCreateProjectResponse = {
__typename?: 'DDNCreateProjectResponse';
id: Scalars['uuid'];
name: Scalars['String'];
project?: Maybe<Ddn_Projects>;
};
export type DdnTunnel = {
__typename?: 'DDNTunnel';
id: Scalars['uuid'];
owner_id: Scalars['uuid'];
reserved_cluster: Scalars['uuid'];
reserved_port: Scalars['Int'];
tunnel_cluster: DdnTunnelCluster;
};
export type DdnTunnelCluster = {
__typename?: 'DDNTunnelCluster';
internal_fqdn: Scalars['String'];
name: Scalars['String'];
public_fqdn: Scalars['String'];
};
/** Table to keep track of dedicated cloud bills. These are not part of automated Stripe invoicing. */
export type Dedicated_Cloud_Bills = {
__typename?: 'dedicated_cloud_bills';
@ -19751,17 +19728,6 @@ export type Hasura_Worker_Updates = {
where: Hasura_Worker_Bool_Exp;
};
export type HasuraSecretList = {
__typename?: 'HasuraSecretList';
key: Scalars['String'];
value: Scalars['String'];
};
export type HasuraSecretMessage = {
__typename?: 'HasuraSecretMessage';
message: Scalars['String'];
};
/** heroku integration metadata (1.4+) */
export type Heroku_Integrations = {
__typename?: 'heroku_integrations';
@ -24811,13 +24777,6 @@ export type Mutation_Root = {
createPersonalAccessToken: PersonalAccessToken;
createTenant?: Maybe<CreateTenantResponse>;
createZendeskSupportTicket: SuccessOrError;
ddnApplyMetadata?: Maybe<DdnApplyMetadataOutput>;
/** ddnCreateBuild */
ddnCreateBuild?: Maybe<DdnCreateBuildOutput>;
ddnCreateProject?: Maybe<DdnCreateProjectResponse>;
ddnCreateTunnel?: Maybe<CreateTunnelOutput>;
ddnHasuraSecretDelete: HasuraSecretMessage;
ddnHasuraSecretSet: HasuraSecretMessage;
declineBillingManagerInvite?: Maybe<BillingManagerInvitation>;
declineInvite: ProjectCollaboratorInvitation;
declineTransferOwnershipInvite: ProjectOwnershipTransferInvitation;
@ -28041,41 +28000,6 @@ export type Mutation_RootCreateZendeskSupportTicketArgs = {
subject: Scalars['String'];
};
/** mutation root */
export type Mutation_RootDdnApplyMetadataArgs = {
build_id?: Maybe<Scalars['String']>;
environment?: Maybe<Scalars['String']>;
project_id: Scalars['String'];
};
/** mutation root */
export type Mutation_RootDdnCreateBuildArgs = {
description?: Maybe<Scalars['String']>;
metadata_json: Scalars['String'];
project_id: Scalars['String'];
};
/** mutation root */
export type Mutation_RootDdnCreateProjectArgs = {
cloud?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
plan?: Maybe<Scalars['String']>;
region?: Maybe<Scalars['String']>;
};
/** mutation root */
export type Mutation_RootDdnHasuraSecretDeleteArgs = {
key: Scalars['String'];
project_id: Scalars['String'];
};
/** mutation root */
export type Mutation_RootDdnHasuraSecretSetArgs = {
key: Scalars['String'];
project_id: Scalars['String'];
value: Scalars['String'];
};
/** mutation root */
export type Mutation_RootDeclineBillingManagerInviteArgs = {
project_id: Scalars['uuid'];
@ -53930,7 +53854,6 @@ export type Query_Root = {
ddn_tunnel_cluster_aggregate: Ddn_Tunnel_Cluster_Aggregate;
/** fetch data from the table: "ddn.tunnel_cluster" using primary key columns */
ddn_tunnel_cluster_by_pk?: Maybe<Ddn_Tunnel_Cluster>;
ddnHasuraSecretList: Array<HasuraSecretList>;
/** fetch data from the table: "dedicated_cloud_bills" */
dedicated_cloud_bills: Array<Dedicated_Cloud_Bills>;
/** fetch aggregated fields from the table: "dedicated_cloud_bills" */
@ -55821,10 +55744,6 @@ export type Query_RootDdn_Tunnel_Cluster_By_PkArgs = {
id: Scalars['uuid'];
};
export type Query_RootDdnHasuraSecretListArgs = {
project_id: Scalars['String'];
};
export type Query_RootDedicated_Cloud_BillsArgs = {
distinct_on?: Maybe<Array<Dedicated_Cloud_Bills_Select_Column>>;
limit?: Maybe<Scalars['Int']>;

View File

@ -0,0 +1,13 @@
To generate GraphQL types for Schema Registry service, Run `yarn generate-schema-registry-gql-types` from the `/frontend` directory
Note: The command uses the config file `frontend/schema-registry-graphql-codegen.yml`. It uses the lux localdev endpoint and the localdev admin secret. Make sure those reflect the current localdev environment. Please update it accordingly if needed.
## Important note
The `InputMaybe` type is not generated by the codegen tool becuase of issues in the version that we use.
For now, ensure you add this line at the top of the file whenever you regenerate the types:
Reference to the issue: https://github.com/dotansimha/graphql-code-generator/issues/7774
```typescript
export type InputMaybe<T> = Maybe<T>;
```

View File

@ -9,8 +9,9 @@ import { AlertsDialog } from './AlertsDialog';
import { Badge } from '../../../new-components/Badge';
import { SCHEMA_REGISTRY_REF_URL } from '../constants';
import { Analytics } from '../../Analytics';
import { useGetV2Info } from '../hooks/useGetV2Info';
const Header: React.VFC = () => {
const SchemaRegistryHeader: React.VFC = () => {
const [isAlertModalOpen, setIsAlertModalOpen] = useState(false);
return (
@ -50,17 +51,33 @@ const Header: React.VFC = () => {
);
};
const Body: React.VFC<{
const SchemaRegistryBody: React.VFC<{
hasFeatureAccess: boolean;
schemaId: string | undefined;
}> = props => {
const { hasFeatureAccess, schemaId } = props;
const projectID = globals.hasuraCloudProjectId || '';
const v2Info = useGetV2Info(projectID);
if (!hasFeatureAccess) {
return <FeatureRequest />;
}
return <SchemaRegistryHome schemaId={schemaId} />;
switch (v2Info.kind) {
case 'loading':
return <p>Loading...</p>;
case 'error':
return <p>Error: {v2Info.message}</p>;
}
return (
<SchemaRegistryHome
schemaId={schemaId}
v2Cursor={v2Info.v2Cursor}
v2Count={v2Info.v2Count}
/>
);
};
type SchemaDetailsViewProps = {
params: {
id?: string;
@ -77,8 +94,11 @@ export const SchemaRegistryContainer: React.VFC<
return (
<div className="p-4 flex flex-col w-full">
<Header />
<Body hasFeatureAccess={hasFeatureAccess} schemaId={schemaId} />
<SchemaRegistryHeader />
<SchemaRegistryBody
hasFeatureAccess={hasFeatureAccess}
schemaId={schemaId}
/>
</div>
);
};

View File

@ -49,7 +49,6 @@ export const SchemaChangeDetails: React.FC<
> = props => {
const { schemaId } = props;
const fetchSchemaResponse = useGetSchema(schemaId);
console.log('fetchSchemaResponse', fetchSchemaResponse);
const { kind } = fetchSchemaResponse;
switch (kind) {

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Dispatch } from 'redux';
import { useGetSchemaChangeList } from '../hooks/useGetSchemaChangeList';
import { useGetSchemaRegistryList } from '../hooks/useGetSchemaRegistryList';
import { Role, SchemaChangeCard, SchemaRegistryTag } from '../types';
import globals from '../../../Globals';
import {
@ -29,32 +29,37 @@ import {
import { IconTooltip } from '../../../new-components/Tooltip';
import _push from '../../../components/Services/Data/push';
import { useAppDispatch } from '../../../storeHooks';
import { useGetURLSchema } from '../hooks/useGetURLSchema';
interface SchemaRegistryHomeProps {
schemaId: string | undefined;
v2Cursor: string;
v2Count: number;
}
export const SchemaRegistryHome: React.FC<SchemaRegistryHomeProps> = props => {
const { schemaId } = props;
const { schemaId, v2Cursor, v2Count } = props;
const projectID = globals.hasuraCloudProjectId || '';
const dispatch = useAppDispatch();
const [pageNo, setPageno] = useState(
parseInt(getSearchParam(window.location.search, 'page') || '0')
);
const schemaRoleID = schemaId ? schemaId : EMPTY_UUID_STRING;
const fetchSchemaResponse = useGetSchemaChangeList(
const fetchSchemasResponse = useGetSchemaRegistryList(
projectID,
SCHEMA_LIST_FETCH_BATCH_SIZE,
pageNo * SCHEMA_LIST_FETCH_BATCH_SIZE,
schemaRoleID
pageNo,
v2Count,
v2Cursor
);
const { kind } = fetchSchemaResponse;
const fetchURLSchemaResponse = useGetURLSchema(schemaRoleID);
//to check if fetchSchemaResponse changed
const { kind } = fetchSchemasResponse;
let latestAdminRoleID: string | null = null;
if (kind === 'success') {
const schemaList = schemaChangeListTransformFn(
fetchSchemaResponse.response
fetchSchemasResponse.response
);
latestAdminRoleID =
schemaList[0]?.roles?.find(item => item.role === ADMIN_ROLE)?.id || null;
@ -67,6 +72,7 @@ export const SchemaRegistryHome: React.FC<SchemaRegistryHomeProps> = props => {
const handlePrev = () => {
setPageno(pageNo - 1);
};
//setting the selected role ID as admin role ID by default
useEffect(() => {
if (schemaRoleID === EMPTY_UUID_STRING) {
@ -78,6 +84,7 @@ export const SchemaRegistryHome: React.FC<SchemaRegistryHomeProps> = props => {
setSelectedRoleID(schemaRoleID);
}
}, [schemaRoleID]);
useEffect(() => {
if (latestAdminRoleID) {
setSelectedRoleID(latestAdminRoleID);
@ -85,22 +92,39 @@ export const SchemaRegistryHome: React.FC<SchemaRegistryHomeProps> = props => {
}
setSearchParam(pageNo);
}, [latestAdminRoleID, pageNo]);
switch (kind) {
case 'loading':
return <p>Loading...</p>;
case 'error':
return <p>Error: {fetchSchemaResponse.message}</p>;
return <p>Error: {fetchSchemasResponse.message}</p>;
case 'success': {
let URLSchemaCard: SchemaChangeCard[] = [];
if (
fetchURLSchemaResponse.kind === 'success' &&
fetchURLSchemaResponse.response[0]
) {
const URLAdminRoleID = URLSchemaCard[0]?.roles.find(
item => item.role === ADMIN_ROLE
)?.id;
if (URLAdminRoleID !== latestAdminRoleID) {
URLSchemaCard = schemaChangeListTransformFn(
fetchURLSchemaResponse.response
);
}
}
const schemaList = schemaChangeListTransformFn(
fetchSchemaResponse.response
fetchSchemasResponse.response
);
return (
<div className="flex w-full">
<div className="w-1/4">
<SchemaChangeList
schemas={schemaList}
urlSchemaCard={URLSchemaCard}
pageNumber={pageNo}
totalCount={fetchSchemaResponse.totalCount}
totalCount={fetchSchemasResponse.totalCount}
selectedRoleID={selectedRoleID}
dispatch={dispatch}
handlePrev={handlePrev}
@ -120,6 +144,7 @@ export const SchemaRegistryHome: React.FC<SchemaRegistryHomeProps> = props => {
export const SchemaChangeList: React.VFC<{
schemas: SchemaChangeCard[];
urlSchemaCard: SchemaChangeCard[];
pageNumber: number;
totalCount: number;
selectedRoleID: string | null;
@ -129,6 +154,7 @@ export const SchemaChangeList: React.VFC<{
}> = props => {
const {
schemas,
urlSchemaCard,
pageNumber,
totalCount,
selectedRoleID,
@ -142,6 +168,7 @@ export const SchemaChangeList: React.VFC<{
totalCount <= (pageNumber + 1) * SCHEMA_LIST_FETCH_BATCH_SIZE;
const isSecondLastPage =
totalCount <= (pageNumber + 2) * SCHEMA_LIST_FETCH_BATCH_SIZE;
const schemaList: SchemaChangeCard[] = [...urlSchemaCard, ...schemas];
return (
<div className="overflow-x-auto rounded-md border-neutral-200 bg-white border mr-sm">
<div className="w-full flex bg-gray-100 px-4 py-2">
@ -152,7 +179,7 @@ export const SchemaChangeList: React.VFC<{
<div className="flex flex-col w-full">
{schemas.length ? (
<div className="mb-md">
{schemas.map((schema, index) => (
{schemaList.map((schema, index) => (
<SchemaCard
cardKey={index}
openSchemaCardIndex={openSchemaCardIndex}

View File

@ -3,9 +3,20 @@ export const FETCH_REGISTRY_SCHEMAS_QUERY_NAME =
'FETCH_REGISTRY_SCHEMAS_QUERY_NAME';
export const FETCH_REGISTRY_SCHEMA_QUERY_NAME =
'FETCH_REGISTRY_SCHEMA_QUERY_NAME';
export const FETCH_URL_REGISTRY_SCHEMA_QUERY_NAME =
'FETCH_URL_REGISTRY_SCHEMA_QUERY_NAME';
export const FETCH_ALERT_CONFIG_QUERY_NAME = 'FETCH_ALERT_CONFIG_QUERY_NAME';
export const FETCH_SLACK_STATE_QUERY_NAME = 'FETCH_SLACK_STATE_QUERY_NAME';
export const FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY_NAME =
'FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY_NAME';
export const FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY_NAME =
'FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY_NAME';
export const FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY_NAME =
'FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY_NAME';
export const FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY_NAME =
'FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY_NAME';
// 5 minutes as default stale time
export const SCHEMA_REGISTRY_REFRESH_TIME = 5 * 60 * 1000;

View File

@ -53,7 +53,6 @@ export const useGetSchema = (schemaId: string): FetchSchemaResponse => {
message: 'error',
};
}
return {
kind: 'success',
response: data.data,

View File

@ -1,112 +0,0 @@
import * as React from 'react';
import { useQuery } from 'react-query';
import { FETCH_SCHEMA_CHANGE_LIST_QUERY } from '../queries';
import { schemaRegsitryControlPlaneClient } from '../utils';
import {
GetSchemaChangeListResponseWithError,
GetSchemaListResponseWithError,
SchemaRegistryDumpsAggregate,
} from '../types';
import {
FETCH_REGISTRY_SCHEMAS_QUERY_NAME,
SCHEMA_REGISTRY_REFRESH_TIME,
} from '../constants';
type FetchSchemaResponse =
| {
kind: 'loading';
}
| {
kind: 'error';
message: string;
}
| {
kind: 'success';
response: NonNullable<
GetSchemaListResponseWithError['data']
>['schema_registry_dumps'];
totalCount: number;
};
export const useGetSchemaChangeList = (
projectId: string,
limit: number,
offset: number,
schemaId: string
): FetchSchemaResponse => {
const [dumps, setDumps] = React.useState<
NonNullable<GetSchemaListResponseWithError['data']>['schema_registry_dumps']
>([]);
const [totalCount, setTotalCount] =
React.useState<
NonNullable<SchemaRegistryDumpsAggregate['aggregate']>['count']
>(0);
const fetchRegistrySchemasQueryFn = React.useCallback(
(projectId: string, limit: number, offset: number, schemaId: string) => {
return schemaRegsitryControlPlaneClient.query<
GetSchemaChangeListResponseWithError,
{ projectId: string; limit: number; offset: number; schemaId: string }
>(FETCH_SCHEMA_CHANGE_LIST_QUERY, {
projectId: projectId,
limit: limit,
offset: offset,
schemaId: schemaId,
});
},
[limit, offset]
);
const { data, error, isLoading, refetch } = useQuery({
queryKey: FETCH_REGISTRY_SCHEMAS_QUERY_NAME,
queryFn: () =>
fetchRegistrySchemasQueryFn(projectId, limit, offset, schemaId),
refetchOnMount: 'always',
refetchOnWindowFocus: true,
staleTime: SCHEMA_REGISTRY_REFRESH_TIME,
onSuccess: response => {
setDumps([]);
setTotalCount(0);
if (response && response.data && response.data.schema_change_list) {
const tempDumps = response.data.schema_change_list;
setDumps(tempDumps);
if (response.data.current_schema_card[0]) {
//adding to the top of the array so that this opens
tempDumps.unshift(response.data.current_schema_card[0]);
setDumps(tempDumps);
}
}
if (
response &&
response.data &&
response.data.schema_registry_dumps_aggregate?.aggregate?.count
) {
const count =
response.data.schema_registry_dumps_aggregate?.aggregate?.count;
setTotalCount(count);
}
},
});
React.useEffect(() => {
refetch();
}, [offset, limit]);
if (isLoading) {
return {
kind: 'loading',
};
}
if (error || !data || !!data.errors || !data.data) {
return {
kind: 'error',
message: 'error',
};
}
return {
kind: 'success',
response: dumps,
totalCount: totalCount,
};
};

View File

@ -1,99 +0,0 @@
import * as React from 'react';
import { useQuery } from 'react-query';
import { FETCH_REGISTRY_SCHEMAS_QUERY } from '../queries';
import { schemaRegsitryControlPlaneClient } from '../utils';
import { GetSchemaListResponseWithError } from '../types';
import {
FETCH_REGISTRY_SCHEMAS_QUERY_NAME,
SCHEMA_REGISTRY_REFRESH_TIME,
SCHEMA_LIST_FETCH_BATCH_SIZE,
} from '../constants';
type FetchSchemaResponse =
| {
kind: 'loading';
}
| {
kind: 'error';
message: string;
}
| {
kind: 'success';
response: NonNullable<
GetSchemaListResponseWithError['data']
>['schema_registry_dumps'];
loadMore: VoidFunction;
isLoadingMore: boolean;
shouldLoadMore: boolean;
};
export const useGetSchemaList = (projectId: string): FetchSchemaResponse => {
const [dumps, setDumps] = React.useState<
NonNullable<GetSchemaListResponseWithError['data']>['schema_registry_dumps']
>([]);
const [loadingMore, setLoadingMore] = React.useState(false);
const [shouldLoadMore, setShouldLoadMore] = React.useState(true);
let cursor = 'now()';
if (dumps && dumps.length > 0) {
cursor = dumps[dumps.length - 1].change_recorded_at;
}
const fetchRegistrySchemasQueryFn = React.useCallback(
(projectId: string) => {
return schemaRegsitryControlPlaneClient.query<
GetSchemaListResponseWithError,
{ projectId: string; cursor: string; limit: number }
>(FETCH_REGISTRY_SCHEMAS_QUERY, {
projectId: projectId,
cursor: cursor,
limit: SCHEMA_LIST_FETCH_BATCH_SIZE,
});
},
[cursor]
);
const { data, error, isLoading, refetch } = useQuery({
queryKey: FETCH_REGISTRY_SCHEMAS_QUERY_NAME,
queryFn: () => fetchRegistrySchemasQueryFn(projectId),
refetchOnMount: 'always',
refetchOnWindowFocus: true,
staleTime: SCHEMA_REGISTRY_REFRESH_TIME,
onSettled: () => {
setLoadingMore(false);
},
onSuccess: response => {
if (response && response.data && response.data.schema_registry_dumps) {
const dumps = response.data.schema_registry_dumps;
setDumps(d => [...(d || []), ...dumps]);
if (dumps.length < SCHEMA_LIST_FETCH_BATCH_SIZE) {
setShouldLoadMore(false);
}
}
},
});
if (isLoading) {
return {
kind: 'loading',
};
}
if (error || !data || !!data.errors || !data.data) {
return {
kind: 'error',
message: 'error',
};
}
return {
kind: 'success',
response: dumps,
loadMore: () => {
setLoadingMore(true);
refetch();
},
isLoadingMore: loadingMore,
shouldLoadMore,
};
};

View File

@ -0,0 +1,255 @@
import React, { useState } from 'react';
import { useQuery } from 'react-query';
import { schemaRegsitryControlPlaneClient } from '../utils';
import {
FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY,
FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY,
FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY,
} from '../queries';
import {
GetSchemaRegstiryDumpsV2ResponseWithError,
GetSchemaRegstiryDumpsV1ResponseWithError,
SchemaRegistryDumpWithSiblingSchema,
GetSchemaRegstiryDumpsV1AggregateResponseWithError,
} from '../types';
import {
FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY_NAME,
FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY_NAME,
SCHEMA_REGISTRY_REFRESH_TIME,
SCHEMA_LIST_FETCH_BATCH_SIZE,
FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY_NAME,
} from '../constants';
type GetSchemaRegistryListResponse =
| {
kind: 'loading';
}
| {
kind: 'error';
message: string;
}
| {
kind: 'success';
response: SchemaRegistryDumpWithSiblingSchema[];
totalCount: number;
};
export const useGetSchemaRegistryList = (
projectId: string,
pageNumber: number,
v2Count: number,
lastV2EntryCursor: string
): GetSchemaRegistryListResponse => {
const [v1Count, setV1Count] = useState<number>(0);
const [v2Dumps, setV2Dumps] = useState<SchemaRegistryDumpWithSiblingSchema[]>(
[]
);
const [v1Dumps, setV1Dumps] = useState<SchemaRegistryDumpWithSiblingSchema[]>(
[]
);
const [returnedDumps, setReturnedDumps] = useState<
SchemaRegistryDumpWithSiblingSchema[]
>([]);
/**
* Fetch the aggregate count for Schema Registry Dumps V1 based on last V2 entry
*/
const fetchSchemaRegistryDumpsV1AggregateFn = (projectId: string) => {
return schemaRegsitryControlPlaneClient.query<
GetSchemaRegstiryDumpsV1AggregateResponseWithError,
{ projectId: string; lastV2EntryCursor: string }
>(FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY, {
projectId: projectId,
lastV2EntryCursor: lastV2EntryCursor,
});
};
const {
data: v1AggregateData,
error: v1AggregateError,
isLoading: v1AggregateLoading,
refetch,
} = useQuery({
queryKey: FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY_NAME,
queryFn: () => fetchSchemaRegistryDumpsV1AggregateFn(projectId),
refetchOnMount: 'always',
refetchOnWindowFocus: true,
staleTime: SCHEMA_REGISTRY_REFRESH_TIME,
onSuccess: response => {
if (
response &&
response.data &&
response.data.schema_registry_dumps_aggregate?.aggregate?.count
) {
const totalV1Dumps =
response.data.schema_registry_dumps_aggregate.aggregate.count;
setV1Count(totalV1Dumps);
}
},
});
React.useEffect(() => {
refetch();
}, [lastV2EntryCursor]);
const lastV2Page = Math.floor(v2Count / SCHEMA_LIST_FETCH_BATCH_SIZE);
const v1PageNumber = pageNumber - lastV2Page;
const v1Offset =
v1PageNumber > 0
? (v1PageNumber - 1) * SCHEMA_LIST_FETCH_BATCH_SIZE +
(SCHEMA_LIST_FETCH_BATCH_SIZE -
(v2Count % SCHEMA_LIST_FETCH_BATCH_SIZE))
: 0;
const v2Offset = pageNumber * SCHEMA_LIST_FETCH_BATCH_SIZE;
/**
* Fetch Schema Registry V2 dumps based on the page number
* Query gets fired only when aggregate data is fetched and lastV2Page >= pageNumber
*/
const fetchSchemaRegistryDumpsV2Fn = (
projectId: string,
limit: number,
offset: number
) => {
return schemaRegsitryControlPlaneClient.query<
GetSchemaRegstiryDumpsV2ResponseWithError,
{ projectId: string; limit: number; offset: number }
>(FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY, {
projectId: projectId,
limit: limit,
offset: offset,
});
};
const {
data: v2Data,
error: v2Error,
isLoading: v2Loading,
refetch: v2Refetch,
} = useQuery({
queryKey: [FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY_NAME, pageNumber],
queryFn: () =>
fetchSchemaRegistryDumpsV2Fn(
projectId,
SCHEMA_LIST_FETCH_BATCH_SIZE,
v2Offset
),
enabled: lastV2Page >= pageNumber,
refetchOnMount: 'always',
refetchOnWindowFocus: true,
onSuccess: response => {
if (response && response.data && response.data.schema_registry_dumps_v2) {
const v2Dumps = response.data.schema_registry_dumps_v2;
setV2Dumps(v2Dumps);
}
},
});
React.useEffect(() => {
if (lastV2Page <= pageNumber) {
v2Refetch();
}
if (v1PageNumber >= 0) {
v1Refetch();
}
}, [pageNumber, lastV2EntryCursor, v1Offset]);
/**
* Fetch Schema Registry V1 dumps based on the page number
* Query gets fired only if change_recorded_at is fetched from V2 and (v1PageNumber >= 0 && v1Offset >= 0)
*/
const fetchSchemaRegistryDumpsV1Fn = (
projectId: string,
limit: number,
offset: number,
changeTimestamp: string
) => {
return schemaRegsitryControlPlaneClient.query<
GetSchemaRegstiryDumpsV1ResponseWithError,
{
projectId: string;
limit: number;
offset: number;
changeTimestamp: string;
}
>(FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY, {
projectId: projectId,
limit: limit,
offset: offset,
changeTimestamp: changeTimestamp,
});
};
const {
data: v1Data,
error: v1Error,
isLoading: v1Loading,
refetch: v1Refetch,
} = useQuery({
queryKey: [
FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY_NAME,
v1Offset,
v1PageNumber,
],
queryFn: () =>
fetchSchemaRegistryDumpsV1Fn(
projectId,
SCHEMA_LIST_FETCH_BATCH_SIZE,
v1Offset,
lastV2EntryCursor
),
enabled: v1PageNumber >= 0 && v1Offset >= 0,
refetchOnMount: 'always',
refetchOnWindowFocus: true,
onSuccess: response => {
if (response && response.data && response.data.schema_registry_dumps) {
const v1Dumps = response.data.schema_registry_dumps;
setV1Dumps(v1Dumps);
}
},
});
React.useEffect(() => {
if (pageNumber === lastV2Page) {
// Slicing the results to SCHEMA_LIST_FETCH_BATCH_SIZE as extra v1Dumps might be present
setReturnedDumps(
[...v2Dumps, ...v1Dumps].slice(0, SCHEMA_LIST_FETCH_BATCH_SIZE)
);
} else if (pageNumber < lastV2Page) {
setReturnedDumps(v2Dumps);
} else {
setReturnedDumps(v1Dumps);
}
}, [pageNumber, v1Dumps, v2Dumps]);
if (v1AggregateLoading || v2Loading || v1Loading) {
return {
kind: 'loading',
};
}
if (
v1AggregateError ||
!!v1AggregateData?.errors ||
v2Error ||
!!v2Data?.errors ||
v1Error ||
!!v1Data?.errors
) {
return {
kind: 'error',
message: 'error',
};
}
return {
kind: 'success',
response: returnedDumps,
totalCount: v2Count + v1Count,
};
};

View File

@ -0,0 +1,62 @@
import * as React from 'react';
import { useQuery } from 'react-query';
import { schemaRegsitryControlPlaneClient } from '../utils';
import { FETCH_URL_REGISTRY_SCHEMA_QUERY } from '../queries';
import {
GetURLRegistrySchemaResponseWithError,
SchemaChangeListDumpWithSiblingSchema,
} from '../types';
import { FETCH_URL_REGISTRY_SCHEMA_QUERY_NAME } from '../constants';
type FetchSchemaResponse =
| {
kind: 'loading';
}
| {
kind: 'error';
message: string;
}
| {
kind: 'success';
response: SchemaChangeListDumpWithSiblingSchema[];
};
export const useGetURLSchema = (schemaId: string): FetchSchemaResponse => {
const fetchRegistrySchemaQueryFn = (schemaId: string) => {
return schemaRegsitryControlPlaneClient.query<
GetURLRegistrySchemaResponseWithError,
{ schemaId: string }
>(FETCH_URL_REGISTRY_SCHEMA_QUERY, {
schemaId: schemaId,
});
};
const { data, error, isLoading } = useQuery({
queryKey: FETCH_URL_REGISTRY_SCHEMA_QUERY_NAME,
queryFn: () => fetchRegistrySchemaQueryFn(schemaId),
refetchOnMount: 'always',
refetchOnWindowFocus: true,
});
if (isLoading) {
return {
kind: 'loading',
};
}
if (error || !data || !!data?.errors || !data?.data) {
return {
kind: 'error',
message: 'error',
};
}
if (data.data?.schema_registry_dumps_v2.length) {
return {
kind: 'success',
response: data.data.schema_registry_dumps_v2,
};
}
return {
kind: 'success',
response: data.data.schema_registry_dumps,
};
};

View File

@ -0,0 +1,95 @@
import React, { useState } from 'react';
import { useQuery } from 'react-query';
import { schemaRegsitryControlPlaneClient } from '../utils';
import { FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY } from '../queries';
import { GetSchemaRegstiryDumpsV2AggregateResponseWithError } from '../types';
import {
FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY_NAME,
SCHEMA_REGISTRY_REFRESH_TIME,
} from '../constants';
type GetSchemaRegistryListResponse =
| {
kind: 'loading';
}
| {
kind: 'error';
message: string;
}
| {
kind: 'success';
v2Count: number;
v2Cursor: string;
};
export const useGetV2Info = (
projectId: string
): GetSchemaRegistryListResponse => {
const [v2Count, setV2Count] = useState<number>(0);
const [lastV2EntryCursor, setLastV2EntryCursor] = useState<string>('now()');
/**
* Fetch the aggregate count for Schema Registry Dumps V2 along with the change_recorded_at of the last entry in the V2 table
*/
const fetchSchemaRegistryDumpsV2AggregateFn = React.useCallback(
(projectId: string) => {
return schemaRegsitryControlPlaneClient.query<
GetSchemaRegstiryDumpsV2AggregateResponseWithError,
{ projectId: string }
>(FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY, {
projectId: projectId,
});
},
[]
);
const {
data: v2InfoData,
error: v2InfoError,
isLoading: v2InfoLoading,
} = useQuery({
queryKey: FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY_NAME,
queryFn: () => fetchSchemaRegistryDumpsV2AggregateFn(projectId),
refetchOnMount: 'always',
refetchOnWindowFocus: true,
staleTime: SCHEMA_REGISTRY_REFRESH_TIME,
onSuccess: response => {
if (response && response.data) {
const totalV2Dumps =
response.data.schema_registry_dumps_v2_aggregate?.aggregate?.count;
setV2Count(totalV2Dumps);
if (
response.data &&
response.data.schema_registry_dumps_v2.length &&
response.data.schema_registry_dumps_v2[0].change_recorded_at
) {
setLastV2EntryCursor(
response.data.schema_registry_dumps_v2[0].change_recorded_at
);
}
}
},
});
if (v2InfoLoading) {
return {
kind: 'loading',
};
}
if (v2InfoError || !!v2InfoData?.errors) {
return {
kind: 'error',
message: 'error',
};
}
return {
kind: 'success',
v2Count: v2Count,
v2Cursor: lastV2EntryCursor,
};
};

View File

@ -36,9 +36,70 @@ query fetchRegistrySchemas($projectId: uuid!, $cursor: timestamptz!, $limit: Int
}
}
`);
export const FETCH_SCHEMA_CHANGE_LIST_QUERY = gql(`
query fetchRegistrySchemas($projectId: uuid!, $limit: Int!, $offset: Int!,$schemaId:uuid!) {
schema_change_list :schema_registry_dumps(
query fetchRegistrySchemas($projectId: uuid!, $limit: Int!, $offset: Int!) {
schema_registry_dumps(
where: {_and: [{project_id: {_eq: $projectId}, hasura_schema_role: {_eq: "admin"}}]},
order_by: {change_recorded_at: desc}
limit: $limit
offset: $offset
) {
id
entry_hash
schema_hash
change_recorded_at
sibling_schemas {
id
hasura_schema_role
}
schema_tags {
id
name
entry_hash
color
}
}
schema_registry_dumps_aggregate(
where: {
hasura_schema_role: {_eq: "admin"},
project_id: {_eq: $projectId}
}
) {
aggregate {
count
}
}
}
`);
export const FETCH_SCHEMA_REGSITRY_DUMPS_V2_INFO_QUERY = gql(`
query fetchSchemaRegistryDumpsV2Info($projectId: uuid!) {
schema_registry_dumps_v2_aggregate(where: {hasura_schema_role: {_eq: "admin"}, project_id: {_eq: $projectId}}) {
aggregate {
count
}
}
schema_registry_dumps_v2(where: {project_id: {_eq: $projectId}}, order_by: {change_recorded_at: asc}, limit: 1) {
change_recorded_at
}
}
`);
export const FETCH_SCHEMA_REGISTRY_DUMPS_V1_AGGREGATE_QUERY = gql(`
query fetchSchemaRegistryDumpsV1Aggregate($projectId: uuid!, $lastV2EntryCursor: timestamptz!) {
schema_registry_dumps_aggregate(where: {hasura_schema_role: {_eq: "admin"}, project_id: {_eq: $projectId}, change_recorded_at: {_lt: $lastV2EntryCursor}}) {
aggregate {
count
}
}
}
`);
export const FETCH_SCHEMA_REGISTRY_DUMPS_V2_QUERY = gql(`
query fetchSchemaRegistryDumpsV2($projectId: uuid!, $limit: Int!, $offset: Int!) {
schema_registry_dumps_v2(
where: {_and: [{project_id: {_eq: $projectId}, hasura_schema_role: {_eq: "admin"}}]},
order_by: {change_recorded_at: desc}
limit: $limit
@ -71,12 +132,12 @@ query fetchRegistrySchemas($projectId: uuid!, $limit: Int!, $offset: Int!,$schem
color
}
}
current_schema_card :schema_registry_dumps(
where: {id:{_eq :$schemaId }},
order_by: {change_recorded_at: desc}
limit: $limit
offset: $offset
) {
}
`);
export const FETCH_SCHEMA_REGISTRY_DUMPS_V1_QUERY = gql(`
query fetchSchemaRegistryDumpsV1($projectId: uuid!, $limit: Int!, $offset: Int!, $changeTimestamp: timestamptz!) {
schema_registry_dumps(where: {_and: [{project_id: {_eq: $projectId}, hasura_schema_role: {_eq: "admin"}}], change_recorded_at: {_lt: $changeTimestamp}}, order_by: {change_recorded_at: desc}, limit: $limit, offset: $offset) {
change_recorded_at
schema_hash
entry_hash
@ -104,16 +165,6 @@ query fetchRegistrySchemas($projectId: uuid!, $limit: Int!, $offset: Int!,$schem
color
}
}
schema_registry_dumps_aggregate(
where: {
hasura_schema_role: {_eq: "admin"},
project_id: {_eq: $projectId}
}
) {
aggregate {
count
}
}
}
`);
@ -140,6 +191,71 @@ query fetchRegistrySchema ($schemaId: uuid!) {
current_schema_id
schema_diff_data
}
}
schema_registry_dumps_v2 (
where: {
id: {
_eq: $schemaId
}
}
) {
id
entry_hash
schema_hash
change_recorded_at
created_at
hasura_schema_role
schema_sdl
diff_with_previous_schema {
current_schema_hash
former_schema_hash
former_schema_id
current_schema_id
schema_diff_data
}
}
}
`);
export const FETCH_URL_REGISTRY_SCHEMA_QUERY = gql(`
query fetchURLRegistrySchema ($schemaId: uuid!) {
schema_registry_dumps(
where: {id:{_eq :$schemaId }}
) {
id
entry_hash
schema_hash
change_recorded_at
sibling_schemas {
id
hasura_schema_role
}
schema_tags {
id
name
entry_hash
color
}
}
schema_registry_dumps_v2(
where: {id:{_eq :$schemaId }}
) {
id
entry_hash
schema_hash
change_recorded_at
sibling_schemas {
id
hasura_schema_role
}
schema_tags {
id
name
entry_hash
color
}
}
}
`);

View File

@ -60,25 +60,84 @@ export type GetSchemaListResponseWithError = {
data?: GetSchemaListQueryResponse;
errors?: GraphQLError[];
};
export type GetSchemaListQueryResponse = {
schema_registry_dumps: SchemaRegistryDumpWithSiblingSchema[];
schema_registry_dumps_aggregate: SchemaRegistryDumpsAggregate;
};
export type GetSchemaChangeListResponseWithError = {
data?: GetSchemaChangeListQueryResponse;
errors?: GraphQLError[];
};
export type GetSchemaChangeListQueryResponse = {
schema_change_list: SchemaRegistryDumpWithSiblingSchema[];
current_schema_card: SchemaRegistryDumpWithSiblingSchema[];
schema_registry_dumps_aggregate: SchemaRegistryDumpsAggregate;
};
export type GetSchemaListQueryResponse = {
schema_registry_dumps: SchemaRegistryDumpWithSiblingSchema[];
schema_registry_dumps: SchemaChangeListDumpWithSiblingSchema[];
schema_registry_dumps_aggregate: SchemaRegistryDumpsAggregate;
};
/**
* Query types for dumps_v2 aggregate
* START
*/
export type SchemaRegistryDumpsAggregate = {
aggregate: SchemaRegistryCountAggregate;
};
export type SchemaRegistryCountAggregate = {
count: number;
};
export type GetSchemaRegstiryDumpsV2AggregateResponseWithError = {
data?: GetSchemaRegstiryDumpsV2AggregateResponse;
errors?: GraphQLError[];
};
export type GetSchemaRegstiryDumpsV2AggregateResponse = {
schema_registry_dumps_v2_aggregate: SchemaRegistryDumpsAggregate;
schema_registry_dumps_v2: SchemaRegistryChangeRecordedAt[];
};
export type GetSchemaRegstiryDumpsV1AggregateResponseWithError = {
data?: GetSchemaRegstiryDumpsV1AggregateResponse;
errors?: GraphQLError[];
};
export type GetSchemaRegstiryDumpsV1AggregateResponse = {
schema_registry_dumps_aggregate: SchemaRegistryDumpsAggregate;
};
export type SchemaRegistryChangeRecordedAt = {
change_recorded_at: string;
};
/**
* END
*/
/**
* Query types for dumps_v2
* START
*/
export type GetSchemaRegstiryDumpsV2ResponseWithError = {
data?: GetSchemaRegstiryDumpsV2Response;
errors?: GraphQLError[];
};
export type GetSchemaRegstiryDumpsV2Response = {
schema_registry_dumps_v2: SchemaRegistryDumpWithSiblingSchema[];
};
/**
* END
*/
/**
* Query types for dumps_v1
* START
*/
export type GetSchemaRegstiryDumpsV1ResponseWithError = {
data?: GetSchemaRegstiryDumpsV1Response;
errors?: GraphQLError[];
};
export type GetSchemaRegstiryDumpsV1Response = {
schema_registry_dumps: SchemaRegistryDumpWithSiblingSchema[];
};
/**
* END
*/
export type SchemaRegistryDump = {
id: string;
entry_hash: string;
@ -89,6 +148,19 @@ export type SchemaRegistryDump = {
schema_sdl: string;
schema_tags: SchemaRegistryTag[];
};
export type SchemaChangeListDumpWithSiblingSchema = {
id: string;
entry_hash: string;
schema_hash: string;
change_recorded_at: string;
schema_tags: SchemaRegistryTag[];
sibling_schemas: SchemaChangeListSiblingSchema[];
};
export type SchemaChangeListSiblingSchema = {
id: string;
hasura_schema_role: string;
};
export type SchemaRegistryDumpWithSiblingSchema = SchemaRegistryDump & {
sibling_schemas: SiblingSchema[];
@ -112,9 +184,19 @@ export type GetRegistrySchemaResponseWithError = {
data?: GetRegistrySchemaQueryResponse;
errors?: GraphQLError[];
};
export type GetURLRegistrySchemaResponseWithError = {
data?: GetURLSchemaChangeQueryResponse;
errors?: GraphQLError[];
};
export type GetURLSchemaChangeQueryResponse = {
schema_registry_dumps: SchemaChangeListDumpWithSiblingSchema[];
schema_registry_dumps_v2: SchemaChangeListDumpWithSiblingSchema[];
};
export type GetRegistrySchemaQueryResponse = {
schema_registry_dumps: SiblingSchema[];
schema_registry_dumps_v2: SiblingSchema[];
};
export type GetAlertConfigResponseWithError = {

View File

@ -4,12 +4,11 @@ import {
Schema,
RoleBasedSchema,
SchemaChange,
GetSchemaListResponseWithError,
SchemaRegistryDumpWithSiblingSchema,
SiblingSchema,
GetRegistrySchemaResponseWithError,
Role,
SchemaChangeCard,
SchemaChangeListDumpWithSiblingSchema,
SchemaChangeListSiblingSchema,
} from './types';
import {
getLSItem,
@ -21,6 +20,9 @@ import { useCallback, useLayoutEffect, useRef } from 'react';
import moment from 'moment';
export const CapitalizeFirstLetter = (str: string) => {
if (str === '') {
return '';
}
return str[0].toUpperCase() + str.slice(1);
};
@ -53,67 +55,21 @@ export const setSearchParam = (pageNumber: number) => {
window.history.pushState({}, '', newUrl);
};
export const schemaListTransformFn = (
dumps: NonNullable<
GetSchemaListResponseWithError['data']
>['schema_registry_dumps']
) => {
const schemaList: Schema[] = [];
dumps.forEach((dump: SchemaRegistryDumpWithSiblingSchema) => {
const roleBasedSchemas: RoleBasedSchema[] = [];
dump.sibling_schemas.forEach((childSchema: SiblingSchema) => {
const prevSchemaDiff = childSchema.diff_with_previous_schema;
let changes: SchemaChange[] | undefined = [];
if (prevSchemaDiff?.length > 0) {
changes = [...(prevSchemaDiff[0]?.schema_diff_data || [])];
} else {
changes = undefined;
}
const roleBasedSchema: RoleBasedSchema = {
raw: childSchema.schema_sdl,
role: childSchema.hasura_schema_role,
hash: childSchema.schema_hash,
entry_hash: dump.entry_hash,
id: childSchema.id,
changes: changes,
};
roleBasedSchemas.push(roleBasedSchema);
});
const schema: Schema = {
hash: dump.schema_hash,
created_at: dump.change_recorded_at,
id: dump.id,
entry_hash: dump.entry_hash,
roleBasedSchemas: roleBasedSchemas,
tags: dump.schema_tags,
};
schemaList.push(schema);
});
return schemaList;
};
export const schemaChangeListTransformFn = (
dumps: NonNullable<
GetSchemaListResponseWithError['data']
>['schema_registry_dumps']
dumps: SchemaChangeListDumpWithSiblingSchema[]
) => {
const schemaList: SchemaChangeCard[] = [];
dumps.forEach((dump: SchemaRegistryDumpWithSiblingSchema) => {
dumps.forEach((dump: SchemaChangeListDumpWithSiblingSchema) => {
const schemaRoles: Role[] = [];
dump.sibling_schemas.forEach((childSchema: SiblingSchema) => {
const schemaRole: Role = {
id: childSchema.id,
role: childSchema.hasura_schema_role,
};
schemaRoles.push(schemaRole);
});
dump.sibling_schemas.forEach(
(childSchema: SchemaChangeListSiblingSchema) => {
const schemaRole: Role = {
id: childSchema.id,
role: childSchema.hasura_schema_role,
};
schemaRoles.push(schemaRole);
}
);
const schema: SchemaChangeCard = {
hash: dump.schema_hash,
created_at: dump.change_recorded_at,
@ -131,7 +87,10 @@ export const schemaChangeListTransformFn = (
export const schemaTransformFn = (
fetchedData: NonNullable<GetRegistrySchemaResponseWithError['data']>
) => {
const data = fetchedData.schema_registry_dumps[0] || [];
const data =
fetchedData.schema_registry_dumps[0] ||
fetchedData.schema_registry_dumps_v2[0] ||
[];
const roleBasedSchemas: RoleBasedSchema[] = [];

View File

@ -19,6 +19,7 @@
"format:write:all": "nx format:write --all",
"install-git-hooks": "cd .. && husky install frontend/.husky",
"generate-control-plane-gql-types": "graphql-codegen --config control-plane-graphql-codegen.yml",
"generate-schema-registry-gql-types": "graphql-codegen --config schema-registry-graphql-codegen.yml",
"check-lock-files": "node ./tools/scripts/check-lock-files.js",
"postinstall": "yarn check-lock-files"
},

View File

@ -0,0 +1,9 @@
overwrite: true
schema:
- 'http://schema-registry.lux-dev.hasura.me/v1/graphql':
headers:
'x-hasura-admin-secret': 'randomsecret'
documents: 'libs/console/legacy-ce/src/lib/features/SchemaRegistry/queries.ts'
generates:
libs/console/legacy-ce/src/lib/features/SchemaRegistry/generatedGraphQLTypes.ts:
plugins: ['typescript', 'typescript-operations']