mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-04-17 12:00:40 +01:00
117 lines
3.9 KiB
TypeScript
117 lines
3.9 KiB
TypeScript
import { PrimaryButton } from "@fluentui/react";
|
|
import { GlobalSecondaryIndexLabels } from "Common/Constants";
|
|
import { MaterializedView } from "Contracts/DataModels";
|
|
import Explorer from "Explorer/Explorer";
|
|
import { loadMonaco } from "Explorer/LazyMonaco";
|
|
import { AddGlobalSecondaryIndexPanel } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/AddGlobalSecondaryIndexPanel";
|
|
import { useDatabases } from "Explorer/useDatabases";
|
|
import { useSidePanel } from "hooks/useSidePanel";
|
|
import * as monaco from "monaco-editor";
|
|
import React, { useEffect, useRef } from "react";
|
|
import * as ViewModels from "../../../../Contracts/ViewModels";
|
|
import { Keys } from "../../../../Localization/Keys.generated";
|
|
import { t } from "../../../../Localization/t";
|
|
|
|
export interface GlobalSecondaryIndexSourceComponentProps {
|
|
collection: ViewModels.Collection;
|
|
explorer: Explorer;
|
|
}
|
|
|
|
export const GlobalSecondaryIndexSourceComponent: React.FC<GlobalSecondaryIndexSourceComponentProps> = ({
|
|
collection,
|
|
explorer,
|
|
}) => {
|
|
const editorContainerRef = useRef<HTMLDivElement>(null);
|
|
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>(null);
|
|
|
|
const globalSecondaryIndexes: MaterializedView[] = collection?.materializedViews() ?? [];
|
|
|
|
// Helper function to fetch the definition and partition key of targetContainer by traversing through all collections and matching id from MaterializedView[] with collection id.
|
|
const getViewDetails = (viewId: string): { definition: string; partitionKey: string[] } => {
|
|
let definition = "";
|
|
let partitionKey: string[] = [];
|
|
|
|
useDatabases.getState().databases.find((database) => {
|
|
const collection = database.collections().find((collection) => collection.id() === viewId);
|
|
if (collection) {
|
|
const globalSecondaryIndexDefinition = collection.materializedViewDefinition();
|
|
globalSecondaryIndexDefinition && (definition = globalSecondaryIndexDefinition.definition);
|
|
collection.partitionKey?.paths && (partitionKey = collection.partitionKey.paths);
|
|
}
|
|
});
|
|
|
|
return { definition, partitionKey };
|
|
};
|
|
|
|
//JSON value for the editor using the fetched id and definitions.
|
|
const jsonValue = JSON.stringify(
|
|
globalSecondaryIndexes.map((view) => {
|
|
const { definition, partitionKey } = getViewDetails(view.id);
|
|
return {
|
|
name: view.id,
|
|
partitionKey: partitionKey.join(", "),
|
|
definition,
|
|
};
|
|
}),
|
|
null,
|
|
2,
|
|
);
|
|
|
|
// Initialize Monaco editor with the computed JSON value.
|
|
useEffect(() => {
|
|
let disposed = false;
|
|
const initMonaco = async () => {
|
|
const monacoInstance = await loadMonaco();
|
|
if (disposed || !editorContainerRef.current) {
|
|
return;
|
|
}
|
|
|
|
editorRef.current = monacoInstance.editor.create(editorContainerRef.current, {
|
|
value: jsonValue,
|
|
language: "json",
|
|
ariaLabel: t(Keys.controls.settings.globalSecondaryIndex.jsonAriaLabel),
|
|
readOnly: true,
|
|
});
|
|
};
|
|
|
|
initMonaco();
|
|
return () => {
|
|
disposed = true;
|
|
editorRef.current?.dispose();
|
|
};
|
|
}, [jsonValue]);
|
|
|
|
// Update the editor when the jsonValue changes.
|
|
useEffect(() => {
|
|
if (editorRef.current) {
|
|
editorRef.current.setValue(jsonValue);
|
|
}
|
|
}, [jsonValue]);
|
|
|
|
return (
|
|
<div>
|
|
<div
|
|
ref={editorContainerRef}
|
|
style={{
|
|
height: 250,
|
|
border: "1px solid #ccc",
|
|
borderRadius: 4,
|
|
overflow: "hidden",
|
|
}}
|
|
/>
|
|
<PrimaryButton
|
|
text={t(Keys.controls.settings.globalSecondaryIndex.addIndex)}
|
|
styles={{ root: { width: "fit-content", marginTop: 12 } }}
|
|
onClick={() =>
|
|
useSidePanel
|
|
.getState()
|
|
.openSidePanel(
|
|
GlobalSecondaryIndexLabels.NewGlobalSecondaryIndex,
|
|
<AddGlobalSecondaryIndexPanel explorer={explorer} sourceContainer={collection} />,
|
|
)
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|