From 59619a856e1d5149a8cfd8ab5fa3b6377b195897 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 14 Feb 2025 14:55:34 -0500 Subject: [PATCH] fetch MV properties from RP API and capture them in our data models --- src/Common/Constants.ts | 4 ++++ src/Common/dataAccess/readCollections.ts | 8 +++++++- src/Contracts/DataModels.ts | 13 +++++++++++++ src/Contracts/ViewModels.ts | 2 ++ src/Explorer/Sidebar.tsx | 22 ++++++++++++++++++++++ src/Explorer/Tree/Collection.ts | 4 ++++ 6 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index 840849904..cca173cb0 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -530,6 +530,10 @@ export class ariaLabelForLearnMoreLink { public static readonly AzureSynapseLink = "Learn more about Azure Synapse Link."; } +export class MaterializedViewsLabels { + public static readonly NewMaterializedView: string = "New Materialized View"; +} + export const QueryCopilotSampleDatabaseId = "CopilotSampleDB"; export const QueryCopilotSampleContainerId = "SampleContainer"; diff --git a/src/Common/dataAccess/readCollections.ts b/src/Common/dataAccess/readCollections.ts index 4098b3fe8..ec86963b1 100644 --- a/src/Common/dataAccess/readCollections.ts +++ b/src/Common/dataAccess/readCollections.ts @@ -126,5 +126,11 @@ async function readCollectionsWithARM(databaseId: string): Promise collection.properties?.resource as DataModels.Collection); + // TO DO: Remove when we get RP API Spec with materializedViews + return rpResponse?.value?.map((collection: any) => { + const collectionDataModel: DataModels.Collection = collection.properties?.resource as DataModels.Collection; + collectionDataModel.materializedViews = collection.properties?.resource.materializedViews; + collectionDataModel.materializedViewDefinition = collection.properties?.resource.materializedViewDefinition; + return collectionDataModel; + }); } diff --git a/src/Contracts/DataModels.ts b/src/Contracts/DataModels.ts index d2bba68d8..6538dc19a 100644 --- a/src/Contracts/DataModels.ts +++ b/src/Contracts/DataModels.ts @@ -165,6 +165,8 @@ export interface Collection extends Resource { schema?: ISchema; requestSchema?: () => void; computedProperties?: ComputedProperties; + materializedViews?: MaterializedView[]; + materializedViewDefinition?: MaterializedViewDefinition; } export interface CollectionsWithPagination { @@ -224,6 +226,17 @@ export interface ComputedProperty { export type ComputedProperties = ComputedProperty[]; +export interface MaterializedView { + id: string; + _rid: string; +} + +export interface MaterializedViewDefinition { + definition: string; + sourceCollectionId: string; + sourceCollectionRid: string; +} + export interface PartitionKey { paths: string[]; kind: "Hash" | "Range" | "MultiHash"; diff --git a/src/Contracts/ViewModels.ts b/src/Contracts/ViewModels.ts index 83afa9ddb..a66d83b86 100644 --- a/src/Contracts/ViewModels.ts +++ b/src/Contracts/ViewModels.ts @@ -143,6 +143,8 @@ export interface Collection extends CollectionBase { geospatialConfig: ko.Observable; documentIds: ko.ObservableArray; computedProperties: ko.Observable; + materializedViews: ko.Observable; + materializedViewDefinition: ko.Observable; cassandraKeys: CassandraTableKeys; cassandraSchema: CassandraTableKey[]; diff --git a/src/Explorer/Sidebar.tsx b/src/Explorer/Sidebar.tsx index 8b96b0422..e48ec770d 100644 --- a/src/Explorer/Sidebar.tsx +++ b/src/Explorer/Sidebar.tsx @@ -13,9 +13,12 @@ import { shorthands, } from "@fluentui/react-components"; import { Add16Regular, ArrowSync12Regular, ChevronLeft12Regular, ChevronRight12Regular } from "@fluentui/react-icons"; +import { MaterializedViewsLabels } from "Common/Constants"; +import { isMaterializedViewsEnabled } from "Common/DatabaseAccountUtility"; import { Platform, configContext } from "ConfigContext"; import Explorer from "Explorer/Explorer"; import { AddDatabasePanel } from "Explorer/Panes/AddDatabasePanel/AddDatabasePanel"; +import { AddMaterializedViewPanel, AddMaterializedViewPanelProps } from "Explorer/Panes/AddMaterializedViewPanel"; import { Tabs } from "Explorer/Tabs/Tabs"; import { CosmosFluentProvider, cosmosShorthands, tokens } from "Explorer/Theme/ThemeUtil"; import { ResourceTree } from "Explorer/Tree/ResourceTree"; @@ -158,6 +161,25 @@ const GlobalCommands: React.FC = ({ explorer }) => { }); } + if (isMaterializedViewsEnabled()) { + const addMaterializedViewPanelProps: AddMaterializedViewPanelProps = { + explorer, + }; + + actions.push({ + id: "new_materialized_view", + label: MaterializedViewsLabels.NewMaterializedView, + icon: , + onClick: () => + useSidePanel + .getState() + .openSidePanel( + MaterializedViewsLabels.NewMaterializedView, + , + ), + }); + } + return actions; }, [explorer]); diff --git a/src/Explorer/Tree/Collection.ts b/src/Explorer/Tree/Collection.ts index 2e08562e4..9dd723762 100644 --- a/src/Explorer/Tree/Collection.ts +++ b/src/Explorer/Tree/Collection.ts @@ -58,6 +58,8 @@ export default class Collection implements ViewModels.Collection { public uniqueKeyPolicy: DataModels.UniqueKeyPolicy; public usageSizeInKB: ko.Observable; public computedProperties: ko.Observable; + public materializedViews: ko.Observable; + public materializedViewDefinition: ko.Observable; public offer: ko.Observable; public conflictResolutionPolicy: ko.Observable; @@ -124,6 +126,8 @@ export default class Collection implements ViewModels.Collection { this.requestSchema = data.requestSchema; this.geospatialConfig = ko.observable(data.geospatialConfig); this.computedProperties = ko.observable(data.computedProperties); + this.materializedViews = ko.observable(data.materializedViews); + this.materializedViewDefinition = ko.observable(data.materializedViewDefinition); this.partitionKeyPropertyHeaders = this.partitionKey?.paths; this.partitionKeyProperties = this.partitionKeyPropertyHeaders?.map((partitionKeyPropertyHeader, i) => {