Migration/edit table entity panel to react (#690)

Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
Sunil Kumar Yadav 2021-04-26 04:21:27 +05:30 committed by GitHub
parent ab283cb8ff
commit 67062c18aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 4012 additions and 598 deletions

View File

@ -6,6 +6,7 @@ export interface TableEntityProps {
entityValuePlaceholder: string; entityValuePlaceholder: string;
entityValue: string | Date; entityValue: string | Date;
isEntityTypeDate: boolean; isEntityTypeDate: boolean;
isEntityValueDisable?: boolean;
entityTimeValue: string; entityTimeValue: string;
entityValueType: string; entityValueType: string;
onEntityValueChange: (event: React.FormEvent<HTMLElement>, newInput?: string) => void; onEntityValueChange: (event: React.FormEvent<HTMLElement>, newInput?: string) => void;
@ -22,6 +23,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
entityValueType, entityValueType,
onEntityValueChange, onEntityValueChange,
onSelectDate, onSelectDate,
isEntityValueDisable,
onEntityTimeValueChange, onEntityTimeValueChange,
}: TableEntityProps): JSX.Element => { }: TableEntityProps): JSX.Element => {
if (isEntityTypeDate) { if (isEntityTypeDate) {
@ -33,6 +35,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
value={entityValue && new Date(entityValue)} value={entityValue && new Date(entityValue)}
ariaLabel={entityValuePlaceholder} ariaLabel={entityValuePlaceholder}
onSelectDate={onSelectDate} onSelectDate={onSelectDate}
disabled={isEntityValueDisable}
/> />
<TextField <TextField
label={entityValueLabel && entityValueLabel} label={entityValueLabel && entityValueLabel}
@ -41,6 +44,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
type="time" type="time"
value={entityTimeValue} value={entityTimeValue}
onChange={onEntityTimeValueChange} onChange={onEntityTimeValueChange}
disabled={isEntityValueDisable}
/> />
</> </>
); );
@ -52,6 +56,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
className="addEntityTextField" className="addEntityTextField"
id="entityValueId" id="entityValueId"
autoFocus autoFocus
disabled={isEntityValueDisable}
type={entityValueType} type={entityValueType}
placeholder={entityValuePlaceholder} placeholder={entityValuePlaceholder}
value={typeof entityValue === "string" && entityValue} value={typeof entityValue === "string" && entityValue}

View File

@ -32,6 +32,7 @@ export interface TableEntityProps {
options: { key: string; text: string }[]; options: { key: string; text: string }[];
isPropertyTypeDisable: boolean; isPropertyTypeDisable: boolean;
entityTimeValue: string; entityTimeValue: string;
isEntityValueDisable?: boolean;
onDeleteEntity?: () => void; onDeleteEntity?: () => void;
onEditEntity?: () => void; onEditEntity?: () => void;
onEntityPropertyChange: (event: React.FormEvent<HTMLElement>, newInput?: string) => void; onEntityPropertyChange: (event: React.FormEvent<HTMLElement>, newInput?: string) => void;
@ -55,6 +56,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
isPropertyTypeDisable, isPropertyTypeDisable,
isEntityTypeDate, isEntityTypeDate,
entityTimeValue, entityTimeValue,
isEntityValueDisable,
onEditEntity, onEditEntity,
onDeleteEntity, onDeleteEntity,
onEntityPropertyChange, onEntityPropertyChange,
@ -113,6 +115,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
<EntityValue <EntityValue
entityValueLabel={entityValueLabel} entityValueLabel={entityValueLabel}
entityValueType={getEntityValueType()} entityValueType={getEntityValueType()}
isEntityValueDisable={isEntityValueDisable}
entityValuePlaceholder={entityValuePlaceholder} entityValuePlaceholder={entityValuePlaceholder}
entityValue={entityValue} entityValue={entityValue}
isEntityTypeDate={isEntityTypeDate} isEntityTypeDate={isEntityTypeDate}
@ -121,10 +124,11 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
onSelectDate={onSelectDate} onSelectDate={onSelectDate}
onEntityTimeValueChange={onEntityTimeValueChange} onEntityTimeValueChange={onEntityTimeValueChange}
/> />
<TooltipHost content="Edit property" id="editTooltip"> {!isEntityValueDisable && (
<Image {...imageProps} src={EditIcon} alt="editEntity" id="editEntity" onClick={onEditEntity} /> <TooltipHost content="Edit property" id="editTooltip">
</TooltipHost> <Image {...imageProps} src={EditIcon} alt="editEntity" id="editEntity" onClick={onEditEntity} />
</TooltipHost>
)}
{isDeleteOptionVisible && userContext.apiType !== "Cassandra" && ( {isDeleteOptionVisible && userContext.apiType !== "Cassandra" && (
<TooltipHost content="Delete property" id="deleteTooltip"> <TooltipHost content="Delete property" id="deleteTooltip">
<Image {...imageProps} src={DeleteIcon} alt="delete entity" id="deleteEntity" onClick={onDeleteEntity} /> <Image {...imageProps} src={DeleteIcon} alt="delete entity" id="deleteEntity" onClick={onDeleteEntity} />

View File

@ -177,40 +177,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -479,40 +445,6 @@ exports[`SettingsComponent renders 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],
@ -805,40 +737,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -1107,40 +1005,6 @@ exports[`SettingsComponent renders 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],
@ -1446,40 +1310,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -1748,40 +1578,6 @@ exports[`SettingsComponent renders 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],
@ -2074,40 +1870,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -2376,40 +2138,6 @@ exports[`SettingsComponent renders 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],

View File

@ -66,7 +66,7 @@ import { SettingsPane } from "./Panes/SettingsPane/SettingsPane";
import { SetupNoteBooksPanel } from "./Panes/SetupNotebooksPanel/SetupNotebooksPanel"; import { SetupNoteBooksPanel } from "./Panes/SetupNotebooksPanel/SetupNotebooksPanel";
import { StringInputPane } from "./Panes/StringInputPane"; import { StringInputPane } from "./Panes/StringInputPane";
import { AddTableEntityPanel } from "./Panes/Tables/AddTableEntityPanel"; import { AddTableEntityPanel } from "./Panes/Tables/AddTableEntityPanel";
import EditTableEntityPane from "./Panes/Tables/EditTableEntityPane"; import { EditTableEntityPanel } from "./Panes/Tables/EditTableEntityPanel";
import { TableQuerySelectPanel } from "./Panes/Tables/TableQuerySelectPanel"; import { TableQuerySelectPanel } from "./Panes/Tables/TableQuerySelectPanel";
import { UploadFilePane } from "./Panes/UploadFilePane/UploadFilePane"; import { UploadFilePane } from "./Panes/UploadFilePane/UploadFilePane";
import { UploadItemsPane } from "./Panes/UploadItemsPane/UploadItemsPane"; import { UploadItemsPane } from "./Panes/UploadItemsPane/UploadItemsPane";
@ -173,7 +173,6 @@ export default class Explorer {
public addDatabasePane: AddDatabasePane; public addDatabasePane: AddDatabasePane;
public addCollectionPane: AddCollectionPane; public addCollectionPane: AddCollectionPane;
public graphStylingPane: GraphStylingPane; public graphStylingPane: GraphStylingPane;
public editTableEntityPane: EditTableEntityPane;
public cassandraAddCollectionPane: CassandraAddCollectionPane; public cassandraAddCollectionPane: CassandraAddCollectionPane;
public stringInputPane: StringInputPane; public stringInputPane: StringInputPane;
public gitHubReposPane: ContextualPaneBase; public gitHubReposPane: ContextualPaneBase;
@ -500,13 +499,6 @@ export default class Explorer {
container: this, container: this,
}); });
this.editTableEntityPane = new EditTableEntityPane({
id: "edittableentitypane",
visible: ko.observable<boolean>(false),
container: this,
});
this.cassandraAddCollectionPane = new CassandraAddCollectionPane({ this.cassandraAddCollectionPane = new CassandraAddCollectionPane({
id: "cassandraaddcollectionpane", id: "cassandraaddcollectionpane",
visible: ko.observable<boolean>(false), visible: ko.observable<boolean>(false),
@ -533,7 +525,6 @@ export default class Explorer {
this.addDatabasePane, this.addDatabasePane,
this.addCollectionPane, this.addCollectionPane,
this.graphStylingPane, this.graphStylingPane,
this.editTableEntityPane,
this.cassandraAddCollectionPane, this.cassandraAddCollectionPane,
this.stringInputPane, this.stringInputPane,
]; ];
@ -604,7 +595,6 @@ export default class Explorer {
this.addCollectionPane.collectionIdTitle("Table id"); this.addCollectionPane.collectionIdTitle("Table id");
this.addCollectionPane.collectionWithThroughputInSharedTitle("Provision dedicated throughput for this table"); this.addCollectionPane.collectionWithThroughputInSharedTitle("Provision dedicated throughput for this table");
this.refreshTreeTitle("Refresh tables"); this.refreshTreeTitle("Refresh tables");
this.editTableEntityPane.title("Edit Table Entity");
this.tableDataClient = new TablesAPIDataClient(); this.tableDataClient = new TablesAPIDataClient();
break; break;
case "Cassandra": case "Cassandra":
@ -618,7 +608,6 @@ export default class Explorer {
this.addCollectionPane.collectionIdTitle("Table id"); this.addCollectionPane.collectionIdTitle("Table id");
this.addCollectionPane.collectionWithThroughputInSharedTitle("Provision dedicated throughput for this table"); this.addCollectionPane.collectionWithThroughputInSharedTitle("Provision dedicated throughput for this table");
this.refreshTreeTitle("Refresh tables"); this.refreshTreeTitle("Refresh tables");
this.editTableEntityPane.title("Edit Table Row");
this.tableDataClient = new CassandraAPIDataClient(); this.tableDataClient = new CassandraAPIDataClient();
break; break;
} }
@ -2211,6 +2200,19 @@ export default class Explorer {
); );
} }
public openEditTableEntityPanel(queryTablesTab: QueryTablesTab, tableEntityListViewModel: TableListViewModal): void {
this.openSidePanel(
"Edit Table Entity",
<EditTableEntityPanel
explorer={this}
closePanel={this.closeSidePanel}
queryTablesTab={queryTablesTab}
tableEntityListViewModel={tableEntityListViewModel}
cassandraApiClient={new CassandraAPIDataClient()}
/>
);
}
public openTableSelectQueryPanel(queryViewModal: QueryViewModel): void { public openTableSelectQueryPanel(queryViewModal: QueryViewModel): void {
this.openSidePanel( this.openSidePanel(
"Select Column", "Select Column",

View File

@ -153,40 +153,6 @@ exports[`Settings Pane should render Default properly 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -455,40 +421,6 @@ exports[`Settings Pane should render Default properly 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],
@ -904,40 +836,6 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -1206,40 +1104,6 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],

View File

@ -0,0 +1,51 @@
import { mount } from "enzyme";
import * as ko from "knockout";
import React from "react";
import Explorer from "../../Explorer";
import TableListViewModal from "../../Tables/DataTable/TableEntityListViewModel";
import * as Entities from "../../Tables/Entities";
import { CassandraAPIDataClient } from "../../Tables/TableDataClient";
import QueryTablesTab from "../../Tabs/QueryTablesTab";
import { EditTableEntityPanel } from "./EditTableEntityPanel";
describe("Excute Edit Table Entity Pane", () => {
const fakeExplorer = {} as Explorer;
const fakeQueryTablesTab = {} as QueryTablesTab;
const fakeTableEntityListViewModel = {} as TableListViewModal;
fakeTableEntityListViewModel.items = ko.observableArray<Entities.ITableEntity>();
const fakeCassandraApiClient = {} as CassandraAPIDataClient;
fakeTableEntityListViewModel.headers = [];
fakeTableEntityListViewModel.selected = ko.observableArray<Entities.ITableEntity>([{}]);
const props = {
explorer: fakeExplorer,
closePanel: (): void => undefined,
queryTablesTab: fakeQueryTablesTab,
tableEntityListViewModel: fakeTableEntityListViewModel,
cassandraApiClient: fakeCassandraApiClient,
};
it("should render Default properly", () => {
const wrapper = mount(<EditTableEntityPanel {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("initially display 4 input field, 2 properties and 1 entity values", () => {
const wrapper = mount(<EditTableEntityPanel {...props} />);
expect(wrapper.find("input[type='text']")).toHaveLength(0);
});
it("add a new entity row", () => {
const wrapper = mount(<EditTableEntityPanel {...props} />);
wrapper.find(".addButtonEntiy").last().simulate("click");
expect(wrapper.find("input[type='text']")).toHaveLength(1);
});
it("remove a entity field", () => {
const wrapper = mount(<EditTableEntityPanel {...props} />);
// Since default entity row doesn't have delete option, so added row then delete for test cases.
wrapper.find(".addButtonEntiy").last().simulate("click");
wrapper.find("#deleteEntity").last().simulate("click");
expect(wrapper.find("input[type='text']")).toHaveLength(0);
});
});

View File

@ -0,0 +1,419 @@
import { useBoolean } from "@uifabric/react-hooks";
import {
IDropdownOption,
Image,
IPanelProps,
IRenderFunction,
Label,
Stack,
Text,
TextField,
} from "office-ui-fabric-react";
import React, { FunctionComponent, useEffect, useState } from "react";
import * as _ from "underscore";
import AddPropertyIcon from "../../../../images/Add-property.svg";
import RevertBackIcon from "../../../../images/RevertBack.svg";
import { TableEntity } from "../../../Common/TableEntity";
import { userContext } from "../../../UserContext";
import Explorer from "../../Explorer";
import * as TableConstants from "../../Tables/Constants";
import * as DataTableUtilities from "../../Tables/DataTable/DataTableUtilities";
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
import * as Entities from "../../Tables/Entities";
import { CassandraAPIDataClient } from "../../Tables/TableDataClient";
import * as TableEntityProcessor from "../../Tables/TableEntityProcessor";
import QueryTablesTab from "../../Tabs/QueryTablesTab";
import { PanelContainerComponent } from "../PanelContainerComponent";
import {
attributeNameLabel,
attributeValueLabel,
backImageProps,
cassandraOptions,
columnProps,
dataTypeLabel,
defaultStringPlaceHolder,
detailedHelp,
entityFromAttributes,
getAddButtonLabel,
getEntityValuePlaceholder,
getFormattedTime,
imageProps,
isValidEntities,
options,
} from "./Validators/EntityTableHelper";
interface EditTableEntityPanelProps {
explorer: Explorer;
closePanel: () => void;
queryTablesTab: QueryTablesTab;
tableEntityListViewModel: TableEntityListViewModel;
cassandraApiClient: CassandraAPIDataClient;
}
interface EntityRowType {
property: string;
type: string;
value: string;
isPropertyTypeDisable: boolean;
isDeleteOptionVisible: boolean;
id: number;
entityValuePlaceholder: string;
isEntityTypeDate: boolean;
entityTimeValue?: string;
isEntityValueDisable?: boolean;
}
export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps> = ({
explorer,
closePanel,
queryTablesTab,
tableEntityListViewModel,
cassandraApiClient,
}: EditTableEntityPanelProps): JSX.Element => {
const [entities, setEntities] = useState<EntityRowType[]>([]);
const [selectedRow, setSelectedRow] = useState<number>(0);
const [entityAttributeValue, setEntityAttributeValue] = useState<string>("");
const [originalDocument, setOriginalDocument] = useState<Entities.ITableEntity>({});
const [entityAttributeProperty, setEntityAttributeProperty] = useState<string>("");
const [
isEntityValuePanelOpen,
{ setTrue: setIsEntityValuePanelTrue, setFalse: setIsEntityValuePanelFalse },
] = useBoolean(false);
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let originalDocument: { [key: string]: any } = {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const entityAttribute: any = tableEntityListViewModel.selected();
const entityFormattedAttribute = constructDisplayedAttributes(entityAttribute[0]);
setEntities(entityFormattedAttribute);
if (userContext.apiType === "Tables") {
originalDocument = TableEntityProcessor.convertEntitiesToDocuments(entityAttribute, queryTablesTab.collection)[0];
originalDocument.id = (): string => originalDocument.$id;
} else {
originalDocument = entityAttribute;
}
setOriginalDocument(originalDocument);
}, []);
const constructDisplayedAttributes = (entity: Entities.ITableEntity): EntityRowType[] => {
const displayedAttributes: EntityRowType[] = [];
const keys = Object.keys(entity);
keys.length &&
keys.forEach((key: string) => {
if (
key !== TableEntityProcessor.keyProperties.attachments &&
key !== TableEntityProcessor.keyProperties.etag &&
key !== TableEntityProcessor.keyProperties.resourceId &&
key !== TableEntityProcessor.keyProperties.self &&
(userContext.apiType !== "Cassandra" || key !== TableConstants.EntityKeyNames.RowKey)
) {
if (userContext.apiType === "Cassandra") {
const cassandraKeys = queryTablesTab.collection.cassandraKeys.partitionKeys
.concat(queryTablesTab.collection.cassandraKeys.clusteringKeys)
.map((key) => key.property);
const entityAttribute: Entities.ITableEntityAttribute = entity[key];
const entityAttributeType: string = entityAttribute.$;
const displayValue: string = getPropertyDisplayValue(entity, key, entityAttributeType);
const nonEditableType: boolean =
entityAttributeType === TableConstants.CassandraType.Blob ||
entityAttributeType === TableConstants.CassandraType.Inet;
const isDisable = !_.contains<string>(cassandraKeys, key) && !nonEditableType;
const time =
entityAttributeType === TableConstants.TableType.DateTime ? getFormattedTime(displayValue) : "";
displayedAttributes.push({
property: key,
type: entityAttributeType,
value: displayValue,
isPropertyTypeDisable: !nonEditableType,
isDeleteOptionVisible: isDisable,
id: displayedAttributes.length,
entityValuePlaceholder: defaultStringPlaceHolder,
isEntityTypeDate: entityAttributeType === "DateTime",
isEntityValueDisable: !isDisable,
entityTimeValue: time,
});
} else {
const entityAttribute: Entities.ITableEntityAttribute = entity[key];
const entityAttributeType: string = entityAttribute.$;
const displayValue: string = getPropertyDisplayValue(entity, key, entityAttributeType);
const editable: boolean = isAttributeEditable(key, entityAttributeType);
// As per VSO:189935, Binary properties are read-only, we still want to be able to remove them.
const removable: boolean = editable || entityAttributeType === TableConstants.TableType.Binary;
const time =
entityAttributeType === TableConstants.TableType.DateTime ? getFormattedTime(displayValue) : "";
displayedAttributes.push({
property: key,
type: entityAttributeType,
value: displayValue,
isPropertyTypeDisable: !editable,
isDeleteOptionVisible: removable,
id: displayedAttributes.length,
entityValuePlaceholder: defaultStringPlaceHolder,
isEntityTypeDate: entityAttributeType === "DateTime",
isEntityValueDisable: !editable,
entityTimeValue: time,
});
}
}
});
return displayedAttributes;
};
const isAttributeEditable = (attributeName: string, entityAttributeType: string) => {
return !(
attributeName === TableConstants.EntityKeyNames.PartitionKey ||
attributeName === TableConstants.EntityKeyNames.RowKey ||
attributeName === TableConstants.EntityKeyNames.Timestamp ||
// As per VSO:189935, Making Binary properties read-only in Edit Entity dialog until we have a full story for it.
entityAttributeType === TableConstants.TableType.Binary
);
};
const getPropertyDisplayValue = (entity: Entities.ITableEntity, name: string, type: string): string => {
const attribute: Entities.ITableEntityAttribute = entity[name];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let displayValue: any = attribute._;
const isBinary: boolean = type === TableConstants.TableType.Binary;
// Showing the value in base64 for binary properties since that is what the Azure Storage Client Library expects.
// This means that, even if the Azure Storage API returns a byte[] of binary content, it needs that same array
// *base64 - encoded * as the value for the updated property or the whole update operation will fail.
if (isBinary && displayValue && $.isArray(displayValue.data)) {
const bytes: number[] = displayValue.data;
displayValue = getBase64DisplayValue(bytes);
}
return displayValue;
};
const getBase64DisplayValue = (bytes: number[]): string => {
let displayValue = "";
try {
const chars: string[] = bytes.map((byte: number) => String.fromCharCode(byte));
const toEncode: string = chars.join("");
displayValue = window.btoa(toEncode);
} catch (error) {
console.error(error);
}
return displayValue;
};
const submit = async (event: React.FormEvent<HTMLInputElement>): Promise<void> => {
if (!isValidEntities(entities)) {
return undefined;
}
event.preventDefault();
const entity: Entities.ITableEntity = entityFromAttributes(entities);
const tableDataClient = userContext.apiType === "Cassandra" ? cassandraApiClient : explorer.tableDataClient;
const originalDocumentData = userContext.apiType === "Cassandra" ? originalDocument[0] : originalDocument;
const newEntity: Entities.ITableEntity = await tableDataClient.updateDocument(
queryTablesTab.collection,
originalDocumentData,
entity
);
await tableEntityListViewModel.updateCachedEntity(newEntity);
if (!tryInsertNewHeaders(tableEntityListViewModel, newEntity)) {
tableEntityListViewModel.redrawTableThrottled();
}
tableEntityListViewModel.selected.removeAll();
tableEntityListViewModel.selected.push(newEntity);
closePanel();
};
const tryInsertNewHeaders = (viewModel: TableEntityListViewModel, newEntity: Entities.ITableEntity): boolean => {
let newHeaders: string[] = [];
const keys = Object.keys(newEntity);
keys &&
keys.forEach((key: string) => {
if (
!_.contains(viewModel.headers, key) &&
key !== TableEntityProcessor.keyProperties.attachments &&
key !== TableEntityProcessor.keyProperties.etag &&
key !== TableEntityProcessor.keyProperties.resourceId &&
key !== TableEntityProcessor.keyProperties.self &&
(!(userContext.apiType === "Cassandra") || key !== TableConstants.EntityKeyNames.RowKey)
) {
newHeaders.push(key);
}
});
let newHeadersInserted = false;
if (newHeaders.length) {
if (!DataTableUtilities.checkForDefaultHeader(viewModel.headers)) {
newHeaders = viewModel.headers.concat(newHeaders);
}
viewModel.updateHeaders(newHeaders, /* notifyColumnChanges */ true, /* enablePrompt */ false);
newHeadersInserted = true;
}
return newHeadersInserted;
};
// Add new entity row
const addNewEntity = (): void => {
const cloneEntities = [...entities];
cloneEntities.splice(cloneEntities.length, 0, {
property: "",
type: TableConstants.TableType.String,
value: "",
isPropertyTypeDisable: false,
isDeleteOptionVisible: true,
id: cloneEntities.length + 1,
entityValuePlaceholder: "",
isEntityTypeDate: false,
});
setEntities(cloneEntities);
};
// Delete entity row
const deleteEntityAtIndex = (indexToRemove: number): void => {
const cloneEntities = [...entities];
cloneEntities.splice(indexToRemove, 1);
setEntities(cloneEntities);
};
// handle Entity change
const entityChange = (value: string | Date, indexOfInput: number, key: string): void => {
const cloneEntities = [...entities];
if (key === "property") {
cloneEntities[indexOfInput].property = value.toString();
} else if (key === "time") {
cloneEntities[indexOfInput].entityTimeValue = value.toString();
} else {
cloneEntities[indexOfInput].value = value.toString();
}
setEntities(cloneEntities);
};
// handle Entity type
const entityTypeChange = (
_event: React.FormEvent<HTMLDivElement>,
selectedType: IDropdownOption,
indexOfEntity: number
): void => {
const entityValuePlaceholder = getEntityValuePlaceholder(selectedType.key);
const cloneEntities = [...entities];
cloneEntities[indexOfEntity].type = selectedType.key.toString();
cloneEntities[indexOfEntity].entityValuePlaceholder = entityValuePlaceholder;
cloneEntities[indexOfEntity].isEntityTypeDate = selectedType.key === TableConstants.TableType.DateTime;
setEntities(cloneEntities);
};
// Open edit entity value modal
const editEntity = (rowEndex: number): void => {
const entityAttribute: EntityRowType = entities[rowEndex] && entities[rowEndex];
setEntityAttributeValue(entityAttribute.value);
setEntityAttributeProperty(entityAttribute.property);
setSelectedRow(rowEndex);
setIsEntityValuePanelTrue();
};
const renderPanelContent = (): JSX.Element => {
return (
<form className="panelFormWrapper">
<div className="panelFormWrapper">
<div className="panelMainContent">
{entities.map((entity, index) => {
return (
<TableEntity
key={"" + entity.id + index}
isDeleteOptionVisible={entity.isDeleteOptionVisible}
entityTypeLabel={index === 0 && dataTypeLabel}
entityPropertyLabel={index === 0 && attributeNameLabel}
entityValueLabel={index === 0 && attributeValueLabel}
options={userContext.apiType === "Cassandra" ? cassandraOptions : options}
isPropertyTypeDisable={entity.isPropertyTypeDisable}
entityProperty={entity.property}
selectedKey={entity.type}
entityPropertyPlaceHolder={detailedHelp}
entityValuePlaceholder={entity.entityValuePlaceholder}
entityValue={entity.value}
isEntityTypeDate={entity.isEntityTypeDate}
entityTimeValue={entity.entityTimeValue}
isEntityValueDisable={entity.isEntityValueDisable}
onEditEntity={() => editEntity(index)}
onSelectDate={(date: Date) => {
entityChange(date, index, "value");
}}
onDeleteEntity={() => deleteEntityAtIndex(index)}
onEntityPropertyChange={(event, newInput?: string) => {
entityChange(newInput, index, "property");
}}
onEntityTypeChange={(event: React.FormEvent<HTMLDivElement>, selectedParam: IDropdownOption) => {
entityTypeChange(event, selectedParam, index);
}}
onEntityValueChange={(event, newInput?: string) => {
entityChange(newInput, index, "value");
}}
onEntityTimeValueChange={(event, newInput?: string) => {
entityChange(newInput, index, "time");
}}
/>
);
})}
{userContext.apiType !== "Cassandra" && (
<Stack horizontal onClick={addNewEntity} className="addButtonEntiy">
<Image {...imageProps} src={AddPropertyIcon} alt="Add Entity" />
<Text className="addNewParamStyle">{getAddButtonLabel(userContext.apiType)}</Text>
</Stack>
)}
</div>
{renderPanelFooter()}
</div>
</form>
);
};
const renderPanelFooter = (): JSX.Element => {
return (
<div className="paneFooter">
<div className="leftpanel-okbut">
<input type="submit" onClick={submit} className="genericPaneSubmitBtn" value="Update Entity" />
</div>
</div>
);
};
const onRenderNavigationContent: IRenderFunction<IPanelProps> = () => (
<Stack horizontal {...columnProps}>
<Image {...backImageProps} src={RevertBackIcon} alt="back" onClick={() => setIsEntityValuePanelFalse()} />
<Label>{entityAttributeProperty}</Label>
</Stack>
);
if (isEntityValuePanelOpen) {
return (
<PanelContainerComponent
headerText=""
onRenderNavigationContent={onRenderNavigationContent}
panelWidth="700px"
isOpen={true}
panelContent={
<TextField
multiline
rows={5}
className="entityValueTextField"
value={entityAttributeValue}
onChange={(event, newInput?: string) => {
setEntityAttributeValue(newInput);
entityChange(newInput, selectedRow, "value");
}}
/>
}
closePanel={() => closePanel()}
isConsoleExpanded={false}
/>
);
}
return (
<PanelContainerComponent
headerText="Edit Table Entity"
panelWidth="700px"
isOpen={true}
panelContent={renderPanelContent()}
closePanel={() => closePanel()}
isConsoleExpanded={false}
/>
);
};

View File

@ -5,28 +5,6 @@ import * as Entities from "../../../Tables/Entities";
import * as Utilities from "../../../Tables/Utilities"; import * as Utilities from "../../../Tables/Utilities";
export const defaultStringPlaceHolder = "Enter identifier value."; export const defaultStringPlaceHolder = "Enter identifier value.";
export const defaultEntities = [
{
property: "PartitionKey",
type: "String",
value: "",
isPropertyTypeDisable: true,
isDeleteOptionVisible: false,
id: 1,
entityValuePlaceholder: defaultStringPlaceHolder,
isEntityTypeDate: false,
},
{
property: "RowKey",
type: "String",
value: "",
isPropertyTypeDisable: true,
isDeleteOptionVisible: false,
id: 2,
entityValuePlaceholder: defaultStringPlaceHolder,
isEntityTypeDate: false,
},
];
// Dropdown options // Dropdown options
const { String, Boolean, Binary, DateTime, Double, Guid, Int32, Int64 } = TableConstants.TableType; const { String, Boolean, Binary, DateTime, Double, Guid, Int32, Int64 } = TableConstants.TableType;
@ -133,20 +111,21 @@ export const entityFromAttributes = (entities: EntityRowType[]): Entities.ITable
// GetPlaceholder according to entity type // GetPlaceholder according to entity type
export const getEntityValuePlaceholder = (entityType: string | number): string => { export const getEntityValuePlaceholder = (entityType: string | number): string => {
const { String, Boolean, DateTime, Double, Guid, Int32, Int64 } = TableConstants.TableType;
switch (entityType) { switch (entityType) {
case "String": case String:
return stringPlaceholder; return stringPlaceholder;
case "Boolean": case Boolean:
return booleanPlaceHolder; return booleanPlaceHolder;
case "DateTime": case DateTime:
return datePlaceholder; return datePlaceholder;
case "Double": case Double:
return doublePlaceholder; return doublePlaceholder;
case "Guid": case Guid:
return guidPlaceholder; return guidPlaceholder;
case "Int32": case Int32:
return intPlaceholder; return intPlaceholder;
case "Int64": case Int64:
return int64Placeholder; return int64Placeholder;
default: default:
return ""; return "";
@ -164,13 +143,13 @@ export const isValidEntities = (entities: EntityRowType[]): boolean => {
}; };
const isEntityPropertyTypeDisable = (header: string): boolean => { const isEntityPropertyTypeDisable = (header: string): boolean => {
if (header === "PartitionKey" || header === "RowKey") { if (header === TableConstants.EntityKeyNames.PartitionKey || header === TableConstants.EntityKeyNames.RowKey) {
return true; return true;
} }
return false; return false;
}; };
export const getDefaultEntities = (headers: string[], entityTypes: { [key: string]: string }): EntityRowType[] => { export const getDefaultEntities = (headers: string[], entityTypes: EntityType): EntityRowType[] => {
const defaultEntities: EntityRowType[] = []; const defaultEntities: EntityRowType[] = [];
headers.forEach((header: string) => { headers.forEach((header: string) => {
if (header !== "Timestamp") { if (header !== "Timestamp") {
@ -183,7 +162,7 @@ export const getDefaultEntities = (headers: string[], entityTypes: { [key: strin
isDeleteOptionVisible: !isEntityPropertyTypeDisable(header), isDeleteOptionVisible: !isEntityPropertyTypeDisable(header),
id: 1, id: 1,
entityValuePlaceholder: defaultStringPlaceHolder, entityValuePlaceholder: defaultStringPlaceHolder,
isEntityTypeDate: entityType === "DateTime", isEntityTypeDate: entityType === TableConstants.TableType.DateTime,
}; };
defaultEntities.push(entityRow); defaultEntities.push(entityRow);
} }
@ -212,6 +191,13 @@ export const getButtonLabel = (apiType: string): string => {
return "Add Entity"; return "Add Entity";
}; };
export const getFormattedTime = (displayValue: string): string => {
const date = new Date(displayValue);
const minutes = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes();
const hours = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours();
return `${hours}:${minutes}`;
};
export const getCassandraDefaultEntities = ( export const getCassandraDefaultEntities = (
headers: string[], headers: string[],
entityTypes: { [key: string]: string } entityTypes: { [key: string]: string }
@ -244,4 +230,9 @@ export interface EntityRowType {
entityValuePlaceholder: string; entityValuePlaceholder: string;
isEntityTypeDate: boolean; isEntityTypeDate: boolean;
entityTimeValue?: string; entityTimeValue?: string;
isEntityValueDisable?: boolean;
}
export interface EntityType {
[key: string]: string;
} }

File diff suppressed because it is too large Load Diff

View File

@ -153,40 +153,6 @@ exports[`Upload Items Pane should render Default properly 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -455,40 +421,6 @@ exports[`Upload Items Pane should render Default properly 1`] = `
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],

View File

@ -154,40 +154,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
CassandraAddCollectionPane { CassandraAddCollectionPane {
"autoPilotUsageCost": [Function], "autoPilotUsageCost": [Function],
"canConfigureThroughput": [Function], "canConfigureThroughput": [Function],
@ -456,40 +422,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
"defaultExperience": [Function], "defaultExperience": [Function],
"deleteCollectionText": [Function], "deleteCollectionText": [Function],
"deleteDatabaseText": [Function], "deleteDatabaseText": [Function],
"editTableEntityPane": EditTableEntityPane {
"addButtonLabel": "Add Property",
"attributeNameLabel": "Property Name",
"attributeValueLabel": "Value",
"canAdd": [Function],
"canApply": [Function],
"container": [Circular],
"dataTypeLabel": "Type",
"displayedAttributes": [Function],
"editAttribute": [Function],
"editButtonLabel": "Edit",
"editingProperty": [Function],
"edmTypes": [Function],
"finishEditingAttribute": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "edittableentitypane",
"insertAttribute": [Function],
"isEditing": [Function],
"isExecuting": [Function],
"isTemplateReady": [Function],
"onAddPropertyKeyDown": [Function],
"onBackButtonKeyDown": [Function],
"onDeletePropertyKeyDown": [Function],
"onEditPropertyKeyDown": [Function],
"onKeyUp": [Function],
"removeAttribute": [Function],
"removeButtonLabel": "Remove",
"scrollId": [Function],
"submitButtonText": [Function],
"title": [Function],
"visible": [Function],
},
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
"container": [Circular], "container": [Circular],
"firstFieldHasFocus": [Function], "firstFieldHasFocus": [Function],

View File

@ -58,10 +58,6 @@ export default class TableCommands {
var entityToUpdate: Entities.ITableEntity = viewModel.selected()[0]; var entityToUpdate: Entities.ITableEntity = viewModel.selected()[0];
var originalNumberOfProperties = entityToUpdate ? 0 : Object.keys(entityToUpdate).length - 1; // .metadata is always a property for etag var originalNumberOfProperties = entityToUpdate ? 0 : Object.keys(entityToUpdate).length - 1; // .metadata is always a property for etag
this._container.editTableEntityPane.originEntity = entityToUpdate;
this._container.editTableEntityPane.tableViewModel = viewModel;
this._container.editTableEntityPane.originalNumberOfProperties = originalNumberOfProperties;
this._container.editTableEntityPane.open();
return null; return null;
} }

View File

@ -151,7 +151,7 @@ export default class QueryTablesTab extends TabsBase {
}; };
public onEditEntityClick = (): Q.Promise<any> => { public onEditEntityClick = (): Q.Promise<any> => {
this.tableCommands.editEntityCommand(this.tableEntityListViewModel()); this.container.openEditTableEntityPanel(this, this.tableEntityListViewModel());
return null; return null;
}; };

View File

@ -231,7 +231,6 @@ const App: React.FunctionComponent = () => {
<div data-bind='component: { name: "add-database-pane", params: {data: addDatabasePane} }' /> <div data-bind='component: { name: "add-database-pane", params: {data: addDatabasePane} }' />
<div data-bind='component: { name: "add-collection-pane", params: { data: addCollectionPane} }' /> <div data-bind='component: { name: "add-collection-pane", params: { data: addCollectionPane} }' />
<div data-bind='component: { name: "graph-styling-pane", params: { data: graphStylingPane} }' /> <div data-bind='component: { name: "graph-styling-pane", params: { data: graphStylingPane} }' />
<div data-bind='component: { name: "table-edit-entity-pane", params: { data: editTableEntityPane} }' />
<div data-bind='component: { name: "cassandra-add-collection-pane", params: { data: cassandraAddCollectionPane} }' /> <div data-bind='component: { name: "cassandra-add-collection-pane", params: { data: cassandraAddCollectionPane} }' />
<div data-bind='component: { name: "string-input-pane", params: { data: stringInputPane} }' /> <div data-bind='component: { name: "string-input-pane", params: { data: stringInputPane} }' />
<KOCommentIfStart if="isGitHubPaneEnabled" /> <KOCommentIfStart if="isGitHubPaneEnabled" />