Migrate Trigger tab to React (#855)
Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
parent
af71a96d54
commit
914c372f5b
|
@ -201,3 +201,11 @@
|
||||||
.migration:disabled {
|
.migration:disabled {
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trigger-field {
|
||||||
|
width: 40%;
|
||||||
|
margin-top: 10px
|
||||||
|
}
|
||||||
|
.trigger-form {
|
||||||
|
padding: 10px 30px 10px 30px;
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
<div class="tab-pane flexContainer" data-bind="attr:{ id: tabId }" role="tabpanel">
|
|
||||||
<!-- Trigger Tab Form - Start -->
|
|
||||||
<div class="storedTabForm flexContainer">
|
|
||||||
<div class="formTitleFirst">Trigger Id</div>
|
|
||||||
<span class="formTitleTextbox">
|
|
||||||
<input
|
|
||||||
class="formTree"
|
|
||||||
type="text"
|
|
||||||
required
|
|
||||||
pattern="[^/?#\\]*[^/?# \\]"
|
|
||||||
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
|
||||||
placeholder="Enter the new trigger id"
|
|
||||||
size="40"
|
|
||||||
data-bind="textInput: id"
|
|
||||||
aria-label="Trigger Id"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="formTitleFirst">Trigger Type</div>
|
|
||||||
<span class="formTitleTextbox">
|
|
||||||
<select class="formTree" required data-bind="value: triggerType" aria-label="Trigger Type">
|
|
||||||
<option>Pre</option>
|
|
||||||
<option>Post</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
<div class="formTitleFirst">Trigger Operation</div>
|
|
||||||
<span class="formTitleTextbox">
|
|
||||||
<select class="formTree" required data-bind="value: triggerOperation" aria-label="Trigger Operation">
|
|
||||||
<option>All</option>
|
|
||||||
<option>Create</option>
|
|
||||||
<option>Delete</option>
|
|
||||||
<option>Replace</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
<div class="spUdfTriggerHeader">Trigger Body</div>
|
|
||||||
<div class="storedUdfTriggerEditor" data-bind=" setTemplateReady: true, attr: { id: editorId } "></div>
|
|
||||||
</div>
|
|
||||||
<!-- Trigger Tab Form - End -->
|
|
||||||
</div>
|
|
|
@ -1,185 +0,0 @@
|
||||||
import * as Constants from "../../Common/Constants";
|
|
||||||
import { createTrigger } from "../../Common/dataAccess/createTrigger";
|
|
||||||
import { updateTrigger } from "../../Common/dataAccess/updateTrigger";
|
|
||||||
import editable from "../../Common/EditableUtility";
|
|
||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
|
||||||
import { SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
|
|
||||||
import Trigger from "../Tree/Trigger";
|
|
||||||
import ScriptTabBase from "./ScriptTabBase";
|
|
||||||
import template from "./TriggerTab.html";
|
|
||||||
|
|
||||||
export default class TriggerTab extends ScriptTabBase {
|
|
||||||
public readonly html = template;
|
|
||||||
public collection: ViewModels.Collection;
|
|
||||||
public node: Trigger;
|
|
||||||
public triggerType: ViewModels.Editable<string>;
|
|
||||||
public triggerOperation: ViewModels.Editable<string>;
|
|
||||||
|
|
||||||
constructor(options: ViewModels.ScriptTabOption) {
|
|
||||||
super(options);
|
|
||||||
super.onActivate.bind(this);
|
|
||||||
this.ariaLabel("Trigger Body");
|
|
||||||
this.triggerType = editable.observable<string>(options.resource.triggerType);
|
|
||||||
this.triggerOperation = editable.observable<string>(options.resource.triggerOperation);
|
|
||||||
|
|
||||||
this.formFields([this.id, this.triggerType, this.triggerOperation, this.editorContent]);
|
|
||||||
super.buildCommandBarOptions.bind(this);
|
|
||||||
super.buildCommandBarOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onSaveClick = (): void => {
|
|
||||||
this._createTrigger({
|
|
||||||
id: this.id(),
|
|
||||||
body: this.editorContent(),
|
|
||||||
triggerOperation: this.triggerOperation() as SqlTriggerResource["triggerOperation"],
|
|
||||||
triggerType: this.triggerType() as SqlTriggerResource["triggerType"],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
public onUpdateClick = (): Promise<any> => {
|
|
||||||
const data = this._getResource();
|
|
||||||
this.isExecutionError(false);
|
|
||||||
this.isExecuting(true);
|
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.UpdateTrigger, {
|
|
||||||
tabTitle: this.tabTitle(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return updateTrigger(this.collection.databaseId, this.collection.id(), {
|
|
||||||
id: this.id(),
|
|
||||||
body: this.editorContent(),
|
|
||||||
triggerOperation: this.triggerOperation() as SqlTriggerResource["triggerOperation"],
|
|
||||||
triggerType: this.triggerType() as SqlTriggerResource["triggerType"],
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
(createdResource) => {
|
|
||||||
this.resource(createdResource);
|
|
||||||
this.tabTitle(createdResource.id);
|
|
||||||
|
|
||||||
this.node.id(createdResource.id);
|
|
||||||
this.node.body(createdResource.body as string);
|
|
||||||
this.node.triggerType(createdResource.triggerOperation);
|
|
||||||
this.node.triggerOperation(createdResource.triggerOperation);
|
|
||||||
TelemetryProcessor.traceSuccess(
|
|
||||||
Action.UpdateTrigger,
|
|
||||||
{
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
|
||||||
tabTitle: this.tabTitle(),
|
|
||||||
},
|
|
||||||
startKey
|
|
||||||
);
|
|
||||||
|
|
||||||
this.setBaselines();
|
|
||||||
|
|
||||||
const editorModel = this.editor().getModel();
|
|
||||||
editorModel.setValue(createdResource.body as string);
|
|
||||||
this.editorContent.setBaseline(createdResource.body as string);
|
|
||||||
},
|
|
||||||
(createError: any) => {
|
|
||||||
this.isExecutionError(true);
|
|
||||||
TelemetryProcessor.traceFailure(
|
|
||||||
Action.UpdateTrigger,
|
|
||||||
{
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
|
||||||
tabTitle: this.tabTitle(),
|
|
||||||
error: getErrorMessage(createError),
|
|
||||||
errorStack: getErrorStack(createError),
|
|
||||||
},
|
|
||||||
startKey
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.finally(() => this.isExecuting(false));
|
|
||||||
};
|
|
||||||
|
|
||||||
public setBaselines() {
|
|
||||||
super.setBaselines();
|
|
||||||
|
|
||||||
const resource = this.resource();
|
|
||||||
this.triggerOperation.setBaseline(resource.triggerOperation);
|
|
||||||
this.triggerType.setBaseline(resource.triggerType);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.isTriggersExpanded()) {
|
|
||||||
this.collection.container.selectedNode(this.collection);
|
|
||||||
} else {
|
|
||||||
this.collection.container.selectedNode(this.node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _createTrigger(resource: SqlTriggerResource): void {
|
|
||||||
this.isExecutionError(false);
|
|
||||||
this.isExecuting(true);
|
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateTrigger, {
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
|
||||||
tabTitle: this.tabTitle(),
|
|
||||||
});
|
|
||||||
|
|
||||||
resource.body = String(resource.body); // Ensure trigger body is converted to string
|
|
||||||
createTrigger(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()
|
|
||||||
)}/triggers/${createdResource.id}`
|
|
||||||
);
|
|
||||||
this.setBaselines();
|
|
||||||
|
|
||||||
const editorModel = this.editor().getModel();
|
|
||||||
editorModel.setValue(createdResource.body as string);
|
|
||||||
this.editorContent.setBaseline(createdResource.body as string);
|
|
||||||
|
|
||||||
this.node = this.collection.createTriggerNode(createdResource);
|
|
||||||
TelemetryProcessor.traceSuccess(
|
|
||||||
Action.CreateTrigger,
|
|
||||||
{
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
|
||||||
tabTitle: this.tabTitle(),
|
|
||||||
},
|
|
||||||
startKey
|
|
||||||
);
|
|
||||||
this.editorState(ViewModels.ScriptEditorState.exisitingNoEdits);
|
|
||||||
return createdResource;
|
|
||||||
},
|
|
||||||
(createError: any) => {
|
|
||||||
this.isExecutionError(true);
|
|
||||||
TelemetryProcessor.traceFailure(
|
|
||||||
Action.CreateTrigger,
|
|
||||||
{
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
|
||||||
tabTitle: this.tabTitle(),
|
|
||||||
error: getErrorMessage(createError),
|
|
||||||
errorStack: getErrorStack(createError),
|
|
||||||
},
|
|
||||||
startKey
|
|
||||||
);
|
|
||||||
return Promise.reject(createError);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.finally(() => this.isExecuting(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getResource() {
|
|
||||||
return {
|
|
||||||
id: this.id(),
|
|
||||||
body: this.editorContent(),
|
|
||||||
triggerOperation: this.triggerOperation(),
|
|
||||||
triggerType: this.triggerType(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { TriggerDefinition } from "@azure/cosmos";
|
||||||
|
import React from "react";
|
||||||
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
|
import { SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
|
||||||
|
import Trigger from "../Tree/Trigger";
|
||||||
|
import ScriptTabBase from "./ScriptTabBase";
|
||||||
|
import { TriggerTabContent } from "./TriggerTabContent";
|
||||||
|
|
||||||
|
export default class TriggerTab extends ScriptTabBase {
|
||||||
|
public onSaveClick: () => void;
|
||||||
|
public onUpdateClick: () => Promise<void>;
|
||||||
|
public collection: ViewModels.Collection;
|
||||||
|
public node: Trigger;
|
||||||
|
public triggerType: ViewModels.Editable<string>;
|
||||||
|
public triggerOperation: ViewModels.Editable<string>;
|
||||||
|
public triggerOptions: ViewModels.ScriptTabOption;
|
||||||
|
|
||||||
|
constructor(options: ViewModels.ScriptTabOption) {
|
||||||
|
super(options);
|
||||||
|
super.onActivate.bind(this);
|
||||||
|
this.triggerOptions = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
addNodeInCollection(createdResource: TriggerDefinition | SqlTriggerResource): void {
|
||||||
|
this.node = this.collection.createTriggerNode(createdResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<TriggerTabContent
|
||||||
|
{...this}
|
||||||
|
addNodeInCollection={(createdResource) => this.addNodeInCollection(createdResource)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,343 @@
|
||||||
|
import { TriggerDefinition } from "@azure/cosmos";
|
||||||
|
import { Dropdown, IDropdownOption, Label, TextField } from "@fluentui/react";
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import DiscardIcon from "../../../images/discard.svg";
|
||||||
|
import SaveIcon from "../../../images/save-cosmos.svg";
|
||||||
|
import * as Constants from "../../Common/Constants";
|
||||||
|
import { createTrigger } from "../../Common/dataAccess/createTrigger";
|
||||||
|
import { updateTrigger } from "../../Common/dataAccess/updateTrigger";
|
||||||
|
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||||
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
|
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
import { SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
import { EditorReact } from "../Controls/Editor/EditorReact";
|
||||||
|
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
|
import TriggerTab from "./TriggerTab";
|
||||||
|
|
||||||
|
const triggerTypeOptions: IDropdownOption[] = [
|
||||||
|
{ key: "Pre", text: "Pre" },
|
||||||
|
{ key: "Post", text: "Post" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const triggerOperationOptions: IDropdownOption[] = [
|
||||||
|
{ key: "All", text: "All" },
|
||||||
|
{ key: "Create", text: "Create" },
|
||||||
|
{ key: "Delete", text: "Delete" },
|
||||||
|
{ key: "Replace", text: "Replace" },
|
||||||
|
];
|
||||||
|
|
||||||
|
interface Ibutton {
|
||||||
|
visible: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITriggerTabContentState {
|
||||||
|
[key: string]: string | boolean;
|
||||||
|
triggerId: string;
|
||||||
|
triggerBody: string;
|
||||||
|
triggerType?: "Pre" | "Post";
|
||||||
|
triggerOperation?: "All" | "Create" | "Update" | "Delete" | "Replace";
|
||||||
|
isIdEditable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TriggerTabContent extends Component<TriggerTab, ITriggerTabContentState> {
|
||||||
|
public saveButton: Ibutton;
|
||||||
|
public updateButton: Ibutton;
|
||||||
|
public discardButton: Ibutton;
|
||||||
|
|
||||||
|
constructor(props: TriggerTab) {
|
||||||
|
super(props);
|
||||||
|
this.saveButton = {
|
||||||
|
visible: props.isNew(),
|
||||||
|
enabled: false,
|
||||||
|
};
|
||||||
|
this.updateButton = {
|
||||||
|
visible: !props.isNew(),
|
||||||
|
enabled: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.discardButton = {
|
||||||
|
visible: true,
|
||||||
|
enabled: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { id, body, triggerType, triggerOperation } = props.triggerOptions.resource;
|
||||||
|
this.state = {
|
||||||
|
triggerId: id,
|
||||||
|
triggerType: triggerType,
|
||||||
|
triggerOperation: triggerOperation,
|
||||||
|
triggerBody: body,
|
||||||
|
isIdEditable: props.isNew() ? true : false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async onSaveClick(): Promise<void> {
|
||||||
|
const { triggerId, triggerType, triggerBody, triggerOperation } = this.state;
|
||||||
|
const resource = {
|
||||||
|
id: triggerId,
|
||||||
|
body: triggerBody,
|
||||||
|
triggerOperation: triggerOperation,
|
||||||
|
triggerType: triggerType,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.props.isExecutionError(false);
|
||||||
|
this.props.isExecuting(true);
|
||||||
|
const startKey: number = TelemetryProcessor.traceStart(Action.CreateTrigger, {
|
||||||
|
dataExplorerArea: Constants.Areas.Tab,
|
||||||
|
tabTitle: this.props.tabTitle(),
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
resource.body = String(resource.body); // Ensure trigger body is converted to string
|
||||||
|
const createdResource: TriggerDefinition | SqlTriggerResource = await createTrigger(
|
||||||
|
this.props.collection.databaseId,
|
||||||
|
this.props.collection.id(),
|
||||||
|
resource
|
||||||
|
);
|
||||||
|
if (createdResource) {
|
||||||
|
this.props.tabTitle(createdResource.id);
|
||||||
|
this.props.isNew(false);
|
||||||
|
this.props.resource(createdResource);
|
||||||
|
this.props.hashLocation(
|
||||||
|
`${Constants.HashRoutePrefixes.collectionsWithIds(
|
||||||
|
this.props.collection.databaseId,
|
||||||
|
this.props.collection.id()
|
||||||
|
)}/triggers/${createdResource.id}`
|
||||||
|
);
|
||||||
|
this.props.editorContent.setBaseline(createdResource.body as string);
|
||||||
|
this.props.addNodeInCollection(createdResource);
|
||||||
|
this.saveButton.visible = false;
|
||||||
|
this.updateButton.visible = true;
|
||||||
|
this.setState({ isIdEditable: false });
|
||||||
|
TelemetryProcessor.traceSuccess(
|
||||||
|
Action.CreateTrigger,
|
||||||
|
{
|
||||||
|
dataExplorerArea: Constants.Areas.Tab,
|
||||||
|
tabTitle: this.props.tabTitle(),
|
||||||
|
},
|
||||||
|
startKey
|
||||||
|
);
|
||||||
|
this.props.editorState(ViewModels.ScriptEditorState.exisitingNoEdits);
|
||||||
|
this.props.isExecuting(false);
|
||||||
|
}
|
||||||
|
} catch (createError) {
|
||||||
|
this.props.isExecutionError(true);
|
||||||
|
TelemetryProcessor.traceFailure(
|
||||||
|
Action.CreateTrigger,
|
||||||
|
{
|
||||||
|
dataExplorerArea: Constants.Areas.Tab,
|
||||||
|
tabTitle: this.props.tabTitle(),
|
||||||
|
error: getErrorMessage(createError),
|
||||||
|
errorStack: getErrorStack(createError),
|
||||||
|
},
|
||||||
|
startKey
|
||||||
|
);
|
||||||
|
this.props.isExecuting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async onUpdateClick(): Promise<void> {
|
||||||
|
this.props.isExecutionError(false);
|
||||||
|
this.props.isExecuting(true);
|
||||||
|
const startKey: number = TelemetryProcessor.traceStart(Action.UpdateTrigger, {
|
||||||
|
tabTitle: this.props.tabTitle(),
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { triggerId, triggerBody, triggerOperation, triggerType } = this.state;
|
||||||
|
const createdResource = await updateTrigger(this.props.collection.databaseId, this.props.collection.id(), {
|
||||||
|
id: triggerId,
|
||||||
|
body: triggerBody,
|
||||||
|
triggerOperation: triggerOperation as SqlTriggerResource["triggerOperation"],
|
||||||
|
triggerType: triggerType as SqlTriggerResource["triggerType"],
|
||||||
|
});
|
||||||
|
if (createdResource) {
|
||||||
|
this.props.resource(createdResource);
|
||||||
|
this.props.tabTitle(createdResource.id);
|
||||||
|
|
||||||
|
this.props.node.id(createdResource.id);
|
||||||
|
this.props.node.body(createdResource.body as string);
|
||||||
|
this.props.node.triggerType(createdResource.triggerType);
|
||||||
|
this.props.node.triggerOperation(createdResource.triggerOperation);
|
||||||
|
TelemetryProcessor.traceSuccess(
|
||||||
|
Action.UpdateTrigger,
|
||||||
|
{
|
||||||
|
dataExplorerArea: Constants.Areas.Tab,
|
||||||
|
tabTitle: this.props.tabTitle(),
|
||||||
|
},
|
||||||
|
startKey
|
||||||
|
);
|
||||||
|
this.props.isExecuting(false);
|
||||||
|
}
|
||||||
|
} catch (createError) {
|
||||||
|
this.props.isExecutionError(true);
|
||||||
|
TelemetryProcessor.traceFailure(
|
||||||
|
Action.UpdateTrigger,
|
||||||
|
{
|
||||||
|
dataExplorerArea: Constants.Areas.Tab,
|
||||||
|
tabTitle: this.props.tabTitle(),
|
||||||
|
error: getErrorMessage(createError),
|
||||||
|
errorStack: getErrorStack(createError),
|
||||||
|
},
|
||||||
|
startKey
|
||||||
|
);
|
||||||
|
this.props.isExecuting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDiscard(): void {
|
||||||
|
const { id, body, triggerType, triggerOperation } = this.props.triggerOptions.resource;
|
||||||
|
this.setState({
|
||||||
|
triggerId: id,
|
||||||
|
triggerType: triggerType,
|
||||||
|
triggerOperation: triggerOperation,
|
||||||
|
triggerBody: body,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private isValidId(id: string): boolean {
|
||||||
|
if (!id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidStartCharacters = /^[/?#\\]/;
|
||||||
|
if (invalidStartCharacters.test(id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidMiddleCharacters = /^.+[/?#\\]/;
|
||||||
|
if (invalidMiddleCharacters.test(id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidEndCharacters = /.*[/?#\\ ]$/;
|
||||||
|
if (invalidEndCharacters.test(id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isNotEmpty(value: string): boolean {
|
||||||
|
return !!value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
|
const label = "Save";
|
||||||
|
if (this.saveButton.visible) {
|
||||||
|
buttons.push({
|
||||||
|
setState: this.setState,
|
||||||
|
...this,
|
||||||
|
iconSrc: SaveIcon,
|
||||||
|
iconAlt: label,
|
||||||
|
onCommandClick: this.onSaveClick,
|
||||||
|
commandButtonLabel: label,
|
||||||
|
ariaLabel: label,
|
||||||
|
hasPopup: false,
|
||||||
|
disabled: !this.saveButton.enabled,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.updateButton.visible) {
|
||||||
|
const label = "Update";
|
||||||
|
buttons.push({
|
||||||
|
...this,
|
||||||
|
iconSrc: SaveIcon,
|
||||||
|
iconAlt: label,
|
||||||
|
onCommandClick: this.onUpdateClick,
|
||||||
|
commandButtonLabel: label,
|
||||||
|
ariaLabel: label,
|
||||||
|
hasPopup: false,
|
||||||
|
disabled: !this.updateButton.enabled,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.discardButton.visible) {
|
||||||
|
const label = "Discard";
|
||||||
|
buttons.push({
|
||||||
|
setState: this.setState,
|
||||||
|
...this,
|
||||||
|
iconSrc: DiscardIcon,
|
||||||
|
iconAlt: label,
|
||||||
|
onCommandClick: this.onDiscard,
|
||||||
|
commandButtonLabel: label,
|
||||||
|
ariaLabel: label,
|
||||||
|
hasPopup: false,
|
||||||
|
disabled: !this.discardButton.enabled,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTriggerIdChange = (
|
||||||
|
_event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
newValue?: string
|
||||||
|
): void => {
|
||||||
|
this.saveButton.enabled = this.isValidId(newValue) && this.isNotEmpty(newValue);
|
||||||
|
this.setState({ triggerId: newValue });
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTriggerTypeOprationChange = (
|
||||||
|
_event: React.FormEvent<HTMLElement>,
|
||||||
|
selectedParam: IDropdownOption,
|
||||||
|
key: string
|
||||||
|
): void => {
|
||||||
|
this.setState({ [key]: String(selectedParam.key) });
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTriggerBodyChange = (newContent: string) => {
|
||||||
|
this.setState({ triggerBody: newContent });
|
||||||
|
};
|
||||||
|
|
||||||
|
render(): JSX.Element {
|
||||||
|
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||||
|
const { triggerId, triggerType, triggerOperation, triggerBody, isIdEditable } = this.state;
|
||||||
|
return (
|
||||||
|
<div className="tab-pane flexContainer trigger-form" role="tabpanel">
|
||||||
|
<TextField
|
||||||
|
className="trigger-field"
|
||||||
|
label="Trigger Id"
|
||||||
|
id="entityTimeId"
|
||||||
|
autoFocus
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
pattern="[^/?#\\]*[^/?# \\]"
|
||||||
|
placeholder="Enter the new trigger id"
|
||||||
|
size={40}
|
||||||
|
value={triggerId}
|
||||||
|
readOnly={!isIdEditable}
|
||||||
|
onChange={this.handleTriggerIdChange}
|
||||||
|
/>
|
||||||
|
<Dropdown
|
||||||
|
placeholder="Trigger Type"
|
||||||
|
label="Trigger Type"
|
||||||
|
options={triggerTypeOptions}
|
||||||
|
selectedKey={triggerType}
|
||||||
|
className="trigger-field"
|
||||||
|
onChange={(event, selectedKey) => this.handleTriggerTypeOprationChange(event, selectedKey, "triggerType")}
|
||||||
|
/>
|
||||||
|
<Dropdown
|
||||||
|
placeholder="Trigger Operation"
|
||||||
|
label="Trigger Operation"
|
||||||
|
selectedKey={triggerOperation}
|
||||||
|
options={triggerOperationOptions}
|
||||||
|
className="trigger-field"
|
||||||
|
onChange={(event, selectedKey) =>
|
||||||
|
this.handleTriggerTypeOprationChange(event, selectedKey, "triggerOperation")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Label className="trigger-field">Trigger Body</Label>
|
||||||
|
<EditorReact
|
||||||
|
language={"json"}
|
||||||
|
content={triggerBody}
|
||||||
|
isReadOnly={false}
|
||||||
|
ariaLabel={"Graph JSON"}
|
||||||
|
onContentChanged={this.handleTriggerBodyChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue