diff --git a/src/Explorer/Tabs/QueryTablesTab/QueryTablesTab.tsx b/src/Explorer/Tabs/QueryTablesTab/QueryTablesTab.tsx new file mode 100644 index 000000000..e55be520a --- /dev/null +++ b/src/Explorer/Tabs/QueryTablesTab/QueryTablesTab.tsx @@ -0,0 +1,558 @@ +import * as ko from "knockout"; +import Q from "q"; +import React, { useState } from 'react'; +import AddEntityIcon from "../../../../images/AddEntity.svg"; +import DeleteEntitiesIcon from "../../../../images/DeleteEntities.svg"; +import EditEntityIcon from "../../../../images/Edit-entity.svg"; +import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg"; +import QueryBuilderIcon from "../../../../images/Query-Builder.svg"; +import QueryTextIcon from "../../../../images/Query-Text.svg"; +import * as ViewModels from "../../../Contracts/ViewModels"; +import { userContext } from "../../../UserContext"; +import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; +import Explorer from "../../Explorer"; +import TableCommands from "../../Tables/DataTable/TableCommands"; +import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel"; +import QueryViewModel from "../../Tables/QueryBuilder/QueryViewModel"; +import { TableDataClient } from "../../Tables/TableDataClient"; +import template from "../QueryTablesTab.html"; + +export default () => { + const html = template; + let collection: ViewModels.Collection; + let tableEntityListViewModel : TableEntityListViewModel; + let queryViewModel :QueryViewModel; + let tableCommands: TableCommands; + let tableDataClient: TableDataClient; + const [queryText, setQueryText] = useState("PartitionKey eq 'partitionKey1'"); + let selectedQueryText = ko.observable("").extend({ notify: "always" }); + + let executeQueryButton: ViewModels.Button; + let addEntityButton: ViewModels.Button; + let editEntityButton: ViewModels.Button; + let deleteEntityButton: ViewModels.Button; + let queryBuilderButton: ViewModels.Button; + let queryTextButton: ViewModels.Button; + let container: Explorer; + + constructor(options: ViewModels.TabOptions) { + super(options); + + this.container = options.collection && options.collection.container; + this.tableCommands = new TableCommands(this.container); + this.tableDataClient = this.container.tableDataClient; + this.tableEntityListViewModel(new TableEntityListViewModel(this.tableCommands, this)); + this.tableEntityListViewModel().queryTablesTab = this; + this.queryViewModel(new QueryViewModel(this)); + const sampleQuerySubscription = this.tableEntityListViewModel().items.subscribe(() => { + if (this.tableEntityListViewModel().items().length > 0 && userContext.apiType === "Tables") { + this.queryViewModel().queryBuilderViewModel().setExample(); + } + sampleQuerySubscription.dispose(); + }); + + this.executeQueryButton = { + enabled: ko.computed(() => { + return true; + }), + + visible: ko.computed(() => { + return true; + }), + }; + + this.queryBuilderButton = { + enabled: ko.computed(() => { + return true; + }), + + visible: ko.computed(() => { + return true; + }), + + isSelected: ko.computed(() => { + return this.queryViewModel() ? this.queryViewModel().isHelperActive() : false; + }), + }; + + this.queryTextButton = { + enabled: ko.computed(() => { + return true; + }), + + visible: ko.computed(() => { + return true; + }), + + isSelected: ko.computed(() => { + return this.queryViewModel() ? this.queryViewModel().isEditorActive() : false; + }), + }; + + this.addEntityButton = { + enabled: ko.computed(() => { + return true; + }), + + visible: ko.computed(() => { + return true; + }), + }; + + this.editEntityButton = { + enabled: ko.computed(() => { + return this.tableCommands.isEnabled( + TableCommands.editEntityCommand, + this.tableEntityListViewModel().selected() + ); + }), + + visible: ko.computed(() => { + return true; + }), + }; + + this.deleteEntityButton = { + enabled: ko.computed(() => { + return this.tableCommands.isEnabled( + TableCommands.deleteEntitiesCommand, + this.tableEntityListViewModel().selected() + ); + }), + + visible: ko.computed(() => { + return true; + }), + }; + + this.buildCommandBarOptions(); + } + + const onExecuteQueryClick = (): Q.Promise => { + this.queryViewModel().runQuery(); + return null; + }; + + const onQueryBuilderClick = (): Q.Promise => { + this.queryViewModel().selectHelper(); + return null; + }; + + const onQueryTextClick = (): Q.Promise => { + this.queryViewModel().selectEditor(); + return null; + }; + + const onAddEntityClick = (): Q.Promise => { + this.container.openAddTableEntityPanel(this, this.tableEntityListViewModel()); + return null; + }; + + const onEditEntityClick = (): Q.Promise => { + this.container.openEditTableEntityPanel(this, this.tableEntityListViewModel()); + return null; + }; + + const onDeleteEntityClick = (): Q.Promise => { + this.tableCommands.deleteEntitiesCommand(this.tableEntityListViewModel()); + return null; + }; + + const onActivate(): void { + super.onActivate(); + const columns = + !!this.tableEntityListViewModel() && + !!this.tableEntityListViewModel().table && + this.tableEntityListViewModel().table.columns; + if (!!columns) { + columns.adjust(); + $(window).resize(); + } + } + + protected getTabsButtons(): CommandButtonComponentProps[] { + const buttons: CommandButtonComponentProps[] = []; + if (this.queryBuilderButton.visible()) { + const label = userContext.apiType === "Cassandra" ? "CQL Query Builder" : "Query Builder"; + buttons.push({ + iconSrc: QueryBuilderIcon, + iconAlt: label, + onCommandClick: this.onQueryBuilderClick, + commandButtonLabel: label, + ariaLabel: label, + hasPopup: false, + disabled: !this.queryBuilderButton.enabled(), + isSelected: this.queryBuilderButton.isSelected(), + }); + } + + if (this.queryTextButton.visible()) { + const label = userContext.apiType === "Cassandra" ? "CQL Query Text" : "Query Text"; + buttons.push({ + iconSrc: QueryTextIcon, + iconAlt: label, + onCommandClick: this.onQueryTextClick, + commandButtonLabel: label, + ariaLabel: label, + hasPopup: false, + disabled: !this.queryTextButton.enabled(), + isSelected: this.queryTextButton.isSelected(), + }); + } + + if (this.executeQueryButton.visible()) { + const label = "Run Query"; + buttons.push({ + iconSrc: ExecuteQueryIcon, + iconAlt: label, + onCommandClick: this.onExecuteQueryClick, + commandButtonLabel: label, + ariaLabel: label, + hasPopup: false, + disabled: !this.executeQueryButton.enabled(), + }); + } + + if (this.addEntityButton.visible()) { + const label = userContext.apiType === "Cassandra" ? "Add Row" : "Add Entity"; + buttons.push({ + iconSrc: AddEntityIcon, + iconAlt: label, + onCommandClick: this.onAddEntityClick, + commandButtonLabel: label, + ariaLabel: label, + hasPopup: true, + disabled: !this.addEntityButton.enabled(), + }); + } + + if (this.editEntityButton.visible()) { + const label = userContext.apiType === "Cassandra" ? "Edit Row" : "Edit Entity"; + buttons.push({ + iconSrc: EditEntityIcon, + iconAlt: label, + onCommandClick: this.onEditEntityClick, + commandButtonLabel: label, + ariaLabel: label, + hasPopup: true, + disabled: !this.editEntityButton.enabled(), + }); + } + + if (this.deleteEntityButton.visible()) { + const label = userContext.apiType === "Cassandra" ? "Delete Rows" : "Delete Entities"; + buttons.push({ + iconSrc: DeleteEntitiesIcon, + iconAlt: label, + onCommandClick: this.onDeleteEntityClick, + commandButtonLabel: label, + ariaLabel: label, + hasPopup: true, + disabled: !this.deleteEntityButton.enabled(), + }); + } + return buttons; + } + + protected buildCommandBarOptions(): void { + ko.computed(() => + ko.toJSON([ + this.queryBuilderButton.visible, + this.queryBuilderButton.enabled, + this.queryTextButton.visible, + this.queryTextButton.enabled, + this.executeQueryButton.visible, + this.executeQueryButton.enabled, + this.addEntityButton.visible, + this.addEntityButton.enabled, + this.editEntityButton.visible, + this.editEntityButton.enabled, + this.deleteEntityButton.visible, + this.deleteEntityButton.enabled, + ]) + ).subscribe(() => this.updateNavbarWithTabsButtons()); + this.updateNavbarWithTabsButtons(); + } + + return ( +
+ +
+
+ { + hasQueryError &&
+ + {queryErrorMessage} +
+ }
+ + {isEditorActive &&
+
+ +
+
+ } + {isHelperActive &&
+
+
+ + + + + + + + + + + + + + + {clauseArray.map((clause, index)=> + + + + + + + + + +) } + + +
+ {actionLabel} + + {canGroupClauses && + + {andLabel} + + {fieldLabel} + + {dataTypeLabel} + + {operatorLabel} + + {valueLabel} +
+ + Add clause + + + Delete clause + + + + + + + + {$parent.getClauseGroupViewModels($data).map((gi, index)=> + + +) + + + +
+ {gi.canUngroup && } + } + + +
+
+ {canAnd && + } + + + {isTypeEditable && } + + {isValue && + + } + + {isTimestamp && + + } + + {isCustomLastTimestamp + && + + } + { isCustomRangeTimestamp && + + } +
+
+
+
+ + Add new clause + {addNewClauseLine} + +
+
+
+
+ }
+
+ +
+ toggle +
+
+ toggle +
+ Advanced Options +
+
+ {isExpanded &&
+
+ Show top results: + + {isExceedingLimit &&
+ + {topValueLimitMessage} +
+ + }
+
+ Select fields for query: + {isSelected &&
+ + {selectMessage} +
+ } + Choose Columns... + +
+
+ }
+
+
+
+
+
+ ); +}