Migrate Stored Procedure tab to react (#894)
Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
parent
f255387ccd
commit
b392bed1b0
|
@ -146,7 +146,7 @@ src/Explorer/Tabs/MongoDocumentsTab.ts
|
|||
# src/Explorer/Tabs/MongoShellTab.ts
|
||||
src/Explorer/Tabs/NotebookV2Tab.ts
|
||||
src/Explorer/Tabs/ScriptTabBase.ts
|
||||
src/Explorer/Tabs/StoredProcedureTab.ts
|
||||
# src/Explorer/Tabs/StoredProcedureTab.ts
|
||||
src/Explorer/Tabs/TabComponents.ts
|
||||
src/Explorer/Tabs/TabsBase.ts
|
||||
src/Explorer/Tabs/TriggerTab.ts
|
||||
|
|
|
@ -724,45 +724,24 @@ execute-sproc-params-pane {
|
|||
|
||||
.results-container,
|
||||
.errors-container {
|
||||
padding: @MediumSpace 0px 0px @MediumSpace;
|
||||
height: 100%;
|
||||
.flex-display();
|
||||
.flex-direction();
|
||||
overflow: hidden;
|
||||
|
||||
.toggles {
|
||||
height: @ToggleHeight;
|
||||
width: @ToggleWidth;
|
||||
margin-left: @MediumSpace;
|
||||
|
||||
&:focus {
|
||||
.focus();
|
||||
}
|
||||
|
||||
.tab {
|
||||
margin-right: @MediumSpace;
|
||||
}
|
||||
|
||||
.toggleSwitch {
|
||||
.toggleSwitch();
|
||||
}
|
||||
|
||||
.selectedToggle {
|
||||
.selectedToggle();
|
||||
}
|
||||
|
||||
.unselectedToggle {
|
||||
.unselectedToggle();
|
||||
}
|
||||
}
|
||||
|
||||
.enterInputParameters {
|
||||
padding: @LargeSpace @MediumSpace;
|
||||
}
|
||||
|
||||
div[role="tabpanel"] {
|
||||
height: 100%;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.errors-container {
|
||||
padding-left: (2 * @MediumSpace);
|
||||
padding: @MediumSpace 0px 0px @MediumSpace;
|
||||
.errors-header {
|
||||
font-weight: 700;
|
||||
font-size: @DefaultFontSize;
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
<div class="tab-pane flexContainer stored-procedure-tab" data-bind="attr:{ id: tabId }" role="tabpanel">
|
||||
<!-- Stored Procedure Tab Form - Start -->
|
||||
<div class="storedTabForm flexContainer">
|
||||
<div class="formTitleFirst">Stored Procedure Id</div>
|
||||
<span class="formTitleTextbox">
|
||||
<input
|
||||
class="formTree"
|
||||
type="text"
|
||||
required
|
||||
pattern="[^/?#\\]*[^/?# \\]"
|
||||
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
||||
aria-label="Stored procedure id"
|
||||
placeholder="Enter the new stored procedure id"
|
||||
size="40"
|
||||
data-bind="
|
||||
textInput: id"
|
||||
/>
|
||||
</span>
|
||||
<div class="spUdfTriggerHeader">Stored Procedure Body</div>
|
||||
<editor
|
||||
params="{
|
||||
content: originalSprocBody,
|
||||
contentType: 'javascript',
|
||||
isReadOnly: false,
|
||||
ariaLabel: 'Stored procedure body',
|
||||
lineNumbers: 'on',
|
||||
updatedContent: editorContent,
|
||||
theme: _theme
|
||||
}"
|
||||
data-bind="attr: { id: editorId }"
|
||||
></editor>
|
||||
<!-- Results & Errors Content - Start-->
|
||||
<div class="results-container" data-bind="visible: hasResults">
|
||||
<div
|
||||
class="toggles"
|
||||
id="execute-storedproc-toggles"
|
||||
aria-label="Successful execution of stored procedure"
|
||||
data-bind="event: { keydown: onToggleKeyDown }"
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="tab">
|
||||
<input type="radio" class="radio" value="result" />
|
||||
<span
|
||||
class="toggleSwitch"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
data-bind="click: toggleResult, css:{ selectedToggle: isResultToggled(), unselectedToggle: !isResultToggled() }"
|
||||
aria-label="Result"
|
||||
>Result</span
|
||||
>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<input type="radio" class="radio" value="logs" />
|
||||
<span
|
||||
class="toggleSwitch"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
data-bind="click: toggleLogs, css:{ selectedToggle: isLogsToggled(), unselectedToggle: !isLogsToggled() }"
|
||||
aria-label="console.log"
|
||||
>console.log</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<json-editor
|
||||
params="{ content: resultsData, isReadOnly: true, ariaLabel: 'Execute stored procedure result' }"
|
||||
data-bind="attr: { id: executeResultsEditorId }, visible: hasResults() && isResultToggled()"
|
||||
>
|
||||
</json-editor>
|
||||
<json-editor
|
||||
params="{ content: logsData, isReadOnly: true, ariaLabel: 'Execute stored procedure logs' }"
|
||||
data-bind="attr: { id: executeLogsEditorId }, visible: hasResults() && isLogsToggled()"
|
||||
></json-editor>
|
||||
</div>
|
||||
<div class="errors-container" data-bind="visible: hasErrors">
|
||||
<div class="errors-header">Errors:</div>
|
||||
<div class="errorContent">
|
||||
<span class="errorMessage" data-bind="text: error"></span>
|
||||
<span class="errorDetailsLink">
|
||||
<a
|
||||
data-bind="click: $data.onErrorDetailsClick, event: { keypress: $data.onErrorDetailsKeyPress }"
|
||||
aria-label="Error details link"
|
||||
>More details</a
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Results & Errors Content - End-->
|
||||
</div>
|
||||
</div>
|
|
@ -1,287 +0,0 @@
|
|||
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
|
||||
import * as ko from "knockout";
|
||||
import Q from "q";
|
||||
import * as _ from "underscore";
|
||||
import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { createStoredProcedure } from "../../Common/dataAccess/createStoredProcedure";
|
||||
import { updateStoredProcedure } from "../../Common/dataAccess/updateStoredProcedure";
|
||||
import editable from "../../Common/EditableUtility";
|
||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { useNotificationConsole } from "../../hooks/useNotificationConsole";
|
||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import StoredProcedure from "../Tree/StoredProcedure";
|
||||
import ScriptTabBase from "./ScriptTabBase";
|
||||
import template from "./StoredProcedureTab.html";
|
||||
|
||||
enum ToggleState {
|
||||
Result = "result",
|
||||
Logs = "logs",
|
||||
}
|
||||
|
||||
export default class StoredProcedureTab extends ScriptTabBase {
|
||||
public readonly html = template;
|
||||
public collection: ViewModels.Collection;
|
||||
public node: StoredProcedure;
|
||||
public executeResultsEditorId: string;
|
||||
public executeLogsEditorId: string;
|
||||
public toggleState: ko.Observable<ToggleState>;
|
||||
public originalSprocBody: ViewModels.Editable<string>;
|
||||
public resultsData: ko.Observable<string>;
|
||||
public logsData: ko.Observable<string>;
|
||||
public error: ko.Observable<string>;
|
||||
public hasResults: ko.Observable<boolean>;
|
||||
public hasErrors: ko.Observable<boolean>;
|
||||
|
||||
constructor(options: ViewModels.ScriptTabOption) {
|
||||
super(options);
|
||||
super.onActivate.bind(this);
|
||||
|
||||
this.executeResultsEditorId = `executestoredprocedureresults${this.tabId}`;
|
||||
this.executeLogsEditorId = `executestoredprocedurelogs${this.tabId}`;
|
||||
this.toggleState = ko.observable<ToggleState>(ToggleState.Result);
|
||||
this.originalSprocBody = editable.observable<string>(this.editorContent());
|
||||
this.resultsData = ko.observable<string>();
|
||||
this.logsData = ko.observable<string>();
|
||||
this.error = ko.observable<string>();
|
||||
this.hasResults = ko.observable<boolean>(false);
|
||||
this.hasErrors = ko.observable<boolean>(false);
|
||||
this.error.subscribe((error: string) => {
|
||||
this.hasErrors(error != null);
|
||||
this.hasResults(error == null);
|
||||
});
|
||||
|
||||
this.ariaLabel("Stored Procedure Body");
|
||||
this.buildCommandBarOptions();
|
||||
}
|
||||
|
||||
public onSaveClick = (): Promise<StoredProcedureDefinition & Resource> => {
|
||||
return this._createStoredProcedure({
|
||||
id: this.id(),
|
||||
body: this.editorContent(),
|
||||
});
|
||||
};
|
||||
|
||||
public onDiscard = (): Q.Promise<any> => {
|
||||
this.setBaselines();
|
||||
const original = this.editorContent.getEditableOriginalValue();
|
||||
this.originalSprocBody(original);
|
||||
this.originalSprocBody.valueHasMutated(); // trigger a re-render of the editor
|
||||
|
||||
return Q();
|
||||
};
|
||||
|
||||
public onUpdateClick = (): Promise<any> => {
|
||||
const data = this._getResource();
|
||||
|
||||
this.isExecutionError(false);
|
||||
this.isExecuting(true);
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.UpdateStoredProcedure, {
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.tabTitle(),
|
||||
});
|
||||
return updateStoredProcedure(this.collection.databaseId, this.collection.id(), data)
|
||||
.then(
|
||||
(updatedResource) => {
|
||||
this.resource(updatedResource);
|
||||
this.tabTitle(updatedResource.id);
|
||||
this.node.id(updatedResource.id);
|
||||
this.node.body(updatedResource.body as string);
|
||||
this.setBaselines();
|
||||
|
||||
const editorModel = this.editor() && this.editor().getModel();
|
||||
editorModel && editorModel.setValue(updatedResource.body as string);
|
||||
this.editorContent.setBaseline(updatedResource.body as string);
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.UpdateStoredProcedure,
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.tabTitle(),
|
||||
},
|
||||
startKey
|
||||
);
|
||||
},
|
||||
(error: any) => {
|
||||
this.isExecutionError(true);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.UpdateStoredProcedure,
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.tabTitle(),
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
);
|
||||
}
|
||||
)
|
||||
.finally(() => this.isExecuting(false));
|
||||
};
|
||||
|
||||
public onExecuteSprocsResult(result: any, logsData: any): void {
|
||||
const resultData: string = this.renderObjectForEditor(_.omit(result, "scriptLogs").result, null, 4);
|
||||
const scriptLogs: string = (result.scriptLogs && decodeURIComponent(result.scriptLogs)) || "";
|
||||
const logs: string = this.renderObjectForEditor(scriptLogs, null, 4);
|
||||
this.error(null);
|
||||
this.resultsData(resultData);
|
||||
this.logsData(logs);
|
||||
}
|
||||
|
||||
public onExecuteSprocsError(error: string): void {
|
||||
this.isExecutionError(true);
|
||||
console.error(error);
|
||||
this.error(error);
|
||||
}
|
||||
|
||||
public onErrorDetailsClick = (src: any, event: MouseEvent): boolean => {
|
||||
useNotificationConsole.getState().expandConsole();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
public onErrorDetailsKeyPress = (src: any, event: KeyboardEvent): boolean => {
|
||||
if (event.keyCode === Constants.KeyCodes.Space || event.keyCode === Constants.KeyCodes.Enter) {
|
||||
this.onErrorDetailsClick(src, null);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
public toggleResult(): void {
|
||||
this.toggleState(ToggleState.Result);
|
||||
this.resultsData.valueHasMutated(); // needed to refresh the json-editor component
|
||||
}
|
||||
|
||||
public toggleLogs(): void {
|
||||
this.toggleState(ToggleState.Logs);
|
||||
this.logsData.valueHasMutated(); // needed to refresh the json-editor component
|
||||
}
|
||||
|
||||
public onToggleKeyDown = (source: any, event: KeyboardEvent): boolean => {
|
||||
if (event.keyCode === Constants.KeyCodes.LeftArrow) {
|
||||
this.toggleResult();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
} else if (event.keyCode === Constants.KeyCodes.RightArrow) {
|
||||
this.toggleLogs();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
public isResultToggled(): boolean {
|
||||
return this.toggleState() === ToggleState.Result;
|
||||
}
|
||||
|
||||
public isLogsToggled(): boolean {
|
||||
return this.toggleState() === ToggleState.Logs;
|
||||
}
|
||||
|
||||
protected updateSelectedNode(): void {
|
||||
if (this.collection == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const database: ViewModels.Database = this.collection.getDatabase();
|
||||
if (!database.isDatabaseExpanded()) {
|
||||
this.collection.container.selectedNode(database);
|
||||
} else if (!this.collection.isCollectionExpanded() || !this.collection.isStoredProceduresExpanded()) {
|
||||
this.collection.container.selectedNode(this.collection);
|
||||
} else {
|
||||
this.collection.container.selectedNode(this.node);
|
||||
}
|
||||
}
|
||||
|
||||
protected buildCommandBarOptions(): void {
|
||||
ko.computed(() => ko.toJSON([this.isNew, this.formIsDirty])).subscribe(() => this.updateNavbarWithTabsButtons());
|
||||
super.buildCommandBarOptions();
|
||||
}
|
||||
|
||||
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||
const label = "Execute";
|
||||
return super.getTabsButtons().concat({
|
||||
iconSrc: ExecuteQueryIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
this.collection && this.collection.container.openExecuteSprocParamsPanel(this.node);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: this.isNew() || this.formIsDirty(),
|
||||
});
|
||||
}
|
||||
|
||||
private _getResource() {
|
||||
return {
|
||||
id: this.id(),
|
||||
body: this.editorContent(),
|
||||
};
|
||||
}
|
||||
|
||||
private _createStoredProcedure(resource: StoredProcedureDefinition): Promise<StoredProcedureDefinition & Resource> {
|
||||
this.isExecutionError(false);
|
||||
this.isExecuting(true);
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateStoredProcedure, {
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.tabTitle(),
|
||||
});
|
||||
|
||||
return createStoredProcedure(this.collection.databaseId, this.collection.id(), resource)
|
||||
.then(
|
||||
(createdResource) => {
|
||||
this.tabTitle(createdResource.id);
|
||||
this.isNew(false);
|
||||
this.resource(createdResource);
|
||||
this.hashLocation(
|
||||
`${Constants.HashRoutePrefixes.collectionsWithIds(
|
||||
this.collection.databaseId,
|
||||
this.collection.id()
|
||||
)}/sprocs/${createdResource.id}`
|
||||
);
|
||||
this.setBaselines();
|
||||
|
||||
const editorModel = this.editor() && this.editor().getModel();
|
||||
editorModel && editorModel.setValue(createdResource.body as string);
|
||||
this.editorContent.setBaseline(createdResource.body as string);
|
||||
this.node = this.collection.createStoredProcedureNode(createdResource);
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.CreateStoredProcedure,
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.tabTitle(),
|
||||
},
|
||||
startKey
|
||||
);
|
||||
this.editorState(ViewModels.ScriptEditorState.exisitingNoEdits);
|
||||
return createdResource;
|
||||
},
|
||||
(createError) => {
|
||||
this.isExecutionError(true);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.CreateStoredProcedure,
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.tabTitle(),
|
||||
error: getErrorMessage(createError),
|
||||
errorStack: getErrorStack(createError),
|
||||
},
|
||||
startKey
|
||||
);
|
||||
return Promise.reject(createError);
|
||||
}
|
||||
)
|
||||
.finally(() => this.isExecuting(false));
|
||||
}
|
||||
|
||||
public onDelete(): Q.Promise<any> {
|
||||
// TODO
|
||||
return Q();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
import React from "react";
|
||||
import { ExecuteSprocResult } from "../../../Common/dataAccess/executeStoredProcedure";
|
||||
import * as DataModels from "../../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import Explorer from "../../Explorer";
|
||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||
import ScriptTabBase from "../ScriptTabBase";
|
||||
import StoredProcedureTabComponent, {
|
||||
IStoredProcTabComponentProps,
|
||||
IStorProcTabComponentAccessor,
|
||||
} from "./StoredProcedureTabComponent";
|
||||
|
||||
export interface IStoredProcTabProps {
|
||||
container: Explorer;
|
||||
collection: ViewModels.Collection;
|
||||
}
|
||||
|
||||
export class NewStoredProcedureTab extends ScriptTabBase {
|
||||
public queryText: string;
|
||||
public currentQuery: string;
|
||||
public partitionKey: DataModels.PartitionKey;
|
||||
public iStoredProcTabComponentProps: IStoredProcTabComponentProps;
|
||||
public iStoreProcAccessor: IStorProcTabComponentAccessor;
|
||||
public node: StoredProcedure;
|
||||
public onSaveClick: () => void;
|
||||
public onUpdateClick: () => Promise<void>;
|
||||
|
||||
constructor(options: ViewModels.ScriptTabOption, private props: IStoredProcTabProps) {
|
||||
super(options);
|
||||
this.partitionKey = options.partitionKey;
|
||||
|
||||
this.iStoredProcTabComponentProps = {
|
||||
resource: options.resource,
|
||||
isNew: options.isNew,
|
||||
tabKind: options.tabKind,
|
||||
title: options.title,
|
||||
tabPath: options.tabPath,
|
||||
collectionBase: options.collection,
|
||||
node: options.node,
|
||||
hasLocation: options.hashLocation,
|
||||
scriptTabBaseInstance: this,
|
||||
collection: props.collection,
|
||||
iStorProcTabComponentAccessor: (instance: IStorProcTabComponentAccessor) => {
|
||||
this.iStoreProcAccessor = instance;
|
||||
},
|
||||
container: props.container,
|
||||
};
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return <StoredProcedureTabComponent {...this.iStoredProcTabComponentProps} />;
|
||||
}
|
||||
|
||||
public onTabClick(): void {
|
||||
this.manager?.activateTab(this);
|
||||
this.iStoreProcAccessor.onTabClickEvent();
|
||||
}
|
||||
|
||||
public onCloseTabButtonClick(): void {
|
||||
this.manager?.closeTab(this);
|
||||
}
|
||||
|
||||
public onExecuteSprocsResult(result: ExecuteSprocResult): void {
|
||||
this.iStoreProcAccessor.onExecuteSprocsResultEvent(result);
|
||||
}
|
||||
|
||||
public onExecuteSprocsError(error: string): void {
|
||||
this.iStoreProcAccessor.onExecuteSprocsErrorEvent(error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,604 @@
|
|||
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
|
||||
import { Pivot, PivotItem } from "@fluentui/react";
|
||||
import React from "react";
|
||||
import DiscardIcon from "../../../../images/discard.svg";
|
||||
import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg";
|
||||
import SaveIcon from "../../../../images/save-cosmos.svg";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { NormalizedEventKey } from "../../../Common/Constants";
|
||||
import { createStoredProcedure } from "../../../Common/dataAccess/createStoredProcedure";
|
||||
import { ExecuteSprocResult } from "../../../Common/dataAccess/executeStoredProcedure";
|
||||
import { updateStoredProcedure } from "../../../Common/dataAccess/updateStoredProcedure";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { useNotificationConsole } from "../../../hooks/useNotificationConsole";
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "../../Controls/Editor/EditorReact";
|
||||
import Explorer from "../../Explorer";
|
||||
import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||
import ScriptTabBase from "../ScriptTabBase";
|
||||
|
||||
export interface IStorProcTabComponentAccessor {
|
||||
onExecuteSprocsResultEvent: (result: ExecuteSprocResult) => void;
|
||||
onExecuteSprocsErrorEvent: (error: string) => void;
|
||||
onTabClickEvent: () => void;
|
||||
}
|
||||
|
||||
export interface Button {
|
||||
visible: boolean;
|
||||
enabled: boolean;
|
||||
isSelected?: boolean;
|
||||
}
|
||||
|
||||
interface IStoredProcTabComponentStates {
|
||||
hasResults: boolean;
|
||||
hasErrors: boolean;
|
||||
error: string;
|
||||
resultData: string;
|
||||
logsData: string;
|
||||
originalSprocBody: string;
|
||||
initialEditorContent: string;
|
||||
sProcEditorContent: string;
|
||||
id: string;
|
||||
executeButton: Button;
|
||||
saveButton: Button;
|
||||
updateButton: Button;
|
||||
discardButton: Button;
|
||||
}
|
||||
|
||||
export interface IStoredProcTabComponentProps {
|
||||
resource: StoredProcedureDefinition;
|
||||
isNew: boolean;
|
||||
tabKind: ViewModels.CollectionTabKind;
|
||||
title: string;
|
||||
tabPath: string;
|
||||
collectionBase: ViewModels.CollectionBase;
|
||||
//eslint-disable-next-line
|
||||
node?: any;
|
||||
hasLocation: string;
|
||||
scriptTabBaseInstance: ScriptTabBase;
|
||||
collection: ViewModels.Collection;
|
||||
iStorProcTabComponentAccessor: (instance: IStorProcTabComponentAccessor) => void;
|
||||
container: Explorer;
|
||||
}
|
||||
|
||||
export default class StoredProcedureTabComponent extends React.Component<
|
||||
IStoredProcTabComponentProps,
|
||||
IStoredProcTabComponentStates
|
||||
> {
|
||||
public node: StoredProcedure;
|
||||
public executeResultsEditorId: string;
|
||||
public executeLogsEditorId: string;
|
||||
public collection: ViewModels.Collection;
|
||||
|
||||
constructor(
|
||||
public storedProcTabCompProps: IStoredProcTabComponentProps,
|
||||
private storedProcTabCompStates: IStoredProcTabComponentStates
|
||||
) {
|
||||
super(storedProcTabCompProps);
|
||||
this.state = {
|
||||
error: "",
|
||||
hasErrors: false,
|
||||
hasResults: false,
|
||||
resultData: "",
|
||||
logsData: "",
|
||||
originalSprocBody: this.props.resource.body.toString(),
|
||||
initialEditorContent: this.props.resource.body.toString(),
|
||||
sProcEditorContent: this.props.resource.body.toString(),
|
||||
id: this.props.resource.id,
|
||||
executeButton: {
|
||||
enabled: !this.props.scriptTabBaseInstance.isNew(),
|
||||
visible: true,
|
||||
},
|
||||
saveButton: {
|
||||
enabled: (() => {
|
||||
if (!this.props.scriptTabBaseInstance.formIsValid()) {
|
||||
return false;
|
||||
}
|
||||
if (!this.props.scriptTabBaseInstance.formIsDirty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})(),
|
||||
visible: this.props.scriptTabBaseInstance.isNew(),
|
||||
},
|
||||
updateButton: {
|
||||
enabled: (() => {
|
||||
if (!this.props.scriptTabBaseInstance.formIsValid()) {
|
||||
return false;
|
||||
}
|
||||
if (!this.props.scriptTabBaseInstance.formIsDirty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})(),
|
||||
visible: !this.props.scriptTabBaseInstance.isNew(),
|
||||
},
|
||||
discardButton: {
|
||||
enabled: (() => {
|
||||
if (!this.props.scriptTabBaseInstance.formIsValid()) {
|
||||
return false;
|
||||
}
|
||||
if (!this.props.scriptTabBaseInstance.formIsDirty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})(),
|
||||
visible: true,
|
||||
},
|
||||
};
|
||||
|
||||
this.collection = this.props.collection;
|
||||
this.executeResultsEditorId = `executestoredprocedureresults${this.props.scriptTabBaseInstance.tabId}`;
|
||||
this.executeLogsEditorId = `executestoredprocedurelogs${this.props.scriptTabBaseInstance.tabId}`;
|
||||
this.props.scriptTabBaseInstance.ariaLabel("Stored Procedure Body");
|
||||
|
||||
this.props.iStorProcTabComponentAccessor({
|
||||
onExecuteSprocsResultEvent: this.onExecuteSprocsResult.bind(this),
|
||||
onExecuteSprocsErrorEvent: this.onExecuteSprocsError.bind(this),
|
||||
onTabClickEvent: this.onTabClick.bind(this),
|
||||
});
|
||||
|
||||
this.node = this.props.node;
|
||||
|
||||
this.buildCommandBarOptions();
|
||||
}
|
||||
|
||||
public onTabClick(): void {
|
||||
if (this.props.container.tabsManager.openedTabs().length > 0) {
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}
|
||||
}
|
||||
|
||||
public onSaveClick = (): Promise<StoredProcedureDefinition & Resource> => {
|
||||
return this._createStoredProcedure({
|
||||
id: this.state.id,
|
||||
body: this.state.sProcEditorContent,
|
||||
});
|
||||
};
|
||||
|
||||
public onDiscard = (): Promise<unknown> => {
|
||||
const onDiscardPromise = new Promise(() => {
|
||||
this.props.scriptTabBaseInstance.setBaselines();
|
||||
const original = this.props.scriptTabBaseInstance.editorContent.getEditableOriginalValue();
|
||||
if (this.state.updateButton.visible) {
|
||||
this.setState({
|
||||
updateButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
sProcEditorContent: original,
|
||||
discardButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
executeButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
saveButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
sProcEditorContent: original,
|
||||
discardButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
executeButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
id: "",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}, 100);
|
||||
|
||||
return onDiscardPromise;
|
||||
};
|
||||
|
||||
public onUpdateClick = (): Promise<void> => {
|
||||
const data = this._getResource();
|
||||
|
||||
this.props.scriptTabBaseInstance.isExecutionError(false);
|
||||
this.props.scriptTabBaseInstance.isExecuting(true);
|
||||
|
||||
return updateStoredProcedure(
|
||||
this.props.scriptTabBaseInstance.collection.databaseId,
|
||||
this.props.scriptTabBaseInstance.collection.id(),
|
||||
data
|
||||
)
|
||||
.then(
|
||||
(updatedResource) => {
|
||||
this.props.scriptTabBaseInstance.resource(updatedResource);
|
||||
this.props.scriptTabBaseInstance.tabTitle(updatedResource.id);
|
||||
this.node.id(updatedResource.id);
|
||||
this.node.body(updatedResource.body as string);
|
||||
this.props.scriptTabBaseInstance.setBaselines();
|
||||
|
||||
const editorModel =
|
||||
this.props.scriptTabBaseInstance.editor() && this.props.scriptTabBaseInstance.editor().getModel();
|
||||
editorModel && editorModel.setValue(updatedResource.body as string);
|
||||
this.props.scriptTabBaseInstance.editorContent.setBaseline(updatedResource.body as string);
|
||||
this.setState({
|
||||
discardButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
updateButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
executeButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
});
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
},
|
||||
() => {
|
||||
this.props.scriptTabBaseInstance.isExecutionError(true);
|
||||
}
|
||||
)
|
||||
.finally(() => this.props.scriptTabBaseInstance.isExecuting(false));
|
||||
};
|
||||
|
||||
public onExecuteSprocsResult(result: ExecuteSprocResult): void {
|
||||
const resultData: string = this.props.scriptTabBaseInstance.renderObjectForEditor(result.result, undefined, 4);
|
||||
const scriptLogs: string = (result.scriptLogs && decodeURIComponent(result.scriptLogs)) || "";
|
||||
const logs: string = this.props.scriptTabBaseInstance.renderObjectForEditor(scriptLogs, undefined, 4);
|
||||
|
||||
this.setState({
|
||||
hasResults: false,
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
error: undefined,
|
||||
resultData: resultData,
|
||||
logsData: logs,
|
||||
hasResults: resultData ? true : false,
|
||||
hasErrors: false,
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public onExecuteSprocsError(error: string): void {
|
||||
this.props.scriptTabBaseInstance.isExecutionError(true);
|
||||
console.error(error);
|
||||
this.setState({
|
||||
error: error,
|
||||
hasErrors: true,
|
||||
hasResults: false,
|
||||
});
|
||||
}
|
||||
|
||||
public onErrorDetailsClick = (): boolean => {
|
||||
useNotificationConsole.getState().expandConsole();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
public onErrorDetailsKeyPress = (event: React.KeyboardEvent<HTMLAnchorElement>): boolean => {
|
||||
if (event.key === NormalizedEventKey.Space || event.key === NormalizedEventKey.Enter) {
|
||||
this.onErrorDetailsClick();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
protected updateSelectedNode(): void {
|
||||
if (this.props.collectionBase === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const database: ViewModels.Database = this.props.collectionBase.getDatabase();
|
||||
if (!database.isDatabaseExpanded()) {
|
||||
this.props.collectionBase.container.selectedNode(database);
|
||||
} else if (!this.props.collectionBase.isCollectionExpanded() || !this.collection.isStoredProceduresExpanded()) {
|
||||
this.props.collectionBase.container.selectedNode(this.props.collectionBase);
|
||||
} else {
|
||||
this.props.collectionBase.container.selectedNode(this.node);
|
||||
}
|
||||
}
|
||||
|
||||
protected buildCommandBarOptions(): void {
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}
|
||||
|
||||
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
const label = "Save";
|
||||
if (this.state.saveButton.visible) {
|
||||
buttons.push({
|
||||
iconSrc: SaveIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: this.onSaveClick,
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: !this.state.saveButton.enabled,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.updateButton.visible) {
|
||||
const label = "Update";
|
||||
buttons.push({
|
||||
iconSrc: SaveIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: this.onUpdateClick,
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: !this.state.updateButton.enabled,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.discardButton.visible) {
|
||||
const label = "Discard";
|
||||
buttons.push({
|
||||
iconSrc: DiscardIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: this.onDiscard,
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: !this.state.discardButton.enabled,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.executeButton.visible) {
|
||||
const label = "Execute";
|
||||
buttons.push({
|
||||
iconSrc: ExecuteQueryIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
this.collection.container.openExecuteSprocParamsPanel(this.node);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: !this.state.executeButton.enabled,
|
||||
});
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
private _getResource() {
|
||||
return {
|
||||
id: this.state.id,
|
||||
body: this.state.sProcEditorContent,
|
||||
};
|
||||
}
|
||||
|
||||
private _createStoredProcedure(resource: StoredProcedureDefinition): Promise<StoredProcedureDefinition & Resource> {
|
||||
this.props.scriptTabBaseInstance.isExecutionError(false);
|
||||
this.props.scriptTabBaseInstance.isExecuting(true);
|
||||
|
||||
return createStoredProcedure(this.props.collectionBase.databaseId, this.props.collectionBase.id(), resource)
|
||||
.then(
|
||||
(createdResource) => {
|
||||
this.props.scriptTabBaseInstance.tabTitle(createdResource.id);
|
||||
this.props.scriptTabBaseInstance.isNew(false);
|
||||
this.props.scriptTabBaseInstance.resource(createdResource);
|
||||
this.props.scriptTabBaseInstance.hashLocation(
|
||||
`${Constants.HashRoutePrefixes.collectionsWithIds(
|
||||
this.props.collectionBase.databaseId,
|
||||
this.props.collectionBase.id()
|
||||
)}/sprocs/${createdResource.id}`
|
||||
);
|
||||
this.props.scriptTabBaseInstance.setBaselines();
|
||||
|
||||
const editorModel =
|
||||
this.props.scriptTabBaseInstance.editor() && this.props.scriptTabBaseInstance.editor().getModel();
|
||||
editorModel && editorModel.setValue(createdResource.body as string);
|
||||
this.props.scriptTabBaseInstance.editorContent.setBaseline(createdResource.body as string);
|
||||
this.node = this.collection.createStoredProcedureNode(createdResource);
|
||||
this.props.container.tabsManager.openedTabs()[
|
||||
this.props.container.tabsManager.openedTabs().length - 1
|
||||
].node = this.node;
|
||||
|
||||
this.props.scriptTabBaseInstance.editorState(ViewModels.ScriptEditorState.exisitingNoEdits);
|
||||
|
||||
this.setState({
|
||||
executeButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
executeButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
updateButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
saveButton: {
|
||||
enabled: false,
|
||||
visible: false,
|
||||
},
|
||||
discardButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
sProcEditorContent: this.state.sProcEditorContent,
|
||||
});
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}, 100);
|
||||
|
||||
return createdResource;
|
||||
},
|
||||
(createError) => {
|
||||
this.props.scriptTabBaseInstance.isExecutionError(true);
|
||||
|
||||
return Promise.reject(createError);
|
||||
}
|
||||
)
|
||||
.finally(() => this.props.scriptTabBaseInstance.isExecuting(false));
|
||||
}
|
||||
|
||||
public onDelete(): Promise<unknown> {
|
||||
const isDeleted = false;
|
||||
const onDeletePromise = new Promise((resolve) => {
|
||||
resolve(isDeleted);
|
||||
});
|
||||
return onDeletePromise;
|
||||
}
|
||||
|
||||
public handleIdOnChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
if (this.state.saveButton.visible) {
|
||||
this.setState({
|
||||
id: event.target.value,
|
||||
saveButton: {
|
||||
enabled: true,
|
||||
visible: this.props.scriptTabBaseInstance.isNew(),
|
||||
},
|
||||
discardButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
public onChangeContent(newConent: string): void {
|
||||
if (this.state.updateButton.visible) {
|
||||
this.setState({
|
||||
updateButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
discardButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
executeButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
sProcEditorContent: newConent,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
saveButton: {
|
||||
enabled: false,
|
||||
visible: this.props.scriptTabBaseInstance.isNew(),
|
||||
},
|
||||
executeButton: {
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
discardButton: {
|
||||
enabled: true,
|
||||
visible: true,
|
||||
},
|
||||
sProcEditorContent: newConent,
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}, 100);
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<div className="tab-pane flexContainer stored-procedure-tab" role="tabpanel">
|
||||
<div className="storedTabForm flexContainer">
|
||||
<div className="formTitleFirst">Stored Procedure Id</div>
|
||||
<span className="formTitleTextbox">
|
||||
<input
|
||||
className="formTree"
|
||||
type="text"
|
||||
required
|
||||
pattern="[^/?#\\]*[^/?# \\]"
|
||||
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
||||
aria-label="Stored procedure id"
|
||||
placeholder="Enter the new stored procedure id"
|
||||
size={40}
|
||||
value={this.state.id}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => this.handleIdOnChange(event)}
|
||||
/>
|
||||
</span>
|
||||
<div className="spUdfTriggerHeader">Stored Procedure Body</div>
|
||||
<EditorReact
|
||||
language={"javascript"}
|
||||
content={this.state.sProcEditorContent}
|
||||
isReadOnly={false}
|
||||
ariaLabel={"Stored procedure body"}
|
||||
lineNumbers={"on"}
|
||||
theme={"_theme"}
|
||||
onContentChanged={(newContent: string) => this.onChangeContent(newContent)}
|
||||
/>
|
||||
{this.state.hasResults && (
|
||||
<div className="results-container">
|
||||
<Pivot aria-label="Successful execution of stored procedure" style={{ height: "100%" }}>
|
||||
<PivotItem
|
||||
headerText="Result"
|
||||
headerButtonProps={{
|
||||
"data-order": 1,
|
||||
"data-title": "Result",
|
||||
}}
|
||||
style={{ height: "100%" }}
|
||||
>
|
||||
<EditorReact
|
||||
language={"javascript"}
|
||||
content={this.state.resultData}
|
||||
isReadOnly={true}
|
||||
ariaLabel={"Execute stored procedure result"}
|
||||
/>
|
||||
</PivotItem>
|
||||
<PivotItem
|
||||
headerText="console.log"
|
||||
headerButtonProps={{
|
||||
"data-order": 2,
|
||||
"data-title": "console.log",
|
||||
}}
|
||||
style={{ height: "100%" }}
|
||||
>
|
||||
<EditorReact
|
||||
language={"javascript"}
|
||||
content={this.state.logsData}
|
||||
isReadOnly={true}
|
||||
ariaLabel={"Execute stored procedure logs"}
|
||||
/>
|
||||
</PivotItem>
|
||||
</Pivot>
|
||||
</div>
|
||||
)}
|
||||
{this.state.hasErrors && (
|
||||
<div className="errors-container">
|
||||
<div className="errors-header">Errors:</div>
|
||||
<div className="errorContent">
|
||||
<span className="errorMessage">{this.state.error}</span>
|
||||
<span className="errorDetailsLink">
|
||||
<a
|
||||
aria-label="Error details link"
|
||||
onClick={() => this.onErrorDetailsClick()}
|
||||
onKeyPress={(event: React.KeyboardEvent<HTMLAnchorElement>) => this.onErrorDetailsKeyPress(event)}
|
||||
>
|
||||
More details
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,13 +3,13 @@ import * as ko from "knockout";
|
|||
import * as Constants from "../../Common/Constants";
|
||||
import { deleteStoredProcedure } from "../../Common/dataAccess/deleteStoredProcedure";
|
||||
import { executeStoredProcedure } from "../../Common/dataAccess/executeStoredProcedure";
|
||||
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import Explorer from "../Explorer";
|
||||
import StoredProcedureTab from "../Tabs/StoredProcedureTab";
|
||||
import { getErrorMessage } from "../Tables/Utilities";
|
||||
import { NewStoredProcedureTab } from "../Tabs/StoredProcedureTab/StoredProcedureTab";
|
||||
import TabsBase from "../Tabs/TabsBase";
|
||||
|
||||
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
|
||||
|
@ -67,16 +67,22 @@ export default class StoredProcedure {
|
|||
body: sampleStoredProcedureBody,
|
||||
};
|
||||
|
||||
const storedProcedureTab: StoredProcedureTab = new StoredProcedureTab({
|
||||
resource: storedProcedure,
|
||||
isNew: true,
|
||||
tabKind: ViewModels.CollectionTabKind.StoredProcedures,
|
||||
title: `New Stored Procedure ${id}`,
|
||||
tabPath: `${source.databaseId}>${source.id()}>New Stored Procedure ${id}`,
|
||||
collection: source,
|
||||
node: source,
|
||||
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/sproc`,
|
||||
});
|
||||
const storedProcedureTab: NewStoredProcedureTab = new NewStoredProcedureTab(
|
||||
{
|
||||
resource: storedProcedure,
|
||||
isNew: true,
|
||||
tabKind: ViewModels.CollectionTabKind.StoredProcedures,
|
||||
title: `New Stored Procedure ${id}`,
|
||||
tabPath: `${source.databaseId}>${source.id()}>New Stored Procedure ${id}`,
|
||||
collection: source,
|
||||
node: source,
|
||||
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/sproc`,
|
||||
},
|
||||
{
|
||||
collection: source,
|
||||
container: source.container,
|
||||
}
|
||||
);
|
||||
|
||||
source.container.tabsManager.activateNewTab(storedProcedureTab);
|
||||
}
|
||||
|
@ -93,11 +99,11 @@ export default class StoredProcedure {
|
|||
public open = () => {
|
||||
this.select();
|
||||
|
||||
const storedProcedureTabs: StoredProcedureTab[] = this.container.tabsManager.getTabs(
|
||||
const storedProcedureTabs: NewStoredProcedureTab[] = this.container.tabsManager.getTabs(
|
||||
ViewModels.CollectionTabKind.StoredProcedures,
|
||||
(tab: TabsBase) => tab.node && tab.node.rid === this.rid
|
||||
) as StoredProcedureTab[];
|
||||
let storedProcedureTab: StoredProcedureTab = storedProcedureTabs && storedProcedureTabs[0];
|
||||
) as NewStoredProcedureTab[];
|
||||
let storedProcedureTab: NewStoredProcedureTab = storedProcedureTabs && storedProcedureTabs[0];
|
||||
|
||||
if (storedProcedureTab) {
|
||||
this.container.tabsManager.activateTab(storedProcedureTab);
|
||||
|
@ -109,24 +115,29 @@ export default class StoredProcedure {
|
|||
body: this.body(),
|
||||
};
|
||||
|
||||
storedProcedureTab = new StoredProcedureTab({
|
||||
resource: storedProcedureData,
|
||||
isNew: false,
|
||||
tabKind: ViewModels.CollectionTabKind.StoredProcedures,
|
||||
title: storedProcedureData.id,
|
||||
tabPath: `${this.collection.databaseId}>${this.collection.id()}>${storedProcedureData.id}`,
|
||||
collection: this.collection,
|
||||
node: this,
|
||||
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(
|
||||
this.collection.databaseId,
|
||||
this.collection.id()
|
||||
)}/sprocs/${this.id()}`,
|
||||
});
|
||||
storedProcedureTab = new NewStoredProcedureTab(
|
||||
{
|
||||
resource: storedProcedureData,
|
||||
isNew: false,
|
||||
tabKind: ViewModels.CollectionTabKind.StoredProcedures,
|
||||
title: storedProcedureData.id,
|
||||
tabPath: `${this.collection.databaseId}>${this.collection.id()}>${storedProcedureData.id}`,
|
||||
collection: this.collection,
|
||||
node: this,
|
||||
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(
|
||||
this.collection.databaseId,
|
||||
this.collection.id()
|
||||
)}/sprocs/${this.id()}`,
|
||||
},
|
||||
{
|
||||
collection: this.collection,
|
||||
container: this.container,
|
||||
}
|
||||
);
|
||||
|
||||
this.container.tabsManager.activateNewTab(storedProcedureTab);
|
||||
}
|
||||
};
|
||||
|
||||
public delete() {
|
||||
if (!window.confirm("Are you sure you want to delete the stored procedure?")) {
|
||||
return;
|
||||
|
@ -142,19 +153,19 @@ export default class StoredProcedure {
|
|||
}
|
||||
|
||||
public execute(params: string[], partitionKeyValue?: string): void {
|
||||
const sprocTabs = this.container.tabsManager.getTabs(
|
||||
const sprocTabs: NewStoredProcedureTab[] = this.container.tabsManager.getTabs(
|
||||
ViewModels.CollectionTabKind.StoredProcedures,
|
||||
(tab: TabsBase) => tab.node && tab.node.rid === this.rid
|
||||
) as StoredProcedureTab[];
|
||||
const sprocTab = sprocTabs && sprocTabs.length > 0 && sprocTabs[0];
|
||||
) as NewStoredProcedureTab[];
|
||||
const sprocTab: NewStoredProcedureTab = sprocTabs && sprocTabs.length > 0 && sprocTabs[0];
|
||||
sprocTab.isExecuting(true);
|
||||
this.container &&
|
||||
executeStoredProcedure(this.collection, this, partitionKeyValue, params)
|
||||
.then(
|
||||
(result: any) => {
|
||||
sprocTab.onExecuteSprocsResult(result, result.scriptLogs);
|
||||
(result) => {
|
||||
sprocTab.onExecuteSprocsResult(result);
|
||||
},
|
||||
(error: any) => {
|
||||
(error) => {
|
||||
sprocTab.onExecuteSprocsError(getErrorMessage(error));
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue