diff --git a/resources/schema.graphql b/resources/schema.graphql index fc3531f0..1dfc3340 100644 --- a/resources/schema.graphql +++ b/resources/schema.graphql @@ -264,6 +264,27 @@ type CompactionMetadataOnly { recursive: Boolean! } +union CompareChainsResult = CompareChainsResultStatus | CompareChainsResultError + +type CompareChainsResultError { + reason: CompareChainsResultReason! +} + +type CompareChainsResultReason { + message: String! +} + +type CompareChainsResultStatus { + message: CompareChainsStatus! +} + +enum CompareChainsStatus { + EQUAL + BEHIND + AHEAD + DIVERGED +} + enum CompressionFormat { GZIP ZIP @@ -635,6 +656,10 @@ type DatasetMetadata { """ currentPushSources: [AddPushSource!]! """ + Sync statuses of push remotes + """ + pushSyncStatuses: DatasetPushStatuses! + """ Current transformation used by the derivative dataset """ currentTransform: SetTransform @@ -705,8 +730,19 @@ type DatasetPermissions { canSchedule: Boolean! } +type DatasetPushStatus { + remote: DatasetRefRemote! + result: CompareChainsResult! +} + +type DatasetPushStatuses { + statuses: [DatasetPushStatus!]! +} + scalar DatasetRef +scalar DatasetRefRemote + type DatasetState { """ Globally unique identity of the dataset diff --git a/src/app/api/dataset.api.ts b/src/app/api/dataset.api.ts index 5aa1059a..6a25f1ed 100644 --- a/src/app/api/dataset.api.ts +++ b/src/app/api/dataset.api.ts @@ -40,6 +40,8 @@ import { UpdateWatermarkMutation, DatasetHeadBlockHashGQL, DatasetHeadBlockHashQuery, + DatasetPushSyncStatusesGQL, + DatasetPushSyncStatusesQuery, } from "src/app/api/kamu.graphql.interface"; import AppValues from "src/app/common/app.values"; import { ApolloQueryResult } from "@apollo/client/core"; @@ -74,6 +76,7 @@ export class DatasetApi { private updateWatermarkGQL = inject(UpdateWatermarkGQL); private datasetHeadBlockHashGQL = inject(DatasetHeadBlockHashGQL); private datasetSystemTimeBlockByHashGQL = inject(DatasetSystemTimeBlockByHashGQL); + private datasetPushSyncStatusesGQL = inject(DatasetPushSyncStatusesGQL); public getDatasetMainData(params: { accountName: string; @@ -439,6 +442,26 @@ export class DatasetApi { ); } + public datasetPushSyncStatuses(datasetId: string): Observable { + return this.datasetPushSyncStatusesGQL + .watch( + { datasetId }, + + { + ...noCacheFetchPolicy, + context: { + skipLoading: true, + }, + }, + ) + .valueChanges.pipe( + first(), + map((result: ApolloQueryResult) => { + return result.data; + }), + ); + } + public static generateDatasetKeyFragment(ownerRef: string | undefined, datasetId: string): StoreObject { return { __typename: "Dataset", diff --git a/src/app/api/gql/dataset-push-sync-statuses.graphql b/src/app/api/gql/dataset-push-sync-statuses.graphql new file mode 100644 index 00000000..cfe751d8 --- /dev/null +++ b/src/app/api/gql/dataset-push-sync-statuses.graphql @@ -0,0 +1,17 @@ +query datasetPushSyncStatuses($datasetId: DatasetID!) { + datasets { + byId(datasetId: $datasetId) { + metadata { + pushSyncStatuses { + statuses { + remote, + result { + ... on CompareChainsResultStatus { message } + ... on CompareChainsResultError { reason { message } } + } + } + } + } + } + } +} diff --git a/src/app/api/kamu.graphql.interface.ts b/src/app/api/kamu.graphql.interface.ts index ba8c70ef..38d1fa6b 100644 --- a/src/app/api/kamu.graphql.interface.ts +++ b/src/app/api/kamu.graphql.interface.ts @@ -23,6 +23,7 @@ export type Scalars = { DatasetID: string; DatasetName: string; DatasetRef: string; + DatasetRefRemote: string; /** * Implement the DateTime scalar * @@ -318,6 +319,30 @@ export type CompactionMetadataOnly = { recursive: Scalars["Boolean"]; }; +export type CompareChainsResult = CompareChainsResultError | CompareChainsResultStatus; + +export type CompareChainsResultError = { + __typename?: "CompareChainsResultError"; + reason: CompareChainsResultReason; +}; + +export type CompareChainsResultReason = { + __typename?: "CompareChainsResultReason"; + message: Scalars["String"]; +}; + +export type CompareChainsResultStatus = { + __typename?: "CompareChainsResultStatus"; + message: CompareChainsStatus; +}; + +export enum CompareChainsStatus { + Ahead = "AHEAD", + Behind = "BEHIND", + Diverged = "DIVERGED", + Equal = "EQUAL", +} + export enum CompressionFormat { Gzip = "GZIP", Zip = "ZIP", @@ -746,6 +771,8 @@ export type DatasetMetadata = { currentVocab?: Maybe; /** Last recorded watermark */ currentWatermark?: Maybe; + /** Sync statuses of push remotes */ + pushSyncStatuses: DatasetPushStatuses; }; export type DatasetMetadataCurrentSchemaArgs = { @@ -797,6 +824,17 @@ export type DatasetPermissions = { canView: Scalars["Boolean"]; }; +export type DatasetPushStatus = { + __typename?: "DatasetPushStatus"; + remote: Scalars["DatasetRefRemote"]; + result: CompareChainsResult; +}; + +export type DatasetPushStatuses = { + __typename?: "DatasetPushStatuses"; + statuses: Array; +}; + export type DatasetState = { __typename?: "DatasetState"; /** Alias to be used in the query */ @@ -2692,6 +2730,36 @@ export type DatasetProtocolsQuery = { }; }; +export type DatasetPushSyncStatusesQueryVariables = Exact<{ + datasetId: Scalars["DatasetID"]; +}>; + +export type DatasetPushSyncStatusesQuery = { + __typename?: "Query"; + datasets: { + __typename?: "Datasets"; + byId?: { + __typename?: "Dataset"; + metadata: { + __typename?: "DatasetMetadata"; + pushSyncStatuses: { + __typename?: "DatasetPushStatuses"; + statuses: Array<{ + __typename?: "DatasetPushStatus"; + remote: string; + result: + | { + __typename?: "CompareChainsResultError"; + reason: { __typename?: "CompareChainsResultReason"; message: string }; + } + | { __typename?: "CompareChainsResultStatus"; message: CompareChainsStatus }; + }>; + }; + }; + } | null; + }; +}; + export type GetDatasetSchemaQueryVariables = Exact<{ datasetId: Scalars["DatasetID"]; }>; @@ -6177,6 +6245,45 @@ export class DatasetProtocolsGQL extends Apollo.Query { + document = DatasetPushSyncStatusesDocument; + + constructor(apollo: Apollo.Apollo) { + super(apollo); + } +} export const GetDatasetSchemaDocument = gql` query getDatasetSchema($datasetId: DatasetID!) { datasets { diff --git a/src/app/components/modal/modal-dialog.component.ts b/src/app/components/modal/modal-dialog.component.ts index a9eb6929..543d4d0e 100755 --- a/src/app/components/modal/modal-dialog.component.ts +++ b/src/app/components/modal/modal-dialog.component.ts @@ -39,6 +39,11 @@ import { DynamicComponent } from "./dynamic.component"; +