+ {userContext.authType !== AuthType.ResourceToken && databases.length > 0 && (
+
+
setSearchText(data?.value || "")}
+ size="small"
+ contentBefore={
}
+ style={{ flex: 1 }}
+ />
+
:
}
+ onClick={toggleSortOrder}
+ />
+
+ )}
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "standardCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "Open Cassandra Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Table",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "",
- "isSelected": [Function],
- "label": "Rows",
- "onClick": [Function],
- },
- {
- "isSelected": [Function],
- "label": "Conflicts",
- "onClick": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "Open Cassandra Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Table",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "conflictsCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Table",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Keyspace",
- "onClick": [Function],
- "styleClass": "deleteDatabaseMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "standardDb",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "children": [
- {
- "iconSrc":
,
- "id": "",
- "isSelected": [Function],
- "label": "Scale",
- "onClick": [Function],
- },
- {
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "Open Cassandra Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Table",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "sampleItems",
- "isSelected": [Function],
- "label": "Rows",
- "onClick": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "Open Cassandra Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Table",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sampleItemsCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Table",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Keyspace",
- "onClick": [Function],
- "styleClass": "deleteDatabaseMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sharedDatabase",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
{
"children": [
{
@@ -323,6 +114,11 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
],
"className": "databaseNode",
"contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
{
"iconSrc": {},
"label": "New Table",
@@ -345,6 +141,225 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
+ {
+ "children": [
+ {
+ "iconSrc":
,
+ "id": "",
+ "isSelected": [Function],
+ "label": "Scale",
+ "onClick": [Function],
+ },
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Open Cassandra Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Table",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "sampleItems",
+ "isSelected": [Function],
+ "label": "Rows",
+ "onClick": [Function],
+ },
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Open Cassandra Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Table",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sampleItemsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Table",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Keyspace",
+ "onClick": [Function],
+ "styleClass": "deleteDatabaseMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sharedDatabase",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Open Cassandra Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Table",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "",
+ "isSelected": [Function],
+ "label": "Rows",
+ "onClick": [Function],
+ },
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Open Cassandra Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Table",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "standardCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Open Cassandra Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Table",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "",
+ "isSelected": [Function],
+ "label": "Rows",
+ "onClick": [Function],
+ },
+ {
+ "isSelected": [Function],
+ "label": "Conflicts",
+ "onClick": [Function],
+ },
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Open Cassandra Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Table",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "conflictsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Table",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Keyspace",
+ "onClick": [Function],
+ "styleClass": "deleteDatabaseMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "standardDb",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
]
`;
@@ -384,6 +399,61 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
"label": "Scale & Settings",
"onClick": [Function],
},
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "label": "string",
+ },
+ {
+ "label": "HasNulls: false",
+ },
+ ],
+ "label": "street",
+ },
+ {
+ "children": [
+ {
+ "label": "string",
+ },
+ {
+ "label": "HasNulls: true",
+ },
+ ],
+ "label": "line2",
+ },
+ {
+ "children": [
+ {
+ "label": "number",
+ },
+ {
+ "label": "HasNulls: false",
+ },
+ ],
+ "label": "zip",
+ },
+ ],
+ "label": "address",
+ },
+ {
+ "children": [
+ {
+ "label": "string",
+ },
+ {
+ "label": "HasNulls: false",
+ },
+ ],
+ "label": "orderId",
+ },
+ ],
+ "label": "Schema",
+ "onClick": [Function],
+ },
],
"className": "collectionNode",
"contextMenu": [
@@ -409,83 +479,25 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
/>,
"isExpanded": true,
"isSelected": [Function],
- "label": "standardCollection",
+ "label": "schemaCollection",
"onClick": [Function],
"onCollapsed": [Function],
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
{
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Open Mongo Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Collection",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "",
- "isSelected": [Function],
- "label": "Documents",
- "onClick": [Function],
- },
- {
- "id": "",
- "isSelected": [Function],
- "label": "Scale & Settings",
- "onClick": [Function],
- },
- {
- "isSelected": [Function],
- "label": "Conflicts",
- "onClick": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Open Mongo Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Collection",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "conflictsCollection",
+ "className": "loadMoreNode",
+ "label": "load more",
"onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
},
],
"className": "databaseNode",
"contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
{
"iconSrc": {},
"label": "New Collection",
@@ -503,7 +515,7 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
/>,
"isExpanded": true,
"isSelected": [Function],
- "label": "standardDb",
+ "label": "giganticDatabase",
"onCollapsed": [Function],
"onContextMenuOpen": [Function],
"onExpanded": [Function],
@@ -585,6 +597,11 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
],
"className": "databaseNode",
"contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
{
"iconSrc": {},
"label": "New Collection",
@@ -641,6 +658,169 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
"label": "Scale & Settings",
"onClick": [Function],
},
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Open Mongo Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Collection",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "standardCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Open Mongo Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Collection",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "",
+ "isSelected": [Function],
+ "label": "Documents",
+ "onClick": [Function],
+ },
+ {
+ "id": "",
+ "isSelected": [Function],
+ "label": "Scale & Settings",
+ "onClick": [Function],
+ },
+ {
+ "isSelected": [Function],
+ "label": "Conflicts",
+ "onClick": [Function],
+ },
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Open Mongo Shell",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Collection",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "conflictsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Collection",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Database",
+ "onClick": [Function],
+ "styleClass": "deleteDatabaseMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "standardDb",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+]
+`;
+
+exports[`createDatabaseTreeNodes generates the correct tree structure for the SQL API, on Fabric non read-only (native) 1`] = `
+[
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "",
+ "isSelected": [Function],
+ "label": "Items",
+ "onClick": [Function],
+ },
+ {
+ "id": "",
+ "isSelected": [Function],
+ "label": "Settings",
+ "onClick": [Function],
+ },
{
"children": [
{
@@ -701,17 +881,12 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
"contextMenu": [
{
"iconSrc": {},
- "label": "New Query",
+ "label": "New SQL Query",
"onClick": [Function],
},
{
"iconSrc": {},
- "label": "Open Mongo Shell",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Collection",
+ "label": "Delete Container",
"onClick": [Function],
"styleClass": "deleteCollectionMenuItem",
},
@@ -737,14 +912,13 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
"contextMenu": [
{
"iconSrc": {},
- "label": "New Collection",
+ "label": "Pin to top",
"onClick": [Function],
},
{
"iconSrc": {},
- "label": "Delete Database",
+ "label": "New Container",
"onClick": [Function],
- "styleClass": "deleteDatabaseMenuItem",
},
],
"iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sampleItemsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Container",
+ "onClick": [Function],
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sharedDatabase",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
{
"children": [
{
@@ -878,6 +1126,11 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
],
"className": "databaseNode",
"contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
{
"iconSrc": {},
"label": "New Container",
@@ -894,36 +1147,15 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
+]
+`;
+
+exports[`createDatabaseTreeNodes generates the correct tree structure for the SQL API, on Fabric read-only (mirrored) 1`] = `
+[
{
"children": [
{
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "sampleItems",
- "isSelected": [Function],
- "label": "Items",
- "onClick": [Function],
- },
- {
- "id": "sampleSettings",
- "isSelected": [Function],
- "label": "Settings",
- "onClick": [Function],
- },
- ],
+ "children": undefined,
"className": "collectionNode",
"contextMenu": [
{
@@ -931,141 +1163,6 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"label": "New SQL Query",
"onClick": [Function],
},
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sampleItemsCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Container",
- "onClick": [Function],
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sharedDatabase",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "children": [
- {
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "",
- "isSelected": [Function],
- "label": "Items",
- "onClick": [Function],
- },
- {
- "id": "",
- "isSelected": [Function],
- "label": "Settings",
- "onClick": [Function],
- },
- {
- "children": [
- {
- "children": [
- {
- "children": [
- {
- "label": "string",
- },
- {
- "label": "HasNulls: false",
- },
- ],
- "label": "street",
- },
- {
- "children": [
- {
- "label": "string",
- },
- {
- "label": "HasNulls: true",
- },
- ],
- "label": "line2",
- },
- {
- "children": [
- {
- "label": "number",
- },
- {
- "label": "HasNulls: false",
- },
- ],
- "label": "zip",
- },
- ],
- "label": "address",
- },
- {
- "children": [
- {
- "label": "string",
- },
- {
- "label": "HasNulls: false",
- },
- ],
- "label": "orderId",
- },
- ],
- "label": "Schema",
- "onClick": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
],
"iconSrc":
,
@@ -1102,11 +1193,42 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
-]
-`;
-
-exports[`createDatabaseTreeNodes generates the correct tree structure for the SQL API, on Fabric read-only (mirrored) 1`] = `
-[
+ {
+ "children": [
+ {
+ "children": undefined,
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sampleItemsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": undefined,
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sharedDatabase",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
{
"children": [
{
@@ -1164,10 +1286,126 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
+]
+`;
+
+exports[`createDatabaseTreeNodes generates the correct tree structure for the SQL API, on Portal 1`] = `
+[
{
"children": [
{
- "children": undefined,
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Stored Procedure",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New UDF",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Trigger",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "",
+ "isSelected": [Function],
+ "label": "Items",
+ "onClick": [Function],
+ },
+ {
+ "id": "",
+ "isSelected": [Function],
+ "label": "Scale & Settings",
+ "onClick": [Function],
+ },
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "label": "string",
+ },
+ {
+ "label": "HasNulls: false",
+ },
+ ],
+ "label": "street",
+ },
+ {
+ "children": [
+ {
+ "label": "string",
+ },
+ {
+ "label": "HasNulls: true",
+ },
+ ],
+ "label": "line2",
+ },
+ {
+ "children": [
+ {
+ "label": "number",
+ },
+ {
+ "label": "HasNulls: false",
+ },
+ ],
+ "label": "zip",
+ },
+ ],
+ "label": "address",
+ },
+ {
+ "children": [
+ {
+ "label": "string",
+ },
+ {
+ "label": "HasNulls: false",
+ },
+ ],
+ "label": "orderId",
+ },
+ ],
+ "label": "Schema",
+ "onClick": [Function],
+ },
+ {
+ "children": [],
+ "label": "Stored Procedures",
+ "onExpanded": [Function],
+ },
+ {
+ "children": [],
+ "label": "User Defined Functions",
+ "onExpanded": [Function],
+ },
+ {
+ "children": [],
+ "label": "Triggers",
+ "onExpanded": [Function],
+ },
+ ],
"className": "collectionNode",
"contextMenu": [
{
@@ -1175,42 +1413,27 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"label": "New SQL Query",
"onClick": [Function],
},
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sampleItemsCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": undefined,
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sharedDatabase",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "children": [
- {
- "children": undefined,
- "className": "collectionNode",
- "contextMenu": [
{
"iconSrc": {},
- "label": "New SQL Query",
+ "label": "New Stored Procedure",
"onClick": [Function],
},
+ {
+ "iconSrc": {},
+ "label": "New UDF",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Trigger",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
],
"iconSrc":
,
@@ -1241,11 +1481,145 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
-]
-`;
-
-exports[`createDatabaseTreeNodes generates the correct tree structure for the SQL API, on Portal 1`] = `
-[
+ {
+ "children": [
+ {
+ "iconSrc":
,
+ "id": "",
+ "isSelected": [Function],
+ "label": "Scale",
+ "onClick": [Function],
+ },
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Stored Procedure",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New UDF",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Trigger",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "sampleItems",
+ "isSelected": [Function],
+ "label": "Items",
+ "onClick": [Function],
+ },
+ {
+ "id": "sampleSettings",
+ "isSelected": [Function],
+ "label": "Settings",
+ "onClick": [Function],
+ },
+ {
+ "children": [],
+ "label": "Stored Procedures",
+ "onExpanded": [Function],
+ },
+ {
+ "children": [],
+ "label": "User Defined Functions",
+ "onExpanded": [Function],
+ },
+ {
+ "children": [],
+ "label": "Triggers",
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Stored Procedure",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New UDF",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Trigger",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sampleItemsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Container",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Database",
+ "onClick": [Function],
+ "styleClass": "deleteDatabaseMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sharedDatabase",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
{
"children": [
{
@@ -1491,6 +1865,11 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
],
"className": "databaseNode",
"contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
{
"iconSrc": {},
"label": "New Container",
@@ -1513,140 +1892,11 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
- {
- "children": [
- {
- "iconSrc":
,
- "id": "",
- "isSelected": [Function],
- "label": "Scale",
- "onClick": [Function],
- },
- {
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Stored Procedure",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New UDF",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Trigger",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "sampleItems",
- "isSelected": [Function],
- "label": "Items",
- "onClick": [Function],
- },
- {
- "id": "sampleSettings",
- "isSelected": [Function],
- "label": "Settings",
- "onClick": [Function],
- },
- {
- "children": [],
- "label": "Stored Procedures",
- "onExpanded": [Function],
- },
- {
- "children": [],
- "label": "User Defined Functions",
- "onExpanded": [Function],
- },
- {
- "children": [],
- "label": "Triggers",
- "onExpanded": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Stored Procedure",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New UDF",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Trigger",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sampleItemsCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Container",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Database",
- "onClick": [Function],
- "styleClass": "deleteDatabaseMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sharedDatabase",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
+]
+`;
+
+exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expected tree 1`] = `
+[
{
"children": [
{
@@ -1810,6 +2060,11 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
],
"className": "databaseNode",
"contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
{
"iconSrc": {},
"label": "New Container",
@@ -1832,11 +2087,145 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
"onContextMenuOpen": [Function],
"onExpanded": [Function],
},
-]
-`;
-
-exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expected tree 1`] = `
-[
+ {
+ "children": [
+ {
+ "iconSrc":
,
+ "id": "",
+ "isSelected": [Function],
+ "label": "Scale",
+ "onClick": [Function],
+ },
+ {
+ "children": [
+ {
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Stored Procedure",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New UDF",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Trigger",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "id": "sampleItems",
+ "isSelected": [Function],
+ "label": "Items",
+ "onClick": [Function],
+ },
+ {
+ "id": "sampleSettings",
+ "isSelected": [Function],
+ "label": "Settings",
+ "onClick": [Function],
+ },
+ {
+ "children": [],
+ "label": "Stored Procedures",
+ "onExpanded": [Function],
+ },
+ {
+ "children": [],
+ "label": "User Defined Functions",
+ "onExpanded": [Function],
+ },
+ {
+ "children": [],
+ "label": "Triggers",
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "collectionNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "New SQL Query",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Stored Procedure",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New UDF",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Trigger",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Container",
+ "onClick": [Function],
+ "styleClass": "deleteCollectionMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sampleItemsCollection",
+ "onClick": [Function],
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
+ ],
+ "className": "databaseNode",
+ "contextMenu": [
+ {
+ "iconSrc": {},
+ "label": "Pin to top",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "New Container",
+ "onClick": [Function],
+ },
+ {
+ "iconSrc": {},
+ "label": "Delete Database",
+ "onClick": [Function],
+ "styleClass": "deleteDatabaseMenuItem",
+ },
+ ],
+ "iconSrc":
,
+ "isExpanded": true,
+ "isSelected": [Function],
+ "label": "sharedDatabase",
+ "onCollapsed": [Function],
+ "onContextMenuOpen": [Function],
+ "onExpanded": [Function],
+ },
{
"children": [
{
@@ -2079,138 +2468,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
"contextMenu": [
{
"iconSrc": {},
- "label": "New Container",
+ "label": "Pin to top",
"onClick": [Function],
},
- {
- "iconSrc": {},
- "label": "Delete Database",
- "onClick": [Function],
- "styleClass": "deleteDatabaseMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "standardDb",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "children": [
- {
- "iconSrc":
,
- "id": "",
- "isSelected": [Function],
- "label": "Scale",
- "onClick": [Function],
- },
- {
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Stored Procedure",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New UDF",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Trigger",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "sampleItems",
- "isSelected": [Function],
- "label": "Items",
- "onClick": [Function],
- },
- {
- "id": "sampleSettings",
- "isSelected": [Function],
- "label": "Settings",
- "onClick": [Function],
- },
- {
- "children": [],
- "label": "Stored Procedures",
- "onExpanded": [Function],
- },
- {
- "children": [],
- "label": "User Defined Functions",
- "onExpanded": [Function],
- },
- {
- "children": [],
- "label": "Triggers",
- "onExpanded": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Stored Procedure",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New UDF",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Trigger",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "sampleItemsCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": [
{
"iconSrc": {},
"label": "New Container",
@@ -2228,192 +2488,7 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
/>,
"isExpanded": true,
"isSelected": [Function],
- "label": "sharedDatabase",
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "children": [
- {
- "children": [
- {
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Stored Procedure",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New UDF",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Trigger",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "id": "",
- "isSelected": [Function],
- "label": "Items",
- "onClick": [Function],
- },
- {
- "id": "",
- "isSelected": [Function],
- "label": "Scale & Settings",
- "onClick": [Function],
- },
- {
- "children": [
- {
- "children": [
- {
- "children": [
- {
- "label": "string",
- },
- {
- "label": "HasNulls: false",
- },
- ],
- "label": "street",
- },
- {
- "children": [
- {
- "label": "string",
- },
- {
- "label": "HasNulls: true",
- },
- ],
- "label": "line2",
- },
- {
- "children": [
- {
- "label": "number",
- },
- {
- "label": "HasNulls: false",
- },
- ],
- "label": "zip",
- },
- ],
- "label": "address",
- },
- {
- "children": [
- {
- "label": "string",
- },
- {
- "label": "HasNulls: false",
- },
- ],
- "label": "orderId",
- },
- ],
- "label": "Schema",
- "onClick": [Function],
- },
- {
- "children": [],
- "label": "Stored Procedures",
- "onExpanded": [Function],
- },
- {
- "children": [],
- "label": "User Defined Functions",
- "onExpanded": [Function],
- },
- {
- "children": [],
- "label": "Triggers",
- "onExpanded": [Function],
- },
- ],
- "className": "collectionNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New SQL Query",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Stored Procedure",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New UDF",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "New Trigger",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Container",
- "onClick": [Function],
- "styleClass": "deleteCollectionMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "schemaCollection",
- "onClick": [Function],
- "onCollapsed": [Function],
- "onContextMenuOpen": [Function],
- "onExpanded": [Function],
- },
- {
- "className": "loadMoreNode",
- "label": "load more",
- "onClick": [Function],
- },
- ],
- "className": "databaseNode",
- "contextMenu": [
- {
- "iconSrc": {},
- "label": "New Container",
- "onClick": [Function],
- },
- {
- "iconSrc": {},
- "label": "Delete Database",
- "onClick": [Function],
- "styleClass": "deleteDatabaseMenuItem",
- },
- ],
- "iconSrc":
,
- "isExpanded": true,
- "isSelected": [Function],
- "label": "giganticDatabase",
+ "label": "standardDb",
"onCollapsed": [Function],
"onContextMenuOpen": [Function],
"onExpanded": [Function],
diff --git a/src/Explorer/Tree/treeNodeUtil.test.ts b/src/Explorer/Tree/treeNodeUtil.test.ts
index 64cc3a6c2..c64f9276e 100644
--- a/src/Explorer/Tree/treeNodeUtil.test.ts
+++ b/src/Explorer/Tree/treeNodeUtil.test.ts
@@ -363,7 +363,7 @@ describe("createDatabaseTreeNodes", () => {
},
} as never,
});
- nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab);
+ nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
});
it("creates expected tree", () => {
@@ -445,6 +445,7 @@ describe("createDatabaseTreeNodes", () => {
isNotebookEnabled,
useDatabases.getState().databases,
refreshActiveTab,
+ "",
);
expect(nodes).toMatchSnapshot();
},
@@ -455,7 +456,7 @@ describe("createDatabaseTreeNodes", () => {
// The goal is to cover some key behaviors like loading child nodes, opening tabs/side panels, etc.
it("adds new collections to database as they appear", () => {
- const nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab);
+ const nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
const giganticDbNode = nodes.find((node) => node.label === giganticDb.id());
expect(giganticDbNode).toBeDefined();
expect(giganticDbNode.children.map((node) => node.label)).toStrictEqual(["schemaCollection", "load more"]);
@@ -487,7 +488,7 @@ describe("createDatabaseTreeNodes", () => {
},
} as unknown as DataModels.DatabaseAccount,
});
- nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab);
+ nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
standardDbNode = nodes.find((node) => node.label === standardDb.id());
sharedDbNode = nodes.find((node) => node.label === sharedDb.id());
giganticDbNode = nodes.find((node) => node.label === giganticDb.id());
@@ -642,7 +643,7 @@ describe("createDatabaseTreeNodes", () => {
setup();
// Rebuild the nodes after changing the user/config context.
- nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab);
+ nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
standardDbNode = nodes.find((node) => node.label === standardDb.id());
standardCollectionNode = standardDbNode.children.find((node) => node.label === standardCollection.id());
diff --git a/src/Explorer/Tree/treeNodeUtil.tsx b/src/Explorer/Tree/treeNodeUtil.tsx
index 04eafed3f..224542755 100644
--- a/src/Explorer/Tree/treeNodeUtil.tsx
+++ b/src/Explorer/Tree/treeNodeUtil.tsx
@@ -1,11 +1,17 @@
-import { DatabaseRegular, DocumentMultipleRegular, EyeRegular, SettingsRegular } from "@fluentui/react-icons";
+import {
+ DatabaseRegular,
+ DocumentMultipleRegular,
+ EyeRegular,
+ Pin16Filled,
+ SettingsRegular,
+} from "@fluentui/react-icons";
import { TreeNode } from "Explorer/Controls/TreeComponent/TreeNodeComponent";
import { collectionWasOpened } from "Explorer/MostRecentActivity/MostRecentActivity";
import TabsBase from "Explorer/Tabs/TabsBase";
import StoredProcedure from "Explorer/Tree/StoredProcedure";
import Trigger from "Explorer/Tree/Trigger";
import UserDefinedFunction from "Explorer/Tree/UserDefinedFunction";
-import { useDatabases } from "Explorer/useDatabases";
+import { DatabaseSortOrder, useDatabases } from "Explorer/useDatabases";
import { isFabric, isFabricMirrored, isFabricNative, isFabricNativeReadOnly } from "Platform/Fabric/FabricUtil";
import { getItemName } from "Utils/APITypeUtils";
import { isServerlessAccount } from "Utils/CapabilityUtils";
@@ -27,7 +33,10 @@ export const shouldShowScriptNodes = (): boolean => {
const TreeDatabaseIcon =
;
const TreeSettingsIcon =
;
const TreeCollectionIcon =
;
-const GlobalSecondaryIndexCollectionIcon =
; //check icon
+const GlobalSecondaryIndexCollectionIcon =
;
+
+const pinnedIconStyle: React.CSSProperties = { display: "inline-flex", alignItems: "center", gap: "2px" };
+const pinnedBadgeStyle: React.CSSProperties = { color: "var(--colorBrandForeground1)" };
export const createSampleDataTreeNodes = (sampleDataResourceTokenCollection: ViewModels.CollectionBase): TreeNode[] => {
const updatedSampleTree: TreeNode = {
@@ -131,8 +140,31 @@ export const createDatabaseTreeNodes = (
isNotebookEnabled: boolean,
databases: ViewModels.Database[],
refreshActiveTab: (comparator: (tab: TabsBase) => boolean) => void,
+ searchText = "",
+ sortOrder: DatabaseSortOrder = "az",
+ pinnedDatabaseIds: Set
= new Set(),
): TreeNode[] => {
- const databaseTreeNodes: TreeNode[] = databases.map((database: ViewModels.Database) => {
+ // Filter databases based on search text (cache lowercase to avoid repeated conversion)
+ const lowerSearch = searchText.toLowerCase();
+ const filteredDatabases = searchText
+ ? databases.filter((db) => db.id().toLowerCase().includes(lowerSearch))
+ : databases;
+
+ // Sort: pinned first, then by name (A-Z or Z-A) within each group
+ const orderedDatabases = [...filteredDatabases].sort((first, second) => {
+ const isFirstPinned = pinnedDatabaseIds.has(first.id());
+ const isSecondPinned = pinnedDatabaseIds.has(second.id());
+ if (isFirstPinned !== isSecondPinned) {
+ return isFirstPinned ? -1 : 1;
+ }
+ const firstName = first.id();
+ const secondName = second.id();
+ return sortOrder === "az"
+ ? firstName.localeCompare(secondName, undefined, { sensitivity: "base" })
+ : secondName.localeCompare(firstName, undefined, { sensitivity: "base" });
+ });
+
+ const databaseTreeNodes: TreeNode[] = orderedDatabases.map((database: ViewModels.Database) => {
const buildDatabaseChildNodes = (databaseNode: TreeNode) => {
databaseNode.children = [];
if (database.isDatabaseShared() && configContext.platform !== Platform.Fabric) {
@@ -170,13 +202,24 @@ export const createDatabaseTreeNodes = (
}
};
+ const isPinned = pinnedDatabaseIds.has(database.id());
+
+ const databaseIcon = isPinned ? (
+
+
+
+
+ ) : (
+ TreeDatabaseIcon
+ );
+
const databaseNode: TreeNode = {
label: database.id(),
className: "databaseNode",
children: [],
isSelected: () => useSelectedNode.getState().isDataNodeSelected(database.id()),
contextMenu: ResourceTreeContextMenuButtonFactory.createDatabaseContextMenu(container, database.id()),
- iconSrc: TreeDatabaseIcon,
+ iconSrc: databaseIcon,
onExpanded: async () => {
useSelectedNode.getState().setSelectedNode(database);
if (!databaseNode.children || databaseNode.children?.length === 0) {
@@ -192,7 +235,6 @@ export const createDatabaseTreeNodes = (
isExpanded: database.isDatabaseExpanded(),
onCollapsed: () => {
database.collapseDatabase();
- // useCommandBar.getState().setContextButtons([]);
useDatabases.getState().updateDatabase(database);
},
};
@@ -242,13 +284,13 @@ export const buildCollectionNode = (
(tab: TabsBase) =>
tab.collection?.id() === collection.id() && tab.collection.databaseId === collection.databaseId,
);
- useDatabases.getState().updateDatabase(database);
-
- // If we're showing script nodes, start loading them.
+ // If we're showing script nodes, start loading them in parallel.
if (shouldShowScriptNodes()) {
- await collection.loadStoredProcedures();
- await collection.loadUserDefinedFunctions();
- await collection.loadTriggers();
+ await Promise.all([
+ collection.loadStoredProcedures(),
+ collection.loadUserDefinedFunctions(),
+ collection.loadTriggers(),
+ ]);
}
useDatabases.getState().updateDatabase(database);
@@ -257,7 +299,6 @@ export const buildCollectionNode = (
onContextMenuOpen: () => useSelectedNode.getState().setSelectedNode(collection),
onCollapsed: () => {
collection.collapseCollection();
- // useCommandBar.getState().setContextButtons([]);
useDatabases.getState().updateDatabase(database);
},
isExpanded: collection.isCollectionExpanded(),
diff --git a/src/Explorer/useDatabases.ts b/src/Explorer/useDatabases.ts
index b6420647e..1d24a545f 100644
--- a/src/Explorer/useDatabases.ts
+++ b/src/Explorer/useDatabases.ts
@@ -1,15 +1,25 @@
-import _ from "underscore";
import create, { UseStore } from "zustand";
import * as Constants from "../Common/Constants";
import * as ViewModels from "../Contracts/ViewModels";
+import * as LocalStorageUtility from "../Shared/LocalStorageUtility";
+import { StorageKey } from "../Shared/StorageUtility";
import { userContext } from "../UserContext";
import { useSelectedNode } from "./useSelectedNode";
+export type DatabaseSortOrder = "az" | "za";
+
interface DatabasesState {
databases: ViewModels.Database[];
resourceTokenCollection: ViewModels.CollectionBase;
sampleDataResourceTokenCollection: ViewModels.CollectionBase;
databasesFetchedSuccessfully: boolean; // Track if last database fetch was successful
+ searchText: string;
+ sortOrder: DatabaseSortOrder;
+ pinnedDatabaseIds: Set;
+ setSearchText: (searchText: string) => void;
+ setSortOrder: (sortOrder: DatabaseSortOrder) => void;
+ togglePinDatabase: (databaseId: string) => void;
+ isPinned: (databaseId: string) => boolean;
updateDatabase: (database: ViewModels.Database) => void;
addDatabases: (databases: ViewModels.Database[]) => void;
deleteDatabase: (database: ViewModels.Database) => void;
@@ -27,11 +37,41 @@ interface DatabasesState {
validateCollectionId: (databaseId: string, collectionId: string) => Promise;
}
+const loadPinnedDatabases = (): Set => {
+ const stored = LocalStorageUtility.getEntryObject(StorageKey.PinnedDatabases);
+ return new Set(Array.isArray(stored) ? stored : []);
+};
+
+const loadSortOrder = (): DatabaseSortOrder => {
+ const stored = LocalStorageUtility.getEntryString(StorageKey.DatabaseSortOrder);
+ return stored === "az" || stored === "za" ? stored : "az";
+};
+
export const useDatabases: UseStore = create((set, get) => ({
databases: [],
resourceTokenCollection: undefined,
sampleDataResourceTokenCollection: undefined,
databasesFetchedSuccessfully: false,
+ searchText: "",
+ sortOrder: loadSortOrder(),
+ pinnedDatabaseIds: loadPinnedDatabases(),
+ setSearchText: (searchText: string) => set({ searchText }),
+ setSortOrder: (sortOrder: DatabaseSortOrder) => {
+ LocalStorageUtility.setEntryString(StorageKey.DatabaseSortOrder, sortOrder);
+ set({ sortOrder });
+ },
+ togglePinDatabase: (databaseId: string) => {
+ const current = get().pinnedDatabaseIds;
+ const updated = new Set(current);
+ if (updated.has(databaseId)) {
+ updated.delete(databaseId);
+ } else {
+ updated.add(databaseId);
+ }
+ LocalStorageUtility.setEntryObject(StorageKey.PinnedDatabases, [...updated]);
+ set({ pinnedDatabaseIds: updated });
+ },
+ isPinned: (databaseId: string) => get().pinnedDatabaseIds.has(databaseId),
updateDatabase: (updatedDatabase: ViewModels.Database) =>
set((state) => {
const updatedDatabases = state.databases.map((database: ViewModels.Database) => {
@@ -45,29 +85,27 @@ export const useDatabases: UseStore = create((set, get) => ({
}),
addDatabases: (databases: ViewModels.Database[]) =>
set((state) => ({
- databases: [...state.databases, ...databases].sort((db1, db2) => db1.id().localeCompare(db2.id())),
+ databases: [...state.databases, ...databases],
})),
deleteDatabase: (database: ViewModels.Database) =>
- set((state) => ({ databases: state.databases.filter((db) => database.id() !== db.id()) })),
+ set((state) => {
+ const updated = new Set(state.pinnedDatabaseIds);
+ if (updated.delete(database.id())) {
+ LocalStorageUtility.setEntryObject(StorageKey.PinnedDatabases, [...updated]);
+ }
+ return {
+ databases: state.databases.filter((db) => database.id() !== db.id()),
+ pinnedDatabaseIds: updated,
+ };
+ }),
clearDatabases: () => set(() => ({ databases: [] })),
isSaveQueryEnabled: () => {
- const savedQueriesDatabase: ViewModels.Database = _.find(
- get().databases,
- (database: ViewModels.Database) => database.id() === Constants.SavedQueries.DatabaseName,
+ const savedQueriesDatabase = get().databases.find(
+ (database) => database.id() === Constants.SavedQueries.DatabaseName,
);
- if (!savedQueriesDatabase) {
- return false;
- }
- const savedQueriesCollection: ViewModels.Collection =
- savedQueriesDatabase &&
- _.find(
- savedQueriesDatabase.collections(),
- (collection: ViewModels.Collection) => collection.id() === Constants.SavedQueries.CollectionName,
- );
- if (!savedQueriesCollection) {
- return false;
- }
- return true;
+ return !!savedQueriesDatabase
+ ?.collections()
+ ?.find((collection) => collection.id() === Constants.SavedQueries.CollectionName);
},
findDatabaseWithId: (databaseId: string, isSampleDatabase?: boolean) => {
return isSampleDatabase === undefined
@@ -100,44 +138,24 @@ export const useDatabases: UseStore = create((set, get) => ({
return true;
},
loadDatabaseOffers: async () => {
- await Promise.all(
- get().databases?.map(async (database: ViewModels.Database) => {
- await database.loadOffer();
- }),
- );
+ await Promise.all(get().databases.map((database: ViewModels.Database) => database.loadOffer()));
},
loadAllOffers: async () => {
await Promise.all(
- get().databases?.map(async (database: ViewModels.Database) => {
- await database.loadOffer();
- await database.loadCollections();
+ get().databases.map(async (database: ViewModels.Database) => {
+ await Promise.all([database.loadOffer(), database.loadCollections()]);
await Promise.all(
- (database.collections() || []).map(async (collection: ViewModels.Collection) => {
- await collection.loadOffer();
- }),
+ (database.collections() || []).map((collection: ViewModels.Collection) => collection.loadOffer()),
);
}),
);
},
isFirstResourceCreated: () => {
const databases = get().databases;
-
- if (!databases || databases.length === 0) {
+ if (databases.length === 0) {
return false;
}
-
- return databases.some((database) => {
- // user has created at least one collection
- if (database.collections()?.length > 0) {
- return true;
- }
- // user has created a database with shared throughput
- if (database.offer()) {
- return true;
- }
- // use has created an empty database without shared throughput
- return false;
- });
+ return databases.some((database) => database.collections()?.length > 0 || !!database.offer());
},
findSelectedDatabase: (): ViewModels.Database => {
const selectedNode = useSelectedNode.getState().selectedNode;
@@ -145,7 +163,7 @@ export const useDatabases: UseStore = create((set, get) => ({
return undefined;
}
if (selectedNode.nodeKind === "Database") {
- return _.find(get().databases, (database: ViewModels.Database) => database.id() === selectedNode.id());
+ return get().databases.find((database) => database.id() === selectedNode.id());
}
if (selectedNode.nodeKind === "Collection") {
diff --git a/src/Main.tsx b/src/Main.tsx
index 43e1a90f6..4b06d0c53 100644
--- a/src/Main.tsx
+++ b/src/Main.tsx
@@ -82,6 +82,32 @@ const useStyles = makeStyles({
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
+ splashContainer: {
+ zIndex: 5,
+ position: "absolute",
+ left: 0,
+ top: 0,
+ width: "100%",
+ height: "100%",
+ backgroundColor: "var(--colorNeutralBackground1)",
+ opacity: "0.7",
+ },
+ splashContent: {
+ display: "flex",
+ flexDirection: "column",
+ height: "100%",
+ textAlign: "center",
+ justifyContent: "center",
+ },
+ splashTitle: {
+ fontSize: "13px",
+ color: "var(--colorNeutralForeground1)",
+ margin: "6px 6px 12px 6px",
+ },
+ splashText: {
+ marginTop: "12px",
+ color: "var(--colorNeutralForeground2)",
+ },
});
const App = (): JSX.Element => {
@@ -234,15 +260,15 @@ function LoadingExplorer(): JSX.Element {
const styles = useStyles();
return (
-
-
+
+
-
+
Welcome to Azure Cosmos DB
-
+
Connecting...
diff --git a/src/Shared/StorageUtility.ts b/src/Shared/StorageUtility.ts
index 7f5c275ce..598f1d6a6 100644
--- a/src/Shared/StorageUtility.ts
+++ b/src/Shared/StorageUtility.ts
@@ -36,6 +36,8 @@ export enum StorageKey {
AppState,
MongoGuidRepresentation,
IgnorePartitionKeyOnDocumentUpdate,
+ PinnedDatabases,
+ DatabaseSortOrder,
}
export const hasRUThresholdBeenConfigured = (): boolean => {