mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 06:56:38 +00:00
Migration/edit table entity panel to react (#690)
Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
parent
ab283cb8ff
commit
67062c18aa
@ -6,6 +6,7 @@ export interface TableEntityProps {
|
||||
entityValuePlaceholder: string;
|
||||
entityValue: string | Date;
|
||||
isEntityTypeDate: boolean;
|
||||
isEntityValueDisable?: boolean;
|
||||
entityTimeValue: string;
|
||||
entityValueType: string;
|
||||
onEntityValueChange: (event: React.FormEvent<HTMLElement>, newInput?: string) => void;
|
||||
@ -22,6 +23,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
|
||||
entityValueType,
|
||||
onEntityValueChange,
|
||||
onSelectDate,
|
||||
isEntityValueDisable,
|
||||
onEntityTimeValueChange,
|
||||
}: TableEntityProps): JSX.Element => {
|
||||
if (isEntityTypeDate) {
|
||||
@ -33,6 +35,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
|
||||
value={entityValue && new Date(entityValue)}
|
||||
ariaLabel={entityValuePlaceholder}
|
||||
onSelectDate={onSelectDate}
|
||||
disabled={isEntityValueDisable}
|
||||
/>
|
||||
<TextField
|
||||
label={entityValueLabel && entityValueLabel}
|
||||
@ -41,6 +44,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
|
||||
type="time"
|
||||
value={entityTimeValue}
|
||||
onChange={onEntityTimeValueChange}
|
||||
disabled={isEntityValueDisable}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@ -52,6 +56,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
|
||||
className="addEntityTextField"
|
||||
id="entityValueId"
|
||||
autoFocus
|
||||
disabled={isEntityValueDisable}
|
||||
type={entityValueType}
|
||||
placeholder={entityValuePlaceholder}
|
||||
value={typeof entityValue === "string" && entityValue}
|
||||
|
@ -32,6 +32,7 @@ export interface TableEntityProps {
|
||||
options: { key: string; text: string }[];
|
||||
isPropertyTypeDisable: boolean;
|
||||
entityTimeValue: string;
|
||||
isEntityValueDisable?: boolean;
|
||||
onDeleteEntity?: () => void;
|
||||
onEditEntity?: () => void;
|
||||
onEntityPropertyChange: (event: React.FormEvent<HTMLElement>, newInput?: string) => void;
|
||||
@ -55,6 +56,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
|
||||
isPropertyTypeDisable,
|
||||
isEntityTypeDate,
|
||||
entityTimeValue,
|
||||
isEntityValueDisable,
|
||||
onEditEntity,
|
||||
onDeleteEntity,
|
||||
onEntityPropertyChange,
|
||||
@ -113,6 +115,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
|
||||
<EntityValue
|
||||
entityValueLabel={entityValueLabel}
|
||||
entityValueType={getEntityValueType()}
|
||||
isEntityValueDisable={isEntityValueDisable}
|
||||
entityValuePlaceholder={entityValuePlaceholder}
|
||||
entityValue={entityValue}
|
||||
isEntityTypeDate={isEntityTypeDate}
|
||||
@ -121,10 +124,11 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
|
||||
onSelectDate={onSelectDate}
|
||||
onEntityTimeValueChange={onEntityTimeValueChange}
|
||||
/>
|
||||
<TooltipHost content="Edit property" id="editTooltip">
|
||||
<Image {...imageProps} src={EditIcon} alt="editEntity" id="editEntity" onClick={onEditEntity} />
|
||||
</TooltipHost>
|
||||
|
||||
{!isEntityValueDisable && (
|
||||
<TooltipHost content="Edit property" id="editTooltip">
|
||||
<Image {...imageProps} src={EditIcon} alt="editEntity" id="editEntity" onClick={onEditEntity} />
|
||||
</TooltipHost>
|
||||
)}
|
||||
{isDeleteOptionVisible && userContext.apiType !== "Cassandra" && (
|
||||
<TooltipHost content="Delete property" id="deleteTooltip">
|
||||
<Image {...imageProps} src={DeleteIcon} alt="delete entity" id="deleteEntity" onClick={onDeleteEntity} />
|
||||
|
@ -177,40 +177,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -479,40 +445,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
@ -805,40 +737,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -1107,40 +1005,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
@ -1446,40 +1310,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -1748,40 +1578,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
@ -2074,40 +1870,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -2376,40 +2138,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
|
@ -66,7 +66,7 @@ import { SettingsPane } from "./Panes/SettingsPane/SettingsPane";
|
||||
import { SetupNoteBooksPanel } from "./Panes/SetupNotebooksPanel/SetupNotebooksPanel";
|
||||
import { StringInputPane } from "./Panes/StringInputPane";
|
||||
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 { UploadFilePane } from "./Panes/UploadFilePane/UploadFilePane";
|
||||
import { UploadItemsPane } from "./Panes/UploadItemsPane/UploadItemsPane";
|
||||
@ -173,7 +173,6 @@ export default class Explorer {
|
||||
public addDatabasePane: AddDatabasePane;
|
||||
public addCollectionPane: AddCollectionPane;
|
||||
public graphStylingPane: GraphStylingPane;
|
||||
public editTableEntityPane: EditTableEntityPane;
|
||||
public cassandraAddCollectionPane: CassandraAddCollectionPane;
|
||||
public stringInputPane: StringInputPane;
|
||||
public gitHubReposPane: ContextualPaneBase;
|
||||
@ -500,13 +499,6 @@ export default class Explorer {
|
||||
container: this,
|
||||
});
|
||||
|
||||
this.editTableEntityPane = new EditTableEntityPane({
|
||||
id: "edittableentitypane",
|
||||
visible: ko.observable<boolean>(false),
|
||||
|
||||
container: this,
|
||||
});
|
||||
|
||||
this.cassandraAddCollectionPane = new CassandraAddCollectionPane({
|
||||
id: "cassandraaddcollectionpane",
|
||||
visible: ko.observable<boolean>(false),
|
||||
@ -533,7 +525,6 @@ export default class Explorer {
|
||||
this.addDatabasePane,
|
||||
this.addCollectionPane,
|
||||
this.graphStylingPane,
|
||||
this.editTableEntityPane,
|
||||
this.cassandraAddCollectionPane,
|
||||
this.stringInputPane,
|
||||
];
|
||||
@ -604,7 +595,6 @@ export default class Explorer {
|
||||
this.addCollectionPane.collectionIdTitle("Table id");
|
||||
this.addCollectionPane.collectionWithThroughputInSharedTitle("Provision dedicated throughput for this table");
|
||||
this.refreshTreeTitle("Refresh tables");
|
||||
this.editTableEntityPane.title("Edit Table Entity");
|
||||
this.tableDataClient = new TablesAPIDataClient();
|
||||
break;
|
||||
case "Cassandra":
|
||||
@ -618,7 +608,6 @@ export default class Explorer {
|
||||
this.addCollectionPane.collectionIdTitle("Table id");
|
||||
this.addCollectionPane.collectionWithThroughputInSharedTitle("Provision dedicated throughput for this table");
|
||||
this.refreshTreeTitle("Refresh tables");
|
||||
this.editTableEntityPane.title("Edit Table Row");
|
||||
this.tableDataClient = new CassandraAPIDataClient();
|
||||
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 {
|
||||
this.openSidePanel(
|
||||
"Select Column",
|
||||
|
@ -153,40 +153,6 @@ exports[`Settings Pane should render Default properly 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -455,40 +421,6 @@ exports[`Settings Pane should render Default properly 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
@ -904,40 +836,6 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -1206,40 +1104,6 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
|
51
src/Explorer/Panes/Tables/EditTableEntityPanel.test.tsx
Normal file
51
src/Explorer/Panes/Tables/EditTableEntityPanel.test.tsx
Normal 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);
|
||||
});
|
||||
});
|
419
src/Explorer/Panes/Tables/EditTableEntityPanel.tsx
Normal file
419
src/Explorer/Panes/Tables/EditTableEntityPanel.tsx
Normal 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}
|
||||
/>
|
||||
);
|
||||
};
|
@ -5,28 +5,6 @@ import * as Entities from "../../../Tables/Entities";
|
||||
import * as Utilities from "../../../Tables/Utilities";
|
||||
|
||||
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
|
||||
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
|
||||
export const getEntityValuePlaceholder = (entityType: string | number): string => {
|
||||
const { String, Boolean, DateTime, Double, Guid, Int32, Int64 } = TableConstants.TableType;
|
||||
switch (entityType) {
|
||||
case "String":
|
||||
case String:
|
||||
return stringPlaceholder;
|
||||
case "Boolean":
|
||||
case Boolean:
|
||||
return booleanPlaceHolder;
|
||||
case "DateTime":
|
||||
case DateTime:
|
||||
return datePlaceholder;
|
||||
case "Double":
|
||||
case Double:
|
||||
return doublePlaceholder;
|
||||
case "Guid":
|
||||
case Guid:
|
||||
return guidPlaceholder;
|
||||
case "Int32":
|
||||
case Int32:
|
||||
return intPlaceholder;
|
||||
case "Int64":
|
||||
case Int64:
|
||||
return int64Placeholder;
|
||||
default:
|
||||
return "";
|
||||
@ -164,13 +143,13 @@ export const isValidEntities = (entities: EntityRowType[]): boolean => {
|
||||
};
|
||||
|
||||
const isEntityPropertyTypeDisable = (header: string): boolean => {
|
||||
if (header === "PartitionKey" || header === "RowKey") {
|
||||
if (header === TableConstants.EntityKeyNames.PartitionKey || header === TableConstants.EntityKeyNames.RowKey) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getDefaultEntities = (headers: string[], entityTypes: { [key: string]: string }): EntityRowType[] => {
|
||||
export const getDefaultEntities = (headers: string[], entityTypes: EntityType): EntityRowType[] => {
|
||||
const defaultEntities: EntityRowType[] = [];
|
||||
headers.forEach((header: string) => {
|
||||
if (header !== "Timestamp") {
|
||||
@ -183,7 +162,7 @@ export const getDefaultEntities = (headers: string[], entityTypes: { [key: strin
|
||||
isDeleteOptionVisible: !isEntityPropertyTypeDisable(header),
|
||||
id: 1,
|
||||
entityValuePlaceholder: defaultStringPlaceHolder,
|
||||
isEntityTypeDate: entityType === "DateTime",
|
||||
isEntityTypeDate: entityType === TableConstants.TableType.DateTime,
|
||||
};
|
||||
defaultEntities.push(entityRow);
|
||||
}
|
||||
@ -212,6 +191,13 @@ export const getButtonLabel = (apiType: string): string => {
|
||||
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 = (
|
||||
headers: string[],
|
||||
entityTypes: { [key: string]: string }
|
||||
@ -244,4 +230,9 @@ export interface EntityRowType {
|
||||
entityValuePlaceholder: string;
|
||||
isEntityTypeDate: boolean;
|
||||
entityTimeValue?: string;
|
||||
isEntityValueDisable?: boolean;
|
||||
}
|
||||
|
||||
export interface EntityType {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -153,40 +153,6 @@ exports[`Upload Items Pane should render Default properly 1`] = `
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -455,40 +421,6 @@ exports[`Upload Items Pane should render Default properly 1`] = `
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
|
@ -154,40 +154,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
||||
"title": [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 {
|
||||
"autoPilotUsageCost": [Function],
|
||||
"canConfigureThroughput": [Function],
|
||||
@ -456,40 +422,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
|
@ -58,10 +58,6 @@ export default class TableCommands {
|
||||
var entityToUpdate: Entities.ITableEntity = viewModel.selected()[0];
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ export default class QueryTablesTab extends TabsBase {
|
||||
};
|
||||
|
||||
public onEditEntityClick = (): Q.Promise<any> => {
|
||||
this.tableCommands.editEntityCommand(this.tableEntityListViewModel());
|
||||
this.container.openEditTableEntityPanel(this, this.tableEntityListViewModel());
|
||||
return null;
|
||||
};
|
||||
|
||||
|
@ -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-collection-pane", params: { data: addCollectionPane} }' />
|
||||
<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: "string-input-pane", params: { data: stringInputPane} }' />
|
||||
<KOCommentIfStart if="isGitHubPaneEnabled" />
|
||||
|
Loading…
Reference in New Issue
Block a user