@deephaven/code-studio 0.80.0 → 0.80.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/build/assets/{AppRoot-2990a62d.js → AppRoot-3f523173.js} +3 -3
  2. package/build/assets/{AppRoot-2990a62d.js.map → AppRoot-3f523173.js.map} +1 -1
  3. package/build/assets/{Chart-768c3454.js → Chart-5c26fb58.js} +2 -2
  4. package/build/assets/{Chart-768c3454.js.map → Chart-5c26fb58.js.map} +1 -1
  5. package/build/assets/{ControlType-b0b9f834.js → ControlType-2c068913.js} +3 -3
  6. package/build/assets/ControlType-2c068913.js.map +1 -0
  7. package/build/assets/{FontBootstrap-8c55dd97.js → FontBootstrap-daa16eaa.js} +2 -2
  8. package/build/assets/{FontBootstrap-8c55dd97.js.map → FontBootstrap-daa16eaa.js.map} +1 -1
  9. package/build/assets/{FormatterUtils-b2e6ac7a.js → FormatterUtils-f385eae9.js} +2 -2
  10. package/build/assets/{FormatterUtils-b2e6ac7a.js.map → FormatterUtils-f385eae9.js.map} +1 -1
  11. package/build/assets/{Grid-4ea09e16.js → Grid-7fa1977b.js} +2 -2
  12. package/build/assets/{Grid-4ea09e16.js.map → Grid-7fa1977b.js.map} +1 -1
  13. package/build/assets/{GridRenderer-8f7f26bf.js → GridRenderer-cf6ba45e.js} +2 -2
  14. package/build/assets/{GridRenderer-8f7f26bf.js.map → GridRenderer-cf6ba45e.js.map} +1 -1
  15. package/build/assets/{IrisGrid-e479d8b3.js → IrisGrid-b6dc5327.js} +2 -2
  16. package/build/assets/{IrisGrid-e479d8b3.js.map → IrisGrid-b6dc5327.js.map} +1 -1
  17. package/build/assets/{IrisGridModel-706e2c07.js → IrisGridModel-86d74eac.js} +2 -2
  18. package/build/assets/{IrisGridModel-706e2c07.js.map → IrisGridModel-86d74eac.js.map} +1 -1
  19. package/build/assets/{IrisGridShortcuts-2c1bd242.js → IrisGridShortcuts-8cd7b8ed.js} +2 -2
  20. package/build/assets/{IrisGridShortcuts-2c1bd242.js.map → IrisGridShortcuts-8cd7b8ed.js.map} +1 -1
  21. package/build/assets/{IrisGridThemeProvider-48907f79.js → IrisGridThemeProvider-5a81f3ae.js} +2 -2
  22. package/build/assets/{IrisGridThemeProvider-48907f79.js.map → IrisGridThemeProvider-5a81f3ae.js.map} +1 -1
  23. package/build/assets/{MarkdownEditor-11c33fb0.js → MarkdownEditor-a5865ea9.js} +2 -2
  24. package/build/assets/{MarkdownEditor-11c33fb0.js.map → MarkdownEditor-a5865ea9.js.map} +1 -1
  25. package/build/assets/{MarkdownNotebook-30e96c11.js → MarkdownNotebook-70806009.js} +2 -2
  26. package/build/assets/{MarkdownNotebook-30e96c11.js.map → MarkdownNotebook-70806009.js.map} +1 -1
  27. package/build/assets/{MissingPartitionError-397eac9a.js → MissingPartitionError-3c6c2d2d.js} +2 -2
  28. package/build/assets/{MissingPartitionError-397eac9a.js.map → MissingPartitionError-3c6c2d2d.js.map} +1 -1
  29. package/build/assets/{StyleGuideRoot-54fc99ff.js → StyleGuideRoot-fc50cb2b.js} +2 -2
  30. package/build/assets/{StyleGuideRoot-54fc99ff.js.map → StyleGuideRoot-fc50cb2b.js.map} +1 -1
  31. package/build/assets/{index-32400752.js → index-07468d4d.js} +3 -3
  32. package/build/assets/{index-32400752.js.map → index-07468d4d.js.map} +1 -1
  33. package/build/assets/{index-b799f6a7.js → index-7017db74.js} +2 -2
  34. package/build/assets/{index-b799f6a7.js.map → index-7017db74.js.map} +1 -1
  35. package/build/assets/{index-2d6b4a49.js → index-f9230f2b.js} +2 -2
  36. package/build/assets/{index-2d6b4a49.js.map → index-f9230f2b.js.map} +1 -1
  37. package/build/assets/{useUser-f36009f1.js → useUser-77a94721.js} +2 -2
  38. package/build/assets/{useUser-f36009f1.js.map → useUser-77a94721.js.map} +1 -1
  39. package/build/index.html +1 -1
  40. package/package.json +30 -30
  41. package/build/assets/ControlType-b0b9f834.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["StorageUtils","columnName","direction","filters","filterItems","filterOperators","filterItem","i","FilterOperator","config1","config2","operator","type","value","siftPrunableItems","items","maxItems","pruneItemsCount","pruneCount","ownKeys","object","enumerableOnly","keys","symbols","sym","_objectSpread","target","source","key","_defineProperty","asyncGeneratorStep","gen","resolve","reject","_next","_throw","arg","info","error","_asyncToGenerator","fn","self","args","err","obj","_toPropertyKey","_toPrimitive","input","hint","prim","res","log","Log","DB_PREFIX","PouchDB","PouchDBFind","makePouchFilter","FilterType","makePouchSelectorFromConfig","config","filter","newFilter","filterOperator","selectorWithFilters","sortWithConfigs","sorts","_sorts$map","reverse","sort","PouchStorageTable","databaseName","dbOptions","callback","other","id","listener","reversed","viewport","_this","_this$viewportUpdateP","item","_this2","newItem","_this$currentViewport","listeners","data","event","selector","_this3","_this4","_this4$infoUpdateProm","_this4$currentFilter","PromiseUtils","findResult","e","_this5","_this6","_this6$currentFilter","_this6$viewportUpdate","viewportData","_this7","sortedRanges","_this8","itemMap","_ref2","_ref","_this8$currentFilter","from","to","limit","findSnapshotResult","index","_x","PouchStorageTable$1","COMMAND_HISTORY_ITEMS_MAX","COMMAND_HISTORY_ITEMS_PRUNE","PouchCommandHistoryTable","language","cache","_this$cache$tableRegi","searchText","_selector","result","allItems","row","name","toKeep","toPrune","_ref3","isReversed","docs","resumeListeners","_this$cache$tableRegi2","_this$cache$tableRegi3","_this$changes","PouchCommandHistoryTable$1","PouchCommandHistoryCache","dbName","_this$tableRegistry$g","pausedTables","table","_this$tableRegistry$g2","_this$tableRegistry$g3","PouchCommandHistoryCache$1","PouchCommandHistoryStorage","scope","command","updateTable","dbItem","updatedItem","SET_LAYOUT_STORAGE","setLayoutStorage","layoutStorage","dh","shim","isFormatStringFormat","format","getFormattedVersionInfo","serverConfigValues","ua","Bowser","browser","os","getFormattedPluginInfo","pluginDataValues","plugin","acc","focusFirstInputInContainer","container","isSameOptions","options1","options2","isSameDecimalOptions","isSameIntegerOptions","isValidColumnName","DbNameValidator","isValidFormat","columnType","DateTimeColumnFormatter","DecimalColumnFormatter","IntegerColumnFormatter","removeFormatRuleExtraProps","isNewRule","rest","isFormatRuleValidForSave","rule","DateTimeOptions","props","timestamp","timeZone","showTimeZone","showTSeparator","isGlobalOptions","legacyGlobalFormat","useApi","formatter","useMemo","Formatter","formats","jsx","Fragment","formatString","TableUtils","TimeZoneOptions","TimeUtils","label","FormattingSectionContent","PureComponent","debounce","defaultDateTimeFormat","defaultDecimalFormatOptions","defaultIntegerFormatOptions","truncateNumbersWithPound","showEmptyStrings","showNullStrings","React","memoize","timestampAtMenuOpen","updates","update","defaults","updateSettings","defaultDecimalFormatString","defaultIntegerFormatString","isTimeZoneDefault","isDateTimeOptionsDefault","isDecimalOptionsDefault","isIntegerOptionsDefault","jsxs","Select","Button","vsRefresh","classNames","Checkbox","mapStateToProps","state","getDefaultDateTimeFormat","getDefaultDecimalFormatOptions","getDefaultIntegerFormatOptions","getApi","getShowTimeZone","getShowTSeparator","getTruncateNumbersWithPound","getShowEmptyStrings","getShowNullStrings","getTimeZone","getDefaultSettings","ConnectedFormattingSectionContent","connect","updateSettingsAction","LegalNotice","modal","setModal","useState","toggle","vsLaw","Modal","ModalHeader","ModalBody","SettingsMenuSection","children","isExpanded","sectionKey","title","onToggle","FontAwesomeIcon","vsTriangleDown","Collapse","PropTypes","ShortcutItem","shortcut","propsDisplayText","categoryName","onChange","displayText","setDisplayText","keyState","setKeyState","isPending","setIsPending","setError","useEffect","Shortcut","conflictNames","ShortcutRegistry","conflict","handleInputKeyDown","newKeyState","backspaceKeyState","KEY","handleInputKeyUp","handleInputFocus","ContextActionUtils","handleInputBlur","handleConfirm","handleUndo","originalKeyState","handleResetToDefaultClick","Tooltip","ShortcutSectionContent","shortcutOverrides","saveShortcutOverrides","useCallback","modifiedShortcuts","isMac","newOverrides","platformOverrides","categories","shortcuts","globalCategoryIndex","category","globalCategory","ShortcutCategory","propsShortcuts","formatCategoryName","word","setShortcuts","handleShortcutChange","conflictingShortcuts","s","modifiedShoftcuts","displayTexts","getShortcutOverrides","mapDispatchToProps","ConnectedShortcutSectionContent","FILENAME_DATE_FORMAT","DEFAULT_PATH_BLACKLIST","stringifyReplacer","blacklist","pathMap","currPath","v","makeSafeToStringify","path","potentiallyCircularValues","output","val","valRecord","curPath","getReduxDataString","reduxData","store","getMetadata","meta","metadata","exportLogs","fileNamePrefix","zip","JSZip","folder","logHistory","blob","link","columnTypesArray","ColumnTypeOptions","columnTypeOptions","ColumnSpecificSectionContent","formatSettings","lastFormatRuleIndex","oldFormatSettings","assertNotNull","resetKeys","newEntry","newFormat","elem","scrollTo","errorMessages","columnNameId","columnTypeId","formatId","onNameChange","onNameBlur","onTypeChange","eventTargetValue","ruleError","vsTrash","isInvalid","selectedFormat","defaultFormatString","formatRulesChanged","formatRules","FadeTransition","addNewRuleButton","dhNewCircleLargeFilled","TransitionGroup","getFormatter","ConnectedColumnSpecificSectionContent","SettingsMenu","Component","BROADCAST_CHANNEL_NAME","expandedSectionKey","makeMessage","BROADCAST_LOGOUT_MESSAGE","x","y","onDone","pluginData","pluginInfo","supportLink","docsLink","user","versionInfo","deephavenVersion","copyShortcut","GLOBAL_SHORTCUTS","getRow","text","ver","userDisplayName","hasUserImage","showUserName","dhUser","dhUserIncognito","vsClose","vsWatch","vsLayers","ThemeContext","contextValue","vsPaintcan","ThemePicker","vsRecordKeys","vsInfo","CopyButton","Logo","MINIMUM_DRAG_DISTANCE","DragSourceMenuItem","action","menuItemDisabled","iconElement","displayShortcut","isMouseSelected","isKeyboardSelected","closeMenu","startX","useRef","startY","startObject","disableDoubleClick","setDisableDoubleClick","handleMouseMove","handleMouseDown","handleMouseUp","AppControlsMenu","handleControlSelect","handleToolSelect","onClearFilter","controlMenuActions","dhInput","dragEvent","ControlType","dhTriangleDownSquare","vsMarkdown","vsDeviceCamera","vsLink","ToolType","dhFilterSlash","IRIS_GRID_SHORTCUTS","DropdownMenu","replaceReducer","reducers","getLayoutStorage","getServerConfigValues","reducer","reducerRegistry","WidgetList","onExportLayout","onImportLayout","onResetLayout","onSelect","widgets","setSearchText","searchField","selectStartEvent","sendSelect","widget","handleSearchChange","filteredWidgets","a","b","widgetElements","ObjectIcon","errorElement","SearchInput","vsPreview","vsArrowSmallDown","vsArrowSmallUp","isLayoutV2","layout","isLayoutV1","DEFAULT_LAYOUT_CONFIG","ConsolePanel","LogPanel","CommandHistoryPanel","FileExplorerPanel","DEFAULT_LAYOUT_CONFIG_NO_CONSOLE","normalizeLayout","getDefaultLayout","isConsoleAvailable","layouts","exportLayout","filterSets","layoutConfig","links","pluginDataMap","UserLayoutUtils","EmptyDashboard","onAutoFillClick","vsArrowUp","AppMainContainer","DashboardUtils","zipFile","bindAllMethods","allDashboardData","versionInfoText","copyToClipboard","DEFAULT_DASHBOARD_ID","vsTerminal","prevProps","prevState","dashboardData","stopListenForCreateDashboard","connection","updated","created","removed","widgetsToRemove","newWidgets","toRemove","toAdd","setDashboardPluginData","updateDashboardData","workspace","workspaceData","pluginKeys","pluginId","match","notebookPath","session","sessionConfig","fileMetadata","notebookSettings","NotebookEvent","InputFilterEvent","PanelEvent","activeTabKey","MarkdownEvent","toolType","activeTool","setActiveTool","updateWorkspaceData","closed","newLayout","oldLayout","listenForCreateDashboard","newId","nanoid","tabs","isPanelsMenuShown","sortedWidgets","exportedConfig","NotebookPanel","file","fileText","exportedLayout","layoutIteration","clipboardData","pastedData","replacedChars","getVariableDescriptor","plugins","getDashboardPlugins","tabId","oldTabs","newTabs","t","tab","newActiveTabKey","oldActiveTabIndex","EMPTY_ARRAY","permissions","canUsePanels","contextActions","isAuthFailed","isDisconnected","isResetLayoutPromptShown","isSettingsMenuShown","unsavedNotebookCount","dashboardPlugins","NavTabList","dhShapes","dhPanels","Popper","vsGear","dhSquareFilled","ThemeExport","vsDebugDisconnect","AppDashboards","LoadingOverlay","ConsolePlugin","SlideTransition","ContextActions","DebouncedModal","InfoModal","LoadingSpinner","BasicModal","getActiveTool","getAllDashboardsData","getDashboardData","getPlugins","getDashboardConnection","getDashboardSessionWrapper","getUser","getWorkspace","ConnectedAppMainContainer","setActiveToolAction","setDashboardDataAction","setDashboardPluginDataAction","updateDashboardDataAction","updateWorkspaceDataAction","withRouter","App","ContextMenuRoot","LocalWorkspaceStorage","settings","serverSettings","options","GrpcLayoutStorage","storageService","root","content","GrpcFileStorageTable","baseRoot","filename","FileUtils","expanded","paths","nextPath","remainingPath","childTable","search","refreshPromise","viewportUpdatePromise","CanceledPromiseError","basename","childViewportData","GrpcFileStorage","fileContents","newName","FileNotFoundError","itemDetails","isFileType","throttle","AppInit","setApi","setCommandHistoryStorage","setDashboardData","setFileStorage","setDashboardConnection","setDashboardSessionWrapper","setPlugins","setUser","setWorkspace","setWorkspaceStorage","setDefaultWorkspaceSettings","setServerConfigValues","api","client","useClient","useConnection","usePlugins","serverConfig","useServerConfig","useUser","loadApp","sessionDetails","getSessionDetails","sessionWrapper","loadSessionWrapper","fileStorage","workspaceStorage","commandHistoryStorage","loadedWorkspace","isLoading","isLoaded","errorMessage","getWorkspaceStorage","ConnectedAppInit","setApiAction","setCommandHistoryStorageAction","setFileStorageAction","setLayoutStorageAction","setDashboardConnectionAction","setDashboardSessionWrapperAction","setPluginsAction","setUserAction","setWorkspaceAction","setDefaultWorkspaceSettingsAction","setWorkspaceStorageAction","setServerConfigValuesAction","StyleGuideRoot","__vitePreload","baseURI","AppRouter","Router","Switch","Route","Redirect","AppRoot","DownloadServiceWorkerUtils","MonacoUtils","MonacoWorker","Provider"],"sources":["../../../storage/dist/StorageUtils.js","../../../pouch-storage/dist/pouchCommandHistoryUtils.js","../../../pouch-storage/dist/PouchStorageTable.js","../../../pouch-storage/dist/PouchCommandHistoryTable.js","../../../pouch-storage/dist/PouchCommandHistoryCache.js","../../../pouch-storage/dist/PouchCommandHistoryStorage.js","../../src/redux/actionTypes.ts","../../src/redux/actions.ts","../../../jsapi-shim/dist/dh.js","../../src/settings/SettingsUtils.tsx","../../src/settings/DateTimeOptions.tsx","../../src/settings/TimeZoneOptions.tsx","../../src/settings/FormattingSectionContent.tsx","../../src/settings/LegalNotice.tsx","../../src/settings/SettingsMenuSection.tsx","../../src/settings/ShortcutItem.tsx","../../src/settings/ShortcutsSectionContent.tsx","../../src/log/LogExport.ts","../../src/settings/ColumnTypeOptions.tsx","../../src/settings/ColumnSpecificSectionContent.tsx","../../src/settings/SettingsMenu.tsx","../../src/main/AppControlsMenu.tsx","../../src/redux/reducers/layoutStorage.ts","../../src/redux/reducers/index.ts","../../src/redux/selectors.ts","../../src/redux/index.ts","../../src/main/WidgetList.tsx","../../src/storage/LayoutStorage.ts","../../src/main/UserLayoutUtils.ts","../../src/main/EmptyDashboard.tsx","../../src/main/AppMainContainer.tsx","../../src/main/App.tsx","../../src/storage/LocalWorkspaceStorage.ts","../../src/storage/grpc/GrpcLayoutStorage.ts","../../src/storage/grpc/GrpcFileStorageTable.ts","../../src/storage/grpc/GrpcFileStorage.ts","../../src/main/AppInit.tsx","../../src/main/AppRouter.tsx","../../src/AppRoot.tsx"],"sourcesContent":["import { Operator as FilterOperator } from '@deephaven/filters';\nexport class StorageUtils {\n static makeSortConfig(columnName, direction) {\n return {\n column: columnName,\n direction\n };\n }\n static makeFilterConfig(filters) {\n var filterItems = [];\n var filterOperators = [];\n filters.forEach((filterItem, i) => {\n filterItems.push(filterItem);\n if (i > 0) {\n filterOperators.push(FilterOperator.and);\n }\n });\n return {\n filterItems,\n filterOperators\n };\n }\n static combineFilterConfigs(config1, config2) {\n var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : FilterOperator.and;\n return {\n filterItems: [...config1.filterItems, ...config2.filterItems],\n filterOperators: [...config1.filterOperators, operator, ...config2.filterOperators]\n };\n }\n static makeFilterItem(columnName, type, value) {\n return {\n columnName,\n type,\n value\n };\n }\n}\nexport default StorageUtils;\n//# sourceMappingURL=StorageUtils.js.map","/**\n * Takes an array of items and determines which ones to keep and which ones to\n * prune based on the given thresholds.\n * @param items items to keep or prune\n * @param maxItems maximum number of items to allow before pruning\n * @param pruneItemsCount if the maxItems count is exceeded, the number we want to keep\n */\n// eslint-disable-next-line import/prefer-default-export\nexport function siftPrunableItems(items, maxItems, pruneItemsCount) {\n if (items.length > maxItems) {\n var pruneCount = items.length - pruneItemsCount;\n return {\n toKeep: items.slice(pruneCount),\n toPrune: items.slice(0, pruneCount)\n };\n }\n return {\n toKeep: items,\n toPrune: []\n };\n}\n//# sourceMappingURL=pouchCommandHistoryUtils.js.map","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\nimport PouchDB from 'pouchdb-browser';\nimport PouchDBFind from 'pouchdb-find';\nimport { Operator as FilterOperator, Type as FilterType } from '@deephaven/filters';\nimport Log from '@deephaven/log';\nimport { PromiseUtils } from '@deephaven/utils';\nvar log = Log.module('PouchStorageTable');\nvar DB_PREFIX = 'Deephaven.';\nPouchDB.plugin(PouchDBFind);\nexport function makePouchFilter(type, value) {\n switch (type) {\n case FilterType.in:\n case FilterType.contains:\n return {\n $regex: new RegExp(\"\".concat(value)).toString()\n };\n case FilterType.inIgnoreCase:\n return {\n $regex: new RegExp(\"\".concat(value), 'i').toString()\n };\n case FilterType.eq:\n return {\n $eq: value\n };\n case FilterType.notEq:\n return {\n $ne: value\n };\n case FilterType.greaterThan:\n return {\n $gt: value\n };\n case FilterType.greaterThanOrEqualTo:\n return {\n $gte: value\n };\n case FilterType.lessThan:\n return {\n $lt: value\n };\n case FilterType.lessThanOrEqualTo:\n return {\n $lte: value\n };\n case FilterType.startsWith:\n return {\n $regex: new RegExp(\"^\".concat(value, \".*\")).toString()\n };\n default:\n throw new Error(\"Unsupported type: \".concat(type));\n }\n}\nfunction makePouchSelectorFromConfig(config) {\n var {\n filterItems,\n filterOperators\n } = config;\n var filter = null;\n for (var i = 0; i < filterItems.length; i += 1) {\n var filterItem = filterItems[i];\n var {\n columnName,\n type,\n value\n } = filterItem;\n var newFilter = {\n [columnName]: makePouchFilter(type, value)\n };\n if (i === 0) {\n filter = newFilter;\n } else if (filter !== null && i - 1 < filterOperators.length) {\n var filterOperator = filterOperators[i - 1];\n if (filterOperator === FilterOperator.and) {\n filter = {\n $and: [filter, newFilter]\n };\n } else if (filterOperator === FilterOperator.or) {\n filter = {\n $or: [filter, newFilter]\n };\n } else {\n throw new Error(\"Unexpected filter operator \".concat(filterOperator, \", \").concat(newFilter));\n }\n }\n }\n if (filter == null) {\n throw new Error(\"Invalid filter config \".concat(config));\n }\n return filter;\n}\nfunction selectorWithFilters() {\n var filters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return {\n $and: [...filters.map(filter => makePouchSelectorFromConfig(filter)), {\n name: {\n $gt: null\n }\n }, {\n id: {\n $gt: null\n }\n }]\n };\n}\nfunction sortWithConfigs(sorts) {\n var _sorts$map;\n var reverse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n return [{\n id: reverse ? 'desc' : 'asc'\n }, ...((_sorts$map = sorts === null || sorts === void 0 ? void 0 : sorts.map(sort => ({\n [sort.column]: sort.direction\n }))) !== null && _sorts$map !== void 0 ? _sorts$map : [])];\n}\nexport class PouchStorageTable {\n constructor(databaseName, dbOptions) {\n _defineProperty(this, \"db\", void 0);\n _defineProperty(this, \"changes\", void 0);\n _defineProperty(this, \"listeners\", []);\n _defineProperty(this, \"itemListeners\", new Map());\n _defineProperty(this, \"currentSize\", 0);\n _defineProperty(this, \"currentViewport\", void 0);\n _defineProperty(this, \"currentReverse\", false);\n _defineProperty(this, \"currentFilter\", null);\n _defineProperty(this, \"currentSort\", null);\n _defineProperty(this, \"infoUpdatePromise\", void 0);\n _defineProperty(this, \"viewportUpdatePromise\", void 0);\n _defineProperty(this, \"currentViewportData\", void 0);\n this.db = new PouchDB(\"\".concat(DB_PREFIX).concat(databaseName), dbOptions);\n\n // Need to set `_remote` to false to remove deprecation warnings: https://github.com/pouchdb/pouchdb/issues/6106\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-underscore-dangle\n this.db._remote = false;\n this.listenForChanges();\n this.db.createIndex({\n index: {\n fields: ['id', 'name']\n }\n });\n this.refreshInfo();\n }\n\n /**\n * Listen for db changes. This can be cancelled by calling\n * `this.changes?.cancel()`\n */\n listenForChanges() {\n this.changes = this.db.changes({\n live: true,\n since: 'now',\n include_docs: true\n }).on('change', this.dbUpdate.bind(this));\n }\n onUpdate(callback) {\n this.listeners = [...this.listeners, callback];\n return () => {\n this.listeners = this.listeners.filter(other => other !== callback);\n };\n }\n onItemUpdate(id, listener) {\n if (!this.itemListeners.has(id)) {\n this.itemListeners.set(id, []);\n }\n this.itemListeners.set(id, [...this.itemListeners.get(id), listener]);\n this.refreshItem(id);\n return () => {\n this.itemListeners.set(id, this.itemListeners.get(id).filter(other => other !== listener));\n };\n }\n close() {\n this.listeners = [];\n }\n get size() {\n return this.currentSize;\n }\n get viewport() {\n return this.currentViewport;\n }\n setReversed(reversed) {\n this.currentReverse = reversed;\n this.currentViewportData = undefined;\n this.refreshData();\n }\n setViewport(viewport) {\n this.currentViewport = viewport;\n this.refreshInfo();\n this.refreshData();\n }\n setSorts(config) {\n this.currentSort = config;\n this.currentViewportData = undefined;\n this.refreshData();\n }\n setFilters(config) {\n this.currentFilter = config;\n this.currentViewportData = undefined;\n this.refreshInfo();\n this.refreshData();\n }\n get data() {\n return this.currentViewportData;\n }\n getViewportData() {\n var _this = this;\n return _asyncToGenerator(function* () {\n var _this$viewportUpdateP;\n if (!_this.viewportUpdatePromise) {\n _this.refreshData();\n }\n return (_this$viewportUpdateP = _this.viewportUpdatePromise) !== null && _this$viewportUpdateP !== void 0 ? _this$viewportUpdateP : Promise.resolve({\n items: [],\n offset: 0\n });\n })();\n }\n put(item) {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n // Put the item ID in both the _id and the id slot\n // PouchDB uses _id everywhere, StorageTable just uses `id` though\n var newItem = _objectSpread(_objectSpread({}, item), {}, {\n _id: item.id\n });\n yield _this2.db.put(newItem);\n return newItem;\n })();\n }\n sendUpdate() {\n var _this$currentViewport;\n // Retain a reference to it in case a listener gets removed while sending an update\n var {\n listeners\n } = this;\n var data = (_this$currentViewport = this.currentViewportData) !== null && _this$currentViewport !== void 0 ? _this$currentViewport : {\n items: [],\n offset: 0\n };\n for (var i = 0; i < listeners.length; i += 1) {\n listeners[i](data);\n }\n }\n sendItemUpdate(item) {\n var listeners = this.itemListeners.get(item.id);\n if (listeners !== undefined) {\n for (var i = 0; i < listeners.length; i += 1) {\n listeners[i](item);\n }\n }\n }\n dbUpdate(event) {\n log.debug('Update received', event);\n this.refreshInfo();\n if (event.doc !== undefined) {\n this.sendItemUpdate(event.doc);\n }\n this.refreshData();\n }\n\n /**\n * Fetch infor for a given selector.\n * @param selector\n */\n fetchInfo(selector) {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n return _this3.db.find({\n selector,\n fields: []\n });\n })();\n }\n refreshInfo() {\n var _this4 = this;\n return _asyncToGenerator(function* () {\n try {\n var _this4$infoUpdateProm, _this4$currentFilter;\n (_this4$infoUpdateProm = _this4.infoUpdatePromise) === null || _this4$infoUpdateProm === void 0 ? void 0 : _this4$infoUpdateProm.cancel();\n _this4.infoUpdatePromise = PromiseUtils.makeCancelable(_this4.fetchInfo(selectorWithFilters((_this4$currentFilter = _this4.currentFilter) !== null && _this4$currentFilter !== void 0 ? _this4$currentFilter : [])));\n var findResult = yield _this4.infoUpdatePromise;\n _this4.currentSize = findResult.docs.length;\n _this4.sendUpdate();\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to refreshInfo', e);\n throw e;\n }\n }\n })();\n }\n\n /**\n * Fetch data for the given viewport, selector, and sort.\n * @param viewport\n * @param selector\n * @param sort\n */\n fetchViewportData(viewport, selector, sort) {\n var _this5 = this;\n return _asyncToGenerator(function* () {\n return _this5.db.find({\n selector,\n skip: viewport.top,\n limit: viewport.bottom - viewport.top + 1,\n sort,\n fields: ['id', 'name']\n }).then(findResult => ({\n items: findResult.docs,\n offset: viewport.top\n }));\n })();\n }\n refreshData() {\n var _this6 = this;\n return _asyncToGenerator(function* () {\n if (!_this6.currentViewport) {\n return;\n }\n try {\n var _this6$currentFilter, _this6$viewportUpdate;\n var selector = selectorWithFilters((_this6$currentFilter = _this6.currentFilter) !== null && _this6$currentFilter !== void 0 ? _this6$currentFilter : []);\n var sort = sortWithConfigs(_this6.currentSort, _this6.currentReverse);\n (_this6$viewportUpdate = _this6.viewportUpdatePromise) === null || _this6$viewportUpdate === void 0 ? void 0 : _this6$viewportUpdate.cancel();\n _this6.viewportUpdatePromise = PromiseUtils.makeCancelable(_this6.fetchViewportData(_this6.currentViewport, selector, sort));\n var viewportData = yield _this6.viewportUpdatePromise;\n _this6.currentViewportData = viewportData;\n _this6.sendUpdate();\n return viewportData;\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to refreshData', e);\n throw e;\n }\n }\n })();\n }\n refreshItem(id) {\n var _this7 = this;\n return _asyncToGenerator(function* () {\n var findResult = yield _this7.db.find({\n selector: {\n id\n },\n limit: 1\n });\n var item = findResult.docs[0];\n if (item !== undefined) {\n _this7.sendItemUpdate(item);\n }\n return item;\n })();\n }\n getSnapshot(sortedRanges) {\n var _this8 = this;\n return _asyncToGenerator(function* () {\n var itemMap = new Map();\n var sort = [{\n id: _this8.currentReverse ? 'desc' : 'asc'\n }];\n yield Promise.all(sortedRanges.map( /*#__PURE__*/function () {\n var _ref2 = _asyncToGenerator(function* (_ref) {\n var _this8$currentFilter;\n var [from, to] = _ref;\n var limit = to - from + 1;\n return _this8.db.find({\n selector: selectorWithFilters((_this8$currentFilter = _this8.currentFilter) !== null && _this8$currentFilter !== void 0 ? _this8$currentFilter : []),\n skip: from,\n limit,\n sort,\n fields: ['id', 'name']\n }).then(findSnapshotResult => {\n for (var i = 0; i < limit; i += 1) {\n var index = from + i;\n itemMap.set(index, findSnapshotResult.docs[i]);\n }\n });\n });\n return function (_x) {\n return _ref2.apply(this, arguments);\n };\n }()));\n return itemMap;\n })();\n }\n}\nexport default PouchStorageTable;\n//# sourceMappingURL=PouchStorageTable.js.map","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\nimport { Type as FilterType } from '@deephaven/filters';\nimport Log from '@deephaven/log';\nimport { StorageUtils } from '@deephaven/storage';\nimport { PromiseUtils } from '@deephaven/utils';\nimport { siftPrunableItems } from \"./pouchCommandHistoryUtils.js\";\nimport PouchStorageTable from \"./PouchStorageTable.js\";\nvar COMMAND_HISTORY_ITEMS_MAX = 2500;\nvar COMMAND_HISTORY_ITEMS_PRUNE = 2000;\nvar log = Log.module('PouchCommandHistoryTable');\nexport class PouchCommandHistoryTable extends PouchStorageTable {\n constructor(language, cache) {\n var _this$cache$tableRegi;\n super(\"CommandHistoryStorage.\".concat(language), {\n // Optimizations to cut down on growing table size. These should be safe\n // since we don't care about revision history for command history\n // documents.\n auto_compaction: true,\n revs_limit: 1\n });\n\n // Add this table instance to the table registry\n _defineProperty(this, \"searchText\", void 0);\n this.cache = cache;\n if (!this.cache.tableRegistry.has(this.cacheKey)) {\n this.cache.tableRegistry.set(this.cacheKey, new Set());\n }\n log.debug('Adding table to registry', this.cacheKey);\n (_this$cache$tableRegi = this.cache.tableRegistry.get(this.cacheKey)) === null || _this$cache$tableRegi === void 0 ? void 0 : _this$cache$tableRegi.add(this);\n }\n get cacheKey() {\n return this.db.name;\n }\n setSearch(searchText) {\n log.debug('Setting search filters', searchText);\n this.searchText = searchText.trim().toLowerCase();\n this.setFilters(searchText ? [StorageUtils.makeFilterConfig([StorageUtils.makeFilterItem('name', FilterType.contains, searchText)])] : []);\n }\n\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n dbUpdate(event) {\n log.debug('Clearing cache and refreshing data', event);\n this.cache.response.delete(this.cacheKey);\n super.dbUpdate(event);\n }\n\n /**\n * Fetch command history data from `this.cache.response` or from\n * PouchDB if data is not found in the cache. If the number of total items in\n * the db exceeds COMMAND_HISTORY_ITEMS_MAX, the database will be pruned down\n * to COMMAND_HISTORY_ITEMS_PRUNE total items. Note that PouchDB doesn't\n * actually remove them from the underlying IndexDB, they are just marked\n * as deleted and won't be present in our query results.\n * @param selector\n */\n fetchData(_selector) {\n var _this = this;\n return _asyncToGenerator(function* () {\n // Wrapping this in a setTimeout so that it executes on next call stack.\n // This is necessary to ensure `this.cache` has been initialized due to some\n // nuances with property initilization with inherited classes.\n return PromiseUtils.withTimeout(0, /*#__PURE__*/_asyncToGenerator(function* () {\n if (_this.cache.response.has(_this.cacheKey)) {\n log.debug('Fetching from cache', _this.searchText, _this.viewport);\n } else {\n log.debug('Fetching from PouchDB', _this.searchText, _this.viewport);\n _this.cache.response.set(_this.cacheKey, _this.db.allDocs({\n include_docs: true\n }).then(result => {\n var allItems = result.rows\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .map(row => row.doc).filter(_ref2 => {\n var {\n name\n } = _ref2;\n return name;\n });\n log.debug(\"Fetched \".concat(allItems.length, \" command history items\"));\n var {\n toKeep,\n toPrune\n } = siftPrunableItems(allItems, COMMAND_HISTORY_ITEMS_MAX, COMMAND_HISTORY_ITEMS_PRUNE);\n\n // If number of items in PouchDB has exceeded COMMAND_HISTORY_ITEMS_MAX\n // prune them down so we have COMMAND_HISTORY_ITEMS_PRUNE left\n if (toPrune.length) {\n _this.pruneItems(toPrune);\n }\n return {\n docs: toKeep\n };\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n var result = _this.cache.response.get(_this.cacheKey);\n if (_this.searchText == null || _this.searchText === '') {\n return result;\n }\n return _objectSpread(_objectSpread({}, result), {}, {\n docs: (yield result).docs.filter(_ref3 => {\n var {\n name\n } = _ref3;\n return (\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n name.toLowerCase().includes(_this.searchText)\n );\n })\n });\n }));\n })();\n }\n\n /**\n * Override `PouchStorageTable.fetchInfo` so we can make use of\n * `PouchCommandHistoryCache`\n * @param selector\n */\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n fetchInfo(selector) {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n return _this2.fetchData(selector);\n })();\n }\n\n /**\n * Override `PouchStorageTable.fetchViewportData` to fetch command history\n * storage items. This override provides caching + optimizations specific to\n * command history. We cache the results to avoid excessive PouchDB queries\n * during scrolling. The cache should only need to be invalidated when search\n * filter changes or commands are added to the storage history.\n *\n * @param viewport\n * @param selector\n * @param sort\n * @returns Promise to array of command history storage items\n */\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n fetchViewportData(viewport, selector, sort) {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n var data = yield _this3.fetchData(selector);\n log.debug('Fetching viewport data', viewport.top, viewport.bottom + 1, sort, data);\n var isReversed = typeof sort[0] === 'object' && sort[0].id === 'desc';\n var docs = isReversed ? data.docs.slice(0).reverse() : data.docs;\n var items = docs.slice(viewport.top, viewport.bottom + 1);\n return {\n items,\n offset: viewport.top\n };\n })();\n }\n\n /**\n * Mark given items as `_deleted` in the database.\n * @param items\n */\n pruneItems(items) {\n var _this4 = this;\n return _asyncToGenerator(function* () {\n if (_this4.cache.isPruning.get(_this4.cacheKey) === true) {\n log.debug('Pruning already in progress. Skipping.');\n return;\n }\n try {\n log.debug(\"Pruning \".concat(items.length, \" command history items\"));\n\n // Disable change notifications while we bulk delete to avoid locking up\n // the app\n var resumeListeners = _this4.cache.pauseChangeListeners(_this4.cacheKey);\n _this4.cache.isPruning.set(_this4.cacheKey, true);\n yield _this4.db.bulkDocs(items.map(item => _objectSpread(_objectSpread({}, item), {}, {\n _deleted: true\n })));\n _this4.cache.isPruning.set(_this4.cacheKey, false);\n resumeListeners();\n log.debug('Finished pruning command history items');\n } catch (err) {\n log.error('An error occurred while pruning db', err);\n }\n })();\n }\n\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n close() {\n var _this$cache$tableRegi2, _this$cache$tableRegi3, _this$changes;\n log.debug('Closing table', this, (_this$cache$tableRegi2 = this.cache.tableRegistry.get(this.cacheKey)) === null || _this$cache$tableRegi2 === void 0 ? void 0 : _this$cache$tableRegi2.size);\n (_this$cache$tableRegi3 = this.cache.tableRegistry.get(this.cacheKey)) === null || _this$cache$tableRegi3 === void 0 ? void 0 : _this$cache$tableRegi3.delete(this);\n (_this$changes = this.changes) === null || _this$changes === void 0 ? void 0 : _this$changes.cancel();\n super.close();\n }\n}\nexport default PouchCommandHistoryTable;\n//# sourceMappingURL=PouchCommandHistoryTable.js.map","function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\nimport Log from '@deephaven/log';\nvar log = Log.module('PouchCommandHistoryCache');\n\n/**\n * Cache for tracking things shared across multiple\n * `PouchCommandHistoryTable` instances.\n */\nclass PouchCommandHistoryCache {\n constructor() {\n _defineProperty(this, \"isPruning\", void 0);\n _defineProperty(this, \"response\", void 0);\n _defineProperty(this, \"tableRegistry\", void 0);\n this.isPruning = new Map();\n this.response = new Map();\n this.tableRegistry = new Map();\n }\n\n /**\n * Keep track of pruning status for a database. This helps ensure only 1\n * pruning operation gets executed if multiple instances of a PouchCommandHistory\n * table load data at the same time.\n */\n\n /**\n * Cache for command history query results keyed by db name. The cached data\n * will be shared across all `PouchCommandHistoryTable` instances that have\n * the same db name.\n */\n\n /**\n * Keeps track of all `PouchCommandHistoryTable` instances.\n */\n\n /**\n * Pauses PouchDB change listeners for any `PouchCommandHistoryTable` with\n * the given database name. This will cancel existing subscriptions and\n * return a callback that can be used to re-subscribe them.\n * @param dbName\n */\n pauseChangeListeners(dbName) {\n var _this$tableRegistry$g;\n var pausedTables = [];\n (_this$tableRegistry$g = this.tableRegistry.get(dbName)) === null || _this$tableRegistry$g === void 0 ? void 0 : _this$tableRegistry$g.forEach(table => {\n if (table.changes) {\n log.debug(\"Pausing event listeners on '\".concat(dbName, \"' table\"), table);\n table.changes.cancel();\n pausedTables.push(table);\n }\n });\n return () => {\n pausedTables.forEach(table => {\n var _this$tableRegistry$g2, _this$tableRegistry$g3;\n // Resume listening for changes if the table is still in the registry\n if ((_this$tableRegistry$g2 = (_this$tableRegistry$g3 = this.tableRegistry.get(dbName)) === null || _this$tableRegistry$g3 === void 0 ? void 0 : _this$tableRegistry$g3.has(table)) !== null && _this$tableRegistry$g2 !== void 0 ? _this$tableRegistry$g2 : false) {\n log.debug(\"Resuming event listeners on '\".concat(dbName, \"' table\"), table);\n table.listenForChanges();\n }\n });\n };\n }\n}\nexport default PouchCommandHistoryCache;\n//# sourceMappingURL=PouchCommandHistoryCache.js.map","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\n/* eslint-disable class-methods-use-this */\nimport Log from '@deephaven/log';\nimport PouchCommandHistoryTable from \"./PouchCommandHistoryTable.js\";\nimport PouchCommandHistoryCache from \"./PouchCommandHistoryCache.js\";\nvar log = Log.module('PouchCommandHistoryStorage');\nexport class PouchCommandHistoryStorage {\n constructor() {\n _defineProperty(this, \"cache\", new PouchCommandHistoryCache());\n _defineProperty(this, \"updateTableMap\", new Map());\n }\n getUpdateTable(language) {\n if (!this.updateTableMap.has(language)) {\n this.updateTableMap.set(language, new PouchCommandHistoryTable(language, this.cache));\n }\n return this.updateTableMap.get(language);\n }\n getTable(language) {\n var _this = this;\n return _asyncToGenerator(function* () {\n return new PouchCommandHistoryTable(language, _this.cache);\n })();\n }\n addItem(language, scope, command, data) {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n return _this2.updateItem(language, {\n id: \"\".concat(new Date().getTime()),\n name: command,\n data\n });\n })();\n }\n updateItem(language, item) {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n var updateTable = _this3.getUpdateTable(language);\n var dbItem = yield updateTable.refreshItem(item.id);\n var updatedItem = _objectSpread(_objectSpread({}, dbItem !== null && dbItem !== void 0 ? dbItem : {}), item);\n log.debug('Updating item', updatedItem);\n yield updateTable.put(updatedItem);\n log.debug('Update saved');\n return item;\n })();\n }\n listenItem(language, id, listener) {\n var updateTable = this.getUpdateTable(language);\n return updateTable.onItemUpdate(id, listener);\n }\n}\nexport default PouchCommandHistoryStorage;\n//# sourceMappingURL=PouchCommandHistoryStorage.js.map","// eslint-disable-next-line import/prefer-default-export\nexport const SET_LAYOUT_STORAGE = 'SET_LAYOUT_STORAGE';\n","import LayoutStorage from '../storage/LayoutStorage';\nimport { SET_LAYOUT_STORAGE } from './actionTypes';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const setLayoutStorage = (\n layoutStorage: LayoutStorage\n): { type: string; payload: LayoutStorage } => ({\n type: SET_LAYOUT_STORAGE,\n payload: layoutStorage,\n});\n","// The Deephaven API script isn't packaged as a module (yet), and is just included in index.html, exported to the global namespace\n// This include file is simply a wrapper so that it behaves like a module, and can be mocked easily for unit tests\n\nvar {\n dh\n} = globalThis;\nexport default dh;\n//# sourceMappingURL=dh.js.map","import { DbNameValidator } from '@deephaven/utils';\nimport {\n DateTimeColumnFormatter,\n IntegerColumnFormatter,\n DecimalColumnFormatter,\n TableColumnFormat,\n FormattingRule,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport type { ServerConfigValues } from '@deephaven/redux';\nimport Bowser from 'bowser';\nimport { PluginModuleMap } from '@deephaven/plugin';\n\nconst log = Log.module('SettingsUtils');\n\nexport type FormatOption = {\n defaultFormatString?: string;\n};\n\nexport type ValidFormatterItem = FormattingRule & {\n id?: number;\n isNewRule?: boolean;\n};\n\nexport type FormatterItem = Omit<ValidFormatterItem, 'format'> & {\n format: Partial<TableColumnFormat>;\n};\n\nfunction isFormatStringFormat(\n format: Partial<TableColumnFormat>\n): format is Pick<TableColumnFormat, 'formatString'> {\n return (\n (format as Pick<TableColumnFormat, 'formatString'>).formatString != null\n );\n}\n\n/**\n * Get an object containing all version information formatted for display\n * @param serverConfigValues The server config values\n * @returns The formatted version info or \"Unknown\" for any value not available\n */\nexport function getFormattedVersionInfo(\n serverConfigValues: ServerConfigValues\n): Record<string, string> {\n const ua = Bowser.parse(window.navigator.userAgent);\n const browser = `${ua.browser.name ?? ''} ${\n // use only the major version and minor version, rest is usually empty 120.1.0.0 -> 120.1\n Number(parseFloat(ua.browser.version ?? '')) || ''\n }`;\n const os = `${ua.os.name ?? ''} ${ua.os.version ?? ''}`;\n return {\n 'Engine Version': serverConfigValues.get('deephaven.version') ?? 'Unknown',\n 'Web UI Version': import.meta.env.npm_package_version ?? 'Unknown',\n 'Java Version': serverConfigValues.get('java.version') ?? 'Unknown',\n 'Barrage Version': serverConfigValues.get('barrage.version') ?? 'Unknown',\n 'Browser Name': browser.trim() || 'Unknown',\n 'OS Name': os.trim() || 'Unknown',\n };\n}\n\n/**\n * Get an object containing all JS plugin information formatted for display\n * @param serverConfigValues The information for all plugins\n * @returns The formatted mapping from plugin name to version\n */\nexport function getFormattedPluginInfo(\n pluginDataValues: PluginModuleMap\n): Record<string, string> {\n return Array.from(pluginDataValues.entries())\n .filter(plugin => plugin[1].version !== undefined)\n .reduce((acc, [key, value]) => ({ ...acc, [key]: value.version }), {});\n}\n\nexport function focusFirstInputInContainer(\n container: HTMLElement | null\n): void {\n const input: HTMLElement | null | undefined = container?.querySelector(\n 'input, select, textarea'\n );\n if (input) {\n input.focus();\n }\n}\n\nexport function isSameOptions(\n options1: FormatOption,\n options2: FormatOption\n): boolean {\n return options1.defaultFormatString === options2.defaultFormatString;\n}\n\nexport function isSameDecimalOptions(\n options1: FormatOption,\n options2: FormatOption\n): boolean {\n return isSameOptions(options1, options2);\n}\n\nexport function isSameIntegerOptions(\n options1: FormatOption,\n options2: FormatOption\n): boolean {\n return isSameOptions(options1, options2);\n}\n\nexport function isValidColumnName(name: string): boolean {\n return name !== '' && DbNameValidator.isValidColumnName(name);\n}\n\nexport function isValidFormat(\n dh: typeof DhType,\n columnType: string,\n format: Partial<TableColumnFormat>\n): boolean {\n // Undefined or empty string formats are always invalid\n if (\n !columnType ||\n format.formatString == null ||\n !isFormatStringFormat(format)\n ) {\n return false;\n }\n switch (columnType) {\n case 'datetime':\n return DateTimeColumnFormatter.isValid(dh, format);\n case 'decimal':\n return DecimalColumnFormatter.isValid(dh, format);\n case 'int':\n return IntegerColumnFormatter.isValid(dh, format);\n default: {\n log.warn('Trying to validate format of unknown type');\n return true;\n }\n }\n}\n\nexport function removeFormatRuleExtraProps(\n item: ValidFormatterItem\n): FormattingRule {\n const { id, isNewRule, ...rest } = item;\n return rest;\n}\n\nexport function isFormatRuleValidForSave(\n dh: typeof DhType,\n rule: FormatterItem\n): rule is ValidFormatterItem {\n return (\n isValidColumnName(rule.columnName) &&\n isValidFormat(dh, rule.columnType, rule.format)\n );\n}\n\nexport default {\n focusFirstInputInContainer,\n isSameOptions,\n isSameDecimalOptions,\n isSameIntegerOptions,\n isValidColumnName,\n isValidFormat,\n removeFormatRuleExtraProps,\n isFormatRuleValidForSave,\n};\n","import React, { ReactElement, useMemo } from 'react';\nimport {\n Formatter,\n DateTimeColumnFormatter,\n TableUtils,\n} from '@deephaven/jsapi-utils';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\n\ninterface DateTimeOptionProps {\n timestamp: Date;\n timeZone: string;\n showTimeZone: boolean;\n showTSeparator: boolean;\n isGlobalOptions: boolean;\n legacyGlobalFormat?: string;\n}\n\nexport default function DateTimeOptions(\n props: DateTimeOptionProps\n): ReactElement {\n const {\n timestamp,\n timeZone,\n showTimeZone,\n showTSeparator,\n isGlobalOptions,\n legacyGlobalFormat,\n } = props;\n\n const dh = useApi();\n\n const formatter = useMemo(\n () =>\n new Formatter(dh, [], {\n timeZone,\n showTimeZone,\n showTSeparator,\n }),\n [dh, showTimeZone, showTSeparator, timeZone]\n );\n const formats = isGlobalOptions\n ? DateTimeColumnFormatter.getGlobalFormats(showTimeZone, showTSeparator)\n : DateTimeColumnFormatter.getFormats(showTimeZone, showTSeparator);\n\n if (legacyGlobalFormat != null && !formats.includes(legacyGlobalFormat)) {\n formats.unshift(legacyGlobalFormat);\n }\n\n return (\n <>\n {formats.map(formatString => {\n const format = DateTimeColumnFormatter.makeFormat(\n '',\n formatString,\n DateTimeColumnFormatter.TYPE_GLOBAL\n );\n return (\n <option\n value={formatString}\n key={formatString}\n data-testid=\"time-format\"\n >\n {formatter.getFormattedString(\n timestamp,\n TableUtils.dataType.DATETIME,\n '',\n format\n )}\n </option>\n );\n })}\n </>\n );\n}\n","import React from 'react';\nimport { TimeUtils } from '@deephaven/utils';\n\nexport default function TimeZoneOptions(): JSX.Element {\n return (\n <>\n {TimeUtils.TIME_ZONES.map(timeZone => {\n const { label, value } = timeZone;\n return (\n <option value={value} key={value}>\n {label}\n </option>\n );\n })}\n </>\n );\n}\n","import React, {\n ChangeEvent,\n PureComponent,\n ReactElement,\n RefObject,\n} from 'react';\nimport { connect } from 'react-redux';\nimport { vsRefresh } from '@deephaven/icons';\nimport memoize from 'memoizee';\nimport debounce from 'lodash.debounce';\nimport classNames from 'classnames';\nimport { Button, Checkbox, Select } from '@deephaven/components';\nimport {\n IntegerColumnFormatter,\n DecimalColumnFormatter,\n TableUtils,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport {\n getApi,\n getDefaultDateTimeFormat,\n getDefaultDecimalFormatOptions,\n getDefaultIntegerFormatOptions,\n getTimeZone,\n getShowTimeZone,\n getShowTSeparator,\n getTruncateNumbersWithPound,\n getShowEmptyStrings,\n getShowNullStrings,\n updateSettings as updateSettingsAction,\n RootState,\n WorkspaceSettings,\n getDefaultSettings,\n} from '@deephaven/redux';\nimport './FormattingSectionContent.scss';\nimport type { DebouncedFunc } from 'lodash';\nimport {\n focusFirstInputInContainer,\n isSameDecimalOptions,\n isSameIntegerOptions,\n isValidFormat,\n} from './SettingsUtils';\nimport type { FormatOption } from './SettingsUtils';\nimport DateTimeOptions from './DateTimeOptions';\nimport TimeZoneOptions from './TimeZoneOptions';\n\nconst log = Log.module('FormattingSectionContent');\n\ninterface FormattingSectionContentProps {\n dh: typeof DhType;\n defaultDateTimeFormat: string;\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n truncateNumbersWithPound: boolean;\n showEmptyStrings: boolean;\n showNullStrings: boolean;\n updateSettings: (settings: Partial<WorkspaceSettings>) => void;\n defaultDecimalFormatOptions: FormatOption;\n defaultIntegerFormatOptions: FormatOption;\n defaults: WorkspaceSettings;\n}\n\ninterface FormattingSectionContentState {\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n defaultDateTimeFormat: string;\n defaultDecimalFormatOptions: FormatOption;\n defaultIntegerFormatOptions: FormatOption;\n truncateNumbersWithPound: boolean;\n showEmptyStrings: boolean;\n showNullStrings: boolean;\n timestampAtMenuOpen: Date;\n}\n\nexport class FormattingSectionContent extends PureComponent<\n FormattingSectionContentProps,\n FormattingSectionContentState\n> {\n static defaultProps = {\n scrollTo: (): void => undefined,\n };\n\n static inputDebounceTime = 250;\n\n constructor(props: FormattingSectionContentProps) {\n super(props);\n\n this.debouncedCommitChanges = debounce(\n this.commitChanges.bind(this),\n FormattingSectionContent.inputDebounceTime\n );\n this.queueUpdate = this.queueUpdate.bind(this);\n this.handleDefaultDateTimeFormatChange =\n this.handleDefaultDateTimeFormatChange.bind(this);\n this.handleDefaultDecimalFormatChange =\n this.handleDefaultDecimalFormatChange.bind(this);\n this.handleDefaultIntegerFormatChange =\n this.handleDefaultIntegerFormatChange.bind(this);\n this.handleShowTimeZoneChange = this.handleShowTimeZoneChange.bind(this);\n this.handleShowTSeparatorChange =\n this.handleShowTSeparatorChange.bind(this);\n this.handleTimeZoneChange = this.handleTimeZoneChange.bind(this);\n this.handleResetDateTimeFormat = this.handleResetDateTimeFormat.bind(this);\n this.handleResetDecimalFormat = this.handleResetDecimalFormat.bind(this);\n this.handleResetIntegerFormat = this.handleResetIntegerFormat.bind(this);\n this.handleResetTimeZone = this.handleResetTimeZone.bind(this);\n this.handleTruncateNumbersWithPoundChange =\n this.handleTruncateNumbersWithPoundChange.bind(this);\n this.handleShowEmptyStringsChange =\n this.handleShowEmptyStringsChange.bind(this);\n this.handleShowNullStringsChange =\n this.handleShowNullStringsChange.bind(this);\n\n const {\n defaultDateTimeFormat,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions,\n showTimeZone,\n showTSeparator,\n timeZone,\n truncateNumbersWithPound,\n showEmptyStrings,\n showNullStrings,\n } = props;\n\n this.containerRef = React.createRef();\n this.pendingUpdates = [];\n\n this.state = {\n showTimeZone,\n showTSeparator,\n timeZone,\n defaultDateTimeFormat,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions,\n truncateNumbersWithPound,\n showEmptyStrings,\n showNullStrings,\n timestampAtMenuOpen: new Date(),\n };\n }\n\n componentDidMount(): void {\n focusFirstInputInContainer(this.containerRef.current);\n }\n\n componentWillUnmount(): void {\n this.debouncedCommitChanges.flush();\n }\n\n debouncedCommitChanges: DebouncedFunc<() => void>;\n\n pendingUpdates: Partial<WorkspaceSettings>[];\n\n containerRef: RefObject<HTMLDivElement>;\n\n getCachedDateTimeFormatOptions = memoize(\n (\n timeZone: string,\n showTimeZone: boolean,\n showTSeparator: boolean,\n isGlobalOptions = false,\n legacyGlobalFormat?: string\n ) => {\n const { timestampAtMenuOpen } = this.state;\n return (\n <DateTimeOptions\n timestamp={timestampAtMenuOpen}\n timeZone={timeZone}\n showTimeZone={showTimeZone}\n showTSeparator={showTSeparator}\n isGlobalOptions={isGlobalOptions}\n legacyGlobalFormat={legacyGlobalFormat}\n />\n );\n }\n );\n\n queueUpdate(updates: Partial<WorkspaceSettings>): void {\n this.pendingUpdates.push(updates);\n this.debouncedCommitChanges();\n }\n\n handleDefaultDateTimeFormatChange(value: string): void {\n log.debug('handleDefaultDateTimeFormatChange', value);\n const update = {\n defaultDateTimeFormat: value,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleDefaultDecimalFormatChange(event: ChangeEvent<HTMLInputElement>): void {\n log.debug('handleDefaultDecimalFormatChange', event.target.value);\n const update = {\n defaultDecimalFormatOptions: {\n defaultFormatString: event.target.value,\n },\n };\n this.setState(update);\n if (\n isValidFormat(\n dh,\n TableUtils.dataType.DECIMAL,\n DecimalColumnFormatter.makeCustomFormat(event.target.value)\n )\n ) {\n this.queueUpdate(update);\n }\n }\n\n handleDefaultIntegerFormatChange(event: ChangeEvent<HTMLInputElement>): void {\n log.debug('handleDefaultIntegerFormatChange', event.target.value);\n const update = {\n defaultIntegerFormatOptions: {\n defaultFormatString: event.target.value,\n },\n };\n this.setState(update);\n if (\n isValidFormat(\n dh,\n TableUtils.dataType.INT,\n IntegerColumnFormatter.makeCustomFormat(event.target.value)\n )\n ) {\n this.queueUpdate(update);\n }\n }\n\n handleShowTimeZoneChange(): void {\n const { showTimeZone } = this.state;\n const update = { showTimeZone: !showTimeZone };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleShowTSeparatorChange(): void {\n const { showTSeparator } = this.state;\n const update = { showTSeparator: !showTSeparator };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleTimeZoneChange(value: string): void {\n const update = { timeZone: value };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleResetDateTimeFormat(): void {\n const { defaults } = this.props;\n const { defaultDateTimeFormat, showTimeZone, showTSeparator } = defaults;\n log.debug('handleResetDateTimeFormat');\n this.setState({\n defaultDateTimeFormat,\n showTimeZone,\n showTSeparator,\n });\n this.queueUpdate({\n defaultDateTimeFormat: undefined,\n showTimeZone: undefined,\n showTSeparator: undefined,\n });\n }\n\n handleResetTimeZone(): void {\n const { defaults } = this.props;\n const { timeZone } = defaults;\n log.debug('handleResetTimeZone');\n this.setState({\n timeZone,\n });\n this.queueUpdate({\n timeZone: undefined,\n });\n }\n\n handleResetDecimalFormat(): void {\n const { defaults } = this.props;\n const { defaultDecimalFormatOptions } = defaults;\n log.debug('handleResetDecimalFormat');\n this.setState({\n defaultDecimalFormatOptions,\n });\n this.queueUpdate({\n defaultDecimalFormatOptions: undefined,\n });\n }\n\n handleResetIntegerFormat(): void {\n const { defaults } = this.props;\n const { defaultIntegerFormatOptions } = defaults;\n log.debug('handleResetIntegerFormat');\n this.setState({\n defaultIntegerFormatOptions,\n });\n this.queueUpdate({\n defaultIntegerFormatOptions: undefined,\n });\n }\n\n handleTruncateNumbersWithPoundChange(): void {\n const { truncateNumbersWithPound } = this.state;\n const update = {\n truncateNumbersWithPound: truncateNumbersWithPound !== true,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleShowEmptyStringsChange(): void {\n const { showEmptyStrings } = this.state;\n const update = {\n showEmptyStrings: !showEmptyStrings,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleShowNullStringsChange(): void {\n const { showNullStrings } = this.state;\n const update = {\n showNullStrings: !showNullStrings,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n commitChanges(): void {\n const { updateSettings } = this.props;\n const updates = this.pendingUpdates.reduce(\n (acc, update) => ({\n ...acc,\n ...update,\n }),\n {}\n );\n this.pendingUpdates = [];\n\n updateSettings(updates);\n }\n\n render(): ReactElement {\n const { defaults, dh } = this.props;\n const {\n defaultDateTimeFormat,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions,\n timeZone,\n showTimeZone,\n showTSeparator,\n truncateNumbersWithPound,\n showEmptyStrings,\n showNullStrings,\n } = this.state;\n\n const {\n defaultFormatString:\n defaultDecimalFormatString = DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n } = defaultDecimalFormatOptions ?? {};\n const {\n defaultFormatString:\n defaultIntegerFormatString = IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n } = defaultIntegerFormatOptions ?? {};\n\n const isTimeZoneDefault = timeZone === defaults.timeZone;\n const isDateTimeOptionsDefault =\n showTSeparator === defaults.showTSeparator &&\n showTimeZone === defaults.showTimeZone &&\n defaultDateTimeFormat === defaults.defaultDateTimeFormat;\n const isDecimalOptionsDefault = isSameDecimalOptions(\n defaultDecimalFormatOptions,\n defaults.defaultDecimalFormatOptions\n );\n const isIntegerOptionsDefault = isSameIntegerOptions(\n defaultIntegerFormatOptions,\n defaults.defaultIntegerFormatOptions\n );\n\n return (\n <div className=\"app-settings-formatting-section\" ref={this.containerRef}>\n <div className=\"container-fluid p-0\">\n <div className=\"app-settings-menu-description mb-3\">\n Choose the default formatting rule to apply to all table columns\n based on their type.\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"select-reset-timezone\"\n >\n Time zone\n </label>\n <div className=\"col pr-0\">\n <Select\n className=\"custom-select\"\n value={timeZone}\n onChange={this.handleTimeZoneChange}\n id=\"select-reset-timezone\"\n >\n <TimeZoneOptions />\n </Select>\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetTimeZone}\n tooltip=\"Reset Time Zone\"\n className={classNames('btn-reset', 'btn-reset-time-zone', {\n hidden: isTimeZoneDefault,\n })}\n />\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"select-default-time-format\"\n >\n DateTime\n </label>\n <div className=\"col pr-0\">\n <Select\n className=\"custom-select\"\n value={defaultDateTimeFormat}\n onChange={this.handleDefaultDateTimeFormatChange}\n id=\"select-default-time-format\"\n >\n {this.getCachedDateTimeFormatOptions(\n timeZone,\n showTimeZone,\n showTSeparator,\n true,\n defaultDateTimeFormat\n )}\n </Select>\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetDateTimeFormat}\n tooltip=\"Reset DateTime Options\"\n className={classNames('btn-reset', 'btn-reset-date-time', {\n hidden: isDateTimeOptionsDefault,\n })}\n />\n </div>\n </div>\n <div className=\"form-row\">\n <div className=\"offset-3 col-9\">\n <Checkbox\n checked={showTimeZone ?? null}\n onChange={this.handleShowTimeZoneChange}\n >\n Show time zone in dates\n </Checkbox>\n </div>\n </div>\n\n <div className=\"form-row mb-3\">\n <div className=\"offset-3 col-9\">\n <Checkbox\n checked={showTSeparator ?? null}\n onChange={this.handleShowTSeparatorChange}\n >\n Show &#39;T&#39; separator\n </Checkbox>\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"default-decimal-format-input\"\n >\n Decimal\n </label>\n <div className=\"col pr-0\">\n <input\n className={classNames(\n 'form-control',\n 'flex-grow-1',\n 'default-decimal-format-input',\n {\n 'is-invalid': !isValidFormat(\n dh,\n TableUtils.dataType.DECIMAL,\n DecimalColumnFormatter.makeCustomFormat(\n defaultDecimalFormatString\n )\n ),\n }\n )}\n data-lpignore\n placeholder={DecimalColumnFormatter.DEFAULT_FORMAT_STRING}\n type=\"text\"\n id=\"default-decimal-format-input\"\n value={defaultDecimalFormatString}\n onChange={this.handleDefaultDecimalFormatChange}\n />\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetDecimalFormat}\n tooltip=\"Reset Decimal Formatting\"\n className={classNames('btn-reset', 'btn-reset-decimal', {\n hidden: isDecimalOptionsDefault,\n })}\n data-testid=\"btn-reset-decimal\"\n />\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"default-integer-format-input\"\n >\n Integer\n </label>\n <div className=\"col pr-0\">\n <input\n className={classNames(\n 'form-control',\n 'flex-grow-1',\n 'default-integer-format-input',\n {\n 'is-invalid': !isValidFormat(\n dh,\n TableUtils.dataType.INT,\n IntegerColumnFormatter.makeCustomFormat(\n defaultIntegerFormatString\n )\n ),\n }\n )}\n data-lpignore\n placeholder={IntegerColumnFormatter.DEFAULT_FORMAT_STRING}\n type=\"text\"\n id=\"default-integer-format-input\"\n value={defaultIntegerFormatString}\n onChange={this.handleDefaultIntegerFormatChange}\n />\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetIntegerFormat}\n tooltip=\"Reset Integer Formatting\"\n className={classNames('btn-reset', 'btn-reset-integer', {\n hidden: isIntegerOptionsDefault,\n })}\n data-testid=\"btn-reset-integer\"\n />\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <div className=\"offset-3 col-9\">\n <Checkbox\n checked={truncateNumbersWithPound ?? null}\n onChange={this.handleTruncateNumbersWithPoundChange}\n >\n Show truncated numbers as ###\n </Checkbox>\n </div>\n </div>\n\n <div className=\"form-row mb-3\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"default-integer-format-input\"\n >\n String\n </label>\n <div className=\"col pr-0 pt-2\">\n <Checkbox\n checked={showEmptyStrings ?? null}\n onChange={this.handleShowEmptyStringsChange}\n >\n Show empty strings as{' '}\n <span className=\"font-italic text-muted\">empty</span>\n </Checkbox>\n <Checkbox\n checked={showNullStrings ?? null}\n onChange={this.handleShowNullStringsChange}\n >\n Show null strings as{' '}\n <span className=\"font-italic text-muted\">null</span>\n </Checkbox>\n </div>\n </div>\n </div>\n </div>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState\n): Omit<FormattingSectionContentProps, 'updateSettings'> => ({\n defaultDateTimeFormat: getDefaultDateTimeFormat(state),\n defaultDecimalFormatOptions: getDefaultDecimalFormatOptions(state),\n defaultIntegerFormatOptions: getDefaultIntegerFormatOptions(state),\n dh: getApi(state),\n showTimeZone: getShowTimeZone(state),\n showTSeparator: getShowTSeparator(state),\n truncateNumbersWithPound: getTruncateNumbersWithPound(state),\n showEmptyStrings: getShowEmptyStrings(state),\n showNullStrings: getShowNullStrings(state),\n timeZone: getTimeZone(state),\n defaults: getDefaultSettings(state),\n});\n\nconst ConnectedFormattingSectionContent = connect(mapStateToProps, {\n updateSettings: updateSettingsAction,\n})(FormattingSectionContent);\n\nexport default ConnectedFormattingSectionContent;\n","import React, { ReactElement, useState } from 'react';\nimport { Button, Modal, ModalBody, ModalHeader } from '@deephaven/components';\nimport { vsLaw } from '@deephaven/icons';\n\nfunction LegalNotice(): ReactElement {\n const [modal, setModal] = useState(false);\n const toggle = (): void => {\n setModal(!modal);\n };\n\n return (\n <>\n <Button kind=\"ghost\" onClick={toggle} icon={vsLaw}>\n Legal Notices\n </Button>\n <Modal isOpen={modal} toggle={toggle}>\n <ModalHeader toggle={toggle}>Legal Notice</ModalHeader>\n <ModalBody>\n <p>\n Deephaven software is protected by U.S. Patent Nos. 9,612,959;\n 9,613,018; 9,613,109; 9,619,210; 9,633,060; 9,639,570; 9,672,238;\n 9,679,006; 9,690,821; 9,710,511; 9,760,591; 9,805,084; 9,836,494;\n 9,836,495; 9,886,469; 9,898,496; 9,934,266; 10,002,153; 10,002,154;\n 10,002,155; 10,003,673; 10,019,138; 10,069,943; 10,176,211;\n 10,198,465; 10,198,466; 10,198,469; 10,212,257; 10,241,960;\n 10,241,965; 10,242,040; 10,242,041; 10,346,394; 10,353,893;\n 10,452,649; 10,496,639; 10,540,351; 10,552,412; 10,565,194;\n 10,565,206; 10,572,474; 10,621,168; 10,642,829; 10,657,184;\n 10,678,787; 10,691,686; 10,783,191; 10,866,943; 10,909,183;\n 10,915,526; 10,922,311; 10,929,394; 11,023,462; 11,126,662;\n 11,151,133; 11,238,036; 11,249,994; 11,263,211; 11,449,557;\n 11,514,037; 11,556,528; and 11,574,018. Other patents pending.\n </p>\n <p>\n © 2016-{new Date().getFullYear()} Deephaven Data Labs LLC. Patent\n Pending.\n </p>\n </ModalBody>\n </Modal>\n </>\n );\n}\n\nexport default LegalNotice;\n","import React, { ReactElement, ReactNode } from 'react';\nimport PropTypes from 'prop-types';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button, Collapse } from '@deephaven/components';\nimport { vsTriangleDown } from '@deephaven/icons';\n\ninterface SettingsMenuSectionProps {\n children: ReactNode;\n isExpanded: boolean;\n sectionKey: string;\n title: ReactElement;\n onToggle: (sectionkey: string) => void;\n}\n\nfunction SettingsMenuSection(props: SettingsMenuSectionProps): ReactElement {\n const { children, isExpanded, sectionKey, title, onToggle } = props;\n return (\n <>\n <div>\n <Button\n kind=\"ghost\"\n className=\"btn-collapse-trigger\"\n onClick={() => onToggle(sectionKey)}\n >\n <div className=\"flex-grow-1\">{title}</div>\n <div className=\"flex-shrink-0\">\n <FontAwesomeIcon\n transform={isExpanded ? 'flip-v' : ''}\n icon={vsTriangleDown}\n />\n </div>\n </Button>\n </div>\n <Collapse in={isExpanded} autoFocusOnShow>\n {children}\n </Collapse>\n </>\n );\n}\n\nSettingsMenuSection.propTypes = {\n children: PropTypes.node,\n isExpanded: PropTypes.bool.isRequired,\n sectionKey: PropTypes.string.isRequired,\n title: PropTypes.node.isRequired,\n onToggle: PropTypes.func,\n};\n\nSettingsMenuSection.defaultProps = {\n children: null,\n onToggle: () => undefined,\n};\n\nexport default SettingsMenuSection;\n","import React, { useState, useEffect } from 'react';\nimport classNames from 'classnames';\nimport {\n Shortcut,\n Tooltip,\n ShortcutRegistry,\n ContextActionUtils,\n Button,\n KEY,\n} from '@deephaven/components';\nimport type { KeyState } from '@deephaven/components';\nimport { vsRefresh } from '@deephaven/icons';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport './ShortcutItem.scss';\n\ntype ShortcutItemProps = {\n shortcut: Shortcut;\n displayText: string;\n categoryName: string;\n onChange: (shortcut: Shortcut) => void;\n};\n\nexport default function ShortcutItem({\n shortcut,\n displayText: propsDisplayText,\n categoryName,\n onChange,\n}: ShortcutItemProps): JSX.Element {\n const [displayText, setDisplayText] = useState(propsDisplayText);\n const [keyState, setKeyState] = useState<KeyState>(shortcut.getKeyState());\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState('');\n\n // If propsDisplayText changes, the shortcut was altered from a conflict state by the parent component\n useEffect(\n function resolveConflictOnPropChange() {\n setDisplayText(propsDisplayText);\n setKeyState(shortcut.getKeyState());\n },\n [propsDisplayText, shortcut]\n );\n\n // Updates displayText when keyState is changed\n useEffect(\n function onNewKeybind() {\n setDisplayText(Shortcut.getDisplayText(keyState));\n if (shortcut.matchesKeyState(keyState)) {\n setIsPending(false);\n }\n },\n [keyState, shortcut]\n );\n\n // Sets error state based on isPending\n useEffect(\n function setErrors() {\n if (isPending) {\n if (!Shortcut.isValidKeyState(keyState)) {\n if (Shortcut.isAllowedKey(keyState.keyValue)) {\n setError('Must contain a modifier key');\n } else {\n setError('Must contain an allowed action key');\n }\n return;\n }\n\n const conflictNames = ShortcutRegistry.getConflictingShortcuts(keyState)\n .filter(\n conflict =>\n conflict.id.startsWith(categoryName) && conflict !== shortcut\n )\n .map(conflict => conflict.name);\n\n if (conflictNames.length) {\n setError(`Conflicts with ${conflictNames.join(', ')}`);\n return;\n }\n\n setError('');\n } else {\n setError('');\n }\n },\n [isPending, keyState, categoryName, shortcut]\n );\n\n // Updates pending key state and sets input display text\n function handleInputKeyDown(e: React.KeyboardEvent<HTMLInputElement>): void {\n e.stopPropagation();\n e.preventDefault();\n\n if (shortcut.isEditable && !e.repeat) {\n const newKeyState = Shortcut.getKeyStateFromEvent(e);\n const backspaceKeyState = Shortcut.createKeyState([KEY.BACKSPACE]);\n\n // Backspace clears the shortcut\n if (Shortcut.doKeyStatesMatch(newKeyState, backspaceKeyState)) {\n setKeyState(Shortcut.NULL_KEY_STATE);\n } else {\n setKeyState(newKeyState);\n }\n }\n }\n\n // Set this shortcut to changing state, check key state validity and set errors\n function handleInputKeyUp(e: React.KeyboardEvent<HTMLInputElement>): void {\n e.stopPropagation();\n e.preventDefault();\n\n if (!shortcut.matchesKeyState(keyState)) {\n setIsPending(true);\n }\n }\n\n function handleInputFocus(): void {\n ContextActionUtils.disableAllActions();\n }\n\n function handleInputBlur(): void {\n ContextActionUtils.enableAllActions();\n }\n\n function handleConfirm(): void {\n shortcut.setKeyState(keyState);\n setIsPending(false);\n onChange(shortcut);\n }\n\n function handleUndo(): void {\n const originalKeyState = shortcut.getKeyState();\n setKeyState(originalKeyState);\n setIsPending(false);\n }\n\n function handleResetToDefaultClick(): void {\n setIsPending(true);\n setKeyState(shortcut.getDefaultKeyState());\n }\n\n return (\n <>\n <div className=\"shortcut-item-container\">\n <label className=\"shortcut-item-name\">\n {shortcut.name}\n {shortcut.tooltip !== undefined && (\n <Tooltip>{shortcut.tooltip}</Tooltip>\n )}\n </label>\n <div className=\"shortcut-item-input-container\">\n <input\n className={classNames('form-control', {\n 'is-invalid': error,\n })}\n onKeyDown={handleInputKeyDown}\n onKeyUp={handleInputKeyUp}\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n disabled={!shortcut.isEditable}\n value={displayText}\n readOnly\n />\n {!Shortcut.doKeyStatesMatch(\n keyState,\n shortcut.getDefaultKeyState()\n ) &&\n !error && (\n <Button\n className=\"reset-to-default-button\"\n kind=\"ghost\"\n icon={\n <FontAwesomeIcon\n icon={vsRefresh}\n transform={{ rotate: 90, flipX: true }}\n />\n }\n tooltip=\"Reset to default\"\n onClick={handleResetToDefaultClick}\n />\n )}\n </div>\n </div>\n {isPending && (\n <div\n className={classNames('shortcut-item-message-container', {\n 'is-invalid': error,\n })}\n >\n <div className=\"shortcut-item-message\">{error}</div>\n <div className=\"shortcut-item-message-buttons\">\n {Shortcut.isValidKeyState(keyState) && (\n <Button kind=\"ghost\" onClick={handleConfirm}>\n Confirm\n </Button>\n )}\n <Button kind=\"ghost\" onClick={handleUndo}>\n Undo\n </Button>\n </div>\n </div>\n )}\n </>\n );\n}\n","import React, { useState, useMemo, useCallback } from 'react';\nimport { connect } from 'react-redux';\nimport { Shortcut, ShortcutRegistry } from '@deephaven/components';\nimport {\n getShortcutOverrides,\n RootState,\n updateSettings as updateSettingsAction,\n WorkspaceSettings,\n} from '@deephaven/redux';\nimport ShortcutItem from './ShortcutItem';\n\ntype ShortcutSectionContentProps = {\n shortcutOverrides: WorkspaceSettings['shortcutOverrides'];\n updateSettings: typeof updateSettingsAction;\n};\n\nfunction ShortcutSectionContent({\n shortcutOverrides = {},\n updateSettings,\n}: ShortcutSectionContentProps): JSX.Element {\n const saveShortcutOverrides = useCallback(\n (modifiedShortcuts: Shortcut[]) => {\n const isMac = Shortcut.isMacPlatform;\n\n // This ensures mac and windows objects both exist\n const newOverrides: Required<typeof shortcutOverrides> = {\n mac: { ...shortcutOverrides.mac },\n windows: { ...shortcutOverrides.windows },\n };\n const platformOverrides = isMac ? newOverrides.mac : newOverrides.windows;\n\n modifiedShortcuts.forEach(shortcut => {\n if (shortcut.isDefault()) {\n // No need to save overrides that are the default value\n delete platformOverrides[shortcut.id];\n } else {\n platformOverrides[shortcut.id] = shortcut.getKeyState();\n }\n });\n\n updateSettings({\n shortcutOverrides: newOverrides,\n });\n },\n [updateSettings, shortcutOverrides]\n );\n\n let categories = Array.from(\n ShortcutRegistry.shortcutsByCategory.entries()\n ).map(([name, shortcuts]) => ({\n name,\n shortcuts,\n }));\n\n // Move global category to the end\n const globalCategoryIndex = categories.findIndex(\n category => category.name.toUpperCase() === 'GLOBAL'\n );\n const globalCategory = categories.splice(globalCategoryIndex, 1);\n categories = categories.concat(globalCategory);\n\n return (\n <>\n <div className=\"app-settings-menu-description\">\n Customize shortcuts below. To prevent unexpected results, avoid\n conflicting shortcuts with the browser or IDE editor.\n </div>\n {categories.map(category => (\n <ShortcutCategory\n key={category.name}\n name={category.name}\n shortcuts={category.shortcuts}\n saveShortcutOverrides={saveShortcutOverrides}\n />\n ))}\n </>\n );\n}\n\ntype ShortcutCategoryProps = {\n name: string;\n shortcuts: Shortcut[];\n saveShortcutOverrides: (shortcuts: Shortcut[]) => void;\n};\n\nfunction ShortcutCategory({\n name,\n shortcuts: propsShortcuts,\n saveShortcutOverrides,\n}: ShortcutCategoryProps): JSX.Element {\n function formatCategoryName(categoryName: string): string {\n return categoryName\n .split('_')\n .map(word => `${word[0].toUpperCase()}${word.slice(1).toLowerCase()}`)\n .join(' ');\n }\n\n // Used to trigger a re-render when a shortcut is changed\n // Since shortcuts are singletons, React doesn't detect changes for a re-render as easily\n const [shortcuts, setShortcuts] = useState(propsShortcuts);\n\n function handleShortcutChange(shortcut: Shortcut): void {\n const conflictingShortcuts = shortcuts.filter(\n s =>\n s !== shortcut &&\n !s.isNull() &&\n s.matchesKeyState(shortcut.getKeyState())\n );\n\n // Set conflicting shortcuts to null\n conflictingShortcuts.forEach(conflict => conflict.setToNull());\n\n const modifiedShoftcuts = [shortcut, ...conflictingShortcuts];\n\n saveShortcutOverrides(modifiedShoftcuts);\n setShortcuts(s => [...s]);\n }\n\n const displayTexts = useMemo(\n () => shortcuts.map(s => s.getDisplayText()),\n [shortcuts]\n );\n\n return (\n <div className=\"mt-3\">\n <div className=\"font-weight-bold\">{formatCategoryName(name)}</div>\n {shortcuts.map((shortcut, i) => (\n <ShortcutItem\n key={shortcut.id}\n shortcut={shortcut}\n displayText={displayTexts[i]}\n categoryName={name}\n onChange={handleShortcutChange}\n />\n ))}\n </div>\n );\n}\n\nconst mapStateToProps = (\n state: RootState\n): Pick<ShortcutSectionContentProps, 'shortcutOverrides'> => ({\n shortcutOverrides: getShortcutOverrides(state),\n});\n\nconst mapDispatchToProps = { updateSettings: updateSettingsAction };\n\nconst ConnectedShortcutSectionContent = connect(\n mapStateToProps,\n mapDispatchToProps\n)(ShortcutSectionContent);\n\nexport default ConnectedShortcutSectionContent;\n","/* eslint-disable import/prefer-default-export */\nimport JSZip from 'jszip';\nimport dh from '@deephaven/jsapi-shim';\nimport { store } from '@deephaven/redux';\nimport { logHistory } from './LogInit';\n\nconst FILENAME_DATE_FORMAT = 'yyyy-MM-dd-HHmmss';\n\n// List of objects to blacklist\n// '' represents the root object\nexport const DEFAULT_PATH_BLACKLIST: string[][] = [\n ['api'],\n ['client'],\n ['dashboardData', 'default', 'connection'],\n ['dashboardData', 'default', 'sessionWrapper', 'dh'],\n ['layoutStorage'],\n ['storage'],\n];\n\nfunction stringifyReplacer(blacklist: string[][]) {\n // modified from:\n // https://stackoverflow.com/questions/61681176/json-stringify-replacer-how-to-get-full-path\n const pathMap = new Map();\n // replacer function is also called for the initial object, key is \"\"\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter\n\n return function replacer(this: unknown, key: string, value: unknown) {\n // get and store path\n const currPath = [...(pathMap.get(this) ?? []), key];\n if (value === Object(value)) pathMap.set(value, [...currPath]);\n currPath.shift();\n\n // check blacklists\n for (let i = 0; i < blacklist.length; i += 1) {\n if (\n currPath.length === blacklist[i].length &&\n currPath.every((v, index) => v === blacklist[i][index])\n ) {\n // blacklist match\n return undefined;\n }\n }\n\n // not in blacklist, return value\n return value;\n };\n}\n\n/**\n * Returns a new object that is safe to stringify\n * All circular references are replaced by the path to the value creating a circular ref\n * A circular ref will display 'Circular ref to root.someKey' in place of the circular ref\n * All BigInts are replaced with their toString since BigInts error JSON.stringify\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Exceptions\n *\n * This tries to stringify each key of the object as an easy way to determine if it is safe\n * If it fails to stringify, then the values that failed repeat the same steps recursively\n * The unsafe objects are kept in a map with their path (e.g. root.someKey.someOtherKey)\n * Then if the object is seen again, it must be a circular ref since that object could not be stringified safely\n *\n * @param obj Object to make safe to stringify\n * @param blacklist List of JSON paths to blacklist. A JSON path is a list representing the path to that value (e.g. client.data would be `['client', 'data']`)\n */\nfunction makeSafeToStringify(\n obj: Record<string, unknown>,\n blacklist: string[][],\n path = 'root',\n potentiallyCircularValues: Map<Record<string, unknown>, string> = new Map([\n [obj, ''],\n ])\n): Record<string, unknown> {\n const output: Record<string, unknown> = {};\n\n Object.entries(obj).forEach(([key, val]) => {\n try {\n JSON.stringify(val, stringifyReplacer(blacklist));\n output[key] = val;\n } catch (e) {\n // The value must be a Circular object or BigInt here\n const valRecord = val as Record<string, unknown>;\n\n if (typeof val === 'bigint') {\n output[key] = val.toString();\n } else if (potentiallyCircularValues.has(valRecord)) {\n // We've seen this object before, so it's a circular ref\n output[key] = `Circular ref to ${potentiallyCircularValues.get(\n valRecord\n )}`;\n } else {\n // Haven't seen the object before, but somewhere in it there is a circular ref\n // The ref could point to this object or just to another child\n const curPath = `${path}.${key}`;\n potentiallyCircularValues.set(valRecord, curPath);\n output[key] = makeSafeToStringify(\n val as Record<string, unknown>,\n blacklist,\n curPath,\n potentiallyCircularValues\n );\n }\n }\n });\n\n return output;\n}\n\nfunction getReduxDataString(blacklist: string[][]): string {\n const reduxData = store.getState();\n return JSON.stringify(\n makeSafeToStringify(reduxData, blacklist),\n stringifyReplacer(blacklist),\n 2 // Indent w/ 2 spaces\n );\n}\n\nfunction getMetadata(\n blacklist: string[][],\n meta?: Record<string, unknown>\n): string {\n const metadata = {\n uiVersion: import.meta.env.npm_package_version,\n userAgent: navigator.userAgent,\n ...meta,\n };\n\n return JSON.stringify(metadata, stringifyReplacer(blacklist), 2);\n}\n\n/**\n * Export support logs with the given name.\n * @param fileNamePrefix The zip file name without the .zip extension. Ex: test will be saved as test.zip\n * @param metadata Additional metadata to include in the metadata.json file\n * @param blacklist List of JSON paths to blacklist. A JSON path is a list representing the path to that value (e.g. client.data would be `['client', 'data']`)\n * @returns A promise that resolves successfully if the log archive is created and downloaded successfully, rejected if there's an error\n */\nexport async function exportLogs(\n fileNamePrefix = `${dh.i18n.DateTimeFormat.format(\n FILENAME_DATE_FORMAT,\n new Date()\n )}_support_logs`,\n metadata?: Record<string, unknown>,\n blacklist: string[][] = DEFAULT_PATH_BLACKLIST\n): Promise<void> {\n const zip = new JSZip();\n const folder = zip.folder(fileNamePrefix) as JSZip;\n folder.file('console.txt', logHistory.getFormattedHistory());\n folder.file('redux.json', getReduxDataString(blacklist));\n folder.file('metadata.json', getMetadata(blacklist, metadata));\n\n const blob = await zip.generateAsync({ type: 'blob' });\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = `${fileNamePrefix}.zip`;\n link.click();\n}\n","import React, { ReactElement } from 'react';\nimport { TableUtils } from '@deephaven/jsapi-utils';\n\nconst columnTypesArray = [\n { value: TableUtils.dataType.DATETIME, label: 'DateTime' },\n { value: TableUtils.dataType.DECIMAL, label: 'Decimal' },\n { value: TableUtils.dataType.INT, label: 'Integer' },\n];\n\nexport default function ColumnTypeOptions(): ReactElement {\n const columnTypeOptions = columnTypesArray.map(item => (\n <option key={`key-columnType-${item.value}`} value={item.value}>\n {item.label}\n </option>\n ));\n\n return (\n <>\n <option key=\"key-columnType-placeholder\" disabled value=\"\">\n Select Type\n </option>\n {columnTypeOptions}\n </>\n );\n}\n","import React, {\n ChangeEvent,\n PureComponent,\n ReactElement,\n RefObject,\n} from 'react';\nimport { connect } from 'react-redux';\nimport { dhNewCircleLargeFilled, vsTrash } from '@deephaven/icons';\nimport memoize from 'memoizee';\nimport { TransitionGroup } from 'react-transition-group';\nimport debounce from 'lodash.debounce';\nimport classNames from 'classnames';\nimport { Button, FadeTransition, Select } from '@deephaven/components';\nimport {\n DateTimeColumnFormatter,\n IntegerColumnFormatter,\n DecimalColumnFormatter,\n TableUtils,\n TableColumnFormat,\n FormattingRule,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport {\n getApi,\n getDefaultDecimalFormatOptions,\n getDefaultIntegerFormatOptions,\n getFormatter,\n getTimeZone,\n getShowTimeZone,\n getShowTSeparator,\n updateSettings as updateSettingsAction,\n RootState,\n WorkspaceSettings,\n} from '@deephaven/redux';\nimport { assertNotNull } from '@deephaven/utils';\nimport './FormattingSectionContent.scss';\nimport type { DebouncedFunc } from 'lodash';\nimport {\n focusFirstInputInContainer,\n isValidColumnName,\n isValidFormat,\n removeFormatRuleExtraProps,\n isFormatRuleValidForSave,\n ValidFormatterItem,\n} from './SettingsUtils';\nimport type { FormatterItem, FormatOption } from './SettingsUtils';\nimport ColumnTypeOptions from './ColumnTypeOptions';\nimport DateTimeOptions from './DateTimeOptions';\n\nexport interface ColumnSpecificSectionContentProps {\n dh: typeof DhType;\n formatter: FormatterItem[];\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n updateSettings: (settings: Partial<WorkspaceSettings>) => void;\n scrollTo: (x: number, y: number) => void;\n defaultDecimalFormatOptions: FormatOption;\n defaultIntegerFormatOptions: FormatOption;\n}\n\ninterface ColumnSpecificSectionContentState {\n formatSettings: FormatterItem[];\n formatRulesChanged: boolean;\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n timestampAtMenuOpen: Date;\n}\n\nexport class ColumnSpecificSectionContent extends PureComponent<\n ColumnSpecificSectionContentProps,\n ColumnSpecificSectionContentState\n> {\n static defaultProps = {\n scrollTo: (): void => undefined,\n };\n\n static inputDebounceTime = 250;\n\n constructor(props: ColumnSpecificSectionContentProps) {\n super(props);\n\n this.debouncedCommitChanges = debounce(\n this.commitChanges.bind(this),\n ColumnSpecificSectionContent.inputDebounceTime\n );\n\n this.handleFormatRuleEntered = this.handleFormatRuleEntered.bind(this);\n this.handleFormatRuleChange = this.handleFormatRuleChange.bind(this);\n this.handleFormatRuleCreate = this.handleFormatRuleCreate.bind(this);\n this.handleFormatRuleDelete = this.handleFormatRuleDelete.bind(this);\n\n const { formatter, showTimeZone, showTSeparator, timeZone } = props;\n\n const formatSettings = formatter.map((item, i) => ({\n ...item,\n id: i,\n }));\n\n this.containerRef = React.createRef();\n this.addFormatRuleButtonRef = React.createRef();\n\n this.lastFormatRuleIndex = formatSettings.length;\n\n this.state = {\n formatSettings,\n formatRulesChanged: false,\n showTimeZone,\n showTSeparator,\n timeZone,\n timestampAtMenuOpen: new Date(),\n };\n }\n\n componentDidMount(): void {\n focusFirstInputInContainer(this.containerRef.current);\n }\n\n componentWillUnmount(): void {\n this.debouncedCommitChanges.flush();\n }\n\n debouncedCommitChanges: DebouncedFunc<() => void>;\n\n containerRef: RefObject<HTMLDivElement>;\n\n addFormatRuleButtonRef: RefObject<HTMLButtonElement>;\n\n lastFormatRuleIndex: number;\n\n isDuplicateRule(rule: FormatterItem): boolean {\n const { formatSettings } = this.state;\n return (\n formatSettings.some(\n item =>\n item.id !== rule.id &&\n item.columnName === rule.columnName &&\n item.columnType === rule.columnType\n ) ?? false\n );\n }\n\n getAutoIncrementFormatRuleIndex(): number {\n const { lastFormatRuleIndex } = this;\n this.lastFormatRuleIndex += 1;\n return lastFormatRuleIndex;\n }\n\n getCachedColumnTypeOptions = memoize(() => <ColumnTypeOptions />);\n\n getCachedDateTimeFormatOptions = memoize(\n (\n timeZone: string,\n showTimeZone: boolean,\n showTSeparator: boolean,\n isGlobalOptions = false,\n legacyGlobalFormat?: string\n ) => {\n const { timestampAtMenuOpen } = this.state;\n return (\n <DateTimeOptions\n timestamp={timestampAtMenuOpen}\n timeZone={timeZone}\n showTimeZone={showTimeZone}\n showTSeparator={showTSeparator}\n isGlobalOptions={isGlobalOptions}\n legacyGlobalFormat={legacyGlobalFormat}\n />\n );\n }\n );\n\n handleFormatRuleChange(\n index: number,\n key: string,\n value: TableColumnFormat | string | boolean\n ): void {\n this.setState(\n state => {\n const { formatSettings: oldFormatSettings } = state;\n assertNotNull(oldFormatSettings);\n const formatSettings = [...oldFormatSettings];\n // Reset format string on type change\n let resetKeys = {};\n if (key === 'columnType') {\n resetKeys = {\n format: this.makeDefaultFormatterItemByType(value as string),\n };\n }\n const newEntry = {\n ...formatSettings[index],\n ...resetKeys,\n [key]: value,\n };\n\n formatSettings[index] = newEntry;\n return {\n formatSettings,\n };\n },\n () => {\n this.debouncedCommitChanges();\n }\n );\n }\n\n handleFormatRuleCreate(): void {\n this.setState(state => {\n const { formatSettings } = state;\n const newFormat = {\n columnType: TableUtils.dataType.DATETIME,\n columnName: '',\n format: {},\n id: this.getAutoIncrementFormatRuleIndex(),\n isNewRule: true,\n };\n return {\n formatSettings: [...formatSettings, newFormat],\n formatRulesChanged: true,\n };\n });\n }\n\n handleFormatRuleDelete(index: number): void {\n this.setState(\n state => {\n const { formatSettings: oldFormatSettings } = state;\n const formatSettings = oldFormatSettings.filter(\n (item, i) => i !== index\n );\n return {\n formatSettings,\n formatRulesChanged: true,\n };\n },\n () => {\n this.debouncedCommitChanges();\n }\n );\n }\n\n handleFormatRuleEntered(elem: HTMLElement): void {\n this.scrollToFormatBlockBottom();\n focusFirstInputInContainer(elem);\n }\n\n commitChanges(): void {\n const { formatSettings } = this.state;\n\n const { dh } = this.props;\n\n const formatter =\n formatSettings\n .filter((format): format is ValidFormatterItem =>\n isFormatRuleValidForSave(dh, format)\n )\n .map(removeFormatRuleExtraProps) ?? [];\n\n const { updateSettings } = this.props;\n const newSettings = {\n formatter: formatter as FormattingRule[],\n };\n updateSettings(newSettings);\n }\n\n scrollToFormatBlockBottom(): void {\n const { scrollTo } = this.props;\n scrollTo(\n 0,\n (this.addFormatRuleButtonRef.current?.offsetHeight ?? 0) +\n (this.addFormatRuleButtonRef.current?.offsetTop ?? 0)\n );\n }\n\n getRuleError(rule: FormatterItem): {\n hasColumnNameError: boolean;\n hasFormatError: boolean;\n message: string;\n } {\n const { dh } = this.props;\n const error = {\n hasColumnNameError: false,\n hasFormatError: false,\n message: '',\n };\n\n const errorMessages = [];\n\n if (rule.isNewRule !== undefined && rule.isNewRule) {\n return error;\n }\n\n if (this.isDuplicateRule(rule)) {\n error.hasColumnNameError = true;\n errorMessages.push('Duplicate column name/type combo.');\n }\n\n if (!isValidColumnName(rule.columnName)) {\n error.hasColumnNameError = true;\n errorMessages.push(\n 'Column names must start with a letter or underscore and contain only alphanumeric characters or underscores.'\n );\n }\n\n if (\n rule.format.formatString != null &&\n rule.format.formatString.length === 0\n ) {\n error.hasFormatError = true;\n errorMessages.push('Empty formatting rule.');\n } else if (!isValidFormat(dh, rule.columnType, rule.format)) {\n error.hasFormatError = true;\n errorMessages.push('Invalid formatting rule.');\n }\n\n error.message = errorMessages.join('\\n');\n return error;\n }\n\n makeDefaultFormatterItemByType(\n columnType: string\n ): TableColumnFormat | string {\n switch (TableUtils.getNormalizedType(columnType)) {\n case TableUtils.dataType.INT: {\n const { defaultIntegerFormatOptions } = this.props;\n const { defaultFormatString: defaultIntegerFormatString } =\n defaultIntegerFormatOptions;\n return IntegerColumnFormatter.makeFormat(\n '',\n defaultIntegerFormatString ??\n IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n IntegerColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n }\n\n case TableUtils.dataType.DECIMAL: {\n const { defaultDecimalFormatOptions } = this.props;\n const { defaultFormatString: defaultDecimalFormatString } =\n defaultDecimalFormatOptions;\n return DecimalColumnFormatter.makeFormat(\n '',\n defaultDecimalFormatString ??\n DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n DecimalColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n }\n default: {\n return '';\n }\n }\n }\n\n renderFormatRule(i: number, rule: FormatterItem): ReactElement {\n const columnNameId = `input-${i}-columnName`;\n const columnTypeId = `input-${i}-columnType`;\n const formatId = `input-${i}-format`;\n const columnTypeOptions = this.getCachedColumnTypeOptions();\n const onNameChange = (e: ChangeEvent<HTMLInputElement>): void =>\n this.handleFormatRuleChange(i, 'columnName', e.target.value);\n const onNameBlur = (): void =>\n this.handleFormatRuleChange(i, 'isNewRule', false);\n const onTypeChange = (eventTargetValue: string): void =>\n this.handleFormatRuleChange(i, 'columnType', eventTargetValue);\n\n const ruleError = this.getRuleError(rule);\n\n return (\n <fieldset key={i} className=\"container-fluid format-rule-container\">\n <div className=\"form-row\">\n <div className=\"form-group col-7 mb-2\">\n <label htmlFor={columnNameId}>Column Name</label>\n <input\n id={columnNameId}\n className={classNames('form-control', {\n 'is-invalid': ruleError.hasColumnNameError,\n })}\n data-lpignore\n type=\"text\"\n value={rule.columnName}\n onChange={onNameChange}\n onBlur={onNameBlur}\n />\n </div>\n <div className=\"form-group col mb-2\">\n <Button\n kind=\"ghost\"\n className=\"btn-delete-format-rule float-right\"\n tabIndex={-1}\n onClick={() => this.handleFormatRuleDelete(i)}\n icon={vsTrash}\n tooltip=\"Delete\"\n aria-label=\"Delete Format Rule\"\n />\n\n <label htmlFor={columnTypeId}>Column Type</label>\n <Select\n id={columnTypeId}\n className=\"custom-select\"\n value={rule.columnType}\n onChange={onTypeChange}\n >\n {columnTypeOptions}\n </Select>\n </div>\n </div>\n <div className=\"form-row\">\n <div className=\"form-group col-12 d-flex mb-2\">\n <label\n className=\"flex-shrink-0 col-form-label mr-3\"\n htmlFor={formatId}\n >\n Formatting Rule\n </label>\n {this.renderFormatRuleInput(\n i,\n rule.columnType,\n formatId,\n rule.format,\n ruleError.hasFormatError\n )}\n </div>\n </div>\n <div className=\"form-row\">\n <div className=\"form-group col-12 d-flex mb-2\">\n {ruleError.message && (\n <p className=\"text-danger\">{ruleError.message}</p>\n )}\n </div>\n </div>\n </fieldset>\n );\n }\n\n renderFormatRuleInput(\n i: number,\n columnType: string,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement | null {\n switch (TableUtils.getNormalizedType(columnType)) {\n case TableUtils.dataType.DATETIME:\n return this.renderDateTimeFormatRuleInput(\n i,\n formatId,\n format,\n isInvalid\n );\n case TableUtils.dataType.DECIMAL:\n return this.renderDecimalFormatRuleInput(\n i,\n formatId,\n format,\n isInvalid\n );\n case TableUtils.dataType.INT:\n return this.renderIntegerFormatRuleInput(\n i,\n formatId,\n format,\n isInvalid\n );\n default:\n throw new Error(`Unrecognized column type: ${columnType}`);\n }\n }\n\n renderDateTimeFormatRuleInput(\n i: number,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement {\n const { showTimeZone, showTSeparator, timeZone } = this.state;\n\n const value = format.formatString ?? '';\n return (\n <Select\n className={classNames('custom-select', { 'is-invalid': isInvalid })}\n value={value}\n id={formatId}\n onChange={eventTargetValue => {\n const selectedFormat = DateTimeColumnFormatter.makeFormat(\n '',\n eventTargetValue,\n DateTimeColumnFormatter.TYPE_GLOBAL\n );\n this.handleFormatRuleChange(i, 'format', selectedFormat);\n }}\n >\n <option key=\"default\" value=\"\" disabled>\n Select format\n </option>\n {this.getCachedDateTimeFormatOptions(\n timeZone,\n showTimeZone,\n showTSeparator\n )}\n </Select>\n );\n }\n\n renderIntegerFormatRuleInput(\n i: number,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement {\n const { defaultIntegerFormatOptions } = this.props;\n assertNotNull(defaultIntegerFormatOptions);\n const { defaultFormatString } = defaultIntegerFormatOptions;\n const value = format.formatString ?? '';\n return (\n <input\n className={classNames('form-control', 'flex-grow-1', {\n 'is-invalid': isInvalid,\n })}\n data-lpignore\n id={formatId}\n placeholder={\n defaultFormatString ?? IntegerColumnFormatter.DEFAULT_FORMAT_STRING\n }\n type=\"text\"\n value={value}\n onChange={e => {\n const selectedFormat = IntegerColumnFormatter.makeFormat(\n '',\n e.target.value,\n IntegerColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n this.handleFormatRuleChange(i, 'format', selectedFormat);\n }}\n />\n );\n }\n\n renderDecimalFormatRuleInput(\n i: number,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement {\n const { defaultDecimalFormatOptions } = this.props;\n const { defaultFormatString } = defaultDecimalFormatOptions;\n\n const value = format.formatString ?? '';\n return (\n <input\n className={classNames('form-control', 'flex-grow-1', {\n 'is-invalid': isInvalid,\n })}\n data-lpignore\n id={formatId}\n placeholder={\n defaultFormatString ?? DecimalColumnFormatter.DEFAULT_FORMAT_STRING\n }\n type=\"text\"\n value={value}\n onChange={e => {\n const selectedFormat = DecimalColumnFormatter.makeFormat(\n '',\n e.target.value,\n DecimalColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n this.handleFormatRuleChange(i, 'format', selectedFormat);\n }}\n />\n );\n }\n\n render(): ReactElement {\n const { formatRulesChanged, formatSettings } = this.state;\n\n const formatRules = formatSettings.map((rule, index) => (\n <FadeTransition key={rule.id} onEnter={this.handleFormatRuleEntered}>\n {this.renderFormatRule(index, rule)}\n </FadeTransition>\n ));\n\n const addNewRuleButton = (\n <Button\n kind=\"ghost\"\n className=\"mb-3\"\n onClick={this.handleFormatRuleCreate}\n ref={this.addFormatRuleButtonRef}\n icon={dhNewCircleLargeFilled}\n >\n Add New Rule\n </Button>\n );\n\n return (\n <div className=\"app-settings-formatting-section\" ref={this.containerRef}>\n <div className=\"app-settings-menu-description mb-3\">\n Customize the formatting of table columns by applying rules based on\n matching both a column name and column type.\n </div>\n\n <TransitionGroup\n appear={formatRulesChanged}\n enter={formatRulesChanged}\n exit={formatRulesChanged}\n >\n {formatRules}\n </TransitionGroup>\n\n {addNewRuleButton}\n </div>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState\n): Omit<ColumnSpecificSectionContentProps, 'updateSettings' | 'scrollTo'> => ({\n formatter: getFormatter(state),\n defaultDecimalFormatOptions: getDefaultDecimalFormatOptions(state),\n defaultIntegerFormatOptions: getDefaultIntegerFormatOptions(state),\n dh: getApi(state),\n showTimeZone: getShowTimeZone(state),\n showTSeparator: getShowTSeparator(state),\n timeZone: getTimeZone(state),\n});\n\nconst ConnectedColumnSpecificSectionContent = connect(mapStateToProps, {\n updateSettings: updateSettingsAction,\n})(ColumnSpecificSectionContent);\n\nexport default ConnectedColumnSpecificSectionContent;\n","import React, { Component, Fragment, ReactElement, RefObject } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n vsClose,\n vsWatch,\n vsRecordKeys,\n vsInfo,\n vsLayers,\n vsPaintcan,\n dhUserIncognito,\n dhUser,\n} from '@deephaven/icons';\nimport {\n Button,\n CopyButton,\n GLOBAL_SHORTCUTS,\n Logo,\n ThemeContext,\n ThemePicker,\n Tooltip,\n} from '@deephaven/components';\nimport { ServerConfigValues, User } from '@deephaven/redux';\nimport {\n BROADCAST_CHANNEL_NAME,\n BROADCAST_LOGOUT_MESSAGE,\n makeMessage,\n} from '@deephaven/jsapi-utils';\nimport { assertNotNull } from '@deephaven/utils';\nimport { PluginModuleMap } from '@deephaven/plugin';\nimport FormattingSectionContent from './FormattingSectionContent';\nimport LegalNotice from './LegalNotice';\nimport SettingsMenuSection from './SettingsMenuSection';\nimport ShortcutSectionContent from './ShortcutsSectionContent';\nimport { exportLogs } from '../log/LogExport';\nimport './SettingsMenu.scss';\nimport ColumnSpecificSectionContent from './ColumnSpecificSectionContent';\nimport {\n getFormattedPluginInfo,\n getFormattedVersionInfo,\n} from './SettingsUtils';\n\ninterface SettingsMenuProps {\n serverConfigValues: ServerConfigValues;\n pluginData: PluginModuleMap;\n user: User;\n onDone: () => void;\n}\n\ninterface SettingsMenuState {\n expandedSectionKey?: string;\n}\n\nexport class SettingsMenu extends Component<\n SettingsMenuProps,\n SettingsMenuState\n> {\n static defaultProps = {\n onDone: (): void => undefined,\n };\n\n static FORMATTING_SECTION_KEY = 'SettingsMenu.formatting';\n\n static COLUMN_SPECIFIC_SECTION_KEY = 'SettingsMenu.columnFormatting';\n\n static APPLICATION_SECTION_KEY = 'ApplicationMenu.settings';\n\n static SHORTCUT_SECTION_KEY = 'SettingsMenu.shortcuts';\n\n static THEME_SECTION_KEY = 'SettingsMenu.theme';\n\n static focusFirstInputInContainer(container: HTMLDivElement | null): void {\n const input = container?.querySelector('input, select, textarea');\n if (input) {\n (input as HTMLElement).focus();\n }\n }\n\n constructor(props: SettingsMenuProps) {\n super(props);\n\n this.handleClose = this.handleClose.bind(this);\n this.handleScrollTo = this.handleScrollTo.bind(this);\n this.handleSectionToggle = this.handleSectionToggle.bind(this);\n this.handleExportSupportLogs = this.handleExportSupportLogs.bind(this);\n this.handleLogout = this.handleLogout.bind(this);\n\n this.menuContentRef = React.createRef();\n this.broadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);\n\n this.state = {\n expandedSectionKey: SettingsMenu.FORMATTING_SECTION_KEY,\n };\n }\n\n componentDidMount(): void {\n SettingsMenu.focusFirstInputInContainer(this.menuContentRef.current);\n }\n\n componentWillUnmount(): void {\n this.broadcastChannel.close();\n }\n\n menuContentRef: RefObject<HTMLDivElement>;\n\n broadcastChannel: BroadcastChannel;\n\n isSectionExpanded(sectionKey: string): boolean {\n const { expandedSectionKey } = this.state;\n return expandedSectionKey === sectionKey;\n }\n\n handleLogout(): void {\n this.broadcastChannel.postMessage(makeMessage(BROADCAST_LOGOUT_MESSAGE));\n }\n\n handleScrollTo(x: number, y: number): void {\n this.menuContentRef.current?.scrollTo(x, y);\n }\n\n handleSectionToggle(sectionKey: string): void {\n this.setState(state => ({\n expandedSectionKey:\n state.expandedSectionKey === sectionKey ? undefined : sectionKey,\n }));\n }\n\n handleClose(): void {\n const { onDone } = this.props;\n onDone();\n }\n\n handleExportSupportLogs(): void {\n const { serverConfigValues, pluginData } = this.props;\n const pluginInfo = getFormattedPluginInfo(pluginData);\n exportLogs(undefined, {\n ...Object.fromEntries(serverConfigValues),\n pluginInfo,\n });\n }\n\n render(): ReactElement {\n const supportLink = import.meta.env.VITE_SUPPORT_LINK;\n const docsLink = import.meta.env.VITE_DOCS_LINK;\n\n const { serverConfigValues, pluginData, user } = this.props;\n const versionInfo = getFormattedVersionInfo(serverConfigValues);\n const pluginInfo = getFormattedPluginInfo(pluginData);\n const deephavenVersion = serverConfigValues.get('deephaven.version');\n const copyShortcut = GLOBAL_SHORTCUTS.COPY_VERSION_INFO.getDisplayText();\n\n const getRow = (text: string, ver?: string): JSX.Element => (\n <Fragment key={text}>\n <div>{text}</div>\n <div>{ver}</div>\n </Fragment>\n );\n\n const userDisplayName = user.displayName ?? user.name;\n const hasUserImage = user.image != null && user.image !== '';\n const showUserName = userDisplayName !== '';\n\n return (\n <div className=\"app-settings-menu\">\n <header className=\"app-settings-menu-header\">\n <div className=\"user-info\">\n <div className=\"user-image\">\n {!hasUserImage && (\n <FontAwesomeIcon icon={dhUser} transform=\"grow-8\" />\n )}\n {hasUserImage && <img src={user.image} alt={userDisplayName} />}\n </div>\n <div className=\"user-details\">\n {showUserName && (\n <div className=\"user-name\">\n {userDisplayName}\n {user.operateAs != null && user.name !== user.operateAs && (\n <>\n <span className=\"font-weight-light font-italic\">\n {' '}\n as{' '}\n </span>\n <span className=\"operating-as-user\">\n <FontAwesomeIcon\n icon={dhUserIncognito}\n className=\"mr-1\"\n />\n {user.operateAs}\n </span>\n </>\n )}\n </div>\n )}\n {user.permissions.canLogout && (\n <button\n type=\"button\"\n className=\"btn btn-link\"\n onClick={this.handleLogout}\n >\n logout\n </button>\n )}\n </div>\n </div>\n <Button\n kind=\"ghost\"\n className=\"btn-close-settings-menu\"\n onClick={this.handleClose}\n icon={<FontAwesomeIcon icon={vsClose} transform=\"grow-4\" />}\n tooltip=\"Close\"\n />\n </header>\n <div className=\"app-settings-menu-content\" ref={this.menuContentRef}>\n <h5>Settings</h5>\n\n <hr className=\"my-0\" />\n\n <SettingsMenuSection\n sectionKey={SettingsMenu.FORMATTING_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.FORMATTING_SECTION_KEY\n )}\n title={\n <>\n <FontAwesomeIcon\n icon={vsWatch}\n transform=\"grow-4\"\n className=\"mr-2\"\n />\n Default Format &amp; Time zone\n </>\n }\n onToggle={this.handleSectionToggle}\n >\n <FormattingSectionContent />\n </SettingsMenuSection>\n\n <SettingsMenuSection\n sectionKey={SettingsMenu.COLUMN_SPECIFIC_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.COLUMN_SPECIFIC_SECTION_KEY\n )}\n title={\n <>\n <FontAwesomeIcon\n icon={vsLayers}\n transform=\"grow-4\"\n className=\"mr-2\"\n />\n Format by Column Name &amp; Type\n </>\n }\n onToggle={this.handleSectionToggle}\n >\n <ColumnSpecificSectionContent scrollTo={this.handleScrollTo} />\n </SettingsMenuSection>\n\n <ThemeContext.Consumer>\n {contextValue => {\n assertNotNull(contextValue, 'ThemeContext value is null');\n\n return contextValue.themes.length > 1 ? (\n <SettingsMenuSection\n sectionKey={SettingsMenu.THEME_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.THEME_SECTION_KEY\n )}\n onToggle={this.handleSectionToggle}\n title={\n <>\n <FontAwesomeIcon\n icon={vsPaintcan}\n transform=\"grow-4\"\n className=\"mr-2\"\n />\n Theme\n </>\n }\n >\n <ThemePicker />\n </SettingsMenuSection>\n ) : null;\n }}\n </ThemeContext.Consumer>\n\n <SettingsMenuSection\n sectionKey={SettingsMenu.SHORTCUT_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.SHORTCUT_SECTION_KEY\n )}\n title={\n <>\n <FontAwesomeIcon icon={vsRecordKeys} transform=\"grow-2\" />{' '}\n Keyboard Shortcuts\n </>\n }\n onToggle={this.handleSectionToggle}\n >\n <ShortcutSectionContent />\n </SettingsMenuSection>\n\n <div className=\"app-settings-footer\">\n <div className=\"app-settings-footer-section\">\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Support</div>\n <div>\n GitHub:&nbsp;\n <a\n href={supportLink}\n className=\"custom-link\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {supportLink}\n </a>\n </div>\n <Button\n kind=\"tertiary\"\n className=\"mt-2 py-2\"\n onClick={this.handleExportSupportLogs}\n >\n Export Logs\n </Button>\n </div>\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Documentation</div>\n <a\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n href={docsLink}\n className=\"custom-link\"\n >\n {docsLink}\n </a>\n </div>\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Version</div>\n <span className=\"d-inline-block text-muted\">\n {deephavenVersion} <FontAwesomeIcon icon={vsInfo} />\n <Tooltip interactive>\n <div className=\"detailed-server-config\">\n {Object.entries(versionInfo).map(([key, value]) =>\n getRow(key, value)\n )}\n </div>\n <CopyButton\n kind=\"inline\"\n tooltip=\"Copy version numbers\"\n copy={Object.entries({\n ...versionInfo,\n ...pluginInfo,\n })\n .map(([key, value]) => `${key}: ${value}`)\n .join('\\n')}\n >\n Copy Versions\n <small className=\"text-muted\">({copyShortcut})</small>\n </CopyButton>\n </Tooltip>\n </span>\n </div>\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Plugins</div>\n <div className=\"container\">\n {Array.from(pluginData.entries())\n .filter(plugin => plugin[1].version !== undefined)\n .map(([key, value]) => (\n <div\n key={key}\n className=\"row justify-content-start align-items-center\"\n >\n <div className=\"col pl-0\">\n <span className=\"my-0 text-truncate\">{key}</span>\n </div>\n <div className=\"col-auto\">\n <span>{value?.version}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n <div className=\"app-settings-footer-item\">\n <LegalNotice />\n </div>\n </div>\n <div className=\"app-settings-footer-section\">\n <a\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n href=\"https://deephaven.io\"\n style={{\n display: 'block',\n width: '61.8%',\n }}\n >\n <Logo />\n </a>\n </div>\n </div>\n </div>\n </div>\n );\n }\n}\n\nexport default SettingsMenu;\n","import React, {\n useRef,\n useEffect,\n useCallback,\n useState,\n useMemo,\n ReactNode,\n ReactElement,\n} from 'react';\nimport classNames from 'classnames';\nimport {\n DropdownAction,\n DropdownMenu,\n GLOBAL_SHORTCUTS,\n} from '@deephaven/components';\nimport { ControlType, ToolType } from '@deephaven/dashboard-core-plugins';\nimport { SHORTCUTS as IRIS_GRID_SHORTCUTS } from '@deephaven/iris-grid';\nimport {\n dhInput,\n dhFilterSlash,\n dhTriangleDownSquare,\n vsLink,\n vsMarkdown,\n vsDeviceCamera,\n} from '@deephaven/icons';\nimport PropTypes from 'prop-types';\n\nconst MINIMUM_DRAG_DISTANCE = 10;\n\ninterface DragSourceMenuItemProps {\n forwardedProps: {\n iconElement: ReactNode;\n displayShortcut: string;\n isMouseSelected: boolean;\n isKeyboardSelected: boolean;\n closeMenu: () => void;\n menuItem: {\n action: (event?: MouseEvent) => void;\n title: string;\n disabled: boolean;\n };\n };\n}\n\n/**\n * helper component that renders a menu item\n * props are fowarded from ContextMenuItem\n * purpose is to add custom mouse handlers\n * for dragging panels directly from menu\n */\n\nfunction DragSourceMenuItem(props: DragSourceMenuItemProps): JSX.Element {\n const {\n forwardedProps: {\n menuItem: { action, title, disabled: menuItemDisabled },\n iconElement,\n displayShortcut,\n isMouseSelected,\n isKeyboardSelected,\n closeMenu,\n },\n } = props;\n\n const startX = useRef<number>();\n const startY = useRef<number>();\n const startObject = useRef<EventTarget | null>(null);\n\n // used to prevent double clicking inserting an object twice\n const [disableDoubleClick, setDisableDoubleClick] = useState(false);\n\n const handleMouseMove = useCallback(\n (event: MouseEvent) => {\n if (\n startX.current != null &&\n startY.current != null &&\n startObject.current &&\n (Math.abs(startX.current - event.clientX) >= MINIMUM_DRAG_DISTANCE ||\n Math.abs(startY.current - event.clientY) >= MINIMUM_DRAG_DISTANCE)\n ) {\n setDisableDoubleClick(true);\n window.removeEventListener('mousemove', handleMouseMove);\n closeMenu();\n action(event);\n startObject.current = null; // null object so mouseUp can't fire\n }\n },\n [action, closeMenu]\n );\n\n function handleMouseDown(event: React.MouseEvent<HTMLButtonElement>): void {\n startX.current = event.clientX;\n startY.current = event.clientY;\n startObject.current = event.target;\n window.addEventListener('mousemove', handleMouseMove);\n }\n\n function handleMouseUp(event: React.MouseEvent<HTMLButtonElement>): void {\n // down and up need to occur on same object to constitute a click event\n if (startObject.current === event.target) {\n setDisableDoubleClick(true);\n closeMenu();\n action();\n window.removeEventListener('mousemove', handleMouseMove);\n }\n startObject.current = null; // null object so mousemove can't fire3\n }\n\n useEffect(\n // funny syntax after prettier, return function for the cleanup function\n function cleanUpMouseEventListener() {\n return function removeOldMouseMoveEventListener() {\n return window.removeEventListener('mousemove', handleMouseMove);\n };\n },\n [handleMouseMove]\n );\n\n return (\n <button\n type=\"button\"\n className={classNames(\n 'btn-context-menu',\n { disabled: menuItemDisabled },\n {\n active: isMouseSelected && !menuItemDisabled,\n },\n { 'keyboard-active': isKeyboardSelected && !menuItemDisabled }\n )}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n disabled={disableDoubleClick}\n >\n <span className={classNames('icon')}>{iconElement}</span>\n <span className=\"title\">{title}</span>\n <span className=\"shortcut\">{displayShortcut}</span>\n </button>\n );\n}\n\ninterface AppControlsMenuProps {\n handleControlSelect: (type: string, event: Event) => void;\n handleToolSelect: (type: string) => void;\n onClearFilter: () => void;\n}\n\nfunction AppControlsMenu(props: AppControlsMenuProps): ReactElement {\n const { handleControlSelect, handleToolSelect, onClearFilter } = props;\n const controlMenuActions: DropdownAction[] = useMemo(\n () => [\n {\n title: 'Input Filter',\n icon: dhInput,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.INPUT_FILTER, dragEvent);\n },\n order: 10,\n },\n {\n title: 'Dropdown Filter',\n icon: dhTriangleDownSquare,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.DROPDOWN_FILTER, dragEvent);\n },\n order: 15,\n },\n {\n title: 'Markdown Widget',\n icon: vsMarkdown,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.MARKDOWN, dragEvent);\n },\n order: 20,\n },\n {\n title: 'Filter Sets',\n icon: vsDeviceCamera,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.FILTER_SET_MANAGER, dragEvent);\n },\n order: 25,\n },\n {\n disabled: true,\n menuElement: <div className=\"context-menu-group-header\">Tools</div>,\n order: 30,\n },\n {\n title: 'Linker',\n icon: vsLink,\n action: () => {\n handleToolSelect(ToolType.LINKER);\n },\n order: 40,\n shortcut: GLOBAL_SHORTCUTS.LINKER,\n },\n {\n disabled: true,\n menuElement: <div className=\"context-menu-group-header\">Actions</div>,\n order: 50,\n },\n {\n title: 'Clear All Filters',\n icon: dhFilterSlash,\n action: () => {\n onClearFilter();\n },\n order: 60,\n shortcut: IRIS_GRID_SHORTCUTS.TABLE.CLEAR_ALL_FILTERS,\n },\n ],\n [handleControlSelect, handleToolSelect, onClearFilter]\n );\n\n return (\n <DropdownMenu\n popperClassName=\"controls-menu-popper\"\n actions={controlMenuActions}\n />\n );\n}\n\nAppControlsMenu.propTypes = {\n handleControlSelect: PropTypes.func,\n handleToolSelect: PropTypes.func,\n onClearFilter: PropTypes.func,\n};\n\nAppControlsMenu.defaultProps = {\n handleControlSelect: () => undefined,\n handleToolSelect: () => undefined,\n onClearFilter: () => undefined,\n};\n\nDragSourceMenuItem.propTypes = {\n forwardedProps: PropTypes.shape({\n iconElement: PropTypes.node,\n displayShortcut: PropTypes.string,\n isMouseSelected: PropTypes.bool.isRequired,\n isKeyboardSelected: PropTypes.bool.isRequired,\n closeMenu: PropTypes.func.isRequired,\n menuItem: PropTypes.shape({\n action: PropTypes.func,\n title: PropTypes.string,\n disabled: PropTypes.bool,\n }).isRequired,\n }),\n};\n\nDragSourceMenuItem.defaultProps = {\n forwardedProps: null,\n};\n\nexport default AppControlsMenu;\n","/**\n * Set the layout storage object being used to load/save the layout\n */\nimport { replaceReducer } from '@deephaven/redux';\nimport { SET_LAYOUT_STORAGE } from '../actionTypes';\n\nexport default replaceReducer(SET_LAYOUT_STORAGE, null);\n","import layoutStorage from './layoutStorage';\n\nexport default { layoutStorage };\n","import { RootState } from '@deephaven/redux';\nimport LayoutStorage from '../storage/LayoutStorage';\n\n/**\n * Get the layout storage used by the app\n * @param store The redux store\n * @returns The layout storage instance\n */\nexport const getLayoutStorage = <State extends RootState = RootState>(\n store: State\n): LayoutStorage => store.layoutStorage as LayoutStorage;\n\n/**\n * Get the configuration values of the server\n * @param store The redux store\n * @returns The layout storage instance\n */\nexport const getServerConfigValues = <State extends RootState = RootState>(\n store: State\n): State['serverConfigValues'] => store.serverConfigValues;\n","import { reducerRegistry } from '@deephaven/redux';\nimport reducers from './reducers';\n\nObject.entries(reducers).map(([name, reducer]) =>\n reducerRegistry.register(name, reducer)\n);\n\nexport * from './actions';\nexport * from './actionTypes';\nexport * from './selectors';\n","import React, {\n ChangeEvent,\n MouseEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Button, SearchInput } from '@deephaven/components';\nimport { ObjectIcon } from '@deephaven/console';\nimport {\n vsArrowSmallDown,\n vsArrowSmallUp,\n vsPreview,\n vsRefresh,\n} from '@deephaven/icons';\nimport type { dh } from '@deephaven/jsapi-types';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport './WidgetList.scss';\n\nconst MINIMUM_DRAG_DISTANCE = 10;\n\n// When we're listening on the window, it emits a `globalThis.MouseEvent`\n// `WindowMouseEvent` is just a convenience alias\nexport type WindowMouseEvent = globalThis.MouseEvent;\n\nexport type SelectStartEvent = {\n x: number;\n y: number;\n widget: dh.ide.VariableDefinition;\n};\n\nexport interface WidgetListProps {\n onSelect: (widget: dh.ide.VariableDefinition, e?: WindowMouseEvent) => void;\n onExportLayout: () => void;\n onImportLayout: () => void;\n onResetLayout: () => void;\n widgets?: dh.ide.VariableDefinition[];\n}\n\n/**\n * Display a search field and a list of widgets, as well as layout export/import buttons.\n * @param props The widgets and handlers to use for this list\n * @returns A JSX element for the list of widgets, along with search\n */\nexport function WidgetList(props: WidgetListProps): JSX.Element {\n const {\n onExportLayout,\n onImportLayout,\n onResetLayout,\n onSelect,\n widgets = [],\n } = props;\n const [disableDoubleClick, setDisableDoubleClick] = useState(false);\n const [searchText, setSearchText] = useState('');\n const searchField = useRef<SearchInput>(null);\n const selectStartEvent = useRef<SelectStartEvent>();\n\n /**\n * Send object to be created, if an event is passed object\n * is treated as createDragSourceFromEvent in golden-layout\n * and uses the event as the starting location for the drag.\n * @param widget\n * @param event\n */\n const sendSelect = useCallback(\n (widget: dh.ide.VariableDefinition, event?: WindowMouseEvent) => {\n if (widget != null) onSelect(widget, event);\n },\n [onSelect]\n );\n\n const handleSearchChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setSearchText(e.target.value);\n }, []);\n\n const handleMouseMove = useCallback(\n (e: WindowMouseEvent) => {\n if (selectStartEvent.current == null) {\n return;\n }\n\n if (\n Math.abs(selectStartEvent.current.x - e.clientX) >=\n MINIMUM_DRAG_DISTANCE ||\n Math.abs(selectStartEvent.current.y - e.clientY) >=\n MINIMUM_DRAG_DISTANCE\n ) {\n setDisableDoubleClick(true);\n window.removeEventListener('mousemove', handleMouseMove);\n sendSelect(selectStartEvent.current.widget, e);\n selectStartEvent.current = undefined; // unset so mouseUp can't fire\n }\n },\n [selectStartEvent, sendSelect]\n );\n\n const handleMouseDown = useCallback(\n (e: MouseEvent, widget: dh.ide.VariableDefinition) => {\n selectStartEvent.current = {\n x: e.clientX,\n y: e.clientY,\n widget,\n };\n window.addEventListener('mousemove', handleMouseMove);\n },\n [handleMouseMove]\n );\n\n const handleMouseUp = useCallback(\n (e: MouseEvent, widget: dh.ide.VariableDefinition) => {\n window.removeEventListener('mousemove', handleMouseMove);\n\n // down and up need to occur on same object to constitute a click event\n if (selectStartEvent.current?.widget === widget) {\n setDisableDoubleClick(true);\n sendSelect(widget);\n }\n selectStartEvent.current = undefined;\n },\n [handleMouseMove, selectStartEvent, sendSelect]\n );\n\n const filteredWidgets = useMemo(\n () =>\n widgets.filter(widget =>\n searchText\n ? widget.name?.toLowerCase().includes(searchText.toLowerCase())\n : true\n ),\n [searchText, widgets]\n ).sort((a, b) => a.name?.localeCompare(b.name ?? '') ?? 0);\n\n const widgetElements = useMemo(\n () =>\n filteredWidgets.map(widget => (\n <li key={widget.name}>\n <Button\n kind=\"ghost\"\n data-testid={`panel-list-item-${widget.name ?? ''}-button`}\n onMouseDown={event => {\n handleMouseDown(event, widget);\n }}\n onMouseUp={event => {\n handleMouseUp(event, widget);\n }}\n onKeyDown={event => {\n if (event.key === 'Enter' || event.key === ' ') {\n sendSelect(widget);\n }\n }}\n disabled={disableDoubleClick}\n onClick={() => {\n // no-op: click is handled by onMouseDown and onMouseUp attributes\n }}\n >\n <ObjectIcon type={widget.type} /> {widget.name ?? ''}\n </Button>\n </li>\n )),\n [\n filteredWidgets,\n disableDoubleClick,\n handleMouseDown,\n handleMouseUp,\n sendSelect,\n ]\n );\n\n const errorElement = useMemo(\n () =>\n widgetElements.length === 0 ? (\n <span>No bound variables found.</span>\n ) : null,\n [widgetElements]\n );\n\n return (\n <div className=\"widget-list-container d-flex flex-column\">\n <div className=\"widget-list-header\">\n <SearchInput\n value={searchText}\n placeholder=\"Find Table, Plot or Widget\"\n onChange={handleSearchChange}\n ref={searchField}\n />\n </div>\n <ul className=\"widget-list flex-grow-1\">\n {errorElement && (\n <li className=\"widget-list-message\">{errorElement}</li>\n )}\n {!errorElement && widgetElements}\n </ul>\n <div>\n <hr />\n </div>\n <div className=\"widget-list-footer\">\n <Button kind=\"ghost\" onClick={onExportLayout}>\n <div className=\"fa-md fa-layers\">\n <FontAwesomeIcon\n mask={vsPreview}\n icon={vsArrowSmallDown}\n transform=\"right-5 down-5\"\n />\n <FontAwesomeIcon\n icon={vsArrowSmallDown}\n transform=\"right-8 down-6\"\n />\n </div>\n Export Layout\n </Button>\n <Button kind=\"ghost\" onClick={onImportLayout}>\n <div className=\"fa-md fa-layers\">\n <FontAwesomeIcon\n mask={vsPreview}\n icon={vsArrowSmallUp}\n transform=\"right-5 down-5\"\n />\n <FontAwesomeIcon icon={vsArrowSmallUp} transform=\"right-8 down-6\" />\n </div>\n Import Layout\n </Button>\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={onResetLayout}\n tooltip=\"Reset Layout\"\n />\n </div>\n </div>\n );\n}\n\nexport default WidgetList;\n","import type { ItemConfigType } from '@deephaven/golden-layout';\nimport { FilterSet, Link } from '@deephaven/dashboard-core-plugins';\nimport { PluginDataMap } from '@deephaven/redux';\n\n/**\n * Have a different version to support legacy layout exports\n */\nexport type ExportedLayoutV1 = ItemConfigType[];\n\nexport type ExportedLayoutV2 = {\n filterSets: FilterSet[];\n links: Link[];\n layoutConfig: ItemConfigType[];\n pluginDataMap?: PluginDataMap;\n version: 2;\n};\n\nexport type ExportedLayout = ExportedLayoutV1 | ExportedLayoutV2;\n\nexport function isLayoutV2(layout: ExportedLayout): layout is ExportedLayoutV2 {\n return (layout as ExportedLayoutV2).version === 2;\n}\n\nexport function isLayoutV1(layout: ExportedLayout): layout is ExportedLayoutV1 {\n return Array.isArray(layout);\n}\n\n/**\n * Interface for accessing layouts from wherever they are stored.\n */\nexport interface LayoutStorage {\n /**\n * Get the name of the layouts available\n * @returns The string array of layout names\n */\n getLayouts: () => Promise<string[]>;\n\n /**\n * Get the layout with the specified name\n * @param name The name of the layout to fetch\n * @returns GoldenLayout layout config\n */\n getLayout: (name: string) => Promise<ExportedLayout>;\n}\n\nexport default LayoutStorage;\n","import {\n CommandHistoryPanel,\n ConsolePanel,\n FileExplorerPanel,\n LogPanel,\n} from '@deephaven/dashboard-core-plugins';\nimport Log from '@deephaven/log';\nimport { CustomizableWorkspaceData } from '@deephaven/redux';\nimport LayoutStorage, {\n ExportedLayout,\n ExportedLayoutV2,\n isLayoutV1,\n isLayoutV2,\n} from '../storage/LayoutStorage';\n\nconst log = Log.module('UserLayoutUtils');\n\nexport const DEFAULT_LAYOUT_CONFIG: ExportedLayoutV2 = {\n layoutConfig: [\n {\n type: 'column',\n content: [\n {\n type: 'row',\n height: 40, // slightly smaller than 50-50 to allow more space for tables below\n content: [\n {\n type: 'stack',\n content: [\n {\n type: 'react-component',\n component: ConsolePanel.COMPONENT,\n title: ConsolePanel.TITLE,\n isClosable: false,\n },\n {\n type: 'react-component',\n component: LogPanel.COMPONENT,\n title: LogPanel.TITLE,\n isClosable: false,\n },\n ],\n },\n {\n type: 'stack',\n width: 25,\n content: [\n {\n type: 'react-component',\n component: CommandHistoryPanel.COMPONENT,\n title: CommandHistoryPanel.TITLE,\n isClosable: false,\n },\n {\n type: 'react-component',\n component: FileExplorerPanel.COMPONENT,\n title: FileExplorerPanel.TITLE,\n isClosable: false,\n },\n ],\n },\n ],\n },\n {\n type: 'row',\n content: [\n {\n type: 'stack',\n title: 'Notebooks',\n content: [],\n },\n ],\n },\n ],\n },\n ],\n links: [],\n filterSets: [],\n version: 2,\n};\n\nexport const DEFAULT_LAYOUT_CONFIG_NO_CONSOLE: ExportedLayoutV2 = {\n layoutConfig: [],\n links: [],\n filterSets: [],\n version: 2,\n};\n\nexport function normalizeLayout(layout: ExportedLayout): ExportedLayoutV2 {\n if (isLayoutV2(layout)) {\n return layout;\n }\n if (isLayoutV1(layout)) {\n const layoutConfig = layout;\n return {\n layoutConfig,\n links: [],\n filterSets: [],\n version: 2,\n };\n }\n\n throw new Error(`Unexpected layout import format: ${layout}`);\n}\n\n/**\n * Get the default layout for the user to use. Checks layout storage for any layouts, and uses the first one if found.\n * @param layoutStorage The layout storage to get the default layouts from\n * @param isConsoleAvailable Whether console sessions are available.\n * @returns The default layout config to use\n */\nexport async function getDefaultLayout(\n layoutStorage: LayoutStorage,\n isConsoleAvailable = true\n): Promise<ExportedLayoutV2> {\n try {\n const layouts = await layoutStorage.getLayouts();\n if (layouts.length > 0) {\n try {\n // We found a layout on the server, use it. It could be an empty layout if they want user to build their own\n const layout = await layoutStorage.getLayout(layouts[0]);\n return normalizeLayout(layout);\n } catch (err) {\n log.error('Unable to load layout', layouts[0], ':', err);\n log.warn('No valid layouts found, falling back to default layout');\n }\n }\n } catch (err) {\n log.error('Unable to fetch layout list', err);\n log.warn('Falling back to default layout');\n }\n // Otherwise, do the default layout\n return isConsoleAvailable\n ? DEFAULT_LAYOUT_CONFIG\n : DEFAULT_LAYOUT_CONFIG_NO_CONSOLE;\n}\n\nexport function exportLayout(\n data: CustomizableWorkspaceData\n): ExportedLayoutV2 {\n const { filterSets, layoutConfig, links, pluginDataMap } = data as Omit<\n ExportedLayoutV2,\n 'version'\n >;\n const exportedLayout: ExportedLayoutV2 = {\n filterSets,\n layoutConfig,\n links,\n pluginDataMap,\n version: 2,\n };\n return exportedLayout;\n}\n\nexport default { exportLayout, getDefaultLayout, normalizeLayout };\n","import React from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button } from '@deephaven/components';\nimport { vsArrowUp } from '@deephaven/icons';\nimport './EmptyDashboard.scss';\n\nexport interface EmptyDashboardProps {\n onAutoFillClick?: (event: React.MouseEvent) => void;\n}\n\nexport function EmptyDashboard({\n onAutoFillClick = () => undefined,\n}: EmptyDashboardProps): JSX.Element {\n return (\n <div className=\"empty-dashboard-container\">\n <div className=\"hint-container\">\n <FontAwesomeIcon icon={vsArrowUp} /> <br />\n Use the panel list to add objects from a query.\n </div>\n <div className=\"empty-dashboard\">\n <div className=\"add-panels-hint\">Drag Panels Here</div>\n <Button kind=\"tertiary\" onClick={onAutoFillClick}>\n Auto fill objects\n </Button>\n </div>\n </div>\n );\n}\n\nexport default EmptyDashboard;\n","import React, {\n ClipboardEvent,\n ChangeEvent,\n Component,\n ReactElement,\n RefObject,\n} from 'react';\nimport classNames from 'classnames';\nimport memoize from 'memoize-one';\nimport { connect } from 'react-redux';\nimport { RouteComponentProps, withRouter } from 'react-router-dom';\nimport { nanoid } from 'nanoid';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n ContextActions,\n ThemeExport,\n GLOBAL_SHORTCUTS,\n Popper,\n ContextAction,\n Button,\n InfoModal,\n LoadingSpinner,\n Logo,\n BasicModal,\n DebouncedModal,\n NavTabList,\n type NavTabItem,\n SlideTransition,\n LoadingOverlay,\n} from '@deephaven/components';\nimport { SHORTCUTS as IRIS_GRID_SHORTCUTS } from '@deephaven/iris-grid';\nimport {\n CreateDashboardPayload,\n DashboardUtils,\n DEFAULT_DASHBOARD_ID,\n DehydratedDashboardPanelProps,\n getAllDashboardsData,\n getDashboardData,\n listenForCreateDashboard,\n PanelEvent,\n setDashboardData as setDashboardDataAction,\n setDashboardPluginData as setDashboardPluginDataAction,\n stopListenForCreateDashboard,\n updateDashboardData as updateDashboardDataAction,\n} from '@deephaven/dashboard';\nimport {\n ConsolePlugin,\n InputFilterEvent,\n MarkdownEvent,\n NotebookEvent,\n getDashboardSessionWrapper,\n ControlType,\n ToolType,\n getDashboardConnection,\n NotebookPanel,\n} from '@deephaven/dashboard-core-plugins';\nimport {\n vsGear,\n dhShapes,\n dhPanels,\n vsDebugDisconnect,\n dhSquareFilled,\n vsTerminal,\n} from '@deephaven/icons';\nimport { getVariableDescriptor } from '@deephaven/jsapi-bootstrap';\nimport dh from '@deephaven/jsapi-shim';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport { SessionConfig } from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport {\n getActiveTool,\n getWorkspace,\n getUser,\n setActiveTool as setActiveToolAction,\n updateWorkspaceData as updateWorkspaceDataAction,\n getPlugins,\n WorkspaceData,\n RootState,\n User,\n ServerConfigValues,\n CustomizableWorkspace,\n DashboardData,\n} from '@deephaven/redux';\nimport {\n bindAllMethods,\n copyToClipboard,\n PromiseUtils,\n EMPTY_ARRAY,\n} from '@deephaven/utils';\nimport GoldenLayout from '@deephaven/golden-layout';\nimport type { ItemConfigType } from '@deephaven/golden-layout';\nimport { type PluginModuleMap, getDashboardPlugins } from '@deephaven/plugin';\nimport { AppDashboards } from '@deephaven/app-utils';\nimport JSZip from 'jszip';\nimport SettingsMenu from '../settings/SettingsMenu';\nimport AppControlsMenu from './AppControlsMenu';\nimport { getLayoutStorage, getServerConfigValues } from '../redux';\nimport './AppMainContainer.scss';\nimport WidgetList, { WindowMouseEvent } from './WidgetList';\nimport UserLayoutUtils from './UserLayoutUtils';\nimport LayoutStorage from '../storage/LayoutStorage';\nimport { getFormattedVersionInfo } from '../settings/SettingsUtils';\nimport EmptyDashboard from './EmptyDashboard';\n\nconst log = Log.module('AppMainContainer');\n\ntype InputFileFormat =\n | string\n | number[]\n | Uint8Array\n | ArrayBuffer\n | Blob\n | NodeJS.ReadableStream;\n\ninterface AppMainContainerProps {\n activeTool: string;\n allDashboardData: Record<string, DashboardData>;\n dashboardData: DashboardData;\n layoutStorage: LayoutStorage;\n match: {\n params: { notebookPath: string };\n };\n connection?: DhType.IdeConnection;\n session?: DhType.IdeSession;\n sessionConfig?: SessionConfig;\n setActiveTool: (tool: string) => void;\n setDashboardData: (id: string, data: DashboardData) => void;\n setDashboardPluginData: (\n dashboardId: string,\n pluginId: string,\n data: unknown\n ) => void;\n updateDashboardData: (id: string, data: Partial<DashboardData>) => void;\n updateWorkspaceData: (workspaceData: Partial<WorkspaceData>) => void;\n user: User;\n workspace: CustomizableWorkspace;\n plugins: PluginModuleMap;\n serverConfigValues: ServerConfigValues;\n}\n\ninterface AppMainContainerState {\n contextActions: ContextAction[];\n isAuthFailed: boolean;\n isDisconnected: boolean;\n isPanelsMenuShown: boolean;\n isResetLayoutPromptShown: boolean;\n isSettingsMenuShown: boolean;\n unsavedNotebookCount: number;\n widgets: DhType.ide.VariableDefinition[];\n tabs: NavTabItem[];\n activeTabKey: string;\n\n // Number of times the layout has been re-initialized\n layoutIteration: number;\n}\n\nexport class AppMainContainer extends Component<\n AppMainContainerProps & RouteComponentProps,\n AppMainContainerState\n> {\n static handleWindowBeforeUnload(event: BeforeUnloadEvent): void {\n // in development, allow auto-reload\n if (import.meta.env.PROD) {\n event.preventDefault();\n // returnValue is required for beforeReload event prompt\n // https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#example\n // eslint-disable-next-line no-param-reassign\n event.returnValue = '';\n }\n }\n\n static hydrateConsole(\n props: DehydratedDashboardPanelProps,\n id: string\n ): DehydratedDashboardPanelProps {\n return DashboardUtils.hydrate(\n {\n ...props,\n unzip: (zipFile: InputFileFormat) =>\n JSZip.loadAsync(zipFile).then(zip => Object.values(zip.files)),\n },\n id\n );\n }\n\n static handleRefresh(): void {\n log.info('Refreshing application');\n window.location.reload();\n }\n\n constructor(props: AppMainContainerProps & RouteComponentProps) {\n super(props);\n\n bindAllMethods(this);\n\n this.importElement = React.createRef();\n\n const { allDashboardData } = this.props;\n\n this.dashboardLayouts = new Map();\n\n this.state = {\n contextActions: [\n {\n action: () => {\n // Copies the version info to the clipboard for easy pasting into a ticket\n const { serverConfigValues } = this.props;\n const versionInfo = getFormattedVersionInfo(serverConfigValues);\n const versionInfoText = Object.entries(versionInfo)\n .map(([key, value]) => `${key}: ${value}`)\n .join('\\n');\n copyToClipboard(versionInfoText);\n },\n shortcut: GLOBAL_SHORTCUTS.COPY_VERSION_INFO,\n isGlobal: true,\n },\n {\n action: () => {\n this.handleToolSelect(ToolType.LINKER);\n },\n shortcut: GLOBAL_SHORTCUTS.LINKER,\n isGlobal: true,\n },\n {\n action: () => {\n // triggers clear all filters tab event, which in turn triggers a glEventhub event\n // widget panels can subscribe to his event, and execute their own clearing logic\n this.sendClearFilter();\n },\n shortcut: IRIS_GRID_SHORTCUTS.TABLE.CLEAR_ALL_FILTERS,\n isGlobal: true,\n },\n {\n action: () => {\n this.sendReopenLast();\n },\n shortcut: GLOBAL_SHORTCUTS.REOPEN_CLOSED_PANEL,\n isGlobal: true,\n },\n {\n action: () => {\n log.debug('Consume unhandled save shortcut');\n },\n shortcut: GLOBAL_SHORTCUTS.SAVE,\n isGlobal: true,\n },\n ],\n isAuthFailed: false,\n isDisconnected: false,\n isPanelsMenuShown: false,\n isResetLayoutPromptShown: false,\n isSettingsMenuShown: false,\n unsavedNotebookCount: 0,\n widgets: [],\n tabs: Object.entries(allDashboardData).map(([key, value]) => ({\n key,\n title: value.title ?? 'Untitled',\n isClosable: key !== DEFAULT_DASHBOARD_ID,\n icon: key === DEFAULT_DASHBOARD_ID ? vsTerminal : undefined,\n })),\n activeTabKey: DEFAULT_DASHBOARD_ID,\n layoutIteration: 0,\n };\n }\n\n componentDidMount(): void {\n this.initWidgets();\n this.initDashboardData();\n this.startListeningForDisconnect();\n\n window.addEventListener(\n 'beforeunload',\n AppMainContainer.handleWindowBeforeUnload\n );\n }\n\n componentDidUpdate(\n prevProps: AppMainContainerProps,\n prevState: AppMainContainerState\n ): void {\n const { dashboardData } = this.props;\n if (prevProps.dashboardData !== dashboardData) {\n this.handleDataChange(dashboardData);\n }\n }\n\n componentWillUnmount(): void {\n this.deinitWidgets();\n this.stopListeningForDisconnect();\n\n this.dashboardLayouts.forEach(layout => {\n stopListenForCreateDashboard(layout.eventHub, this.handleCreateDashboard);\n });\n\n window.removeEventListener(\n 'beforeunload',\n AppMainContainer.handleWindowBeforeUnload\n );\n }\n\n /** Map from the dashboard ID to the GoldenLayout instance for that dashboard */\n dashboardLayouts: Map<string, GoldenLayout>;\n\n importElement: RefObject<HTMLInputElement>;\n\n widgetListenerRemover?: () => void;\n\n initWidgets(): void {\n const { connection } = this.props;\n if (connection == null) {\n return;\n }\n\n if (connection.subscribeToFieldUpdates == null) {\n log.warn(\n 'subscribeToFieldUpdates not supported, not initializing widgets'\n );\n return;\n }\n\n this.widgetListenerRemover = connection.subscribeToFieldUpdates(updates => {\n log.debug('Got updates', updates);\n this.setState(({ widgets }) => {\n const { updated, created, removed } = updates;\n\n // Remove from the array if it's been removed OR modified. We'll add it back after if it was modified.\n const widgetsToRemove = [...updated, ...removed];\n const newWidgets = widgets.filter(\n widget =>\n !widgetsToRemove.some(toRemove => toRemove.name === widget.name)\n );\n\n // Now add all the modified and updated widgets back in\n const widgetsToAdd = [...updated, ...created];\n widgetsToAdd.forEach(toAdd => {\n if (toAdd.name != null && toAdd.name !== '') {\n newWidgets.push(toAdd);\n }\n });\n\n return { widgets: newWidgets };\n });\n });\n }\n\n deinitWidgets(): void {\n this.widgetListenerRemover?.();\n }\n\n initDashboardData(): void {\n // TODO: #1746 We should be loading data from a dashboard storage store\n // For now only the default dashboard data is stored with the workspace and set on the default dashboard\n const { setDashboardPluginData, updateDashboardData, workspace } =\n this.props;\n const { data: workspaceData } = workspace;\n const { filterSets, links, pluginDataMap } = workspaceData;\n updateDashboardData(DEFAULT_DASHBOARD_ID, {\n filterSets,\n links,\n });\n if (pluginDataMap != null) {\n const pluginKeys = Object.keys(pluginDataMap);\n for (let i = 0; i < pluginKeys.length; i += 1) {\n const pluginId = pluginKeys[i];\n const pluginData = pluginDataMap[pluginId];\n log.debug('initDashboardData plugin data', pluginId, pluginData);\n setDashboardPluginData(DEFAULT_DASHBOARD_ID, pluginId, pluginData);\n }\n }\n }\n\n openNotebookFromURL(): void {\n const { match } = this.props;\n const { notebookPath } = match.params;\n\n if (notebookPath) {\n const { session, sessionConfig } = this.props;\n if (session == null || sessionConfig == null) {\n log.error('No session available to open notebook URL', notebookPath);\n return;\n }\n const fileMetadata = {\n id: `/${notebookPath}`,\n itemName: `/${notebookPath}`,\n };\n\n const language = sessionConfig.type;\n const notebookSettings = {\n value: null,\n language,\n };\n\n this.emitLayoutEvent(\n NotebookEvent.SELECT_NOTEBOOK,\n session,\n language,\n notebookSettings,\n fileMetadata,\n true\n );\n }\n }\n\n sendClearFilter(): void {\n this.emitLayoutEvent(InputFilterEvent.CLEAR_ALL_FILTERS);\n }\n\n sendReopenLast(): void {\n this.emitLayoutEvent(PanelEvent.REOPEN_LAST);\n }\n\n emitLayoutEvent(event: string, ...args: unknown[]): void {\n const { activeTabKey } = this.state;\n const layout = this.dashboardLayouts.get(activeTabKey);\n layout?.eventHub.emit(event, ...args);\n }\n\n handleCancelResetLayoutPrompt(): void {\n this.setState({\n isResetLayoutPromptShown: false,\n });\n }\n\n handleConfirmResetLayoutPrompt(): void {\n this.setState({\n isResetLayoutPromptShown: false,\n });\n\n this.resetLayout();\n }\n\n // eslint-disable-next-line class-methods-use-this\n handleError(error: unknown): void {\n if (PromiseUtils.isCanceled(error)) {\n return;\n }\n log.error(error);\n }\n\n handleSettingsMenuHide(): void {\n this.setState({ isSettingsMenuShown: false });\n }\n\n handleSettingsMenuShow(): void {\n this.setState({ isSettingsMenuShown: true });\n }\n\n handleControlSelect(type: string, dragEvent: Event): void {\n log.debug('handleControlSelect', type);\n\n switch (type) {\n case ControlType.DROPDOWN_FILTER:\n this.emitLayoutEvent(InputFilterEvent.OPEN_DROPDOWN, {\n title: 'DropdownFilter',\n type,\n createNewStack: true,\n dragEvent,\n });\n break;\n case ControlType.INPUT_FILTER:\n this.emitLayoutEvent(InputFilterEvent.OPEN_INPUT, {\n title: 'InputFilter',\n type,\n createNewStack: true,\n dragEvent,\n });\n break;\n case ControlType.MARKDOWN:\n this.emitLayoutEvent(MarkdownEvent.OPEN, {\n title: 'Markdown',\n type,\n dragEvent,\n });\n break;\n case ControlType.FILTER_SET_MANAGER:\n this.emitLayoutEvent(InputFilterEvent.OPEN_FILTER_SET_MANAGER, {\n title: 'FilterSets',\n type,\n dragEvent,\n });\n break;\n default:\n throw new Error(`Unrecognized control type ${type}`);\n }\n }\n\n handleToolSelect(toolType: string): void {\n log.debug('handleToolSelect', toolType);\n\n const { activeTool, setActiveTool } = this.props;\n if (activeTool === toolType) {\n setActiveTool(ToolType.DEFAULT);\n } else {\n setActiveTool(toolType);\n }\n }\n\n handleClearFilter(): void {\n this.sendClearFilter();\n }\n\n handleDataChange(data: DashboardData): void {\n const { updateWorkspaceData } = this.props;\n\n // Only save the data that is serializable/we want to persist to the workspace\n const { closed, filterSets, links, pluginDataMap } = data;\n updateWorkspaceData({ closed, filterSets, links, pluginDataMap });\n }\n\n handleGoldenLayoutChange(newLayout: GoldenLayout): void {\n const { activeTabKey } = this.state;\n const oldLayout = this.dashboardLayouts.get(activeTabKey);\n if (oldLayout === newLayout) return;\n\n if (oldLayout != null) {\n stopListenForCreateDashboard(\n oldLayout.eventHub,\n this.handleCreateDashboard\n );\n }\n\n this.dashboardLayouts.set(activeTabKey, newLayout);\n\n listenForCreateDashboard(newLayout.eventHub, this.handleCreateDashboard);\n }\n\n handleCreateDashboard({\n pluginId,\n title,\n data,\n }: CreateDashboardPayload): void {\n const newId = nanoid();\n const { setDashboardPluginData } = this.props;\n setDashboardPluginData(newId, pluginId, data);\n this.setState(({ tabs }) => ({\n tabs: [\n ...tabs,\n {\n key: newId,\n title,\n },\n ],\n activeTabKey: newId,\n }));\n }\n\n handleWidgetMenuClick(): void {\n this.setState(({ isPanelsMenuShown }) => ({\n isPanelsMenuShown: !isPanelsMenuShown,\n }));\n }\n\n handleWidgetSelect(\n widget: DhType.ide.VariableDefinition,\n dragEvent?: WindowMouseEvent\n ): void {\n this.setState({ isPanelsMenuShown: false });\n\n log.debug('handleWidgetSelect', widget, dragEvent);\n\n this.openWidget(widget, dragEvent);\n }\n\n handleWidgetsMenuClose(): void {\n this.setState({ isPanelsMenuShown: false });\n }\n\n handleAutoFillClick(): void {\n const { widgets } = this.state;\n\n log.debug('handleAutoFillClick', widgets);\n\n const sortedWidgets = widgets.sort((a, b) =>\n a.title != null && b.title != null ? a.title.localeCompare(b.title) : 0\n );\n for (let i = 0; i < sortedWidgets.length; i += 1) {\n this.openWidget(sortedWidgets[i]);\n }\n }\n\n handleExportLayoutClick(): void {\n log.info('handleExportLayoutClick');\n\n this.setState({ isPanelsMenuShown: false });\n\n try {\n const { workspace } = this.props;\n const { data } = workspace;\n const exportedConfig = UserLayoutUtils.exportLayout(data);\n\n log.info('handleExportLayoutClick exportedConfig', exportedConfig);\n\n const blob = new Blob([JSON.stringify(exportedConfig)], {\n type: 'application/json',\n });\n const timestamp = dh.i18n.DateTimeFormat.format(\n 'yyyy-MM-dd-HHmmss',\n new Date()\n );\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = `deephaven-app-layout-${timestamp}.json`;\n link.click();\n } catch (e) {\n log.error('Unable to export layout', e);\n }\n }\n\n handleImportLayoutClick(): void {\n log.info('handleImportLayoutClick');\n\n this.setState({ isPanelsMenuShown: false });\n\n // Reset the file list on the import element, otherwise user won't be prompted again\n if (this.importElement.current != null) {\n this.importElement.current.value = '';\n this.importElement.current.click();\n }\n }\n\n handleResetLayoutClick(): void {\n log.info('handleResetLayoutClick');\n\n this.setState({\n isPanelsMenuShown: false,\n isResetLayoutPromptShown: true,\n unsavedNotebookCount: NotebookPanel.unsavedNotebookCount(),\n });\n }\n\n handleImportLayoutFiles(event: ChangeEvent<HTMLInputElement>): void {\n event.stopPropagation();\n event.preventDefault();\n\n if (event.target.files != null) {\n this.importLayoutFile(event.target.files?.[0]);\n }\n }\n\n handleDisconnect(): void {\n log.info('Disconnected from server');\n this.setState({ isDisconnected: true });\n }\n\n handleReconnect(): void {\n log.info('Reconnected to server');\n this.setState({ isDisconnected: false });\n }\n\n handleReconnectAuthFailed(): void {\n log.warn('Reconnect authentication failed');\n this.setState({ isAuthFailed: true });\n }\n\n /**\n * Import the provided file and set it in the workspace data (which should then load it in the dashboard)\n * @param file JSON file to import\n */\n async importLayoutFile(file: File): Promise<void> {\n try {\n const { updateDashboardData, updateWorkspaceData } = this.props;\n const fileText = await file.text();\n const exportedLayout = JSON.parse(fileText);\n const { filterSets, layoutConfig, links, pluginDataMap } =\n UserLayoutUtils.normalizeLayout(exportedLayout);\n\n updateWorkspaceData({ layoutConfig });\n updateDashboardData(DEFAULT_DASHBOARD_ID, {\n filterSets,\n links,\n pluginDataMap,\n });\n this.setState(({ layoutIteration }) => ({\n layoutIteration: layoutIteration + 1,\n }));\n } catch (e) {\n log.error('Unable to import layout', e);\n }\n }\n\n /**\n * Resets the users layout to the default layout\n */\n async resetLayout(): Promise<void> {\n const { layoutStorage, session } = this.props;\n const { filterSets, layoutConfig, links } =\n await UserLayoutUtils.getDefaultLayout(\n layoutStorage,\n session !== undefined\n );\n\n const { updateDashboardData, updateWorkspaceData } = this.props;\n updateWorkspaceData({ layoutConfig });\n updateDashboardData(DEFAULT_DASHBOARD_ID, {\n filterSets,\n links,\n });\n }\n\n // eslint-disable-next-line class-methods-use-this\n handlePaste(event: ClipboardEvent<HTMLDivElement>): void {\n if (\n event.target instanceof HTMLElement &&\n event.target.closest('.monaco-editor')\n ) {\n // Skip if this is inside a monaco editor\n return;\n }\n\n const { clipboardData } = event;\n const pastedData = clipboardData.getData('Text');\n const replacedChars = /“|”/g;\n if (replacedChars.test(pastedData)) {\n event.preventDefault();\n event.stopPropagation();\n\n document.execCommand(\n 'insertText',\n false,\n pastedData.replace(replacedChars, '\"')\n );\n }\n }\n\n startListeningForDisconnect(): void {\n const { connection } = this.props;\n if (connection == null) {\n return;\n }\n\n connection.addEventListener(\n dh.IdeConnection.EVENT_DISCONNECT,\n this.handleDisconnect\n );\n connection.addEventListener(\n dh.IdeConnection.EVENT_RECONNECT,\n this.handleReconnect\n );\n connection.addEventListener(\n dh.CoreClient.EVENT_RECONNECT_AUTH_FAILED,\n this.handleReconnectAuthFailed\n );\n }\n\n stopListeningForDisconnect(): void {\n const { connection } = this.props;\n if (connection == null) {\n return;\n }\n\n connection.removeEventListener(\n dh.IdeConnection.EVENT_DISCONNECT,\n this.handleDisconnect\n );\n connection.removeEventListener(\n dh.IdeConnection.EVENT_RECONNECT,\n this.handleReconnect\n );\n connection.removeEventListener(\n dh.CoreClient.EVENT_RECONNECT_AUTH_FAILED,\n this.handleReconnectAuthFailed\n );\n }\n\n /**\n * Open a widget up, using a drag event if specified.\n * @param widget The widget to open\n * @param dragEvent The mouse drag event that trigger it, undefined if it was not triggered by a drag\n */\n openWidget(\n widget: DhType.ide.VariableDefinition,\n dragEvent?: WindowMouseEvent\n ): void {\n const { connection } = this.props;\n this.emitLayoutEvent(PanelEvent.OPEN, {\n dragEvent,\n fetch: async () => connection?.getObject(widget),\n widget: getVariableDescriptor(widget),\n });\n }\n\n getDashboardPlugins = memoize((plugins: PluginModuleMap) =>\n getDashboardPlugins(plugins)\n );\n\n handleHomeClick(): void {\n this.handleTabSelect(DEFAULT_DASHBOARD_ID);\n }\n\n handleTabSelect(tabId: string): void {\n this.setState({ activeTabKey: tabId });\n }\n\n handleTabReorder(from: number, to: number): void {\n this.setState(({ tabs: oldTabs }) => {\n const newTabs = [...oldTabs];\n const [t] = newTabs.splice(from, 1);\n newTabs.splice(to, 0, t);\n return { tabs: newTabs };\n });\n }\n\n handleTabClose(tabId: string): void {\n // TODO: #1746 Do something to mark the dashboard as closed\n // Remove any dashboard data we no longer need to keep so\n // the dashboard data store doesn't grow unbounded\n this.setState(({ tabs: oldTabs, activeTabKey }) => {\n const newTabs = oldTabs.filter(tab => tab.key !== tabId);\n let newActiveTabKey = activeTabKey;\n if (activeTabKey === tabId && newTabs.length > 0) {\n const oldActiveTabIndex = oldTabs.findIndex(tab => tab.key === tabId);\n newActiveTabKey =\n oldActiveTabIndex < oldTabs.length - 1\n ? oldTabs[oldActiveTabIndex + 1].key\n : oldTabs[oldActiveTabIndex - 1].key;\n }\n\n if (newTabs.length === 0) {\n newActiveTabKey = DEFAULT_DASHBOARD_ID;\n }\n\n return { tabs: newTabs, activeTabKey: newActiveTabKey };\n });\n }\n\n getDashboards(): {\n id: string;\n layoutConfig: ItemConfigType[];\n key?: string;\n }[] {\n const { layoutIteration, tabs } = this.state;\n const { allDashboardData, workspace } = this.props;\n const { data: workspaceData } = workspace;\n const { layoutConfig } = workspaceData;\n // TODO: #1746 Read the default dashboard layout from dashboardData instead of workspaceData\n return [\n {\n id: DEFAULT_DASHBOARD_ID,\n layoutConfig: layoutConfig as ItemConfigType[],\n key: `${DEFAULT_DASHBOARD_ID}-${layoutIteration}`,\n },\n ...tabs\n .filter(tab => tab.key !== DEFAULT_DASHBOARD_ID)\n .map(tab => ({\n id: tab.key,\n layoutConfig: (allDashboardData[tab.key]?.layoutConfig ??\n EMPTY_ARRAY) as ItemConfigType[],\n key: `${tab.key}-${layoutIteration}`,\n })),\n ];\n }\n\n render(): ReactElement {\n const { activeTool, plugins, user, serverConfigValues } = this.props;\n const { permissions } = user;\n const { canUsePanels } = permissions;\n const {\n contextActions,\n isAuthFailed,\n isDisconnected,\n isPanelsMenuShown,\n isResetLayoutPromptShown,\n isSettingsMenuShown,\n unsavedNotebookCount,\n widgets,\n tabs,\n activeTabKey,\n } = this.state;\n const dashboardPlugins = this.getDashboardPlugins(plugins);\n\n return (\n <div\n className={classNames(\n 'app-main-tabs',\n 'w-100',\n 'h-100',\n 'd-flex',\n 'flex-column',\n activeTool ? `active-tool-${activeTool.toLowerCase()}` : ''\n )}\n onPaste={this.handlePaste}\n tabIndex={-1}\n >\n <div className=\"app-main-top-nav-menus\">\n <Logo className=\"ml-1\" style={{ maxHeight: '20px' }} />\n {/* Only show the Code Studio tab if there is also an open dashboard */}\n {tabs.length > 1 && (\n <div style={{ flexShrink: 0, flexGrow: 1, display: 'flex' }}>\n <NavTabList\n tabs={tabs}\n activeKey={activeTabKey}\n onSelect={this.handleTabSelect}\n onReorder={this.handleTabReorder}\n onClose={this.handleTabClose}\n />\n </div>\n )}\n <div className=\"app-main-right-menu-buttons\">\n <Button\n kind=\"ghost\"\n className=\"btn-panels-menu\"\n icon={dhShapes}\n onClick={() => {\n // no-op: click is handled in `AppControlsMenu` (which uses a `DropdownMenu`)\n }}\n >\n Controls\n <AppControlsMenu\n handleControlSelect={this.handleControlSelect}\n handleToolSelect={this.handleToolSelect}\n onClearFilter={this.handleClearFilter}\n />\n </Button>\n {canUsePanels && (\n <Button\n kind=\"ghost\"\n className=\"btn-panels-menu btn-show-panels\"\n data-testid=\"app-main-panels-button\"\n onClick={this.handleWidgetMenuClick}\n icon={dhPanels}\n >\n Panels\n <Popper\n isShown={isPanelsMenuShown}\n className=\"panels-menu-popper\"\n onExited={this.handleWidgetsMenuClose}\n options={{\n placement: 'bottom',\n }}\n closeOnBlur\n interactive\n >\n <WidgetList\n widgets={widgets}\n onExportLayout={this.handleExportLayoutClick}\n onImportLayout={this.handleImportLayoutClick}\n onResetLayout={this.handleResetLayoutClick}\n onSelect={this.handleWidgetSelect}\n />\n </Popper>\n </Button>\n )}\n <Button\n kind=\"ghost\"\n className={classNames('btn-settings-menu', {\n 'text-warning':\n user.operateAs != null && user.operateAs !== user.name,\n })}\n onClick={this.handleSettingsMenuShow}\n icon={\n <span className=\"fa-layers\">\n <FontAwesomeIcon icon={vsGear} transform=\"grow-3\" />\n {isDisconnected && !isAuthFailed && (\n <>\n <FontAwesomeIcon\n icon={dhSquareFilled}\n color={ThemeExport.background}\n transform=\"grow-2 right-8 down-8.5 rotate-45\"\n />\n <FontAwesomeIcon\n icon={vsDebugDisconnect}\n color={ThemeExport.danger}\n transform=\"shrink-5 right-6 down-6\"\n />\n </>\n )}\n </span>\n }\n tooltip={\n isDisconnected && !isAuthFailed\n ? 'Server disconnected'\n : 'User Settings'\n }\n />\n </div>\n </div>\n <AppDashboards\n dashboards={this.getDashboards()}\n activeDashboard={activeTabKey}\n onGoldenLayoutChange={this.handleGoldenLayoutChange}\n emptyDashboard={\n activeTabKey === DEFAULT_DASHBOARD_ID ? (\n <EmptyDashboard onAutoFillClick={this.handleAutoFillClick} />\n ) : (\n <LoadingOverlay />\n )\n }\n plugins={[\n <ConsolePlugin\n key=\"ConsolePlugin\"\n hydrateConsole={AppMainContainer.hydrateConsole}\n notebooksUrl={\n new URL(\n `${import.meta.env.VITE_ROUTE_NOTEBOOKS}`,\n document.baseURI\n ).href\n }\n />,\n ...dashboardPlugins,\n ]}\n />\n <SlideTransition in={isSettingsMenuShown} mountOnEnter unmountOnExit>\n <SettingsMenu\n serverConfigValues={serverConfigValues}\n pluginData={plugins}\n onDone={this.handleSettingsMenuHide}\n user={user}\n />\n </SlideTransition>\n <ContextActions actions={contextActions} />\n <input\n ref={this.importElement}\n type=\"file\"\n accept=\".json\"\n style={{ display: 'none' }}\n onChange={this.handleImportLayoutFiles}\n data-testid=\"input-import-layout\"\n />\n <DebouncedModal\n isOpen={isDisconnected && !isAuthFailed}\n debounceMs={1000}\n >\n <InfoModal\n icon={vsDebugDisconnect}\n title={\n <>\n <LoadingSpinner /> Attempting to reconnect...\n </>\n }\n subtitle=\"Please check your network connection.\"\n />\n </DebouncedModal>\n <BasicModal\n confirmButtonText=\"Reset\"\n onConfirm={this.handleConfirmResetLayoutPrompt}\n onCancel={this.handleCancelResetLayoutPrompt}\n isConfirmDanger\n isOpen={isResetLayoutPromptShown}\n headerText={\n unsavedNotebookCount === 0\n ? 'Reset Layout'\n : 'Reset layout and discard unsaved changes'\n }\n bodyText={\n unsavedNotebookCount === 0\n ? 'Do you want to reset your layout? Your existing layout will be lost.'\n : 'Do you want to reset your layout? Any unsaved notebooks will be lost.'\n }\n />\n <BasicModal\n confirmButtonText=\"Refresh\"\n onConfirm={AppMainContainer.handleRefresh}\n isOpen={isAuthFailed}\n headerText=\"Authentication failed\"\n bodyText=\"Credentials are invalid. Please refresh your browser to try and reconnect.\"\n />\n </div>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState\n): Omit<\n AppMainContainerProps,\n | 'match'\n | 'setActiveTool'\n | 'updateDashboardData'\n | 'updateWorkspaceData'\n | 'setDashboardData'\n | 'setDashboardPluginData'\n> => ({\n activeTool: getActiveTool(state),\n allDashboardData: getAllDashboardsData(state),\n dashboardData: getDashboardData(state, DEFAULT_DASHBOARD_ID),\n layoutStorage: getLayoutStorage(state),\n plugins: getPlugins(state),\n connection: getDashboardConnection(state, DEFAULT_DASHBOARD_ID),\n session: getDashboardSessionWrapper(state, DEFAULT_DASHBOARD_ID)?.session,\n sessionConfig: getDashboardSessionWrapper(state, DEFAULT_DASHBOARD_ID)\n ?.config,\n user: getUser(state),\n workspace: getWorkspace(state),\n serverConfigValues: getServerConfigValues(state),\n});\n\nconst ConnectedAppMainContainer = connect(mapStateToProps, {\n setActiveTool: setActiveToolAction,\n setDashboardData: setDashboardDataAction,\n setDashboardPluginData: setDashboardPluginDataAction,\n updateDashboardData: updateDashboardDataAction,\n updateWorkspaceData: updateWorkspaceDataAction,\n})(withRouter(AppMainContainer));\n\nexport default ConnectedAppMainContainer;\n","import React, { ReactElement } from 'react';\nimport { ContextMenuRoot } from '@deephaven/components';\nimport AppMainContainer from './AppMainContainer';\n\nfunction App(): ReactElement {\n return (\n <div className=\"app\">\n <AppMainContainer />\n <ContextMenuRoot />\n </div>\n );\n}\n\nexport default App;\n","import Log from '@deephaven/log';\nimport {\n WorkspaceStorage,\n WorkspaceStorageLoadOptions,\n CustomizableWorkspaceData,\n CustomizableWorkspace,\n WorkspaceSettings,\n ServerConfigValues,\n} from '@deephaven/redux';\nimport {\n DateTimeColumnFormatter,\n DecimalColumnFormatter,\n IntegerColumnFormatter,\n} from '@deephaven/jsapi-utils';\nimport UserLayoutUtils from '../main/UserLayoutUtils';\nimport LayoutStorage from './LayoutStorage';\n\nconst log = Log.module('LocalWorkspaceStorage');\n\n/**\n * Implementation of WorkspaceStorage that just stores the workspace data in localStorage\n */\nexport class LocalWorkspaceStorage implements WorkspaceStorage {\n static readonly STORAGE_KEY = 'deephaven.WorkspaceStorage';\n\n static getBooleanServerConfig(\n serverConfigValues: Map<string, string> | undefined,\n key: string\n ): boolean | undefined {\n if (serverConfigValues?.get(key)?.toLowerCase() === 'true') {\n return true;\n }\n if (serverConfigValues?.get(key)?.toLowerCase() === 'false') {\n return false;\n }\n return undefined;\n }\n\n static makeDefaultWorkspaceSettings(\n serverConfigValues: ServerConfigValues\n ): WorkspaceSettings {\n const settings = {\n defaultDateTimeFormat:\n DateTimeColumnFormatter.DEFAULT_DATETIME_FORMAT_STRING,\n formatter: [],\n timeZone: DateTimeColumnFormatter.DEFAULT_TIME_ZONE_ID,\n showTimeZone: false,\n showTSeparator: true,\n disableMoveConfirmation: false,\n defaultDecimalFormatOptions: {\n defaultFormatString: DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n },\n defaultIntegerFormatOptions: {\n defaultFormatString: IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n },\n truncateNumbersWithPound: false,\n showEmptyStrings: true,\n showNullStrings: true,\n defaultNotebookSettings: {\n isMinimapEnabled: false,\n },\n };\n const serverSettings = {\n defaultDateTimeFormat: serverConfigValues?.get('dateTimeFormat'),\n formatter: [],\n timeZone: serverConfigValues?.get('timeZone'),\n showTimeZone: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showTimeZone'\n ),\n showTSeparator: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showTSeparator'\n ),\n disableMoveConfirmation: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'disableMoveConfirmation'\n ),\n defaultDecimalFormatOptions:\n serverConfigValues?.get('decimalFormat') !== undefined\n ? {\n defaultFormatString: serverConfigValues?.get('decimalFormat'),\n }\n : undefined,\n defaultIntegerFormatOptions:\n serverConfigValues?.get('integerFormat') !== undefined\n ? {\n defaultFormatString: serverConfigValues?.get('integerFormat'),\n }\n : undefined,\n truncateNumbersWithPound: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'truncateNumbersWithPound'\n ),\n showEmptyStrings: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showEmptyStrings'\n ),\n showNullStrings: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showNullStrings'\n ),\n defaultNotebookSettings:\n serverConfigValues?.get('isMinimapEnabled') !== undefined\n ? {\n isMinimapEnabled: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'isMinimapEnabled'\n ) as boolean,\n }\n : undefined,\n };\n\n const keys = Object.keys(serverSettings) as Array<keyof typeof settings>;\n for (let i = 0; i < keys.length; i += 1) {\n const key = keys[i];\n if (serverSettings[key] !== undefined) {\n // @ts-expect-error override default for defined server settings\n settings[key] = serverSettings[key];\n }\n }\n return settings;\n }\n\n static async makeWorkspaceData(\n layoutStorage: LayoutStorage,\n options?: WorkspaceStorageLoadOptions\n ): Promise<CustomizableWorkspaceData> {\n const {\n filterSets,\n links,\n layoutConfig,\n pluginDataMap = {},\n } = await UserLayoutUtils.getDefaultLayout(\n layoutStorage,\n options?.isConsoleAvailable\n );\n return {\n settings: {},\n layoutConfig,\n closed: [{}],\n links,\n filterSets,\n pluginDataMap,\n };\n }\n\n static async makeDefaultWorkspace(\n layoutStorage: LayoutStorage,\n options?: WorkspaceStorageLoadOptions\n ): Promise<CustomizableWorkspace> {\n return {\n data: await LocalWorkspaceStorage.makeWorkspaceData(\n layoutStorage,\n options\n ),\n };\n }\n\n private layoutStorage: LayoutStorage;\n\n constructor(layoutStorage: LayoutStorage) {\n this.layoutStorage = layoutStorage;\n }\n\n // eslint-disable-next-line class-methods-use-this\n async load(\n options?: WorkspaceStorageLoadOptions\n ): Promise<CustomizableWorkspace> {\n try {\n const workspace = JSON.parse(\n localStorage.getItem(LocalWorkspaceStorage.STORAGE_KEY) ?? ''\n );\n return workspace;\n } catch (e) {\n log.info('Unable to load workspace data, initializing to default data');\n\n return LocalWorkspaceStorage.makeDefaultWorkspace(\n this.layoutStorage,\n options\n );\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n async save(workspace: CustomizableWorkspace): Promise<CustomizableWorkspace> {\n localStorage.setItem(\n LocalWorkspaceStorage.STORAGE_KEY,\n JSON.stringify(workspace)\n );\n return workspace;\n }\n}\n\nexport default LocalWorkspaceStorage;\n","import type { dh } from '@deephaven/jsapi-types';\nimport LayoutStorage, { ExportedLayout } from '../LayoutStorage';\n\nexport class GrpcLayoutStorage implements LayoutStorage {\n readonly storageService: dh.storage.StorageService;\n\n readonly root: string;\n\n /**\n *\n * @param storageService The gRPC storage service to use\n * @param root The root path where the layouts are stored\n */\n constructor(storageService: dh.storage.StorageService, root = '') {\n this.storageService = storageService;\n this.root = root;\n }\n\n async getLayouts(): Promise<string[]> {\n const files = await this.storageService.listItems(this.root, '*.json');\n\n return files.map(file => file.basename);\n }\n\n async getLayout(name: string): Promise<ExportedLayout> {\n const fileContents = await this.storageService.loadFile(\n `${this.root}/${name}`\n );\n const content = await fileContents.text();\n\n return JSON.parse(content);\n }\n}\n\nexport default GrpcLayoutStorage;\n","/* eslint-disable class-methods-use-this */\n\nimport Log from '@deephaven/log';\nimport {\n StorageTableViewport,\n StorageListenerRemover,\n ViewportUpdateCallback,\n ViewportData,\n IndexRange,\n StorageSnapshot,\n} from '@deephaven/storage';\nimport {\n CancelablePromise,\n CanceledPromiseError,\n PromiseUtils,\n} from '@deephaven/utils';\nimport {\n FileStorageItem,\n FileStorageTable,\n FileUtils,\n} from '@deephaven/file-explorer';\nimport type { dh } from '@deephaven/jsapi-types';\nimport debounce from 'lodash.debounce';\n\nconst log = Log.module('GrpcFileStorageTable');\n\n/**\n * Implementation of FileStorageTable for gRPC service.\n * Takes a path to specify what root this table should start at.\n */\nexport class GrpcFileStorageTable implements FileStorageTable {\n static REFRESH_DEBOUNCE = 50;\n\n private readonly storageService: dh.storage.StorageService;\n\n private readonly baseRoot: string;\n\n private readonly root: string;\n\n private currentSize = 0;\n\n private currentViewport?: StorageTableViewport;\n\n private listeners: ViewportUpdateCallback<FileStorageItem>[] = [];\n\n private viewportUpdatePromise?: CancelablePromise<\n ViewportData<FileStorageItem>\n >;\n\n private currentViewportData?: ViewportData<FileStorageItem>;\n\n /**\n * Map of expanded directory paths to the tables that manage that path.\n * We use a tree of tables to query the server so we just get the directories that are expanded.\n */\n private childTables: Map<string, GrpcFileStorageTable> = new Map();\n\n /**\n * @param storageService The storage service to use\n * @param baseRoot Base root for the service\n * @param root The root path for this storage table\n */\n constructor(\n storageService: dh.storage.StorageService,\n baseRoot = '',\n root = baseRoot\n ) {\n this.storageService = storageService;\n this.baseRoot = baseRoot;\n this.root = root;\n if (root === baseRoot) {\n this.doRefresh = debounce(\n this.doRefresh.bind(this),\n GrpcFileStorageTable.REFRESH_DEBOUNCE\n );\n }\n }\n\n private removeBaseRoot(filename: string): string {\n return FileUtils.removeRoot(this.baseRoot, filename);\n }\n\n getViewportData(): Promise<ViewportData<FileStorageItem>> {\n if (!this.viewportUpdatePromise) {\n this.refreshInternal();\n }\n return (\n this.viewportUpdatePromise ?? Promise.resolve({ items: [], offset: 0 })\n );\n }\n\n getSnapshot(\n sortedRanges: IndexRange[]\n ): Promise<StorageSnapshot<FileStorageItem>> {\n throw new Error('Method not implemented.');\n }\n\n get size(): number {\n return this.currentSize;\n }\n\n setExpanded(path: string, expanded: boolean): void {\n const paths = path.split('/');\n let nextPath = paths.shift();\n if (nextPath === undefined || nextPath === '') {\n nextPath = paths.shift();\n }\n if (nextPath === undefined || nextPath === '') {\n throw new Error(`Invalid path: ${path}`);\n }\n const remainingPath = paths.join('/');\n if (expanded) {\n if (!this.childTables.has(nextPath)) {\n const childTable = new GrpcFileStorageTable(\n this.storageService,\n this.baseRoot,\n `${this.root}/${nextPath}`\n );\n this.childTables.set(nextPath, childTable);\n }\n if (remainingPath) {\n const childTable = this.childTables.get(nextPath);\n childTable?.setExpanded(remainingPath, expanded);\n }\n } else if (this.childTables.has(nextPath)) {\n if (remainingPath) {\n const childTable = this.childTables.get(nextPath);\n childTable?.setExpanded(remainingPath, expanded);\n } else {\n this.childTables.delete(nextPath);\n }\n }\n if (this.currentViewport) {\n this.refreshInternal();\n }\n }\n\n collapseAll(): void {\n this.childTables.clear();\n if (this.currentViewport) {\n this.refreshInternal();\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n setSearch(search: string): void {\n throw new Error('Method not implemented.');\n }\n\n setViewport(viewport: StorageTableViewport): void {\n this.currentViewport = viewport;\n\n this.refreshInternal();\n }\n\n setFilters(): void {\n throw new Error('Method not implemented.');\n }\n\n setSorts(): void {\n throw new Error('Method not implemented.');\n }\n\n setReversed(): void {\n throw new Error('Method not implemented.');\n }\n\n close(): void {\n this.listeners = [];\n }\n\n onUpdate(\n callback: ViewportUpdateCallback<FileStorageItem>\n ): StorageListenerRemover {\n this.listeners = [...this.listeners, callback];\n return () => {\n this.listeners = this.listeners.filter(other => other !== callback);\n };\n }\n\n doRefresh(\n callback: (fetchPromise: Promise<ViewportData<FileStorageItem>>) => void\n ): void {\n log.debug2('doRefresh', this.root);\n callback(this.fetchData());\n }\n\n refresh(): void {\n log.debug2('refresh', this.root);\n\n this.viewportUpdatePromise?.cancel();\n\n const refreshPromise = new Promise<ViewportData<FileStorageItem>>(\n resolve => {\n this.doRefresh(resolve);\n }\n );\n\n const viewportUpdatePromise = PromiseUtils.makeCancelable(\n refreshPromise.then(viewportData => {\n if (this.viewportUpdatePromise !== viewportUpdatePromise) {\n throw new CanceledPromiseError();\n }\n\n this.currentViewportData = viewportData;\n\n this.sendUpdate();\n\n return viewportData;\n })\n );\n\n // Add a catch here as we're not catching the promises anywhere else\n viewportUpdatePromise.catch(e => {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Error updating viewport', e);\n }\n });\n\n this.viewportUpdatePromise = viewportUpdatePromise;\n }\n\n /**\n * Refreshes data, but catches any errors and logs them\n */\n private refreshInternal(): void {\n try {\n this.refresh();\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to refresh data', e);\n }\n }\n }\n\n private async fetchData(): Promise<ViewportData<FileStorageItem>> {\n const { currentViewport: viewport } = this;\n if (!viewport) {\n throw new Error('No viewport set');\n }\n\n // First get the root directory contents\n const dirContents = await this.storageService.listItems(this.root);\n let items = dirContents\n .map(file => ({\n type: file.type,\n filename: this.removeBaseRoot(file.filename),\n basename: file.basename,\n id: this.removeBaseRoot(file.filename),\n isExpanded:\n file.type === 'directory'\n ? this.childTables.has(file.basename)\n : undefined,\n }))\n .sort((a, b) => {\n if (a.type !== b.type) {\n return a.type === 'directory' ? -1 : 1;\n }\n return a.basename.localeCompare(b.basename);\n }) as FileStorageItem[];\n\n // Get the data from all expanded directories\n for (let i = 0; i < items.length; i += 1) {\n const item = items[i];\n const { basename, filename } = item;\n if (\n filename === this.removeBaseRoot(`${this.root}/${basename}`) &&\n item.type === 'directory'\n ) {\n const childTable = this.childTables.get(basename);\n if (childTable != null) {\n childTable.setViewport({ top: 0, bottom: viewport.bottom - i });\n // eslint-disable-next-line no-await-in-loop\n const childViewportData = await childTable.getViewportData();\n items.splice(i + 1, 0, ...childViewportData.items);\n }\n }\n }\n\n this.currentSize = items.length;\n\n log.debug2(this.root, 'items', items, viewport);\n\n // Slice it to the correct viewport\n items = items.slice(viewport.top, viewport.bottom);\n\n return { items, offset: viewport.top };\n }\n\n private sendUpdate(): void {\n // Retain a reference to it in case a listener gets removed while sending an update\n const { listeners } = this;\n const data = this.currentViewportData ?? { items: [], offset: 0 };\n for (let i = 0; i < listeners.length; i += 1) {\n listeners[i](data);\n }\n }\n}\n\nexport default GrpcFileStorageTable;\n","/* eslint-disable class-methods-use-this */\n\nimport throttle from 'lodash.throttle';\nimport {\n FileNotFoundError,\n FileStorage,\n File,\n FileStorageItem,\n FileStorageTable,\n FileUtils,\n isFileType,\n} from '@deephaven/file-explorer';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport GrpcFileStorageTable from './GrpcFileStorageTable';\n\nconst log = Log.module('GrpcFileStorage');\n\nexport class GrpcFileStorage implements FileStorage {\n private static readonly REFRESH_THROTTLE = 150;\n\n private readonly storageService: DhType.storage.StorageService;\n\n private tables = [] as GrpcFileStorageTable[];\n\n private readonly root: string;\n\n /**\n * FileStorage implementation using gRPC\n * @param storageService Storage service to use\n * @param root Root path for this instance. Should not contain trailing slash.\n */\n constructor(storageService: DhType.storage.StorageService, root = '') {\n this.storageService = storageService;\n this.root = root;\n }\n\n private removeRoot(filename: string): string {\n return FileUtils.removeRoot(this.root, filename);\n }\n\n private addRoot(path: string): string {\n return FileUtils.addRoot(this.root, path);\n }\n\n async createDirectory(path: string): Promise<FileStorageItem> {\n await this.storageService.createDirectory(this.addRoot(path));\n this.refreshTables();\n return {\n type: 'directory',\n id: path,\n filename: path,\n basename: FileUtils.getBaseName(path),\n };\n }\n\n async getTable(): Promise<FileStorageTable> {\n const table = new GrpcFileStorageTable(this.storageService, this.root);\n this.tables.push(table);\n return table;\n }\n\n async saveFile(file: File): Promise<File> {\n const fileContents = dh.storage.FileContents.text(file.content);\n await this.storageService.saveFile(\n this.addRoot(file.filename),\n fileContents,\n true\n );\n this.refreshTables();\n return file;\n }\n\n async loadFile(name: string): Promise<File> {\n const fileContents = await this.storageService.loadFile(this.addRoot(name));\n const content = await fileContents.text();\n return {\n filename: name,\n basename: FileUtils.getBaseName(name),\n content,\n };\n }\n\n async copyFile(name: string, newName: string): Promise<void> {\n const fileContents = await this.storageService.loadFile(this.addRoot(name));\n await this.storageService.saveFile(\n this.addRoot(newName),\n fileContents,\n false\n );\n this.refreshTables();\n }\n\n async deleteFile(name: string): Promise<void> {\n await this.storageService.deleteItem(this.addRoot(name));\n this.refreshTables();\n }\n\n async moveFile(name: string, newName: string): Promise<void> {\n await this.storageService.moveItem(\n this.addRoot(name),\n this.addRoot(newName)\n );\n this.refreshTables();\n }\n\n async info(name: string): Promise<FileStorageItem> {\n const allItems = await this.storageService.listItems(\n this.addRoot(FileUtils.getPath(name)),\n FileUtils.getBaseName(name)\n );\n if (allItems.length === 0) {\n throw new FileNotFoundError();\n }\n if (allItems.length > 1) {\n log.error(\n 'More than one matching file found, should never happen.',\n allItems\n );\n throw new Error('More than one matching file found');\n }\n\n const itemDetails = allItems[0];\n\n if (!isFileType(itemDetails.type)) {\n throw new Error(`Unexpected file type: ${itemDetails.type}`);\n }\n\n return {\n filename: this.removeRoot(itemDetails.filename),\n basename: itemDetails.basename,\n id: this.removeRoot(itemDetails.filename),\n type: itemDetails.type,\n };\n }\n\n private refreshTables = throttle(() => {\n this.tables.forEach(table => table.refresh());\n }, GrpcFileStorage.REFRESH_THROTTLE);\n}\n\nexport default GrpcFileStorage;\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { connect } from 'react-redux';\nimport {\n LoadingOverlay,\n Shortcut,\n ShortcutRegistry,\n} from '@deephaven/components';\nimport {\n DEFAULT_DASHBOARD_ID,\n setDashboardData as setDashboardDataAction,\n} from '@deephaven/dashboard';\nimport {\n setDashboardConnection as setDashboardConnectionAction,\n setDashboardSessionWrapper as setDashboardSessionWrapperAction,\n ToolType,\n} from '@deephaven/dashboard-core-plugins';\nimport { FileStorage } from '@deephaven/file-explorer';\nimport { useApi, useClient } from '@deephaven/jsapi-bootstrap';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport {\n getSessionDetails,\n loadSessionWrapper,\n SessionWrapper,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { PouchCommandHistoryStorage } from '@deephaven/pouch-storage';\nimport {\n getWorkspace,\n getWorkspaceStorage,\n RootState,\n setActiveTool as setActiveToolAction,\n setApi as setApiAction,\n setCommandHistoryStorage as setCommandHistoryStorageAction,\n setFileStorage as setFileStorageAction,\n setPlugins as setPluginsAction,\n setUser as setUserAction,\n setWorkspace as setWorkspaceAction,\n setDefaultWorkspaceSettings as setDefaultWorkspaceSettingsAction,\n setWorkspaceStorage as setWorkspaceStorageAction,\n setServerConfigValues as setServerConfigValuesAction,\n User,\n WorkspaceStorage,\n ServerConfigValues,\n WorkspaceSettings,\n CustomizableWorkspace,\n} from '@deephaven/redux';\nimport { useConnection, useServerConfig, useUser } from '@deephaven/app-utils';\nimport { type PluginModuleMap, usePlugins } from '@deephaven/plugin';\nimport { setLayoutStorage as setLayoutStorageAction } from '../redux/actions';\nimport App from './App';\nimport LocalWorkspaceStorage from '../storage/LocalWorkspaceStorage';\nimport LayoutStorage from '../storage/LayoutStorage';\nimport GrpcLayoutStorage from '../storage/grpc/GrpcLayoutStorage';\nimport GrpcFileStorage from '../storage/grpc/GrpcFileStorage';\n\nconst log = Log.module('AppInit');\n\ninterface AppInitProps {\n workspace: CustomizableWorkspace;\n workspaceStorage: WorkspaceStorage;\n\n setActiveTool: (type: (typeof ToolType)[keyof typeof ToolType]) => void;\n setApi: (api: typeof DhType) => void;\n setCommandHistoryStorage: (storage: PouchCommandHistoryStorage) => void;\n setDashboardData: (\n id: string,\n dashboardData: Record<string, unknown>\n ) => void;\n setFileStorage: (fileStorage: FileStorage) => void;\n setLayoutStorage: (layoutStorage: LayoutStorage) => void;\n setDashboardConnection: (\n id: string,\n connection: DhType.IdeConnection\n ) => void;\n setDashboardSessionWrapper: (id: string, wrapper: SessionWrapper) => void;\n setPlugins: (map: PluginModuleMap) => void;\n setUser: (user: User) => void;\n setWorkspace: (workspace: CustomizableWorkspace) => void;\n setDefaultWorkspaceSettings: (settings: WorkspaceSettings) => void;\n setWorkspaceStorage: (workspaceStorage: WorkspaceStorage) => void;\n setServerConfigValues: (config: ServerConfigValues) => void;\n}\n\n/**\n * Component that sets some default values needed\n */\nfunction AppInit(props: AppInitProps): JSX.Element {\n const {\n workspace,\n setActiveTool,\n setApi,\n setCommandHistoryStorage,\n setDashboardData,\n setFileStorage,\n setLayoutStorage,\n setDashboardConnection,\n setDashboardSessionWrapper,\n setPlugins,\n setUser,\n setWorkspace,\n setWorkspaceStorage,\n setDefaultWorkspaceSettings,\n setServerConfigValues,\n } = props;\n\n const api = useApi();\n const client = useClient();\n const connection = useConnection();\n const plugins = usePlugins();\n const serverConfig = useServerConfig();\n const user = useUser();\n\n // General error means the app is dead and is unlikely to recover\n const [error, setError] = useState<unknown>();\n\n useEffect(\n function setReduxPlugins() {\n setPlugins(plugins);\n },\n [plugins, setPlugins]\n );\n\n useEffect(\n function initApp() {\n async function loadApp(): Promise<void> {\n try {\n const sessionDetails = await getSessionDetails();\n const sessionWrapper = await loadSessionWrapper(\n api,\n connection,\n sessionDetails\n );\n\n const storageService = client.getStorageService();\n const layoutStorage = new GrpcLayoutStorage(\n storageService,\n import.meta.env.VITE_STORAGE_PATH_LAYOUTS ?? ''\n );\n const fileStorage = new GrpcFileStorage(\n storageService,\n import.meta.env.VITE_STORAGE_PATH_NOTEBOOKS ?? ''\n );\n\n const workspaceStorage = new LocalWorkspaceStorage(layoutStorage);\n const commandHistoryStorage = new PouchCommandHistoryStorage();\n\n const loadedWorkspace = await workspaceStorage.load({\n isConsoleAvailable: sessionWrapper !== undefined,\n });\n\n const { data } = loadedWorkspace;\n\n // Fill in settings that have not yet been set\n const { settings } = data;\n\n // Set any shortcuts that user has overridden on this platform\n const { shortcutOverrides = {} } = settings;\n const isMac = Shortcut.isMacPlatform;\n const platformOverrides = isMac\n ? shortcutOverrides.mac ?? {}\n : shortcutOverrides.windows ?? {};\n\n Object.entries(platformOverrides).forEach(([id, keyState]) => {\n ShortcutRegistry.get(id)?.setKeyState(keyState);\n });\n\n const dashboardData = {\n title: 'Code Studio',\n filterSets: data.filterSets,\n links: data.links,\n };\n\n setApi(api);\n setActiveTool(ToolType.DEFAULT);\n setServerConfigValues(serverConfig);\n setCommandHistoryStorage(commandHistoryStorage);\n setDashboardData(DEFAULT_DASHBOARD_ID, dashboardData);\n setFileStorage(fileStorage);\n setLayoutStorage(layoutStorage);\n setDashboardConnection(DEFAULT_DASHBOARD_ID, connection);\n if (sessionWrapper !== undefined) {\n setDashboardSessionWrapper(DEFAULT_DASHBOARD_ID, sessionWrapper);\n }\n setUser(user);\n setWorkspaceStorage(workspaceStorage);\n setWorkspace(loadedWorkspace);\n setDefaultWorkspaceSettings(\n LocalWorkspaceStorage.makeDefaultWorkspaceSettings(serverConfig)\n );\n } catch (e) {\n log.error(e);\n setError(e);\n }\n }\n loadApp();\n },\n [\n api,\n client,\n connection,\n serverConfig,\n setActiveTool,\n setApi,\n setCommandHistoryStorage,\n setDashboardData,\n setFileStorage,\n setLayoutStorage,\n setDashboardConnection,\n setDashboardSessionWrapper,\n setUser,\n setWorkspace,\n setDefaultWorkspaceSettings,\n setWorkspaceStorage,\n setServerConfigValues,\n user,\n ]\n );\n\n const isLoading = workspace == null && error == null;\n const isLoaded = !isLoading && error == null;\n const errorMessage = error != null ? `${error}` : null;\n\n return (\n <>\n {isLoaded && <App />}\n <LoadingOverlay\n isLoading={isLoading && errorMessage == null}\n isLoaded={isLoaded}\n errorMessage={errorMessage}\n />\n </>\n );\n}\n\nAppInit.propTypes = {\n workspace: PropTypes.shape({}),\n workspaceStorage: PropTypes.shape({ close: PropTypes.func }),\n\n setActiveTool: PropTypes.func.isRequired,\n setApi: PropTypes.func.isRequired,\n setCommandHistoryStorage: PropTypes.func.isRequired,\n setDashboardData: PropTypes.func.isRequired,\n setFileStorage: PropTypes.func.isRequired,\n setLayoutStorage: PropTypes.func.isRequired,\n setDashboardConnection: PropTypes.func.isRequired,\n setDashboardSessionWrapper: PropTypes.func.isRequired,\n setPlugins: PropTypes.func.isRequired,\n setUser: PropTypes.func.isRequired,\n setWorkspace: PropTypes.func.isRequired,\n setWorkspaceStorage: PropTypes.func.isRequired,\n};\n\nAppInit.defaultProps = {\n workspace: null,\n workspaceStorage: null,\n};\n\nconst mapStateToProps = (\n state: RootState\n): Pick<AppInitProps, 'workspace' | 'workspaceStorage'> => ({\n workspace: getWorkspace(state),\n workspaceStorage: getWorkspaceStorage(state),\n});\n\nconst ConnectedAppInit = connect(mapStateToProps, {\n setActiveTool: setActiveToolAction,\n setApi: setApiAction,\n setCommandHistoryStorage: setCommandHistoryStorageAction,\n setDashboardData: setDashboardDataAction,\n setFileStorage: setFileStorageAction,\n setLayoutStorage: setLayoutStorageAction,\n setDashboardConnection: setDashboardConnectionAction,\n setDashboardSessionWrapper: setDashboardSessionWrapperAction,\n setPlugins: setPluginsAction,\n setUser: setUserAction,\n setWorkspace: setWorkspaceAction,\n setDefaultWorkspaceSettings: setDefaultWorkspaceSettingsAction,\n setWorkspaceStorage: setWorkspaceStorageAction,\n setServerConfigValues: setServerConfigValuesAction,\n})(AppInit);\n\nexport default ConnectedAppInit;\n","import React, { ReactElement } from 'react';\nimport {\n BrowserRouter as Router,\n Route,\n Redirect,\n Switch,\n} from 'react-router-dom';\nimport AppInit from './AppInit';\n\nconst StyleGuideRoot = React.lazy(() => import('../styleguide/StyleGuideRoot'));\n\nconst baseURI = new URL(document.baseURI).pathname.replace(/\\/$/, '');\n\nfunction AppRouter(): ReactElement {\n return (\n <Router basename={baseURI}>\n <Switch>\n <Route exact path=\"/\" component={AppInit} />\n <Route\n path={`/${import.meta.env.VITE_ROUTE_NOTEBOOKS}:notebookPath+`}\n component={AppInit}\n />\n <Route path=\"/styleguide\" component={StyleGuideRoot} />\n <Redirect from=\"*\" to=\"/\" />\n </Switch>\n </Router>\n );\n}\n\nexport default AppRouter;\n","import React from 'react';\nimport { Provider } from 'react-redux';\nimport { MonacoUtils } from '@deephaven/console';\nimport { store } from '@deephaven/redux';\nimport { DownloadServiceWorkerUtils } from '@deephaven/iris-grid';\nimport MonacoWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';\nimport AppRouter from './main/AppRouter';\n\n// load addional css for playwright docker tests\nif (import.meta.env.VITE_PLAYWRIGHT_CSS === '1') {\n await import('./Playwright.css');\n}\n\nexport function AppRoot(): JSX.Element {\n DownloadServiceWorkerUtils.register(\n new URL(\n `${import.meta.env.BASE_URL ?? ''}download/serviceWorker.js`,\n window.location.href\n )\n );\n MonacoUtils.init({ getWorker: () => new MonacoWorker() });\n\n // disable annoying dnd-react warnings\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n window['__react-beautiful-dnd-disable-dev-warnings'] = true;\n\n return (\n <Provider store={store}>\n <AppRouter />\n </Provider>\n );\n}\n\nexport default AppRoot;\n"],"file":"assets/AppRoot-2990a62d.js"}
1
+ {"version":3,"mappings":"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","names":["StorageUtils","columnName","direction","filters","filterItems","filterOperators","filterItem","i","FilterOperator","config1","config2","operator","type","value","siftPrunableItems","items","maxItems","pruneItemsCount","pruneCount","ownKeys","object","enumerableOnly","keys","symbols","sym","_objectSpread","target","source","key","_defineProperty","asyncGeneratorStep","gen","resolve","reject","_next","_throw","arg","info","error","_asyncToGenerator","fn","self","args","err","obj","_toPropertyKey","_toPrimitive","input","hint","prim","res","log","Log","DB_PREFIX","PouchDB","PouchDBFind","makePouchFilter","FilterType","makePouchSelectorFromConfig","config","filter","newFilter","filterOperator","selectorWithFilters","sortWithConfigs","sorts","_sorts$map","reverse","sort","PouchStorageTable","databaseName","dbOptions","callback","other","id","listener","reversed","viewport","_this","_this$viewportUpdateP","item","_this2","newItem","_this$currentViewport","listeners","data","event","selector","_this3","_this4","_this4$infoUpdateProm","_this4$currentFilter","PromiseUtils","findResult","e","_this5","_this6","_this6$currentFilter","_this6$viewportUpdate","viewportData","_this7","sortedRanges","_this8","itemMap","_ref2","_ref","_this8$currentFilter","from","to","limit","findSnapshotResult","index","_x","PouchStorageTable$1","COMMAND_HISTORY_ITEMS_MAX","COMMAND_HISTORY_ITEMS_PRUNE","PouchCommandHistoryTable","language","cache","_this$cache$tableRegi","searchText","_selector","result","allItems","row","name","toKeep","toPrune","_ref3","isReversed","docs","resumeListeners","_this$cache$tableRegi2","_this$cache$tableRegi3","_this$changes","PouchCommandHistoryTable$1","PouchCommandHistoryCache","dbName","_this$tableRegistry$g","pausedTables","table","_this$tableRegistry$g2","_this$tableRegistry$g3","PouchCommandHistoryCache$1","PouchCommandHistoryStorage","scope","command","updateTable","dbItem","updatedItem","SET_LAYOUT_STORAGE","setLayoutStorage","layoutStorage","dh","shim","isFormatStringFormat","format","getFormattedVersionInfo","serverConfigValues","ua","Bowser","browser","os","getFormattedPluginInfo","pluginDataValues","plugin","acc","focusFirstInputInContainer","container","isSameOptions","options1","options2","isSameDecimalOptions","isSameIntegerOptions","isValidColumnName","DbNameValidator","isValidFormat","columnType","DateTimeColumnFormatter","DecimalColumnFormatter","IntegerColumnFormatter","removeFormatRuleExtraProps","isNewRule","rest","isFormatRuleValidForSave","rule","DateTimeOptions","props","timestamp","timeZone","showTimeZone","showTSeparator","isGlobalOptions","legacyGlobalFormat","useApi","formatter","useMemo","Formatter","formats","jsx","Fragment","formatString","TableUtils","TimeZoneOptions","TimeUtils","label","FormattingSectionContent","PureComponent","debounce","defaultDateTimeFormat","defaultDecimalFormatOptions","defaultIntegerFormatOptions","truncateNumbersWithPound","showEmptyStrings","showNullStrings","React","memoize","timestampAtMenuOpen","updates","update","defaults","updateSettings","defaultDecimalFormatString","defaultIntegerFormatString","isTimeZoneDefault","isDateTimeOptionsDefault","isDecimalOptionsDefault","isIntegerOptionsDefault","jsxs","Select","Button","vsRefresh","classNames","Checkbox","mapStateToProps","state","getDefaultDateTimeFormat","getDefaultDecimalFormatOptions","getDefaultIntegerFormatOptions","getApi","getShowTimeZone","getShowTSeparator","getTruncateNumbersWithPound","getShowEmptyStrings","getShowNullStrings","getTimeZone","getDefaultSettings","ConnectedFormattingSectionContent","connect","updateSettingsAction","LegalNotice","modal","setModal","useState","toggle","vsLaw","Modal","ModalHeader","ModalBody","SettingsMenuSection","children","isExpanded","sectionKey","title","onToggle","FontAwesomeIcon","vsTriangleDown","Collapse","PropTypes","ShortcutItem","shortcut","propsDisplayText","categoryName","onChange","displayText","setDisplayText","keyState","setKeyState","isPending","setIsPending","setError","useEffect","Shortcut","conflictNames","ShortcutRegistry","conflict","handleInputKeyDown","newKeyState","backspaceKeyState","KEY","handleInputKeyUp","handleInputFocus","ContextActionUtils","handleInputBlur","handleConfirm","handleUndo","originalKeyState","handleResetToDefaultClick","Tooltip","ShortcutSectionContent","shortcutOverrides","saveShortcutOverrides","useCallback","modifiedShortcuts","isMac","newOverrides","platformOverrides","categories","shortcuts","globalCategoryIndex","category","globalCategory","ShortcutCategory","propsShortcuts","formatCategoryName","word","setShortcuts","handleShortcutChange","conflictingShortcuts","s","modifiedShoftcuts","displayTexts","getShortcutOverrides","mapDispatchToProps","ConnectedShortcutSectionContent","FILENAME_DATE_FORMAT","DEFAULT_PATH_BLACKLIST","stringifyReplacer","blacklist","pathMap","currPath","v","makeSafeToStringify","path","potentiallyCircularValues","output","val","valRecord","curPath","getReduxDataString","reduxData","store","getMetadata","meta","metadata","exportLogs","fileNamePrefix","zip","JSZip","folder","logHistory","blob","link","columnTypesArray","ColumnTypeOptions","columnTypeOptions","ColumnSpecificSectionContent","formatSettings","lastFormatRuleIndex","oldFormatSettings","assertNotNull","resetKeys","newEntry","newFormat","elem","scrollTo","errorMessages","columnNameId","columnTypeId","formatId","onNameChange","onNameBlur","onTypeChange","eventTargetValue","ruleError","vsTrash","isInvalid","selectedFormat","defaultFormatString","formatRulesChanged","formatRules","FadeTransition","addNewRuleButton","dhNewCircleLargeFilled","TransitionGroup","getFormatter","ConnectedColumnSpecificSectionContent","SettingsMenu","Component","BROADCAST_CHANNEL_NAME","expandedSectionKey","makeMessage","BROADCAST_LOGOUT_MESSAGE","x","y","onDone","pluginData","pluginInfo","supportLink","docsLink","user","versionInfo","deephavenVersion","copyShortcut","GLOBAL_SHORTCUTS","getRow","text","ver","userDisplayName","hasUserImage","showUserName","dhUser","dhUserIncognito","vsClose","vsWatch","vsLayers","ThemeContext","contextValue","vsPaintcan","ThemePicker","vsRecordKeys","vsInfo","CopyButton","Logo","MINIMUM_DRAG_DISTANCE","DragSourceMenuItem","action","menuItemDisabled","iconElement","displayShortcut","isMouseSelected","isKeyboardSelected","closeMenu","startX","useRef","startY","startObject","disableDoubleClick","setDisableDoubleClick","handleMouseMove","handleMouseDown","handleMouseUp","AppControlsMenu","handleControlSelect","handleToolSelect","onClearFilter","controlMenuActions","dhInput","dragEvent","ControlType","dhTriangleDownSquare","vsMarkdown","vsDeviceCamera","vsLink","ToolType","dhFilterSlash","IRIS_GRID_SHORTCUTS","DropdownMenu","replaceReducer","reducers","getLayoutStorage","getServerConfigValues","reducer","reducerRegistry","WidgetList","onExportLayout","onImportLayout","onResetLayout","onSelect","widgets","setSearchText","searchField","selectStartEvent","sendSelect","widget","handleSearchChange","filteredWidgets","a","b","widgetElements","ObjectIcon","errorElement","SearchInput","vsPreview","vsArrowSmallDown","vsArrowSmallUp","isLayoutV2","layout","isLayoutV1","DEFAULT_LAYOUT_CONFIG","ConsolePanel","LogPanel","CommandHistoryPanel","FileExplorerPanel","DEFAULT_LAYOUT_CONFIG_NO_CONSOLE","normalizeLayout","getDefaultLayout","isConsoleAvailable","layouts","exportLayout","filterSets","layoutConfig","links","pluginDataMap","UserLayoutUtils","EmptyDashboard","onAutoFillClick","vsArrowUp","AppMainContainer","DashboardUtils","zipFile","bindAllMethods","allDashboardData","versionInfoText","copyToClipboard","DEFAULT_DASHBOARD_ID","vsTerminal","prevProps","prevState","dashboardData","stopListenForCreateDashboard","connection","updated","created","removed","widgetsToRemove","newWidgets","toRemove","toAdd","setDashboardPluginData","updateDashboardData","workspace","workspaceData","pluginKeys","pluginId","match","notebookPath","session","sessionConfig","fileMetadata","notebookSettings","NotebookEvent","InputFilterEvent","PanelEvent","activeTabKey","MarkdownEvent","toolType","activeTool","setActiveTool","updateWorkspaceData","closed","newLayout","oldLayout","listenForCreateDashboard","newId","nanoid","tabs","isPanelsMenuShown","sortedWidgets","exportedConfig","NotebookPanel","file","fileText","exportedLayout","layoutIteration","clipboardData","pastedData","replacedChars","getVariableDescriptor","plugins","getDashboardPlugins","tabId","oldTabs","newTabs","t","tab","newActiveTabKey","oldActiveTabIndex","EMPTY_ARRAY","permissions","canUsePanels","contextActions","isAuthFailed","isDisconnected","isResetLayoutPromptShown","isSettingsMenuShown","unsavedNotebookCount","dashboardPlugins","NavTabList","dhShapes","dhPanels","Popper","vsGear","dhSquareFilled","ThemeExport","vsDebugDisconnect","AppDashboards","LoadingOverlay","ConsolePlugin","SlideTransition","ContextActions","DebouncedModal","InfoModal","LoadingSpinner","BasicModal","getActiveTool","getAllDashboardsData","getDashboardData","getPlugins","getDashboardConnection","getDashboardSessionWrapper","getUser","getWorkspace","ConnectedAppMainContainer","setActiveToolAction","setDashboardDataAction","setDashboardPluginDataAction","updateDashboardDataAction","updateWorkspaceDataAction","withRouter","App","ContextMenuRoot","LocalWorkspaceStorage","settings","serverSettings","options","GrpcLayoutStorage","storageService","root","content","GrpcFileStorageTable","baseRoot","filename","FileUtils","expanded","paths","nextPath","remainingPath","childTable","search","refreshPromise","viewportUpdatePromise","CanceledPromiseError","basename","childViewportData","GrpcFileStorage","fileContents","newName","FileNotFoundError","itemDetails","isFileType","throttle","AppInit","setApi","setCommandHistoryStorage","setDashboardData","setFileStorage","setDashboardConnection","setDashboardSessionWrapper","setPlugins","setUser","setWorkspace","setWorkspaceStorage","setDefaultWorkspaceSettings","setServerConfigValues","api","client","useClient","useConnection","usePlugins","serverConfig","useServerConfig","useUser","loadApp","sessionDetails","getSessionDetails","sessionWrapper","loadSessionWrapper","fileStorage","workspaceStorage","commandHistoryStorage","loadedWorkspace","isLoading","isLoaded","errorMessage","getWorkspaceStorage","ConnectedAppInit","setApiAction","setCommandHistoryStorageAction","setFileStorageAction","setLayoutStorageAction","setDashboardConnectionAction","setDashboardSessionWrapperAction","setPluginsAction","setUserAction","setWorkspaceAction","setDefaultWorkspaceSettingsAction","setWorkspaceStorageAction","setServerConfigValuesAction","StyleGuideRoot","__vitePreload","baseURI","AppRouter","Router","Switch","Route","Redirect","AppRoot","DownloadServiceWorkerUtils","MonacoUtils","MonacoWorker","Provider"],"sources":["../../../storage/dist/StorageUtils.js","../../../pouch-storage/dist/pouchCommandHistoryUtils.js","../../../pouch-storage/dist/PouchStorageTable.js","../../../pouch-storage/dist/PouchCommandHistoryTable.js","../../../pouch-storage/dist/PouchCommandHistoryCache.js","../../../pouch-storage/dist/PouchCommandHistoryStorage.js","../../src/redux/actionTypes.ts","../../src/redux/actions.ts","../../../jsapi-shim/dist/dh.js","../../src/settings/SettingsUtils.tsx","../../src/settings/DateTimeOptions.tsx","../../src/settings/TimeZoneOptions.tsx","../../src/settings/FormattingSectionContent.tsx","../../src/settings/LegalNotice.tsx","../../src/settings/SettingsMenuSection.tsx","../../src/settings/ShortcutItem.tsx","../../src/settings/ShortcutsSectionContent.tsx","../../src/log/LogExport.ts","../../src/settings/ColumnTypeOptions.tsx","../../src/settings/ColumnSpecificSectionContent.tsx","../../src/settings/SettingsMenu.tsx","../../src/main/AppControlsMenu.tsx","../../src/redux/reducers/layoutStorage.ts","../../src/redux/reducers/index.ts","../../src/redux/selectors.ts","../../src/redux/index.ts","../../src/main/WidgetList.tsx","../../src/storage/LayoutStorage.ts","../../src/main/UserLayoutUtils.ts","../../src/main/EmptyDashboard.tsx","../../src/main/AppMainContainer.tsx","../../src/main/App.tsx","../../src/storage/LocalWorkspaceStorage.ts","../../src/storage/grpc/GrpcLayoutStorage.ts","../../src/storage/grpc/GrpcFileStorageTable.ts","../../src/storage/grpc/GrpcFileStorage.ts","../../src/main/AppInit.tsx","../../src/main/AppRouter.tsx","../../src/AppRoot.tsx"],"sourcesContent":["import { Operator as FilterOperator } from '@deephaven/filters';\nexport class StorageUtils {\n static makeSortConfig(columnName, direction) {\n return {\n column: columnName,\n direction\n };\n }\n static makeFilterConfig(filters) {\n var filterItems = [];\n var filterOperators = [];\n filters.forEach((filterItem, i) => {\n filterItems.push(filterItem);\n if (i > 0) {\n filterOperators.push(FilterOperator.and);\n }\n });\n return {\n filterItems,\n filterOperators\n };\n }\n static combineFilterConfigs(config1, config2) {\n var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : FilterOperator.and;\n return {\n filterItems: [...config1.filterItems, ...config2.filterItems],\n filterOperators: [...config1.filterOperators, operator, ...config2.filterOperators]\n };\n }\n static makeFilterItem(columnName, type, value) {\n return {\n columnName,\n type,\n value\n };\n }\n}\nexport default StorageUtils;\n//# sourceMappingURL=StorageUtils.js.map","/**\n * Takes an array of items and determines which ones to keep and which ones to\n * prune based on the given thresholds.\n * @param items items to keep or prune\n * @param maxItems maximum number of items to allow before pruning\n * @param pruneItemsCount if the maxItems count is exceeded, the number we want to keep\n */\n// eslint-disable-next-line import/prefer-default-export\nexport function siftPrunableItems(items, maxItems, pruneItemsCount) {\n if (items.length > maxItems) {\n var pruneCount = items.length - pruneItemsCount;\n return {\n toKeep: items.slice(pruneCount),\n toPrune: items.slice(0, pruneCount)\n };\n }\n return {\n toKeep: items,\n toPrune: []\n };\n}\n//# sourceMappingURL=pouchCommandHistoryUtils.js.map","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\nimport PouchDB from 'pouchdb-browser';\nimport PouchDBFind from 'pouchdb-find';\nimport { Operator as FilterOperator, Type as FilterType } from '@deephaven/filters';\nimport Log from '@deephaven/log';\nimport { PromiseUtils } from '@deephaven/utils';\nvar log = Log.module('PouchStorageTable');\nvar DB_PREFIX = 'Deephaven.';\nPouchDB.plugin(PouchDBFind);\nexport function makePouchFilter(type, value) {\n switch (type) {\n case FilterType.in:\n case FilterType.contains:\n return {\n $regex: new RegExp(\"\".concat(value)).toString()\n };\n case FilterType.inIgnoreCase:\n return {\n $regex: new RegExp(\"\".concat(value), 'i').toString()\n };\n case FilterType.eq:\n return {\n $eq: value\n };\n case FilterType.notEq:\n return {\n $ne: value\n };\n case FilterType.greaterThan:\n return {\n $gt: value\n };\n case FilterType.greaterThanOrEqualTo:\n return {\n $gte: value\n };\n case FilterType.lessThan:\n return {\n $lt: value\n };\n case FilterType.lessThanOrEqualTo:\n return {\n $lte: value\n };\n case FilterType.startsWith:\n return {\n $regex: new RegExp(\"^\".concat(value, \".*\")).toString()\n };\n default:\n throw new Error(\"Unsupported type: \".concat(type));\n }\n}\nfunction makePouchSelectorFromConfig(config) {\n var {\n filterItems,\n filterOperators\n } = config;\n var filter = null;\n for (var i = 0; i < filterItems.length; i += 1) {\n var filterItem = filterItems[i];\n var {\n columnName,\n type,\n value\n } = filterItem;\n var newFilter = {\n [columnName]: makePouchFilter(type, value)\n };\n if (i === 0) {\n filter = newFilter;\n } else if (filter !== null && i - 1 < filterOperators.length) {\n var filterOperator = filterOperators[i - 1];\n if (filterOperator === FilterOperator.and) {\n filter = {\n $and: [filter, newFilter]\n };\n } else if (filterOperator === FilterOperator.or) {\n filter = {\n $or: [filter, newFilter]\n };\n } else {\n throw new Error(\"Unexpected filter operator \".concat(filterOperator, \", \").concat(newFilter));\n }\n }\n }\n if (filter == null) {\n throw new Error(\"Invalid filter config \".concat(config));\n }\n return filter;\n}\nfunction selectorWithFilters() {\n var filters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return {\n $and: [...filters.map(filter => makePouchSelectorFromConfig(filter)), {\n name: {\n $gt: null\n }\n }, {\n id: {\n $gt: null\n }\n }]\n };\n}\nfunction sortWithConfigs(sorts) {\n var _sorts$map;\n var reverse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n return [{\n id: reverse ? 'desc' : 'asc'\n }, ...((_sorts$map = sorts === null || sorts === void 0 ? void 0 : sorts.map(sort => ({\n [sort.column]: sort.direction\n }))) !== null && _sorts$map !== void 0 ? _sorts$map : [])];\n}\nexport class PouchStorageTable {\n constructor(databaseName, dbOptions) {\n _defineProperty(this, \"db\", void 0);\n _defineProperty(this, \"changes\", void 0);\n _defineProperty(this, \"listeners\", []);\n _defineProperty(this, \"itemListeners\", new Map());\n _defineProperty(this, \"currentSize\", 0);\n _defineProperty(this, \"currentViewport\", void 0);\n _defineProperty(this, \"currentReverse\", false);\n _defineProperty(this, \"currentFilter\", null);\n _defineProperty(this, \"currentSort\", null);\n _defineProperty(this, \"infoUpdatePromise\", void 0);\n _defineProperty(this, \"viewportUpdatePromise\", void 0);\n _defineProperty(this, \"currentViewportData\", void 0);\n this.db = new PouchDB(\"\".concat(DB_PREFIX).concat(databaseName), dbOptions);\n\n // Need to set `_remote` to false to remove deprecation warnings: https://github.com/pouchdb/pouchdb/issues/6106\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-underscore-dangle\n this.db._remote = false;\n this.listenForChanges();\n this.db.createIndex({\n index: {\n fields: ['id', 'name']\n }\n });\n this.refreshInfo();\n }\n\n /**\n * Listen for db changes. This can be cancelled by calling\n * `this.changes?.cancel()`\n */\n listenForChanges() {\n this.changes = this.db.changes({\n live: true,\n since: 'now',\n include_docs: true\n }).on('change', this.dbUpdate.bind(this));\n }\n onUpdate(callback) {\n this.listeners = [...this.listeners, callback];\n return () => {\n this.listeners = this.listeners.filter(other => other !== callback);\n };\n }\n onItemUpdate(id, listener) {\n if (!this.itemListeners.has(id)) {\n this.itemListeners.set(id, []);\n }\n this.itemListeners.set(id, [...this.itemListeners.get(id), listener]);\n this.refreshItem(id);\n return () => {\n this.itemListeners.set(id, this.itemListeners.get(id).filter(other => other !== listener));\n };\n }\n close() {\n this.listeners = [];\n }\n get size() {\n return this.currentSize;\n }\n get viewport() {\n return this.currentViewport;\n }\n setReversed(reversed) {\n this.currentReverse = reversed;\n this.currentViewportData = undefined;\n this.refreshData();\n }\n setViewport(viewport) {\n this.currentViewport = viewport;\n this.refreshInfo();\n this.refreshData();\n }\n setSorts(config) {\n this.currentSort = config;\n this.currentViewportData = undefined;\n this.refreshData();\n }\n setFilters(config) {\n this.currentFilter = config;\n this.currentViewportData = undefined;\n this.refreshInfo();\n this.refreshData();\n }\n get data() {\n return this.currentViewportData;\n }\n getViewportData() {\n var _this = this;\n return _asyncToGenerator(function* () {\n var _this$viewportUpdateP;\n if (!_this.viewportUpdatePromise) {\n _this.refreshData();\n }\n return (_this$viewportUpdateP = _this.viewportUpdatePromise) !== null && _this$viewportUpdateP !== void 0 ? _this$viewportUpdateP : Promise.resolve({\n items: [],\n offset: 0\n });\n })();\n }\n put(item) {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n // Put the item ID in both the _id and the id slot\n // PouchDB uses _id everywhere, StorageTable just uses `id` though\n var newItem = _objectSpread(_objectSpread({}, item), {}, {\n _id: item.id\n });\n yield _this2.db.put(newItem);\n return newItem;\n })();\n }\n sendUpdate() {\n var _this$currentViewport;\n // Retain a reference to it in case a listener gets removed while sending an update\n var {\n listeners\n } = this;\n var data = (_this$currentViewport = this.currentViewportData) !== null && _this$currentViewport !== void 0 ? _this$currentViewport : {\n items: [],\n offset: 0\n };\n for (var i = 0; i < listeners.length; i += 1) {\n listeners[i](data);\n }\n }\n sendItemUpdate(item) {\n var listeners = this.itemListeners.get(item.id);\n if (listeners !== undefined) {\n for (var i = 0; i < listeners.length; i += 1) {\n listeners[i](item);\n }\n }\n }\n dbUpdate(event) {\n log.debug('Update received', event);\n this.refreshInfo();\n if (event.doc !== undefined) {\n this.sendItemUpdate(event.doc);\n }\n this.refreshData();\n }\n\n /**\n * Fetch infor for a given selector.\n * @param selector\n */\n fetchInfo(selector) {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n return _this3.db.find({\n selector,\n fields: []\n });\n })();\n }\n refreshInfo() {\n var _this4 = this;\n return _asyncToGenerator(function* () {\n try {\n var _this4$infoUpdateProm, _this4$currentFilter;\n (_this4$infoUpdateProm = _this4.infoUpdatePromise) === null || _this4$infoUpdateProm === void 0 ? void 0 : _this4$infoUpdateProm.cancel();\n _this4.infoUpdatePromise = PromiseUtils.makeCancelable(_this4.fetchInfo(selectorWithFilters((_this4$currentFilter = _this4.currentFilter) !== null && _this4$currentFilter !== void 0 ? _this4$currentFilter : [])));\n var findResult = yield _this4.infoUpdatePromise;\n _this4.currentSize = findResult.docs.length;\n _this4.sendUpdate();\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to refreshInfo', e);\n throw e;\n }\n }\n })();\n }\n\n /**\n * Fetch data for the given viewport, selector, and sort.\n * @param viewport\n * @param selector\n * @param sort\n */\n fetchViewportData(viewport, selector, sort) {\n var _this5 = this;\n return _asyncToGenerator(function* () {\n return _this5.db.find({\n selector,\n skip: viewport.top,\n limit: viewport.bottom - viewport.top + 1,\n sort,\n fields: ['id', 'name']\n }).then(findResult => ({\n items: findResult.docs,\n offset: viewport.top\n }));\n })();\n }\n refreshData() {\n var _this6 = this;\n return _asyncToGenerator(function* () {\n if (!_this6.currentViewport) {\n return;\n }\n try {\n var _this6$currentFilter, _this6$viewportUpdate;\n var selector = selectorWithFilters((_this6$currentFilter = _this6.currentFilter) !== null && _this6$currentFilter !== void 0 ? _this6$currentFilter : []);\n var sort = sortWithConfigs(_this6.currentSort, _this6.currentReverse);\n (_this6$viewportUpdate = _this6.viewportUpdatePromise) === null || _this6$viewportUpdate === void 0 ? void 0 : _this6$viewportUpdate.cancel();\n _this6.viewportUpdatePromise = PromiseUtils.makeCancelable(_this6.fetchViewportData(_this6.currentViewport, selector, sort));\n var viewportData = yield _this6.viewportUpdatePromise;\n _this6.currentViewportData = viewportData;\n _this6.sendUpdate();\n return viewportData;\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to refreshData', e);\n throw e;\n }\n }\n })();\n }\n refreshItem(id) {\n var _this7 = this;\n return _asyncToGenerator(function* () {\n var findResult = yield _this7.db.find({\n selector: {\n id\n },\n limit: 1\n });\n var item = findResult.docs[0];\n if (item !== undefined) {\n _this7.sendItemUpdate(item);\n }\n return item;\n })();\n }\n getSnapshot(sortedRanges) {\n var _this8 = this;\n return _asyncToGenerator(function* () {\n var itemMap = new Map();\n var sort = [{\n id: _this8.currentReverse ? 'desc' : 'asc'\n }];\n yield Promise.all(sortedRanges.map( /*#__PURE__*/function () {\n var _ref2 = _asyncToGenerator(function* (_ref) {\n var _this8$currentFilter;\n var [from, to] = _ref;\n var limit = to - from + 1;\n return _this8.db.find({\n selector: selectorWithFilters((_this8$currentFilter = _this8.currentFilter) !== null && _this8$currentFilter !== void 0 ? _this8$currentFilter : []),\n skip: from,\n limit,\n sort,\n fields: ['id', 'name']\n }).then(findSnapshotResult => {\n for (var i = 0; i < limit; i += 1) {\n var index = from + i;\n itemMap.set(index, findSnapshotResult.docs[i]);\n }\n });\n });\n return function (_x) {\n return _ref2.apply(this, arguments);\n };\n }()));\n return itemMap;\n })();\n }\n}\nexport default PouchStorageTable;\n//# sourceMappingURL=PouchStorageTable.js.map","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\nimport { Type as FilterType } from '@deephaven/filters';\nimport Log from '@deephaven/log';\nimport { StorageUtils } from '@deephaven/storage';\nimport { PromiseUtils } from '@deephaven/utils';\nimport { siftPrunableItems } from \"./pouchCommandHistoryUtils.js\";\nimport PouchStorageTable from \"./PouchStorageTable.js\";\nvar COMMAND_HISTORY_ITEMS_MAX = 2500;\nvar COMMAND_HISTORY_ITEMS_PRUNE = 2000;\nvar log = Log.module('PouchCommandHistoryTable');\nexport class PouchCommandHistoryTable extends PouchStorageTable {\n constructor(language, cache) {\n var _this$cache$tableRegi;\n super(\"CommandHistoryStorage.\".concat(language), {\n // Optimizations to cut down on growing table size. These should be safe\n // since we don't care about revision history for command history\n // documents.\n auto_compaction: true,\n revs_limit: 1\n });\n\n // Add this table instance to the table registry\n _defineProperty(this, \"searchText\", void 0);\n this.cache = cache;\n if (!this.cache.tableRegistry.has(this.cacheKey)) {\n this.cache.tableRegistry.set(this.cacheKey, new Set());\n }\n log.debug('Adding table to registry', this.cacheKey);\n (_this$cache$tableRegi = this.cache.tableRegistry.get(this.cacheKey)) === null || _this$cache$tableRegi === void 0 ? void 0 : _this$cache$tableRegi.add(this);\n }\n get cacheKey() {\n return this.db.name;\n }\n setSearch(searchText) {\n log.debug('Setting search filters', searchText);\n this.searchText = searchText.trim().toLowerCase();\n this.setFilters(searchText ? [StorageUtils.makeFilterConfig([StorageUtils.makeFilterItem('name', FilterType.contains, searchText)])] : []);\n }\n\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n dbUpdate(event) {\n log.debug('Clearing cache and refreshing data', event);\n this.cache.response.delete(this.cacheKey);\n super.dbUpdate(event);\n }\n\n /**\n * Fetch command history data from `this.cache.response` or from\n * PouchDB if data is not found in the cache. If the number of total items in\n * the db exceeds COMMAND_HISTORY_ITEMS_MAX, the database will be pruned down\n * to COMMAND_HISTORY_ITEMS_PRUNE total items. Note that PouchDB doesn't\n * actually remove them from the underlying IndexDB, they are just marked\n * as deleted and won't be present in our query results.\n * @param selector\n */\n fetchData(_selector) {\n var _this = this;\n return _asyncToGenerator(function* () {\n // Wrapping this in a setTimeout so that it executes on next call stack.\n // This is necessary to ensure `this.cache` has been initialized due to some\n // nuances with property initilization with inherited classes.\n return PromiseUtils.withTimeout(0, /*#__PURE__*/_asyncToGenerator(function* () {\n if (_this.cache.response.has(_this.cacheKey)) {\n log.debug('Fetching from cache', _this.searchText, _this.viewport);\n } else {\n log.debug('Fetching from PouchDB', _this.searchText, _this.viewport);\n _this.cache.response.set(_this.cacheKey, _this.db.allDocs({\n include_docs: true\n }).then(result => {\n var allItems = result.rows\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .map(row => row.doc).filter(_ref2 => {\n var {\n name\n } = _ref2;\n return name;\n });\n log.debug(\"Fetched \".concat(allItems.length, \" command history items\"));\n var {\n toKeep,\n toPrune\n } = siftPrunableItems(allItems, COMMAND_HISTORY_ITEMS_MAX, COMMAND_HISTORY_ITEMS_PRUNE);\n\n // If number of items in PouchDB has exceeded COMMAND_HISTORY_ITEMS_MAX\n // prune them down so we have COMMAND_HISTORY_ITEMS_PRUNE left\n if (toPrune.length) {\n _this.pruneItems(toPrune);\n }\n return {\n docs: toKeep\n };\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n var result = _this.cache.response.get(_this.cacheKey);\n if (_this.searchText == null || _this.searchText === '') {\n return result;\n }\n return _objectSpread(_objectSpread({}, result), {}, {\n docs: (yield result).docs.filter(_ref3 => {\n var {\n name\n } = _ref3;\n return (\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n name.toLowerCase().includes(_this.searchText)\n );\n })\n });\n }));\n })();\n }\n\n /**\n * Override `PouchStorageTable.fetchInfo` so we can make use of\n * `PouchCommandHistoryCache`\n * @param selector\n */\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n fetchInfo(selector) {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n return _this2.fetchData(selector);\n })();\n }\n\n /**\n * Override `PouchStorageTable.fetchViewportData` to fetch command history\n * storage items. This override provides caching + optimizations specific to\n * command history. We cache the results to avoid excessive PouchDB queries\n * during scrolling. The cache should only need to be invalidated when search\n * filter changes or commands are added to the storage history.\n *\n * @param viewport\n * @param selector\n * @param sort\n * @returns Promise to array of command history storage items\n */\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n fetchViewportData(viewport, selector, sort) {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n var data = yield _this3.fetchData(selector);\n log.debug('Fetching viewport data', viewport.top, viewport.bottom + 1, sort, data);\n var isReversed = typeof sort[0] === 'object' && sort[0].id === 'desc';\n var docs = isReversed ? data.docs.slice(0).reverse() : data.docs;\n var items = docs.slice(viewport.top, viewport.bottom + 1);\n return {\n items,\n offset: viewport.top\n };\n })();\n }\n\n /**\n * Mark given items as `_deleted` in the database.\n * @param items\n */\n pruneItems(items) {\n var _this4 = this;\n return _asyncToGenerator(function* () {\n if (_this4.cache.isPruning.get(_this4.cacheKey) === true) {\n log.debug('Pruning already in progress. Skipping.');\n return;\n }\n try {\n log.debug(\"Pruning \".concat(items.length, \" command history items\"));\n\n // Disable change notifications while we bulk delete to avoid locking up\n // the app\n var resumeListeners = _this4.cache.pauseChangeListeners(_this4.cacheKey);\n _this4.cache.isPruning.set(_this4.cacheKey, true);\n yield _this4.db.bulkDocs(items.map(item => _objectSpread(_objectSpread({}, item), {}, {\n _deleted: true\n })));\n _this4.cache.isPruning.set(_this4.cacheKey, false);\n resumeListeners();\n log.debug('Finished pruning command history items');\n } catch (err) {\n log.error('An error occurred while pruning db', err);\n }\n })();\n }\n\n // Our current version of eslint + prettier doesn't always like the `override`\n // keyword. Whenever we upgrade, we should annotate this function with `override`.\n close() {\n var _this$cache$tableRegi2, _this$cache$tableRegi3, _this$changes;\n log.debug('Closing table', this, (_this$cache$tableRegi2 = this.cache.tableRegistry.get(this.cacheKey)) === null || _this$cache$tableRegi2 === void 0 ? void 0 : _this$cache$tableRegi2.size);\n (_this$cache$tableRegi3 = this.cache.tableRegistry.get(this.cacheKey)) === null || _this$cache$tableRegi3 === void 0 ? void 0 : _this$cache$tableRegi3.delete(this);\n (_this$changes = this.changes) === null || _this$changes === void 0 ? void 0 : _this$changes.cancel();\n super.close();\n }\n}\nexport default PouchCommandHistoryTable;\n//# sourceMappingURL=PouchCommandHistoryTable.js.map","function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\nimport Log from '@deephaven/log';\nvar log = Log.module('PouchCommandHistoryCache');\n\n/**\n * Cache for tracking things shared across multiple\n * `PouchCommandHistoryTable` instances.\n */\nclass PouchCommandHistoryCache {\n constructor() {\n _defineProperty(this, \"isPruning\", void 0);\n _defineProperty(this, \"response\", void 0);\n _defineProperty(this, \"tableRegistry\", void 0);\n this.isPruning = new Map();\n this.response = new Map();\n this.tableRegistry = new Map();\n }\n\n /**\n * Keep track of pruning status for a database. This helps ensure only 1\n * pruning operation gets executed if multiple instances of a PouchCommandHistory\n * table load data at the same time.\n */\n\n /**\n * Cache for command history query results keyed by db name. The cached data\n * will be shared across all `PouchCommandHistoryTable` instances that have\n * the same db name.\n */\n\n /**\n * Keeps track of all `PouchCommandHistoryTable` instances.\n */\n\n /**\n * Pauses PouchDB change listeners for any `PouchCommandHistoryTable` with\n * the given database name. This will cancel existing subscriptions and\n * return a callback that can be used to re-subscribe them.\n * @param dbName\n */\n pauseChangeListeners(dbName) {\n var _this$tableRegistry$g;\n var pausedTables = [];\n (_this$tableRegistry$g = this.tableRegistry.get(dbName)) === null || _this$tableRegistry$g === void 0 ? void 0 : _this$tableRegistry$g.forEach(table => {\n if (table.changes) {\n log.debug(\"Pausing event listeners on '\".concat(dbName, \"' table\"), table);\n table.changes.cancel();\n pausedTables.push(table);\n }\n });\n return () => {\n pausedTables.forEach(table => {\n var _this$tableRegistry$g2, _this$tableRegistry$g3;\n // Resume listening for changes if the table is still in the registry\n if ((_this$tableRegistry$g2 = (_this$tableRegistry$g3 = this.tableRegistry.get(dbName)) === null || _this$tableRegistry$g3 === void 0 ? void 0 : _this$tableRegistry$g3.has(table)) !== null && _this$tableRegistry$g2 !== void 0 ? _this$tableRegistry$g2 : false) {\n log.debug(\"Resuming event listeners on '\".concat(dbName, \"' table\"), table);\n table.listenForChanges();\n }\n });\n };\n }\n}\nexport default PouchCommandHistoryCache;\n//# sourceMappingURL=PouchCommandHistoryCache.js.map","function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return typeof key === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (typeof input !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (typeof res !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\n/* eslint-disable class-methods-use-this */\nimport Log from '@deephaven/log';\nimport PouchCommandHistoryTable from \"./PouchCommandHistoryTable.js\";\nimport PouchCommandHistoryCache from \"./PouchCommandHistoryCache.js\";\nvar log = Log.module('PouchCommandHistoryStorage');\nexport class PouchCommandHistoryStorage {\n constructor() {\n _defineProperty(this, \"cache\", new PouchCommandHistoryCache());\n _defineProperty(this, \"updateTableMap\", new Map());\n }\n getUpdateTable(language) {\n if (!this.updateTableMap.has(language)) {\n this.updateTableMap.set(language, new PouchCommandHistoryTable(language, this.cache));\n }\n return this.updateTableMap.get(language);\n }\n getTable(language) {\n var _this = this;\n return _asyncToGenerator(function* () {\n return new PouchCommandHistoryTable(language, _this.cache);\n })();\n }\n addItem(language, scope, command, data) {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n return _this2.updateItem(language, {\n id: \"\".concat(new Date().getTime()),\n name: command,\n data\n });\n })();\n }\n updateItem(language, item) {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n var updateTable = _this3.getUpdateTable(language);\n var dbItem = yield updateTable.refreshItem(item.id);\n var updatedItem = _objectSpread(_objectSpread({}, dbItem !== null && dbItem !== void 0 ? dbItem : {}), item);\n log.debug('Updating item', updatedItem);\n yield updateTable.put(updatedItem);\n log.debug('Update saved');\n return item;\n })();\n }\n listenItem(language, id, listener) {\n var updateTable = this.getUpdateTable(language);\n return updateTable.onItemUpdate(id, listener);\n }\n}\nexport default PouchCommandHistoryStorage;\n//# sourceMappingURL=PouchCommandHistoryStorage.js.map","// eslint-disable-next-line import/prefer-default-export\nexport const SET_LAYOUT_STORAGE = 'SET_LAYOUT_STORAGE';\n","import LayoutStorage from '../storage/LayoutStorage';\nimport { SET_LAYOUT_STORAGE } from './actionTypes';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const setLayoutStorage = (\n layoutStorage: LayoutStorage\n): { type: string; payload: LayoutStorage } => ({\n type: SET_LAYOUT_STORAGE,\n payload: layoutStorage,\n});\n","// The Deephaven API script isn't packaged as a module (yet), and is just included in index.html, exported to the global namespace\n// This include file is simply a wrapper so that it behaves like a module, and can be mocked easily for unit tests\n\nvar {\n dh\n} = globalThis;\nexport default dh;\n//# sourceMappingURL=dh.js.map","import { DbNameValidator } from '@deephaven/utils';\nimport {\n DateTimeColumnFormatter,\n IntegerColumnFormatter,\n DecimalColumnFormatter,\n TableColumnFormat,\n FormattingRule,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport type { ServerConfigValues } from '@deephaven/redux';\nimport Bowser from 'bowser';\nimport { PluginModuleMap } from '@deephaven/plugin';\n\nconst log = Log.module('SettingsUtils');\n\nexport type FormatOption = {\n defaultFormatString?: string;\n};\n\nexport type ValidFormatterItem = FormattingRule & {\n id?: number;\n isNewRule?: boolean;\n};\n\nexport type FormatterItem = Omit<ValidFormatterItem, 'format'> & {\n format: Partial<TableColumnFormat>;\n};\n\nfunction isFormatStringFormat(\n format: Partial<TableColumnFormat>\n): format is Pick<TableColumnFormat, 'formatString'> {\n return (\n (format as Pick<TableColumnFormat, 'formatString'>).formatString != null\n );\n}\n\n/**\n * Get an object containing all version information formatted for display\n * @param serverConfigValues The server config values\n * @returns The formatted version info or \"Unknown\" for any value not available\n */\nexport function getFormattedVersionInfo(\n serverConfigValues: ServerConfigValues\n): Record<string, string> {\n const ua = Bowser.parse(window.navigator.userAgent);\n const browser = `${ua.browser.name ?? ''} ${\n // use only the major version and minor version, rest is usually empty 120.1.0.0 -> 120.1\n Number(parseFloat(ua.browser.version ?? '')) || ''\n }`;\n const os = `${ua.os.name ?? ''} ${ua.os.version ?? ''}`;\n return {\n 'Engine Version': serverConfigValues.get('deephaven.version') ?? 'Unknown',\n 'Web UI Version': import.meta.env.npm_package_version ?? 'Unknown',\n 'Java Version': serverConfigValues.get('java.version') ?? 'Unknown',\n 'Barrage Version': serverConfigValues.get('barrage.version') ?? 'Unknown',\n 'Browser Name': browser.trim() || 'Unknown',\n 'OS Name': os.trim() || 'Unknown',\n };\n}\n\n/**\n * Get an object containing all JS plugin information formatted for display\n * @param serverConfigValues The information for all plugins\n * @returns The formatted mapping from plugin name to version\n */\nexport function getFormattedPluginInfo(\n pluginDataValues: PluginModuleMap\n): Record<string, string> {\n return Array.from(pluginDataValues.entries())\n .filter(plugin => plugin[1].version !== undefined)\n .reduce((acc, [key, value]) => ({ ...acc, [key]: value.version }), {});\n}\n\nexport function focusFirstInputInContainer(\n container: HTMLElement | null\n): void {\n const input: HTMLElement | null | undefined = container?.querySelector(\n 'input, select, textarea'\n );\n if (input) {\n input.focus();\n }\n}\n\nexport function isSameOptions(\n options1: FormatOption,\n options2: FormatOption\n): boolean {\n return options1.defaultFormatString === options2.defaultFormatString;\n}\n\nexport function isSameDecimalOptions(\n options1: FormatOption,\n options2: FormatOption\n): boolean {\n return isSameOptions(options1, options2);\n}\n\nexport function isSameIntegerOptions(\n options1: FormatOption,\n options2: FormatOption\n): boolean {\n return isSameOptions(options1, options2);\n}\n\nexport function isValidColumnName(name: string): boolean {\n return name !== '' && DbNameValidator.isValidColumnName(name);\n}\n\nexport function isValidFormat(\n dh: typeof DhType,\n columnType: string,\n format: Partial<TableColumnFormat>\n): boolean {\n // Undefined or empty string formats are always invalid\n if (\n !columnType ||\n format.formatString == null ||\n !isFormatStringFormat(format)\n ) {\n return false;\n }\n switch (columnType) {\n case 'datetime':\n return DateTimeColumnFormatter.isValid(dh, format);\n case 'decimal':\n return DecimalColumnFormatter.isValid(dh, format);\n case 'int':\n return IntegerColumnFormatter.isValid(dh, format);\n default: {\n log.warn('Trying to validate format of unknown type');\n return true;\n }\n }\n}\n\nexport function removeFormatRuleExtraProps(\n item: ValidFormatterItem\n): FormattingRule {\n const { id, isNewRule, ...rest } = item;\n return rest;\n}\n\nexport function isFormatRuleValidForSave(\n dh: typeof DhType,\n rule: FormatterItem\n): rule is ValidFormatterItem {\n return (\n isValidColumnName(rule.columnName) &&\n isValidFormat(dh, rule.columnType, rule.format)\n );\n}\n\nexport default {\n focusFirstInputInContainer,\n isSameOptions,\n isSameDecimalOptions,\n isSameIntegerOptions,\n isValidColumnName,\n isValidFormat,\n removeFormatRuleExtraProps,\n isFormatRuleValidForSave,\n};\n","import React, { ReactElement, useMemo } from 'react';\nimport {\n Formatter,\n DateTimeColumnFormatter,\n TableUtils,\n} from '@deephaven/jsapi-utils';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\n\ninterface DateTimeOptionProps {\n timestamp: Date;\n timeZone: string;\n showTimeZone: boolean;\n showTSeparator: boolean;\n isGlobalOptions: boolean;\n legacyGlobalFormat?: string;\n}\n\nexport default function DateTimeOptions(\n props: DateTimeOptionProps\n): ReactElement {\n const {\n timestamp,\n timeZone,\n showTimeZone,\n showTSeparator,\n isGlobalOptions,\n legacyGlobalFormat,\n } = props;\n\n const dh = useApi();\n\n const formatter = useMemo(\n () =>\n new Formatter(dh, [], {\n timeZone,\n showTimeZone,\n showTSeparator,\n }),\n [dh, showTimeZone, showTSeparator, timeZone]\n );\n const formats = isGlobalOptions\n ? DateTimeColumnFormatter.getGlobalFormats(showTimeZone, showTSeparator)\n : DateTimeColumnFormatter.getFormats(showTimeZone, showTSeparator);\n\n if (legacyGlobalFormat != null && !formats.includes(legacyGlobalFormat)) {\n formats.unshift(legacyGlobalFormat);\n }\n\n return (\n <>\n {formats.map(formatString => {\n const format = DateTimeColumnFormatter.makeFormat(\n '',\n formatString,\n DateTimeColumnFormatter.TYPE_GLOBAL\n );\n return (\n <option\n value={formatString}\n key={formatString}\n data-testid=\"time-format\"\n >\n {formatter.getFormattedString(\n timestamp,\n TableUtils.dataType.DATETIME,\n '',\n format\n )}\n </option>\n );\n })}\n </>\n );\n}\n","import React from 'react';\nimport { TimeUtils } from '@deephaven/utils';\n\nexport default function TimeZoneOptions(): JSX.Element {\n return (\n <>\n {TimeUtils.TIME_ZONES.map(timeZone => {\n const { label, value } = timeZone;\n return (\n <option value={value} key={value}>\n {label}\n </option>\n );\n })}\n </>\n );\n}\n","import React, {\n ChangeEvent,\n PureComponent,\n ReactElement,\n RefObject,\n} from 'react';\nimport { connect } from 'react-redux';\nimport { vsRefresh } from '@deephaven/icons';\nimport memoize from 'memoizee';\nimport debounce from 'lodash.debounce';\nimport classNames from 'classnames';\nimport { Button, Checkbox, Select } from '@deephaven/components';\nimport {\n IntegerColumnFormatter,\n DecimalColumnFormatter,\n TableUtils,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport {\n getApi,\n getDefaultDateTimeFormat,\n getDefaultDecimalFormatOptions,\n getDefaultIntegerFormatOptions,\n getTimeZone,\n getShowTimeZone,\n getShowTSeparator,\n getTruncateNumbersWithPound,\n getShowEmptyStrings,\n getShowNullStrings,\n updateSettings as updateSettingsAction,\n RootState,\n WorkspaceSettings,\n getDefaultSettings,\n} from '@deephaven/redux';\nimport './FormattingSectionContent.scss';\nimport type { DebouncedFunc } from 'lodash';\nimport {\n focusFirstInputInContainer,\n isSameDecimalOptions,\n isSameIntegerOptions,\n isValidFormat,\n} from './SettingsUtils';\nimport type { FormatOption } from './SettingsUtils';\nimport DateTimeOptions from './DateTimeOptions';\nimport TimeZoneOptions from './TimeZoneOptions';\n\nconst log = Log.module('FormattingSectionContent');\n\ninterface FormattingSectionContentProps {\n dh: typeof DhType;\n defaultDateTimeFormat: string;\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n truncateNumbersWithPound: boolean;\n showEmptyStrings: boolean;\n showNullStrings: boolean;\n updateSettings: (settings: Partial<WorkspaceSettings>) => void;\n defaultDecimalFormatOptions: FormatOption;\n defaultIntegerFormatOptions: FormatOption;\n defaults: WorkspaceSettings;\n}\n\ninterface FormattingSectionContentState {\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n defaultDateTimeFormat: string;\n defaultDecimalFormatOptions: FormatOption;\n defaultIntegerFormatOptions: FormatOption;\n truncateNumbersWithPound: boolean;\n showEmptyStrings: boolean;\n showNullStrings: boolean;\n timestampAtMenuOpen: Date;\n}\n\nexport class FormattingSectionContent extends PureComponent<\n FormattingSectionContentProps,\n FormattingSectionContentState\n> {\n static defaultProps = {\n scrollTo: (): void => undefined,\n };\n\n static inputDebounceTime = 250;\n\n constructor(props: FormattingSectionContentProps) {\n super(props);\n\n this.debouncedCommitChanges = debounce(\n this.commitChanges.bind(this),\n FormattingSectionContent.inputDebounceTime\n );\n this.queueUpdate = this.queueUpdate.bind(this);\n this.handleDefaultDateTimeFormatChange =\n this.handleDefaultDateTimeFormatChange.bind(this);\n this.handleDefaultDecimalFormatChange =\n this.handleDefaultDecimalFormatChange.bind(this);\n this.handleDefaultIntegerFormatChange =\n this.handleDefaultIntegerFormatChange.bind(this);\n this.handleShowTimeZoneChange = this.handleShowTimeZoneChange.bind(this);\n this.handleShowTSeparatorChange =\n this.handleShowTSeparatorChange.bind(this);\n this.handleTimeZoneChange = this.handleTimeZoneChange.bind(this);\n this.handleResetDateTimeFormat = this.handleResetDateTimeFormat.bind(this);\n this.handleResetDecimalFormat = this.handleResetDecimalFormat.bind(this);\n this.handleResetIntegerFormat = this.handleResetIntegerFormat.bind(this);\n this.handleResetTimeZone = this.handleResetTimeZone.bind(this);\n this.handleTruncateNumbersWithPoundChange =\n this.handleTruncateNumbersWithPoundChange.bind(this);\n this.handleShowEmptyStringsChange =\n this.handleShowEmptyStringsChange.bind(this);\n this.handleShowNullStringsChange =\n this.handleShowNullStringsChange.bind(this);\n\n const {\n defaultDateTimeFormat,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions,\n showTimeZone,\n showTSeparator,\n timeZone,\n truncateNumbersWithPound,\n showEmptyStrings,\n showNullStrings,\n } = props;\n\n this.containerRef = React.createRef();\n this.pendingUpdates = [];\n\n this.state = {\n showTimeZone,\n showTSeparator,\n timeZone,\n defaultDateTimeFormat,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions,\n truncateNumbersWithPound,\n showEmptyStrings,\n showNullStrings,\n timestampAtMenuOpen: new Date(),\n };\n }\n\n componentDidMount(): void {\n focusFirstInputInContainer(this.containerRef.current);\n }\n\n componentWillUnmount(): void {\n this.debouncedCommitChanges.flush();\n }\n\n debouncedCommitChanges: DebouncedFunc<() => void>;\n\n pendingUpdates: Partial<WorkspaceSettings>[];\n\n containerRef: RefObject<HTMLDivElement>;\n\n getCachedDateTimeFormatOptions = memoize(\n (\n timeZone: string,\n showTimeZone: boolean,\n showTSeparator: boolean,\n isGlobalOptions = false,\n legacyGlobalFormat?: string\n ) => {\n const { timestampAtMenuOpen } = this.state;\n return (\n <DateTimeOptions\n timestamp={timestampAtMenuOpen}\n timeZone={timeZone}\n showTimeZone={showTimeZone}\n showTSeparator={showTSeparator}\n isGlobalOptions={isGlobalOptions}\n legacyGlobalFormat={legacyGlobalFormat}\n />\n );\n }\n );\n\n queueUpdate(updates: Partial<WorkspaceSettings>): void {\n this.pendingUpdates.push(updates);\n this.debouncedCommitChanges();\n }\n\n handleDefaultDateTimeFormatChange(value: string): void {\n log.debug('handleDefaultDateTimeFormatChange', value);\n const update = {\n defaultDateTimeFormat: value,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleDefaultDecimalFormatChange(event: ChangeEvent<HTMLInputElement>): void {\n log.debug('handleDefaultDecimalFormatChange', event.target.value);\n const update = {\n defaultDecimalFormatOptions: {\n defaultFormatString: event.target.value,\n },\n };\n this.setState(update);\n if (\n isValidFormat(\n dh,\n TableUtils.dataType.DECIMAL,\n DecimalColumnFormatter.makeCustomFormat(event.target.value)\n )\n ) {\n this.queueUpdate(update);\n }\n }\n\n handleDefaultIntegerFormatChange(event: ChangeEvent<HTMLInputElement>): void {\n log.debug('handleDefaultIntegerFormatChange', event.target.value);\n const update = {\n defaultIntegerFormatOptions: {\n defaultFormatString: event.target.value,\n },\n };\n this.setState(update);\n if (\n isValidFormat(\n dh,\n TableUtils.dataType.INT,\n IntegerColumnFormatter.makeCustomFormat(event.target.value)\n )\n ) {\n this.queueUpdate(update);\n }\n }\n\n handleShowTimeZoneChange(): void {\n const { showTimeZone } = this.state;\n const update = { showTimeZone: !showTimeZone };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleShowTSeparatorChange(): void {\n const { showTSeparator } = this.state;\n const update = { showTSeparator: !showTSeparator };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleTimeZoneChange(value: string): void {\n const update = { timeZone: value };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleResetDateTimeFormat(): void {\n const { defaults } = this.props;\n const { defaultDateTimeFormat, showTimeZone, showTSeparator } = defaults;\n log.debug('handleResetDateTimeFormat');\n this.setState({\n defaultDateTimeFormat,\n showTimeZone,\n showTSeparator,\n });\n this.queueUpdate({\n defaultDateTimeFormat: undefined,\n showTimeZone: undefined,\n showTSeparator: undefined,\n });\n }\n\n handleResetTimeZone(): void {\n const { defaults } = this.props;\n const { timeZone } = defaults;\n log.debug('handleResetTimeZone');\n this.setState({\n timeZone,\n });\n this.queueUpdate({\n timeZone: undefined,\n });\n }\n\n handleResetDecimalFormat(): void {\n const { defaults } = this.props;\n const { defaultDecimalFormatOptions } = defaults;\n log.debug('handleResetDecimalFormat');\n this.setState({\n defaultDecimalFormatOptions,\n });\n this.queueUpdate({\n defaultDecimalFormatOptions: undefined,\n });\n }\n\n handleResetIntegerFormat(): void {\n const { defaults } = this.props;\n const { defaultIntegerFormatOptions } = defaults;\n log.debug('handleResetIntegerFormat');\n this.setState({\n defaultIntegerFormatOptions,\n });\n this.queueUpdate({\n defaultIntegerFormatOptions: undefined,\n });\n }\n\n handleTruncateNumbersWithPoundChange(): void {\n const { truncateNumbersWithPound } = this.state;\n const update = {\n truncateNumbersWithPound: truncateNumbersWithPound !== true,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleShowEmptyStringsChange(): void {\n const { showEmptyStrings } = this.state;\n const update = {\n showEmptyStrings: !showEmptyStrings,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n handleShowNullStringsChange(): void {\n const { showNullStrings } = this.state;\n const update = {\n showNullStrings: !showNullStrings,\n };\n this.setState(update);\n this.queueUpdate(update);\n }\n\n commitChanges(): void {\n const { updateSettings } = this.props;\n const updates = this.pendingUpdates.reduce(\n (acc, update) => ({\n ...acc,\n ...update,\n }),\n {}\n );\n this.pendingUpdates = [];\n\n updateSettings(updates);\n }\n\n render(): ReactElement {\n const { defaults, dh } = this.props;\n const {\n defaultDateTimeFormat,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions,\n timeZone,\n showTimeZone,\n showTSeparator,\n truncateNumbersWithPound,\n showEmptyStrings,\n showNullStrings,\n } = this.state;\n\n const {\n defaultFormatString:\n defaultDecimalFormatString = DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n } = defaultDecimalFormatOptions ?? {};\n const {\n defaultFormatString:\n defaultIntegerFormatString = IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n } = defaultIntegerFormatOptions ?? {};\n\n const isTimeZoneDefault = timeZone === defaults.timeZone;\n const isDateTimeOptionsDefault =\n showTSeparator === defaults.showTSeparator &&\n showTimeZone === defaults.showTimeZone &&\n defaultDateTimeFormat === defaults.defaultDateTimeFormat;\n const isDecimalOptionsDefault = isSameDecimalOptions(\n defaultDecimalFormatOptions,\n defaults.defaultDecimalFormatOptions\n );\n const isIntegerOptionsDefault = isSameIntegerOptions(\n defaultIntegerFormatOptions,\n defaults.defaultIntegerFormatOptions\n );\n\n return (\n <div className=\"app-settings-formatting-section\" ref={this.containerRef}>\n <div className=\"container-fluid p-0\">\n <div className=\"app-settings-menu-description mb-3\">\n Choose the default formatting rule to apply to all table columns\n based on their type.\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"select-reset-timezone\"\n >\n Time zone\n </label>\n <div className=\"col pr-0\">\n <Select\n className=\"custom-select\"\n value={timeZone}\n onChange={this.handleTimeZoneChange}\n id=\"select-reset-timezone\"\n >\n <TimeZoneOptions />\n </Select>\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetTimeZone}\n tooltip=\"Reset Time Zone\"\n className={classNames('btn-reset', 'btn-reset-time-zone', {\n hidden: isTimeZoneDefault,\n })}\n />\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"select-default-time-format\"\n >\n DateTime\n </label>\n <div className=\"col pr-0\">\n <Select\n className=\"custom-select\"\n value={defaultDateTimeFormat}\n onChange={this.handleDefaultDateTimeFormatChange}\n id=\"select-default-time-format\"\n >\n {this.getCachedDateTimeFormatOptions(\n timeZone,\n showTimeZone,\n showTSeparator,\n true,\n defaultDateTimeFormat\n )}\n </Select>\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetDateTimeFormat}\n tooltip=\"Reset DateTime Options\"\n className={classNames('btn-reset', 'btn-reset-date-time', {\n hidden: isDateTimeOptionsDefault,\n })}\n />\n </div>\n </div>\n <div className=\"form-row\">\n <div className=\"offset-3 col-9\">\n <Checkbox\n checked={showTimeZone ?? null}\n onChange={this.handleShowTimeZoneChange}\n >\n Show time zone in dates\n </Checkbox>\n </div>\n </div>\n\n <div className=\"form-row mb-3\">\n <div className=\"offset-3 col-9\">\n <Checkbox\n checked={showTSeparator ?? null}\n onChange={this.handleShowTSeparatorChange}\n >\n Show &#39;T&#39; separator\n </Checkbox>\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"default-decimal-format-input\"\n >\n Decimal\n </label>\n <div className=\"col pr-0\">\n <input\n className={classNames(\n 'form-control',\n 'flex-grow-1',\n 'default-decimal-format-input',\n {\n 'is-invalid': !isValidFormat(\n dh,\n TableUtils.dataType.DECIMAL,\n DecimalColumnFormatter.makeCustomFormat(\n defaultDecimalFormatString\n )\n ),\n }\n )}\n data-lpignore\n placeholder={DecimalColumnFormatter.DEFAULT_FORMAT_STRING}\n type=\"text\"\n id=\"default-decimal-format-input\"\n value={defaultDecimalFormatString}\n onChange={this.handleDefaultDecimalFormatChange}\n />\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetDecimalFormat}\n tooltip=\"Reset Decimal Formatting\"\n className={classNames('btn-reset', 'btn-reset-decimal', {\n hidden: isDecimalOptionsDefault,\n })}\n data-testid=\"btn-reset-decimal\"\n />\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"default-integer-format-input\"\n >\n Integer\n </label>\n <div className=\"col pr-0\">\n <input\n className={classNames(\n 'form-control',\n 'flex-grow-1',\n 'default-integer-format-input',\n {\n 'is-invalid': !isValidFormat(\n dh,\n TableUtils.dataType.INT,\n IntegerColumnFormatter.makeCustomFormat(\n defaultIntegerFormatString\n )\n ),\n }\n )}\n data-lpignore\n placeholder={IntegerColumnFormatter.DEFAULT_FORMAT_STRING}\n type=\"text\"\n id=\"default-integer-format-input\"\n value={defaultIntegerFormatString}\n onChange={this.handleDefaultIntegerFormatChange}\n />\n </div>\n <div className=\"col-1 btn-col\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={this.handleResetIntegerFormat}\n tooltip=\"Reset Integer Formatting\"\n className={classNames('btn-reset', 'btn-reset-integer', {\n hidden: isIntegerOptionsDefault,\n })}\n data-testid=\"btn-reset-integer\"\n />\n </div>\n </div>\n <div className=\"form-row mb-2\">\n <div className=\"offset-3 col-9\">\n <Checkbox\n checked={truncateNumbersWithPound ?? null}\n onChange={this.handleTruncateNumbersWithPoundChange}\n >\n Show truncated numbers as ###\n </Checkbox>\n </div>\n </div>\n\n <div className=\"form-row mb-3\">\n <label\n className=\"col-form-label col-3\"\n htmlFor=\"default-integer-format-input\"\n >\n String\n </label>\n <div className=\"col pr-0 pt-2\">\n <Checkbox\n checked={showEmptyStrings ?? null}\n onChange={this.handleShowEmptyStringsChange}\n >\n Show empty strings as{' '}\n <span className=\"font-italic text-muted\">empty</span>\n </Checkbox>\n <Checkbox\n checked={showNullStrings ?? null}\n onChange={this.handleShowNullStringsChange}\n >\n Show null strings as{' '}\n <span className=\"font-italic text-muted\">null</span>\n </Checkbox>\n </div>\n </div>\n </div>\n </div>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState\n): Omit<FormattingSectionContentProps, 'updateSettings'> => ({\n defaultDateTimeFormat: getDefaultDateTimeFormat(state),\n defaultDecimalFormatOptions: getDefaultDecimalFormatOptions(state),\n defaultIntegerFormatOptions: getDefaultIntegerFormatOptions(state),\n dh: getApi(state),\n showTimeZone: getShowTimeZone(state),\n showTSeparator: getShowTSeparator(state),\n truncateNumbersWithPound: getTruncateNumbersWithPound(state),\n showEmptyStrings: getShowEmptyStrings(state),\n showNullStrings: getShowNullStrings(state),\n timeZone: getTimeZone(state),\n defaults: getDefaultSettings(state),\n});\n\nconst ConnectedFormattingSectionContent = connect(mapStateToProps, {\n updateSettings: updateSettingsAction,\n})(FormattingSectionContent);\n\nexport default ConnectedFormattingSectionContent;\n","import React, { ReactElement, useState } from 'react';\nimport { Button, Modal, ModalBody, ModalHeader } from '@deephaven/components';\nimport { vsLaw } from '@deephaven/icons';\n\nfunction LegalNotice(): ReactElement {\n const [modal, setModal] = useState(false);\n const toggle = (): void => {\n setModal(!modal);\n };\n\n return (\n <>\n <Button kind=\"ghost\" onClick={toggle} icon={vsLaw}>\n Legal Notices\n </Button>\n <Modal isOpen={modal} toggle={toggle}>\n <ModalHeader toggle={toggle}>Legal Notice</ModalHeader>\n <ModalBody>\n <p>\n Deephaven software is protected by U.S. Patent Nos. 9,612,959;\n 9,613,018; 9,613,109; 9,619,210; 9,633,060; 9,639,570; 9,672,238;\n 9,679,006; 9,690,821; 9,710,511; 9,760,591; 9,805,084; 9,836,494;\n 9,836,495; 9,886,469; 9,898,496; 9,934,266; 10,002,153; 10,002,154;\n 10,002,155; 10,003,673; 10,019,138; 10,069,943; 10,176,211;\n 10,198,465; 10,198,466; 10,198,469; 10,212,257; 10,241,960;\n 10,241,965; 10,242,040; 10,242,041; 10,346,394; 10,353,893;\n 10,452,649; 10,496,639; 10,540,351; 10,552,412; 10,565,194;\n 10,565,206; 10,572,474; 10,621,168; 10,642,829; 10,657,184;\n 10,678,787; 10,691,686; 10,783,191; 10,866,943; 10,909,183;\n 10,915,526; 10,922,311; 10,929,394; 11,023,462; 11,126,662;\n 11,151,133; 11,238,036; 11,249,994; 11,263,211; 11,449,557;\n 11,514,037; 11,556,528; and 11,574,018. Other patents pending.\n </p>\n <p>\n © 2016-{new Date().getFullYear()} Deephaven Data Labs LLC. Patent\n Pending.\n </p>\n </ModalBody>\n </Modal>\n </>\n );\n}\n\nexport default LegalNotice;\n","import React, { ReactElement, ReactNode } from 'react';\nimport PropTypes from 'prop-types';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button, Collapse } from '@deephaven/components';\nimport { vsTriangleDown } from '@deephaven/icons';\n\ninterface SettingsMenuSectionProps {\n children: ReactNode;\n isExpanded: boolean;\n sectionKey: string;\n title: ReactElement;\n onToggle: (sectionkey: string) => void;\n}\n\nfunction SettingsMenuSection(props: SettingsMenuSectionProps): ReactElement {\n const { children, isExpanded, sectionKey, title, onToggle } = props;\n return (\n <>\n <div>\n <Button\n kind=\"ghost\"\n className=\"btn-collapse-trigger\"\n onClick={() => onToggle(sectionKey)}\n >\n <div className=\"flex-grow-1\">{title}</div>\n <div className=\"flex-shrink-0\">\n <FontAwesomeIcon\n transform={isExpanded ? 'flip-v' : ''}\n icon={vsTriangleDown}\n />\n </div>\n </Button>\n </div>\n <Collapse in={isExpanded} autoFocusOnShow>\n {children}\n </Collapse>\n </>\n );\n}\n\nSettingsMenuSection.propTypes = {\n children: PropTypes.node,\n isExpanded: PropTypes.bool.isRequired,\n sectionKey: PropTypes.string.isRequired,\n title: PropTypes.node.isRequired,\n onToggle: PropTypes.func,\n};\n\nSettingsMenuSection.defaultProps = {\n children: null,\n onToggle: () => undefined,\n};\n\nexport default SettingsMenuSection;\n","import React, { useState, useEffect } from 'react';\nimport classNames from 'classnames';\nimport {\n Shortcut,\n Tooltip,\n ShortcutRegistry,\n ContextActionUtils,\n Button,\n KEY,\n} from '@deephaven/components';\nimport type { KeyState } from '@deephaven/components';\nimport { vsRefresh } from '@deephaven/icons';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport './ShortcutItem.scss';\n\ntype ShortcutItemProps = {\n shortcut: Shortcut;\n displayText: string;\n categoryName: string;\n onChange: (shortcut: Shortcut) => void;\n};\n\nexport default function ShortcutItem({\n shortcut,\n displayText: propsDisplayText,\n categoryName,\n onChange,\n}: ShortcutItemProps): JSX.Element {\n const [displayText, setDisplayText] = useState(propsDisplayText);\n const [keyState, setKeyState] = useState<KeyState>(shortcut.getKeyState());\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState('');\n\n // If propsDisplayText changes, the shortcut was altered from a conflict state by the parent component\n useEffect(\n function resolveConflictOnPropChange() {\n setDisplayText(propsDisplayText);\n setKeyState(shortcut.getKeyState());\n },\n [propsDisplayText, shortcut]\n );\n\n // Updates displayText when keyState is changed\n useEffect(\n function onNewKeybind() {\n setDisplayText(Shortcut.getDisplayText(keyState));\n if (shortcut.matchesKeyState(keyState)) {\n setIsPending(false);\n }\n },\n [keyState, shortcut]\n );\n\n // Sets error state based on isPending\n useEffect(\n function setErrors() {\n if (isPending) {\n if (!Shortcut.isValidKeyState(keyState)) {\n if (Shortcut.isAllowedKey(keyState.keyValue)) {\n setError('Must contain a modifier key');\n } else {\n setError('Must contain an allowed action key');\n }\n return;\n }\n\n const conflictNames = ShortcutRegistry.getConflictingShortcuts(keyState)\n .filter(\n conflict =>\n conflict.id.startsWith(categoryName) && conflict !== shortcut\n )\n .map(conflict => conflict.name);\n\n if (conflictNames.length) {\n setError(`Conflicts with ${conflictNames.join(', ')}`);\n return;\n }\n\n setError('');\n } else {\n setError('');\n }\n },\n [isPending, keyState, categoryName, shortcut]\n );\n\n // Updates pending key state and sets input display text\n function handleInputKeyDown(e: React.KeyboardEvent<HTMLInputElement>): void {\n e.stopPropagation();\n e.preventDefault();\n\n if (shortcut.isEditable && !e.repeat) {\n const newKeyState = Shortcut.getKeyStateFromEvent(e);\n const backspaceKeyState = Shortcut.createKeyState([KEY.BACKSPACE]);\n\n // Backspace clears the shortcut\n if (Shortcut.doKeyStatesMatch(newKeyState, backspaceKeyState)) {\n setKeyState(Shortcut.NULL_KEY_STATE);\n } else {\n setKeyState(newKeyState);\n }\n }\n }\n\n // Set this shortcut to changing state, check key state validity and set errors\n function handleInputKeyUp(e: React.KeyboardEvent<HTMLInputElement>): void {\n e.stopPropagation();\n e.preventDefault();\n\n if (!shortcut.matchesKeyState(keyState)) {\n setIsPending(true);\n }\n }\n\n function handleInputFocus(): void {\n ContextActionUtils.disableAllActions();\n }\n\n function handleInputBlur(): void {\n ContextActionUtils.enableAllActions();\n }\n\n function handleConfirm(): void {\n shortcut.setKeyState(keyState);\n setIsPending(false);\n onChange(shortcut);\n }\n\n function handleUndo(): void {\n const originalKeyState = shortcut.getKeyState();\n setKeyState(originalKeyState);\n setIsPending(false);\n }\n\n function handleResetToDefaultClick(): void {\n setIsPending(true);\n setKeyState(shortcut.getDefaultKeyState());\n }\n\n return (\n <>\n <div className=\"shortcut-item-container\">\n <label className=\"shortcut-item-name\">\n {shortcut.name}\n {shortcut.tooltip !== undefined && (\n <Tooltip>{shortcut.tooltip}</Tooltip>\n )}\n </label>\n <div className=\"shortcut-item-input-container\">\n <input\n className={classNames('form-control', {\n 'is-invalid': error,\n })}\n onKeyDown={handleInputKeyDown}\n onKeyUp={handleInputKeyUp}\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n disabled={!shortcut.isEditable}\n value={displayText}\n readOnly\n />\n {!Shortcut.doKeyStatesMatch(\n keyState,\n shortcut.getDefaultKeyState()\n ) &&\n !error && (\n <Button\n className=\"reset-to-default-button\"\n kind=\"ghost\"\n icon={\n <FontAwesomeIcon\n icon={vsRefresh}\n transform={{ rotate: 90, flipX: true }}\n />\n }\n tooltip=\"Reset to default\"\n onClick={handleResetToDefaultClick}\n />\n )}\n </div>\n </div>\n {isPending && (\n <div\n className={classNames('shortcut-item-message-container', {\n 'is-invalid': error,\n })}\n >\n <div className=\"shortcut-item-message\">{error}</div>\n <div className=\"shortcut-item-message-buttons\">\n {Shortcut.isValidKeyState(keyState) && (\n <Button kind=\"ghost\" onClick={handleConfirm}>\n Confirm\n </Button>\n )}\n <Button kind=\"ghost\" onClick={handleUndo}>\n Undo\n </Button>\n </div>\n </div>\n )}\n </>\n );\n}\n","import React, { useState, useMemo, useCallback } from 'react';\nimport { connect } from 'react-redux';\nimport { Shortcut, ShortcutRegistry } from '@deephaven/components';\nimport {\n getShortcutOverrides,\n RootState,\n updateSettings as updateSettingsAction,\n WorkspaceSettings,\n} from '@deephaven/redux';\nimport ShortcutItem from './ShortcutItem';\n\ntype ShortcutSectionContentProps = {\n shortcutOverrides: WorkspaceSettings['shortcutOverrides'];\n updateSettings: typeof updateSettingsAction;\n};\n\nfunction ShortcutSectionContent({\n shortcutOverrides = {},\n updateSettings,\n}: ShortcutSectionContentProps): JSX.Element {\n const saveShortcutOverrides = useCallback(\n (modifiedShortcuts: Shortcut[]) => {\n const isMac = Shortcut.isMacPlatform;\n\n // This ensures mac and windows objects both exist\n const newOverrides: Required<typeof shortcutOverrides> = {\n mac: { ...shortcutOverrides.mac },\n windows: { ...shortcutOverrides.windows },\n };\n const platformOverrides = isMac ? newOverrides.mac : newOverrides.windows;\n\n modifiedShortcuts.forEach(shortcut => {\n if (shortcut.isDefault()) {\n // No need to save overrides that are the default value\n delete platformOverrides[shortcut.id];\n } else {\n platformOverrides[shortcut.id] = shortcut.getKeyState();\n }\n });\n\n updateSettings({\n shortcutOverrides: newOverrides,\n });\n },\n [updateSettings, shortcutOverrides]\n );\n\n let categories = Array.from(\n ShortcutRegistry.shortcutsByCategory.entries()\n ).map(([name, shortcuts]) => ({\n name,\n shortcuts,\n }));\n\n // Move global category to the end\n const globalCategoryIndex = categories.findIndex(\n category => category.name.toUpperCase() === 'GLOBAL'\n );\n const globalCategory = categories.splice(globalCategoryIndex, 1);\n categories = categories.concat(globalCategory);\n\n return (\n <>\n <div className=\"app-settings-menu-description\">\n Customize shortcuts below. To prevent unexpected results, avoid\n conflicting shortcuts with the browser or IDE editor.\n </div>\n {categories.map(category => (\n <ShortcutCategory\n key={category.name}\n name={category.name}\n shortcuts={category.shortcuts}\n saveShortcutOverrides={saveShortcutOverrides}\n />\n ))}\n </>\n );\n}\n\ntype ShortcutCategoryProps = {\n name: string;\n shortcuts: Shortcut[];\n saveShortcutOverrides: (shortcuts: Shortcut[]) => void;\n};\n\nfunction ShortcutCategory({\n name,\n shortcuts: propsShortcuts,\n saveShortcutOverrides,\n}: ShortcutCategoryProps): JSX.Element {\n function formatCategoryName(categoryName: string): string {\n return categoryName\n .split('_')\n .map(word => `${word[0].toUpperCase()}${word.slice(1).toLowerCase()}`)\n .join(' ');\n }\n\n // Used to trigger a re-render when a shortcut is changed\n // Since shortcuts are singletons, React doesn't detect changes for a re-render as easily\n const [shortcuts, setShortcuts] = useState(propsShortcuts);\n\n function handleShortcutChange(shortcut: Shortcut): void {\n const conflictingShortcuts = shortcuts.filter(\n s =>\n s !== shortcut &&\n !s.isNull() &&\n s.matchesKeyState(shortcut.getKeyState())\n );\n\n // Set conflicting shortcuts to null\n conflictingShortcuts.forEach(conflict => conflict.setToNull());\n\n const modifiedShoftcuts = [shortcut, ...conflictingShortcuts];\n\n saveShortcutOverrides(modifiedShoftcuts);\n setShortcuts(s => [...s]);\n }\n\n const displayTexts = useMemo(\n () => shortcuts.map(s => s.getDisplayText()),\n [shortcuts]\n );\n\n return (\n <div className=\"mt-3\">\n <div className=\"font-weight-bold\">{formatCategoryName(name)}</div>\n {shortcuts.map((shortcut, i) => (\n <ShortcutItem\n key={shortcut.id}\n shortcut={shortcut}\n displayText={displayTexts[i]}\n categoryName={name}\n onChange={handleShortcutChange}\n />\n ))}\n </div>\n );\n}\n\nconst mapStateToProps = (\n state: RootState\n): Pick<ShortcutSectionContentProps, 'shortcutOverrides'> => ({\n shortcutOverrides: getShortcutOverrides(state),\n});\n\nconst mapDispatchToProps = { updateSettings: updateSettingsAction };\n\nconst ConnectedShortcutSectionContent = connect(\n mapStateToProps,\n mapDispatchToProps\n)(ShortcutSectionContent);\n\nexport default ConnectedShortcutSectionContent;\n","/* eslint-disable import/prefer-default-export */\nimport JSZip from 'jszip';\nimport dh from '@deephaven/jsapi-shim';\nimport { store } from '@deephaven/redux';\nimport { logHistory } from './LogInit';\n\nconst FILENAME_DATE_FORMAT = 'yyyy-MM-dd-HHmmss';\n\n// List of objects to blacklist\n// '' represents the root object\nexport const DEFAULT_PATH_BLACKLIST: string[][] = [\n ['api'],\n ['client'],\n ['dashboardData', 'default', 'connection'],\n ['dashboardData', 'default', 'sessionWrapper', 'dh'],\n ['layoutStorage'],\n ['storage'],\n];\n\nfunction stringifyReplacer(blacklist: string[][]) {\n // modified from:\n // https://stackoverflow.com/questions/61681176/json-stringify-replacer-how-to-get-full-path\n const pathMap = new Map();\n // replacer function is also called for the initial object, key is \"\"\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter\n\n return function replacer(this: unknown, key: string, value: unknown) {\n // get and store path\n const currPath = [...(pathMap.get(this) ?? []), key];\n if (value === Object(value)) pathMap.set(value, [...currPath]);\n currPath.shift();\n\n // check blacklists\n for (let i = 0; i < blacklist.length; i += 1) {\n if (\n currPath.length === blacklist[i].length &&\n currPath.every((v, index) => v === blacklist[i][index])\n ) {\n // blacklist match\n return undefined;\n }\n }\n\n // not in blacklist, return value\n return value;\n };\n}\n\n/**\n * Returns a new object that is safe to stringify\n * All circular references are replaced by the path to the value creating a circular ref\n * A circular ref will display 'Circular ref to root.someKey' in place of the circular ref\n * All BigInts are replaced with their toString since BigInts error JSON.stringify\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Exceptions\n *\n * This tries to stringify each key of the object as an easy way to determine if it is safe\n * If it fails to stringify, then the values that failed repeat the same steps recursively\n * The unsafe objects are kept in a map with their path (e.g. root.someKey.someOtherKey)\n * Then if the object is seen again, it must be a circular ref since that object could not be stringified safely\n *\n * @param obj Object to make safe to stringify\n * @param blacklist List of JSON paths to blacklist. A JSON path is a list representing the path to that value (e.g. client.data would be `['client', 'data']`)\n */\nfunction makeSafeToStringify(\n obj: Record<string, unknown>,\n blacklist: string[][],\n path = 'root',\n potentiallyCircularValues: Map<Record<string, unknown>, string> = new Map([\n [obj, ''],\n ])\n): Record<string, unknown> {\n const output: Record<string, unknown> = {};\n\n Object.entries(obj).forEach(([key, val]) => {\n try {\n JSON.stringify(val, stringifyReplacer(blacklist));\n output[key] = val;\n } catch (e) {\n // The value must be a Circular object or BigInt here\n const valRecord = val as Record<string, unknown>;\n\n if (typeof val === 'bigint') {\n output[key] = val.toString();\n } else if (potentiallyCircularValues.has(valRecord)) {\n // We've seen this object before, so it's a circular ref\n output[key] = `Circular ref to ${potentiallyCircularValues.get(\n valRecord\n )}`;\n } else {\n // Haven't seen the object before, but somewhere in it there is a circular ref\n // The ref could point to this object or just to another child\n const curPath = `${path}.${key}`;\n potentiallyCircularValues.set(valRecord, curPath);\n output[key] = makeSafeToStringify(\n val as Record<string, unknown>,\n blacklist,\n curPath,\n potentiallyCircularValues\n );\n }\n }\n });\n\n return output;\n}\n\nfunction getReduxDataString(blacklist: string[][]): string {\n const reduxData = store.getState();\n return JSON.stringify(\n makeSafeToStringify(reduxData, blacklist),\n stringifyReplacer(blacklist),\n 2 // Indent w/ 2 spaces\n );\n}\n\nfunction getMetadata(\n blacklist: string[][],\n meta?: Record<string, unknown>\n): string {\n const metadata = {\n uiVersion: import.meta.env.npm_package_version,\n userAgent: navigator.userAgent,\n ...meta,\n };\n\n return JSON.stringify(metadata, stringifyReplacer(blacklist), 2);\n}\n\n/**\n * Export support logs with the given name.\n * @param fileNamePrefix The zip file name without the .zip extension. Ex: test will be saved as test.zip\n * @param metadata Additional metadata to include in the metadata.json file\n * @param blacklist List of JSON paths to blacklist. A JSON path is a list representing the path to that value (e.g. client.data would be `['client', 'data']`)\n * @returns A promise that resolves successfully if the log archive is created and downloaded successfully, rejected if there's an error\n */\nexport async function exportLogs(\n fileNamePrefix = `${dh.i18n.DateTimeFormat.format(\n FILENAME_DATE_FORMAT,\n new Date()\n )}_support_logs`,\n metadata?: Record<string, unknown>,\n blacklist: string[][] = DEFAULT_PATH_BLACKLIST\n): Promise<void> {\n const zip = new JSZip();\n const folder = zip.folder(fileNamePrefix) as JSZip;\n folder.file('console.txt', logHistory.getFormattedHistory());\n folder.file('redux.json', getReduxDataString(blacklist));\n folder.file('metadata.json', getMetadata(blacklist, metadata));\n\n const blob = await zip.generateAsync({ type: 'blob' });\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = `${fileNamePrefix}.zip`;\n link.click();\n}\n","import React, { ReactElement } from 'react';\nimport { TableUtils } from '@deephaven/jsapi-utils';\n\nconst columnTypesArray = [\n { value: TableUtils.dataType.DATETIME, label: 'DateTime' },\n { value: TableUtils.dataType.DECIMAL, label: 'Decimal' },\n { value: TableUtils.dataType.INT, label: 'Integer' },\n];\n\nexport default function ColumnTypeOptions(): ReactElement {\n const columnTypeOptions = columnTypesArray.map(item => (\n <option key={`key-columnType-${item.value}`} value={item.value}>\n {item.label}\n </option>\n ));\n\n return (\n <>\n <option key=\"key-columnType-placeholder\" disabled value=\"\">\n Select Type\n </option>\n {columnTypeOptions}\n </>\n );\n}\n","import React, {\n ChangeEvent,\n PureComponent,\n ReactElement,\n RefObject,\n} from 'react';\nimport { connect } from 'react-redux';\nimport { dhNewCircleLargeFilled, vsTrash } from '@deephaven/icons';\nimport memoize from 'memoizee';\nimport { TransitionGroup } from 'react-transition-group';\nimport debounce from 'lodash.debounce';\nimport classNames from 'classnames';\nimport { Button, FadeTransition, Select } from '@deephaven/components';\nimport {\n DateTimeColumnFormatter,\n IntegerColumnFormatter,\n DecimalColumnFormatter,\n TableUtils,\n TableColumnFormat,\n FormattingRule,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport {\n getApi,\n getDefaultDecimalFormatOptions,\n getDefaultIntegerFormatOptions,\n getFormatter,\n getTimeZone,\n getShowTimeZone,\n getShowTSeparator,\n updateSettings as updateSettingsAction,\n RootState,\n WorkspaceSettings,\n} from '@deephaven/redux';\nimport { assertNotNull } from '@deephaven/utils';\nimport './FormattingSectionContent.scss';\nimport type { DebouncedFunc } from 'lodash';\nimport {\n focusFirstInputInContainer,\n isValidColumnName,\n isValidFormat,\n removeFormatRuleExtraProps,\n isFormatRuleValidForSave,\n ValidFormatterItem,\n} from './SettingsUtils';\nimport type { FormatterItem, FormatOption } from './SettingsUtils';\nimport ColumnTypeOptions from './ColumnTypeOptions';\nimport DateTimeOptions from './DateTimeOptions';\n\nexport interface ColumnSpecificSectionContentProps {\n dh: typeof DhType;\n formatter: FormatterItem[];\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n updateSettings: (settings: Partial<WorkspaceSettings>) => void;\n scrollTo: (x: number, y: number) => void;\n defaultDecimalFormatOptions: FormatOption;\n defaultIntegerFormatOptions: FormatOption;\n}\n\ninterface ColumnSpecificSectionContentState {\n formatSettings: FormatterItem[];\n formatRulesChanged: boolean;\n showTimeZone: boolean;\n showTSeparator: boolean;\n timeZone: string;\n timestampAtMenuOpen: Date;\n}\n\nexport class ColumnSpecificSectionContent extends PureComponent<\n ColumnSpecificSectionContentProps,\n ColumnSpecificSectionContentState\n> {\n static defaultProps = {\n scrollTo: (): void => undefined,\n };\n\n static inputDebounceTime = 250;\n\n constructor(props: ColumnSpecificSectionContentProps) {\n super(props);\n\n this.debouncedCommitChanges = debounce(\n this.commitChanges.bind(this),\n ColumnSpecificSectionContent.inputDebounceTime\n );\n\n this.handleFormatRuleEntered = this.handleFormatRuleEntered.bind(this);\n this.handleFormatRuleChange = this.handleFormatRuleChange.bind(this);\n this.handleFormatRuleCreate = this.handleFormatRuleCreate.bind(this);\n this.handleFormatRuleDelete = this.handleFormatRuleDelete.bind(this);\n\n const { formatter, showTimeZone, showTSeparator, timeZone } = props;\n\n const formatSettings = formatter.map((item, i) => ({\n ...item,\n id: i,\n }));\n\n this.containerRef = React.createRef();\n this.addFormatRuleButtonRef = React.createRef();\n\n this.lastFormatRuleIndex = formatSettings.length;\n\n this.state = {\n formatSettings,\n formatRulesChanged: false,\n showTimeZone,\n showTSeparator,\n timeZone,\n timestampAtMenuOpen: new Date(),\n };\n }\n\n componentDidMount(): void {\n focusFirstInputInContainer(this.containerRef.current);\n }\n\n componentWillUnmount(): void {\n this.debouncedCommitChanges.flush();\n }\n\n debouncedCommitChanges: DebouncedFunc<() => void>;\n\n containerRef: RefObject<HTMLDivElement>;\n\n addFormatRuleButtonRef: RefObject<HTMLButtonElement>;\n\n lastFormatRuleIndex: number;\n\n isDuplicateRule(rule: FormatterItem): boolean {\n const { formatSettings } = this.state;\n return (\n formatSettings.some(\n item =>\n item.id !== rule.id &&\n item.columnName === rule.columnName &&\n item.columnType === rule.columnType\n ) ?? false\n );\n }\n\n getAutoIncrementFormatRuleIndex(): number {\n const { lastFormatRuleIndex } = this;\n this.lastFormatRuleIndex += 1;\n return lastFormatRuleIndex;\n }\n\n getCachedColumnTypeOptions = memoize(() => <ColumnTypeOptions />);\n\n getCachedDateTimeFormatOptions = memoize(\n (\n timeZone: string,\n showTimeZone: boolean,\n showTSeparator: boolean,\n isGlobalOptions = false,\n legacyGlobalFormat?: string\n ) => {\n const { timestampAtMenuOpen } = this.state;\n return (\n <DateTimeOptions\n timestamp={timestampAtMenuOpen}\n timeZone={timeZone}\n showTimeZone={showTimeZone}\n showTSeparator={showTSeparator}\n isGlobalOptions={isGlobalOptions}\n legacyGlobalFormat={legacyGlobalFormat}\n />\n );\n }\n );\n\n handleFormatRuleChange(\n index: number,\n key: string,\n value: TableColumnFormat | string | boolean\n ): void {\n this.setState(\n state => {\n const { formatSettings: oldFormatSettings } = state;\n assertNotNull(oldFormatSettings);\n const formatSettings = [...oldFormatSettings];\n // Reset format string on type change\n let resetKeys = {};\n if (key === 'columnType') {\n resetKeys = {\n format: this.makeDefaultFormatterItemByType(value as string),\n };\n }\n const newEntry = {\n ...formatSettings[index],\n ...resetKeys,\n [key]: value,\n };\n\n formatSettings[index] = newEntry;\n return {\n formatSettings,\n };\n },\n () => {\n this.debouncedCommitChanges();\n }\n );\n }\n\n handleFormatRuleCreate(): void {\n this.setState(state => {\n const { formatSettings } = state;\n const newFormat = {\n columnType: TableUtils.dataType.DATETIME,\n columnName: '',\n format: {},\n id: this.getAutoIncrementFormatRuleIndex(),\n isNewRule: true,\n };\n return {\n formatSettings: [...formatSettings, newFormat],\n formatRulesChanged: true,\n };\n });\n }\n\n handleFormatRuleDelete(index: number): void {\n this.setState(\n state => {\n const { formatSettings: oldFormatSettings } = state;\n const formatSettings = oldFormatSettings.filter(\n (item, i) => i !== index\n );\n return {\n formatSettings,\n formatRulesChanged: true,\n };\n },\n () => {\n this.debouncedCommitChanges();\n }\n );\n }\n\n handleFormatRuleEntered(elem: HTMLElement): void {\n this.scrollToFormatBlockBottom();\n focusFirstInputInContainer(elem);\n }\n\n commitChanges(): void {\n const { formatSettings } = this.state;\n\n const { dh } = this.props;\n\n const formatter =\n formatSettings\n .filter((format): format is ValidFormatterItem =>\n isFormatRuleValidForSave(dh, format)\n )\n .map(removeFormatRuleExtraProps) ?? [];\n\n const { updateSettings } = this.props;\n const newSettings = {\n formatter: formatter as FormattingRule[],\n };\n updateSettings(newSettings);\n }\n\n scrollToFormatBlockBottom(): void {\n const { scrollTo } = this.props;\n scrollTo(\n 0,\n (this.addFormatRuleButtonRef.current?.offsetHeight ?? 0) +\n (this.addFormatRuleButtonRef.current?.offsetTop ?? 0)\n );\n }\n\n getRuleError(rule: FormatterItem): {\n hasColumnNameError: boolean;\n hasFormatError: boolean;\n message: string;\n } {\n const { dh } = this.props;\n const error = {\n hasColumnNameError: false,\n hasFormatError: false,\n message: '',\n };\n\n const errorMessages = [];\n\n if (rule.isNewRule !== undefined && rule.isNewRule) {\n return error;\n }\n\n if (this.isDuplicateRule(rule)) {\n error.hasColumnNameError = true;\n errorMessages.push('Duplicate column name/type combo.');\n }\n\n if (!isValidColumnName(rule.columnName)) {\n error.hasColumnNameError = true;\n errorMessages.push(\n 'Column names must start with a letter or underscore and contain only alphanumeric characters or underscores.'\n );\n }\n\n if (\n rule.format.formatString != null &&\n rule.format.formatString.length === 0\n ) {\n error.hasFormatError = true;\n errorMessages.push('Empty formatting rule.');\n } else if (!isValidFormat(dh, rule.columnType, rule.format)) {\n error.hasFormatError = true;\n errorMessages.push('Invalid formatting rule.');\n }\n\n error.message = errorMessages.join('\\n');\n return error;\n }\n\n makeDefaultFormatterItemByType(\n columnType: string\n ): TableColumnFormat | string {\n switch (TableUtils.getNormalizedType(columnType)) {\n case TableUtils.dataType.INT: {\n const { defaultIntegerFormatOptions } = this.props;\n const { defaultFormatString: defaultIntegerFormatString } =\n defaultIntegerFormatOptions;\n return IntegerColumnFormatter.makeFormat(\n '',\n defaultIntegerFormatString ??\n IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n IntegerColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n }\n\n case TableUtils.dataType.DECIMAL: {\n const { defaultDecimalFormatOptions } = this.props;\n const { defaultFormatString: defaultDecimalFormatString } =\n defaultDecimalFormatOptions;\n return DecimalColumnFormatter.makeFormat(\n '',\n defaultDecimalFormatString ??\n DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n DecimalColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n }\n default: {\n return '';\n }\n }\n }\n\n renderFormatRule(i: number, rule: FormatterItem): ReactElement {\n const columnNameId = `input-${i}-columnName`;\n const columnTypeId = `input-${i}-columnType`;\n const formatId = `input-${i}-format`;\n const columnTypeOptions = this.getCachedColumnTypeOptions();\n const onNameChange = (e: ChangeEvent<HTMLInputElement>): void =>\n this.handleFormatRuleChange(i, 'columnName', e.target.value);\n const onNameBlur = (): void =>\n this.handleFormatRuleChange(i, 'isNewRule', false);\n const onTypeChange = (eventTargetValue: string): void =>\n this.handleFormatRuleChange(i, 'columnType', eventTargetValue);\n\n const ruleError = this.getRuleError(rule);\n\n return (\n <fieldset key={i} className=\"container-fluid format-rule-container\">\n <div className=\"form-row\">\n <div className=\"form-group col-7 mb-2\">\n <label htmlFor={columnNameId}>Column Name</label>\n <input\n id={columnNameId}\n className={classNames('form-control', {\n 'is-invalid': ruleError.hasColumnNameError,\n })}\n data-lpignore\n type=\"text\"\n value={rule.columnName}\n onChange={onNameChange}\n onBlur={onNameBlur}\n />\n </div>\n <div className=\"form-group col mb-2\">\n <Button\n kind=\"ghost\"\n className=\"btn-delete-format-rule float-right\"\n tabIndex={-1}\n onClick={() => this.handleFormatRuleDelete(i)}\n icon={vsTrash}\n tooltip=\"Delete\"\n aria-label=\"Delete Format Rule\"\n />\n\n <label htmlFor={columnTypeId}>Column Type</label>\n <Select\n id={columnTypeId}\n className=\"custom-select\"\n value={rule.columnType}\n onChange={onTypeChange}\n >\n {columnTypeOptions}\n </Select>\n </div>\n </div>\n <div className=\"form-row\">\n <div className=\"form-group col-12 d-flex mb-2\">\n <label\n className=\"flex-shrink-0 col-form-label mr-3\"\n htmlFor={formatId}\n >\n Formatting Rule\n </label>\n {this.renderFormatRuleInput(\n i,\n rule.columnType,\n formatId,\n rule.format,\n ruleError.hasFormatError\n )}\n </div>\n </div>\n <div className=\"form-row\">\n <div className=\"form-group col-12 d-flex mb-2\">\n {ruleError.message && (\n <p className=\"text-danger\">{ruleError.message}</p>\n )}\n </div>\n </div>\n </fieldset>\n );\n }\n\n renderFormatRuleInput(\n i: number,\n columnType: string,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement | null {\n switch (TableUtils.getNormalizedType(columnType)) {\n case TableUtils.dataType.DATETIME:\n return this.renderDateTimeFormatRuleInput(\n i,\n formatId,\n format,\n isInvalid\n );\n case TableUtils.dataType.DECIMAL:\n return this.renderDecimalFormatRuleInput(\n i,\n formatId,\n format,\n isInvalid\n );\n case TableUtils.dataType.INT:\n return this.renderIntegerFormatRuleInput(\n i,\n formatId,\n format,\n isInvalid\n );\n default:\n throw new Error(`Unrecognized column type: ${columnType}`);\n }\n }\n\n renderDateTimeFormatRuleInput(\n i: number,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement {\n const { showTimeZone, showTSeparator, timeZone } = this.state;\n\n const value = format.formatString ?? '';\n return (\n <Select\n className={classNames('custom-select', { 'is-invalid': isInvalid })}\n value={value}\n id={formatId}\n onChange={eventTargetValue => {\n const selectedFormat = DateTimeColumnFormatter.makeFormat(\n '',\n eventTargetValue,\n DateTimeColumnFormatter.TYPE_GLOBAL\n );\n this.handleFormatRuleChange(i, 'format', selectedFormat);\n }}\n >\n <option key=\"default\" value=\"\" disabled>\n Select format\n </option>\n {this.getCachedDateTimeFormatOptions(\n timeZone,\n showTimeZone,\n showTSeparator\n )}\n </Select>\n );\n }\n\n renderIntegerFormatRuleInput(\n i: number,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement {\n const { defaultIntegerFormatOptions } = this.props;\n assertNotNull(defaultIntegerFormatOptions);\n const { defaultFormatString } = defaultIntegerFormatOptions;\n const value = format.formatString ?? '';\n return (\n <input\n className={classNames('form-control', 'flex-grow-1', {\n 'is-invalid': isInvalid,\n })}\n data-lpignore\n id={formatId}\n placeholder={\n defaultFormatString ?? IntegerColumnFormatter.DEFAULT_FORMAT_STRING\n }\n type=\"text\"\n value={value}\n onChange={e => {\n const selectedFormat = IntegerColumnFormatter.makeFormat(\n '',\n e.target.value,\n IntegerColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n this.handleFormatRuleChange(i, 'format', selectedFormat);\n }}\n />\n );\n }\n\n renderDecimalFormatRuleInput(\n i: number,\n formatId: string,\n format: Partial<TableColumnFormat>,\n isInvalid: boolean\n ): ReactElement {\n const { defaultDecimalFormatOptions } = this.props;\n const { defaultFormatString } = defaultDecimalFormatOptions;\n\n const value = format.formatString ?? '';\n return (\n <input\n className={classNames('form-control', 'flex-grow-1', {\n 'is-invalid': isInvalid,\n })}\n data-lpignore\n id={formatId}\n placeholder={\n defaultFormatString ?? DecimalColumnFormatter.DEFAULT_FORMAT_STRING\n }\n type=\"text\"\n value={value}\n onChange={e => {\n const selectedFormat = DecimalColumnFormatter.makeFormat(\n '',\n e.target.value,\n DecimalColumnFormatter.TYPE_GLOBAL,\n undefined\n );\n this.handleFormatRuleChange(i, 'format', selectedFormat);\n }}\n />\n );\n }\n\n render(): ReactElement {\n const { formatRulesChanged, formatSettings } = this.state;\n\n const formatRules = formatSettings.map((rule, index) => (\n <FadeTransition key={rule.id} onEnter={this.handleFormatRuleEntered}>\n {this.renderFormatRule(index, rule)}\n </FadeTransition>\n ));\n\n const addNewRuleButton = (\n <Button\n kind=\"ghost\"\n className=\"mb-3\"\n onClick={this.handleFormatRuleCreate}\n ref={this.addFormatRuleButtonRef}\n icon={dhNewCircleLargeFilled}\n >\n Add New Rule\n </Button>\n );\n\n return (\n <div className=\"app-settings-formatting-section\" ref={this.containerRef}>\n <div className=\"app-settings-menu-description mb-3\">\n Customize the formatting of table columns by applying rules based on\n matching both a column name and column type.\n </div>\n\n <TransitionGroup\n appear={formatRulesChanged}\n enter={formatRulesChanged}\n exit={formatRulesChanged}\n >\n {formatRules}\n </TransitionGroup>\n\n {addNewRuleButton}\n </div>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState\n): Omit<ColumnSpecificSectionContentProps, 'updateSettings' | 'scrollTo'> => ({\n formatter: getFormatter(state),\n defaultDecimalFormatOptions: getDefaultDecimalFormatOptions(state),\n defaultIntegerFormatOptions: getDefaultIntegerFormatOptions(state),\n dh: getApi(state),\n showTimeZone: getShowTimeZone(state),\n showTSeparator: getShowTSeparator(state),\n timeZone: getTimeZone(state),\n});\n\nconst ConnectedColumnSpecificSectionContent = connect(mapStateToProps, {\n updateSettings: updateSettingsAction,\n})(ColumnSpecificSectionContent);\n\nexport default ConnectedColumnSpecificSectionContent;\n","import React, { Component, Fragment, ReactElement, RefObject } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n vsClose,\n vsWatch,\n vsRecordKeys,\n vsInfo,\n vsLayers,\n vsPaintcan,\n dhUserIncognito,\n dhUser,\n} from '@deephaven/icons';\nimport {\n Button,\n CopyButton,\n GLOBAL_SHORTCUTS,\n Logo,\n ThemeContext,\n ThemePicker,\n Tooltip,\n} from '@deephaven/components';\nimport { ServerConfigValues, User } from '@deephaven/redux';\nimport {\n BROADCAST_CHANNEL_NAME,\n BROADCAST_LOGOUT_MESSAGE,\n makeMessage,\n} from '@deephaven/jsapi-utils';\nimport { assertNotNull } from '@deephaven/utils';\nimport { PluginModuleMap } from '@deephaven/plugin';\nimport FormattingSectionContent from './FormattingSectionContent';\nimport LegalNotice from './LegalNotice';\nimport SettingsMenuSection from './SettingsMenuSection';\nimport ShortcutSectionContent from './ShortcutsSectionContent';\nimport { exportLogs } from '../log/LogExport';\nimport './SettingsMenu.scss';\nimport ColumnSpecificSectionContent from './ColumnSpecificSectionContent';\nimport {\n getFormattedPluginInfo,\n getFormattedVersionInfo,\n} from './SettingsUtils';\n\ninterface SettingsMenuProps {\n serverConfigValues: ServerConfigValues;\n pluginData: PluginModuleMap;\n user: User;\n onDone: () => void;\n}\n\ninterface SettingsMenuState {\n expandedSectionKey?: string;\n}\n\nexport class SettingsMenu extends Component<\n SettingsMenuProps,\n SettingsMenuState\n> {\n static defaultProps = {\n onDone: (): void => undefined,\n };\n\n static FORMATTING_SECTION_KEY = 'SettingsMenu.formatting';\n\n static COLUMN_SPECIFIC_SECTION_KEY = 'SettingsMenu.columnFormatting';\n\n static APPLICATION_SECTION_KEY = 'ApplicationMenu.settings';\n\n static SHORTCUT_SECTION_KEY = 'SettingsMenu.shortcuts';\n\n static THEME_SECTION_KEY = 'SettingsMenu.theme';\n\n static focusFirstInputInContainer(container: HTMLDivElement | null): void {\n const input = container?.querySelector('input, select, textarea');\n if (input) {\n (input as HTMLElement).focus();\n }\n }\n\n constructor(props: SettingsMenuProps) {\n super(props);\n\n this.handleClose = this.handleClose.bind(this);\n this.handleScrollTo = this.handleScrollTo.bind(this);\n this.handleSectionToggle = this.handleSectionToggle.bind(this);\n this.handleExportSupportLogs = this.handleExportSupportLogs.bind(this);\n this.handleLogout = this.handleLogout.bind(this);\n\n this.menuContentRef = React.createRef();\n this.broadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);\n\n this.state = {\n expandedSectionKey: SettingsMenu.FORMATTING_SECTION_KEY,\n };\n }\n\n componentDidMount(): void {\n SettingsMenu.focusFirstInputInContainer(this.menuContentRef.current);\n }\n\n componentWillUnmount(): void {\n this.broadcastChannel.close();\n }\n\n menuContentRef: RefObject<HTMLDivElement>;\n\n broadcastChannel: BroadcastChannel;\n\n isSectionExpanded(sectionKey: string): boolean {\n const { expandedSectionKey } = this.state;\n return expandedSectionKey === sectionKey;\n }\n\n handleLogout(): void {\n this.broadcastChannel.postMessage(makeMessage(BROADCAST_LOGOUT_MESSAGE));\n }\n\n handleScrollTo(x: number, y: number): void {\n this.menuContentRef.current?.scrollTo(x, y);\n }\n\n handleSectionToggle(sectionKey: string): void {\n this.setState(state => ({\n expandedSectionKey:\n state.expandedSectionKey === sectionKey ? undefined : sectionKey,\n }));\n }\n\n handleClose(): void {\n const { onDone } = this.props;\n onDone();\n }\n\n handleExportSupportLogs(): void {\n const { serverConfigValues, pluginData } = this.props;\n const pluginInfo = getFormattedPluginInfo(pluginData);\n exportLogs(undefined, {\n ...Object.fromEntries(serverConfigValues),\n pluginInfo,\n });\n }\n\n render(): ReactElement {\n const supportLink = import.meta.env.VITE_SUPPORT_LINK;\n const docsLink = import.meta.env.VITE_DOCS_LINK;\n\n const { serverConfigValues, pluginData, user } = this.props;\n const versionInfo = getFormattedVersionInfo(serverConfigValues);\n const pluginInfo = getFormattedPluginInfo(pluginData);\n const deephavenVersion = serverConfigValues.get('deephaven.version');\n const copyShortcut = GLOBAL_SHORTCUTS.COPY_VERSION_INFO.getDisplayText();\n\n const getRow = (text: string, ver?: string): JSX.Element => (\n <Fragment key={text}>\n <div>{text}</div>\n <div>{ver}</div>\n </Fragment>\n );\n\n const userDisplayName = user.displayName ?? user.name;\n const hasUserImage = user.image != null && user.image !== '';\n const showUserName = userDisplayName !== '';\n\n return (\n <div className=\"app-settings-menu\">\n <header className=\"app-settings-menu-header\">\n <div className=\"user-info\">\n <div className=\"user-image\">\n {!hasUserImage && (\n <FontAwesomeIcon icon={dhUser} transform=\"grow-8\" />\n )}\n {hasUserImage && <img src={user.image} alt={userDisplayName} />}\n </div>\n <div className=\"user-details\">\n {showUserName && (\n <div className=\"user-name\">\n {userDisplayName}\n {user.operateAs != null && user.name !== user.operateAs && (\n <>\n <span className=\"font-weight-light font-italic\">\n {' '}\n as{' '}\n </span>\n <span className=\"operating-as-user\">\n <FontAwesomeIcon\n icon={dhUserIncognito}\n className=\"mr-1\"\n />\n {user.operateAs}\n </span>\n </>\n )}\n </div>\n )}\n {user.permissions.canLogout && (\n <button\n type=\"button\"\n className=\"btn btn-link\"\n onClick={this.handleLogout}\n >\n logout\n </button>\n )}\n </div>\n </div>\n <Button\n kind=\"ghost\"\n className=\"btn-close-settings-menu\"\n onClick={this.handleClose}\n icon={<FontAwesomeIcon icon={vsClose} transform=\"grow-4\" />}\n tooltip=\"Close\"\n />\n </header>\n <div className=\"app-settings-menu-content\" ref={this.menuContentRef}>\n <h5>Settings</h5>\n\n <hr className=\"my-0\" />\n\n <SettingsMenuSection\n sectionKey={SettingsMenu.FORMATTING_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.FORMATTING_SECTION_KEY\n )}\n title={\n <>\n <FontAwesomeIcon\n icon={vsWatch}\n transform=\"grow-4\"\n className=\"mr-2\"\n />\n Default Format &amp; Time zone\n </>\n }\n onToggle={this.handleSectionToggle}\n >\n <FormattingSectionContent />\n </SettingsMenuSection>\n\n <SettingsMenuSection\n sectionKey={SettingsMenu.COLUMN_SPECIFIC_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.COLUMN_SPECIFIC_SECTION_KEY\n )}\n title={\n <>\n <FontAwesomeIcon\n icon={vsLayers}\n transform=\"grow-4\"\n className=\"mr-2\"\n />\n Format by Column Name &amp; Type\n </>\n }\n onToggle={this.handleSectionToggle}\n >\n <ColumnSpecificSectionContent scrollTo={this.handleScrollTo} />\n </SettingsMenuSection>\n\n <ThemeContext.Consumer>\n {contextValue => {\n assertNotNull(contextValue, 'ThemeContext value is null');\n\n return contextValue.themes.length > 1 ? (\n <SettingsMenuSection\n sectionKey={SettingsMenu.THEME_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.THEME_SECTION_KEY\n )}\n onToggle={this.handleSectionToggle}\n title={\n <>\n <FontAwesomeIcon\n icon={vsPaintcan}\n transform=\"grow-4\"\n className=\"mr-2\"\n />\n Theme\n </>\n }\n >\n <ThemePicker />\n </SettingsMenuSection>\n ) : null;\n }}\n </ThemeContext.Consumer>\n\n <SettingsMenuSection\n sectionKey={SettingsMenu.SHORTCUT_SECTION_KEY}\n isExpanded={this.isSectionExpanded(\n SettingsMenu.SHORTCUT_SECTION_KEY\n )}\n title={\n <>\n <FontAwesomeIcon icon={vsRecordKeys} transform=\"grow-2\" />{' '}\n Keyboard Shortcuts\n </>\n }\n onToggle={this.handleSectionToggle}\n >\n <ShortcutSectionContent />\n </SettingsMenuSection>\n\n <div className=\"app-settings-footer\">\n <div className=\"app-settings-footer-section\">\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Support</div>\n <div>\n GitHub:&nbsp;\n <a\n href={supportLink}\n className=\"custom-link\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {supportLink}\n </a>\n </div>\n <Button\n kind=\"tertiary\"\n className=\"mt-2 py-2\"\n onClick={this.handleExportSupportLogs}\n >\n Export Logs\n </Button>\n </div>\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Documentation</div>\n <a\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n href={docsLink}\n className=\"custom-link\"\n >\n {docsLink}\n </a>\n </div>\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Version</div>\n <span className=\"d-inline-block text-muted\">\n {deephavenVersion} <FontAwesomeIcon icon={vsInfo} />\n <Tooltip interactive>\n <div className=\"detailed-server-config\">\n {Object.entries(versionInfo).map(([key, value]) =>\n getRow(key, value)\n )}\n </div>\n <CopyButton\n kind=\"inline\"\n tooltip=\"Copy version numbers\"\n copy={Object.entries({\n ...versionInfo,\n ...pluginInfo,\n })\n .map(([key, value]) => `${key}: ${value}`)\n .join('\\n')}\n >\n Copy Versions\n <small className=\"text-muted\">({copyShortcut})</small>\n </CopyButton>\n </Tooltip>\n </span>\n </div>\n <div className=\"app-settings-footer-item\">\n <div className=\"font-weight-bold\">Plugins</div>\n <div className=\"container\">\n {Array.from(pluginData.entries())\n .filter(plugin => plugin[1].version !== undefined)\n .map(([key, value]) => (\n <div\n key={key}\n className=\"row justify-content-start align-items-center\"\n >\n <div className=\"col pl-0\">\n <span className=\"my-0 text-truncate\">{key}</span>\n </div>\n <div className=\"col-auto\">\n <span>{value?.version}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n <div className=\"app-settings-footer-item\">\n <LegalNotice />\n </div>\n </div>\n <div className=\"app-settings-footer-section\">\n <a\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n href=\"https://deephaven.io\"\n style={{\n display: 'block',\n width: '61.8%',\n }}\n >\n <Logo />\n </a>\n </div>\n </div>\n </div>\n </div>\n );\n }\n}\n\nexport default SettingsMenu;\n","import React, {\n useRef,\n useEffect,\n useCallback,\n useState,\n useMemo,\n ReactNode,\n ReactElement,\n} from 'react';\nimport classNames from 'classnames';\nimport {\n DropdownAction,\n DropdownMenu,\n GLOBAL_SHORTCUTS,\n} from '@deephaven/components';\nimport { ControlType, ToolType } from '@deephaven/dashboard-core-plugins';\nimport { SHORTCUTS as IRIS_GRID_SHORTCUTS } from '@deephaven/iris-grid';\nimport {\n dhInput,\n dhFilterSlash,\n dhTriangleDownSquare,\n vsLink,\n vsMarkdown,\n vsDeviceCamera,\n} from '@deephaven/icons';\nimport PropTypes from 'prop-types';\n\nconst MINIMUM_DRAG_DISTANCE = 10;\n\ninterface DragSourceMenuItemProps {\n forwardedProps: {\n iconElement: ReactNode;\n displayShortcut: string;\n isMouseSelected: boolean;\n isKeyboardSelected: boolean;\n closeMenu: () => void;\n menuItem: {\n action: (event?: MouseEvent) => void;\n title: string;\n disabled: boolean;\n };\n };\n}\n\n/**\n * helper component that renders a menu item\n * props are fowarded from ContextMenuItem\n * purpose is to add custom mouse handlers\n * for dragging panels directly from menu\n */\n\nfunction DragSourceMenuItem(props: DragSourceMenuItemProps): JSX.Element {\n const {\n forwardedProps: {\n menuItem: { action, title, disabled: menuItemDisabled },\n iconElement,\n displayShortcut,\n isMouseSelected,\n isKeyboardSelected,\n closeMenu,\n },\n } = props;\n\n const startX = useRef<number>();\n const startY = useRef<number>();\n const startObject = useRef<EventTarget | null>(null);\n\n // used to prevent double clicking inserting an object twice\n const [disableDoubleClick, setDisableDoubleClick] = useState(false);\n\n const handleMouseMove = useCallback(\n (event: MouseEvent) => {\n if (\n startX.current != null &&\n startY.current != null &&\n startObject.current &&\n (Math.abs(startX.current - event.clientX) >= MINIMUM_DRAG_DISTANCE ||\n Math.abs(startY.current - event.clientY) >= MINIMUM_DRAG_DISTANCE)\n ) {\n setDisableDoubleClick(true);\n window.removeEventListener('mousemove', handleMouseMove);\n closeMenu();\n action(event);\n startObject.current = null; // null object so mouseUp can't fire\n }\n },\n [action, closeMenu]\n );\n\n function handleMouseDown(event: React.MouseEvent<HTMLButtonElement>): void {\n startX.current = event.clientX;\n startY.current = event.clientY;\n startObject.current = event.target;\n window.addEventListener('mousemove', handleMouseMove);\n }\n\n function handleMouseUp(event: React.MouseEvent<HTMLButtonElement>): void {\n // down and up need to occur on same object to constitute a click event\n if (startObject.current === event.target) {\n setDisableDoubleClick(true);\n closeMenu();\n action();\n window.removeEventListener('mousemove', handleMouseMove);\n }\n startObject.current = null; // null object so mousemove can't fire3\n }\n\n useEffect(\n // funny syntax after prettier, return function for the cleanup function\n function cleanUpMouseEventListener() {\n return function removeOldMouseMoveEventListener() {\n return window.removeEventListener('mousemove', handleMouseMove);\n };\n },\n [handleMouseMove]\n );\n\n return (\n <button\n type=\"button\"\n className={classNames(\n 'btn-context-menu',\n { disabled: menuItemDisabled },\n {\n active: isMouseSelected && !menuItemDisabled,\n },\n { 'keyboard-active': isKeyboardSelected && !menuItemDisabled }\n )}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n disabled={disableDoubleClick}\n >\n <span className={classNames('icon')}>{iconElement}</span>\n <span className=\"title\">{title}</span>\n <span className=\"shortcut\">{displayShortcut}</span>\n </button>\n );\n}\n\ninterface AppControlsMenuProps {\n handleControlSelect: (type: string, event: Event) => void;\n handleToolSelect: (type: string) => void;\n onClearFilter: () => void;\n}\n\nfunction AppControlsMenu(props: AppControlsMenuProps): ReactElement {\n const { handleControlSelect, handleToolSelect, onClearFilter } = props;\n const controlMenuActions: DropdownAction[] = useMemo(\n () => [\n {\n title: 'Input Filter',\n icon: dhInput,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.INPUT_FILTER, dragEvent);\n },\n order: 10,\n },\n {\n title: 'Dropdown Filter',\n icon: dhTriangleDownSquare,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.DROPDOWN_FILTER, dragEvent);\n },\n order: 15,\n },\n {\n title: 'Markdown Widget',\n icon: vsMarkdown,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.MARKDOWN, dragEvent);\n },\n order: 20,\n },\n {\n title: 'Filter Sets',\n icon: vsDeviceCamera,\n menuElement: <DragSourceMenuItem />,\n action: (dragEvent: Event) => {\n handleControlSelect(ControlType.FILTER_SET_MANAGER, dragEvent);\n },\n order: 25,\n },\n {\n disabled: true,\n menuElement: <div className=\"context-menu-group-header\">Tools</div>,\n order: 30,\n },\n {\n title: 'Linker',\n icon: vsLink,\n action: () => {\n handleToolSelect(ToolType.LINKER);\n },\n order: 40,\n shortcut: GLOBAL_SHORTCUTS.LINKER,\n },\n {\n disabled: true,\n menuElement: <div className=\"context-menu-group-header\">Actions</div>,\n order: 50,\n },\n {\n title: 'Clear All Filters',\n icon: dhFilterSlash,\n action: () => {\n onClearFilter();\n },\n order: 60,\n shortcut: IRIS_GRID_SHORTCUTS.TABLE.CLEAR_ALL_FILTERS,\n },\n ],\n [handleControlSelect, handleToolSelect, onClearFilter]\n );\n\n return (\n <DropdownMenu\n popperClassName=\"controls-menu-popper\"\n actions={controlMenuActions}\n />\n );\n}\n\nAppControlsMenu.propTypes = {\n handleControlSelect: PropTypes.func,\n handleToolSelect: PropTypes.func,\n onClearFilter: PropTypes.func,\n};\n\nAppControlsMenu.defaultProps = {\n handleControlSelect: () => undefined,\n handleToolSelect: () => undefined,\n onClearFilter: () => undefined,\n};\n\nDragSourceMenuItem.propTypes = {\n forwardedProps: PropTypes.shape({\n iconElement: PropTypes.node,\n displayShortcut: PropTypes.string,\n isMouseSelected: PropTypes.bool.isRequired,\n isKeyboardSelected: PropTypes.bool.isRequired,\n closeMenu: PropTypes.func.isRequired,\n menuItem: PropTypes.shape({\n action: PropTypes.func,\n title: PropTypes.string,\n disabled: PropTypes.bool,\n }).isRequired,\n }),\n};\n\nDragSourceMenuItem.defaultProps = {\n forwardedProps: null,\n};\n\nexport default AppControlsMenu;\n","/**\n * Set the layout storage object being used to load/save the layout\n */\nimport { replaceReducer } from '@deephaven/redux';\nimport { SET_LAYOUT_STORAGE } from '../actionTypes';\n\nexport default replaceReducer(SET_LAYOUT_STORAGE, null);\n","import layoutStorage from './layoutStorage';\n\nexport default { layoutStorage };\n","import { RootState } from '@deephaven/redux';\nimport LayoutStorage from '../storage/LayoutStorage';\n\n/**\n * Get the layout storage used by the app\n * @param store The redux store\n * @returns The layout storage instance\n */\nexport const getLayoutStorage = <State extends RootState = RootState>(\n store: State\n): LayoutStorage => store.layoutStorage as LayoutStorage;\n\n/**\n * Get the configuration values of the server\n * @param store The redux store\n * @returns The layout storage instance\n */\nexport const getServerConfigValues = <State extends RootState = RootState>(\n store: State\n): State['serverConfigValues'] => store.serverConfigValues;\n","import { reducerRegistry } from '@deephaven/redux';\nimport reducers from './reducers';\n\nObject.entries(reducers).map(([name, reducer]) =>\n reducerRegistry.register(name, reducer)\n);\n\nexport * from './actions';\nexport * from './actionTypes';\nexport * from './selectors';\n","import React, {\n ChangeEvent,\n MouseEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Button, SearchInput } from '@deephaven/components';\nimport { ObjectIcon } from '@deephaven/console';\nimport {\n vsArrowSmallDown,\n vsArrowSmallUp,\n vsPreview,\n vsRefresh,\n} from '@deephaven/icons';\nimport type { dh } from '@deephaven/jsapi-types';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport './WidgetList.scss';\n\nconst MINIMUM_DRAG_DISTANCE = 10;\n\n// When we're listening on the window, it emits a `globalThis.MouseEvent`\n// `WindowMouseEvent` is just a convenience alias\nexport type WindowMouseEvent = globalThis.MouseEvent;\n\nexport type SelectStartEvent = {\n x: number;\n y: number;\n widget: dh.ide.VariableDefinition;\n};\n\nexport interface WidgetListProps {\n onSelect: (widget: dh.ide.VariableDefinition, e?: WindowMouseEvent) => void;\n onExportLayout: () => void;\n onImportLayout: () => void;\n onResetLayout: () => void;\n widgets?: dh.ide.VariableDefinition[];\n}\n\n/**\n * Display a search field and a list of widgets, as well as layout export/import buttons.\n * @param props The widgets and handlers to use for this list\n * @returns A JSX element for the list of widgets, along with search\n */\nexport function WidgetList(props: WidgetListProps): JSX.Element {\n const {\n onExportLayout,\n onImportLayout,\n onResetLayout,\n onSelect,\n widgets = [],\n } = props;\n const [disableDoubleClick, setDisableDoubleClick] = useState(false);\n const [searchText, setSearchText] = useState('');\n const searchField = useRef<SearchInput>(null);\n const selectStartEvent = useRef<SelectStartEvent>();\n\n /**\n * Send object to be created, if an event is passed object\n * is treated as createDragSourceFromEvent in golden-layout\n * and uses the event as the starting location for the drag.\n * @param widget\n * @param event\n */\n const sendSelect = useCallback(\n (widget: dh.ide.VariableDefinition, event?: WindowMouseEvent) => {\n if (widget != null) onSelect(widget, event);\n },\n [onSelect]\n );\n\n const handleSearchChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setSearchText(e.target.value);\n }, []);\n\n const handleMouseMove = useCallback(\n (e: WindowMouseEvent) => {\n if (selectStartEvent.current == null) {\n return;\n }\n\n if (\n Math.abs(selectStartEvent.current.x - e.clientX) >=\n MINIMUM_DRAG_DISTANCE ||\n Math.abs(selectStartEvent.current.y - e.clientY) >=\n MINIMUM_DRAG_DISTANCE\n ) {\n setDisableDoubleClick(true);\n window.removeEventListener('mousemove', handleMouseMove);\n sendSelect(selectStartEvent.current.widget, e);\n selectStartEvent.current = undefined; // unset so mouseUp can't fire\n }\n },\n [selectStartEvent, sendSelect]\n );\n\n const handleMouseDown = useCallback(\n (e: MouseEvent, widget: dh.ide.VariableDefinition) => {\n selectStartEvent.current = {\n x: e.clientX,\n y: e.clientY,\n widget,\n };\n window.addEventListener('mousemove', handleMouseMove);\n },\n [handleMouseMove]\n );\n\n const handleMouseUp = useCallback(\n (e: MouseEvent, widget: dh.ide.VariableDefinition) => {\n window.removeEventListener('mousemove', handleMouseMove);\n\n // down and up need to occur on same object to constitute a click event\n if (selectStartEvent.current?.widget === widget) {\n setDisableDoubleClick(true);\n sendSelect(widget);\n }\n selectStartEvent.current = undefined;\n },\n [handleMouseMove, selectStartEvent, sendSelect]\n );\n\n const filteredWidgets = useMemo(\n () =>\n widgets.filter(widget =>\n searchText\n ? widget.name?.toLowerCase().includes(searchText.toLowerCase())\n : true\n ),\n [searchText, widgets]\n ).sort((a, b) => a.name?.localeCompare(b.name ?? '') ?? 0);\n\n const widgetElements = useMemo(\n () =>\n filteredWidgets.map(widget => (\n <li key={widget.name}>\n <Button\n kind=\"ghost\"\n data-testid={`panel-list-item-${widget.name ?? ''}-button`}\n onMouseDown={event => {\n handleMouseDown(event, widget);\n }}\n onMouseUp={event => {\n handleMouseUp(event, widget);\n }}\n onKeyDown={event => {\n if (event.key === 'Enter' || event.key === ' ') {\n sendSelect(widget);\n }\n }}\n disabled={disableDoubleClick}\n onClick={() => {\n // no-op: click is handled by onMouseDown and onMouseUp attributes\n }}\n >\n <ObjectIcon type={widget.type} /> {widget.name ?? ''}\n </Button>\n </li>\n )),\n [\n filteredWidgets,\n disableDoubleClick,\n handleMouseDown,\n handleMouseUp,\n sendSelect,\n ]\n );\n\n const errorElement = useMemo(\n () =>\n widgetElements.length === 0 ? (\n <span>No bound variables found.</span>\n ) : null,\n [widgetElements]\n );\n\n return (\n <div className=\"widget-list-container d-flex flex-column\">\n <div className=\"widget-list-header\">\n <SearchInput\n value={searchText}\n placeholder=\"Find Table, Plot or Widget\"\n onChange={handleSearchChange}\n ref={searchField}\n />\n </div>\n <ul className=\"widget-list flex-grow-1\">\n {errorElement && (\n <li className=\"widget-list-message\">{errorElement}</li>\n )}\n {!errorElement && widgetElements}\n </ul>\n <div>\n <hr />\n </div>\n <div className=\"widget-list-footer\">\n <Button kind=\"ghost\" onClick={onExportLayout}>\n <div className=\"fa-md fa-layers\">\n <FontAwesomeIcon\n mask={vsPreview}\n icon={vsArrowSmallDown}\n transform=\"right-5 down-5\"\n />\n <FontAwesomeIcon\n icon={vsArrowSmallDown}\n transform=\"right-8 down-6\"\n />\n </div>\n Export Layout\n </Button>\n <Button kind=\"ghost\" onClick={onImportLayout}>\n <div className=\"fa-md fa-layers\">\n <FontAwesomeIcon\n mask={vsPreview}\n icon={vsArrowSmallUp}\n transform=\"right-5 down-5\"\n />\n <FontAwesomeIcon icon={vsArrowSmallUp} transform=\"right-8 down-6\" />\n </div>\n Import Layout\n </Button>\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n onClick={onResetLayout}\n tooltip=\"Reset Layout\"\n />\n </div>\n </div>\n );\n}\n\nexport default WidgetList;\n","import type { ItemConfigType } from '@deephaven/golden-layout';\nimport { FilterSet, Link } from '@deephaven/dashboard-core-plugins';\nimport { PluginDataMap } from '@deephaven/redux';\n\n/**\n * Have a different version to support legacy layout exports\n */\nexport type ExportedLayoutV1 = ItemConfigType[];\n\nexport type ExportedLayoutV2 = {\n filterSets: FilterSet[];\n links: Link[];\n layoutConfig: ItemConfigType[];\n pluginDataMap?: PluginDataMap;\n version: 2;\n};\n\nexport type ExportedLayout = ExportedLayoutV1 | ExportedLayoutV2;\n\nexport function isLayoutV2(layout: ExportedLayout): layout is ExportedLayoutV2 {\n return (layout as ExportedLayoutV2).version === 2;\n}\n\nexport function isLayoutV1(layout: ExportedLayout): layout is ExportedLayoutV1 {\n return Array.isArray(layout);\n}\n\n/**\n * Interface for accessing layouts from wherever they are stored.\n */\nexport interface LayoutStorage {\n /**\n * Get the name of the layouts available\n * @returns The string array of layout names\n */\n getLayouts: () => Promise<string[]>;\n\n /**\n * Get the layout with the specified name\n * @param name The name of the layout to fetch\n * @returns GoldenLayout layout config\n */\n getLayout: (name: string) => Promise<ExportedLayout>;\n}\n\nexport default LayoutStorage;\n","import {\n CommandHistoryPanel,\n ConsolePanel,\n FileExplorerPanel,\n LogPanel,\n} from '@deephaven/dashboard-core-plugins';\nimport Log from '@deephaven/log';\nimport { CustomizableWorkspaceData } from '@deephaven/redux';\nimport LayoutStorage, {\n ExportedLayout,\n ExportedLayoutV2,\n isLayoutV1,\n isLayoutV2,\n} from '../storage/LayoutStorage';\n\nconst log = Log.module('UserLayoutUtils');\n\nexport const DEFAULT_LAYOUT_CONFIG: ExportedLayoutV2 = {\n layoutConfig: [\n {\n type: 'column',\n content: [\n {\n type: 'row',\n height: 40, // slightly smaller than 50-50 to allow more space for tables below\n content: [\n {\n type: 'stack',\n content: [\n {\n type: 'react-component',\n component: ConsolePanel.COMPONENT,\n title: ConsolePanel.TITLE,\n isClosable: false,\n },\n {\n type: 'react-component',\n component: LogPanel.COMPONENT,\n title: LogPanel.TITLE,\n isClosable: false,\n },\n ],\n },\n {\n type: 'stack',\n width: 25,\n content: [\n {\n type: 'react-component',\n component: CommandHistoryPanel.COMPONENT,\n title: CommandHistoryPanel.TITLE,\n isClosable: false,\n },\n {\n type: 'react-component',\n component: FileExplorerPanel.COMPONENT,\n title: FileExplorerPanel.TITLE,\n isClosable: false,\n },\n ],\n },\n ],\n },\n {\n type: 'row',\n content: [\n {\n type: 'stack',\n title: 'Notebooks',\n content: [],\n },\n ],\n },\n ],\n },\n ],\n links: [],\n filterSets: [],\n version: 2,\n};\n\nexport const DEFAULT_LAYOUT_CONFIG_NO_CONSOLE: ExportedLayoutV2 = {\n layoutConfig: [],\n links: [],\n filterSets: [],\n version: 2,\n};\n\nexport function normalizeLayout(layout: ExportedLayout): ExportedLayoutV2 {\n if (isLayoutV2(layout)) {\n return layout;\n }\n if (isLayoutV1(layout)) {\n const layoutConfig = layout;\n return {\n layoutConfig,\n links: [],\n filterSets: [],\n version: 2,\n };\n }\n\n throw new Error(`Unexpected layout import format: ${layout}`);\n}\n\n/**\n * Get the default layout for the user to use. Checks layout storage for any layouts, and uses the first one if found.\n * @param layoutStorage The layout storage to get the default layouts from\n * @param isConsoleAvailable Whether console sessions are available.\n * @returns The default layout config to use\n */\nexport async function getDefaultLayout(\n layoutStorage: LayoutStorage,\n isConsoleAvailable = true\n): Promise<ExportedLayoutV2> {\n try {\n const layouts = await layoutStorage.getLayouts();\n if (layouts.length > 0) {\n try {\n // We found a layout on the server, use it. It could be an empty layout if they want user to build their own\n const layout = await layoutStorage.getLayout(layouts[0]);\n return normalizeLayout(layout);\n } catch (err) {\n log.error('Unable to load layout', layouts[0], ':', err);\n log.warn('No valid layouts found, falling back to default layout');\n }\n }\n } catch (err) {\n log.error('Unable to fetch layout list', err);\n log.warn('Falling back to default layout');\n }\n // Otherwise, do the default layout\n return isConsoleAvailable\n ? DEFAULT_LAYOUT_CONFIG\n : DEFAULT_LAYOUT_CONFIG_NO_CONSOLE;\n}\n\nexport function exportLayout(\n data: CustomizableWorkspaceData\n): ExportedLayoutV2 {\n const { filterSets, layoutConfig, links, pluginDataMap } = data as Omit<\n ExportedLayoutV2,\n 'version'\n >;\n const exportedLayout: ExportedLayoutV2 = {\n filterSets,\n layoutConfig,\n links,\n pluginDataMap,\n version: 2,\n };\n return exportedLayout;\n}\n\nexport default { exportLayout, getDefaultLayout, normalizeLayout };\n","import React from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button } from '@deephaven/components';\nimport { vsArrowUp } from '@deephaven/icons';\nimport './EmptyDashboard.scss';\n\nexport interface EmptyDashboardProps {\n onAutoFillClick?: (event: React.MouseEvent) => void;\n}\n\nexport function EmptyDashboard({\n onAutoFillClick = () => undefined,\n}: EmptyDashboardProps): JSX.Element {\n return (\n <div className=\"empty-dashboard-container\">\n <div className=\"hint-container\">\n <FontAwesomeIcon icon={vsArrowUp} /> <br />\n Use the panel list to add objects from a query.\n </div>\n <div className=\"empty-dashboard\">\n <div className=\"add-panels-hint\">Drag Panels Here</div>\n <Button kind=\"tertiary\" onClick={onAutoFillClick}>\n Auto fill objects\n </Button>\n </div>\n </div>\n );\n}\n\nexport default EmptyDashboard;\n","import React, {\n ClipboardEvent,\n ChangeEvent,\n Component,\n ReactElement,\n RefObject,\n} from 'react';\nimport classNames from 'classnames';\nimport memoize from 'memoize-one';\nimport { connect } from 'react-redux';\nimport { RouteComponentProps, withRouter } from 'react-router-dom';\nimport { nanoid } from 'nanoid';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n ContextActions,\n ThemeExport,\n GLOBAL_SHORTCUTS,\n Popper,\n ContextAction,\n Button,\n InfoModal,\n LoadingSpinner,\n Logo,\n BasicModal,\n DebouncedModal,\n NavTabList,\n type NavTabItem,\n SlideTransition,\n LoadingOverlay,\n} from '@deephaven/components';\nimport { SHORTCUTS as IRIS_GRID_SHORTCUTS } from '@deephaven/iris-grid';\nimport {\n CreateDashboardPayload,\n DashboardUtils,\n DEFAULT_DASHBOARD_ID,\n DehydratedDashboardPanelProps,\n getAllDashboardsData,\n getDashboardData,\n listenForCreateDashboard,\n PanelEvent,\n setDashboardData as setDashboardDataAction,\n setDashboardPluginData as setDashboardPluginDataAction,\n stopListenForCreateDashboard,\n updateDashboardData as updateDashboardDataAction,\n} from '@deephaven/dashboard';\nimport {\n ConsolePlugin,\n InputFilterEvent,\n MarkdownEvent,\n NotebookEvent,\n getDashboardSessionWrapper,\n ControlType,\n ToolType,\n getDashboardConnection,\n NotebookPanel,\n} from '@deephaven/dashboard-core-plugins';\nimport {\n vsGear,\n dhShapes,\n dhPanels,\n vsDebugDisconnect,\n dhSquareFilled,\n vsTerminal,\n} from '@deephaven/icons';\nimport { getVariableDescriptor } from '@deephaven/jsapi-bootstrap';\nimport dh from '@deephaven/jsapi-shim';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport { SessionConfig } from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport {\n getActiveTool,\n getWorkspace,\n getUser,\n setActiveTool as setActiveToolAction,\n updateWorkspaceData as updateWorkspaceDataAction,\n getPlugins,\n WorkspaceData,\n RootState,\n User,\n ServerConfigValues,\n CustomizableWorkspace,\n DashboardData,\n} from '@deephaven/redux';\nimport {\n bindAllMethods,\n copyToClipboard,\n PromiseUtils,\n EMPTY_ARRAY,\n} from '@deephaven/utils';\nimport GoldenLayout from '@deephaven/golden-layout';\nimport type { ItemConfigType } from '@deephaven/golden-layout';\nimport { type PluginModuleMap, getDashboardPlugins } from '@deephaven/plugin';\nimport { AppDashboards } from '@deephaven/app-utils';\nimport JSZip from 'jszip';\nimport SettingsMenu from '../settings/SettingsMenu';\nimport AppControlsMenu from './AppControlsMenu';\nimport { getLayoutStorage, getServerConfigValues } from '../redux';\nimport './AppMainContainer.scss';\nimport WidgetList, { WindowMouseEvent } from './WidgetList';\nimport UserLayoutUtils from './UserLayoutUtils';\nimport LayoutStorage from '../storage/LayoutStorage';\nimport { getFormattedVersionInfo } from '../settings/SettingsUtils';\nimport EmptyDashboard from './EmptyDashboard';\n\nconst log = Log.module('AppMainContainer');\n\ntype InputFileFormat =\n | string\n | number[]\n | Uint8Array\n | ArrayBuffer\n | Blob\n | NodeJS.ReadableStream;\n\ninterface AppMainContainerProps {\n activeTool: string;\n allDashboardData: Record<string, DashboardData>;\n dashboardData: DashboardData;\n layoutStorage: LayoutStorage;\n match: {\n params: { notebookPath: string };\n };\n connection?: DhType.IdeConnection;\n session?: DhType.IdeSession;\n sessionConfig?: SessionConfig;\n setActiveTool: (tool: string) => void;\n setDashboardData: (id: string, data: DashboardData) => void;\n setDashboardPluginData: (\n dashboardId: string,\n pluginId: string,\n data: unknown\n ) => void;\n updateDashboardData: (id: string, data: Partial<DashboardData>) => void;\n updateWorkspaceData: (workspaceData: Partial<WorkspaceData>) => void;\n user: User;\n workspace: CustomizableWorkspace;\n plugins: PluginModuleMap;\n serverConfigValues: ServerConfigValues;\n}\n\ninterface AppMainContainerState {\n contextActions: ContextAction[];\n isAuthFailed: boolean;\n isDisconnected: boolean;\n isPanelsMenuShown: boolean;\n isResetLayoutPromptShown: boolean;\n isSettingsMenuShown: boolean;\n unsavedNotebookCount: number;\n widgets: DhType.ide.VariableDefinition[];\n tabs: NavTabItem[];\n activeTabKey: string;\n\n // Number of times the layout has been re-initialized\n layoutIteration: number;\n}\n\nexport class AppMainContainer extends Component<\n AppMainContainerProps & RouteComponentProps,\n AppMainContainerState\n> {\n static handleWindowBeforeUnload(event: BeforeUnloadEvent): void {\n // in development, allow auto-reload\n if (import.meta.env.PROD) {\n event.preventDefault();\n // returnValue is required for beforeReload event prompt\n // https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#example\n // eslint-disable-next-line no-param-reassign\n event.returnValue = '';\n }\n }\n\n static hydrateConsole(\n props: DehydratedDashboardPanelProps,\n id: string\n ): DehydratedDashboardPanelProps {\n return DashboardUtils.hydrate(\n {\n ...props,\n unzip: (zipFile: InputFileFormat) =>\n JSZip.loadAsync(zipFile).then(zip => Object.values(zip.files)),\n },\n id\n );\n }\n\n static handleRefresh(): void {\n log.info('Refreshing application');\n window.location.reload();\n }\n\n constructor(props: AppMainContainerProps & RouteComponentProps) {\n super(props);\n\n bindAllMethods(this);\n\n this.importElement = React.createRef();\n\n const { allDashboardData } = this.props;\n\n this.dashboardLayouts = new Map();\n\n this.state = {\n contextActions: [\n {\n action: () => {\n // Copies the version info to the clipboard for easy pasting into a ticket\n const { serverConfigValues } = this.props;\n const versionInfo = getFormattedVersionInfo(serverConfigValues);\n const versionInfoText = Object.entries(versionInfo)\n .map(([key, value]) => `${key}: ${value}`)\n .join('\\n');\n copyToClipboard(versionInfoText);\n },\n shortcut: GLOBAL_SHORTCUTS.COPY_VERSION_INFO,\n isGlobal: true,\n },\n {\n action: () => {\n this.handleToolSelect(ToolType.LINKER);\n },\n shortcut: GLOBAL_SHORTCUTS.LINKER,\n isGlobal: true,\n },\n {\n action: () => {\n // triggers clear all filters tab event, which in turn triggers a glEventhub event\n // widget panels can subscribe to his event, and execute their own clearing logic\n this.sendClearFilter();\n },\n shortcut: IRIS_GRID_SHORTCUTS.TABLE.CLEAR_ALL_FILTERS,\n isGlobal: true,\n },\n {\n action: () => {\n this.sendReopenLast();\n },\n shortcut: GLOBAL_SHORTCUTS.REOPEN_CLOSED_PANEL,\n isGlobal: true,\n },\n {\n action: () => {\n log.debug('Consume unhandled save shortcut');\n },\n shortcut: GLOBAL_SHORTCUTS.SAVE,\n isGlobal: true,\n },\n ],\n isAuthFailed: false,\n isDisconnected: false,\n isPanelsMenuShown: false,\n isResetLayoutPromptShown: false,\n isSettingsMenuShown: false,\n unsavedNotebookCount: 0,\n widgets: [],\n tabs: Object.entries(allDashboardData).map(([key, value]) => ({\n key,\n title: value.title ?? 'Untitled',\n isClosable: key !== DEFAULT_DASHBOARD_ID,\n icon: key === DEFAULT_DASHBOARD_ID ? vsTerminal : undefined,\n })),\n activeTabKey: DEFAULT_DASHBOARD_ID,\n layoutIteration: 0,\n };\n }\n\n componentDidMount(): void {\n this.initWidgets();\n this.initDashboardData();\n this.startListeningForDisconnect();\n\n window.addEventListener(\n 'beforeunload',\n AppMainContainer.handleWindowBeforeUnload\n );\n }\n\n componentDidUpdate(\n prevProps: AppMainContainerProps,\n prevState: AppMainContainerState\n ): void {\n const { dashboardData } = this.props;\n if (prevProps.dashboardData !== dashboardData) {\n this.handleDataChange(dashboardData);\n }\n }\n\n componentWillUnmount(): void {\n this.deinitWidgets();\n this.stopListeningForDisconnect();\n\n this.dashboardLayouts.forEach(layout => {\n stopListenForCreateDashboard(layout.eventHub, this.handleCreateDashboard);\n });\n\n window.removeEventListener(\n 'beforeunload',\n AppMainContainer.handleWindowBeforeUnload\n );\n }\n\n /** Map from the dashboard ID to the GoldenLayout instance for that dashboard */\n dashboardLayouts: Map<string, GoldenLayout>;\n\n importElement: RefObject<HTMLInputElement>;\n\n widgetListenerRemover?: () => void;\n\n initWidgets(): void {\n const { connection } = this.props;\n if (connection == null) {\n return;\n }\n\n if (connection.subscribeToFieldUpdates == null) {\n log.warn(\n 'subscribeToFieldUpdates not supported, not initializing widgets'\n );\n return;\n }\n\n this.widgetListenerRemover = connection.subscribeToFieldUpdates(updates => {\n log.debug('Got updates', updates);\n this.setState(({ widgets }) => {\n const { updated, created, removed } = updates;\n\n // Remove from the array if it's been removed OR modified. We'll add it back after if it was modified.\n const widgetsToRemove = [...updated, ...removed];\n const newWidgets = widgets.filter(\n widget =>\n !widgetsToRemove.some(toRemove => toRemove.name === widget.name)\n );\n\n // Now add all the modified and updated widgets back in\n const widgetsToAdd = [...updated, ...created];\n widgetsToAdd.forEach(toAdd => {\n if (toAdd.name != null && toAdd.name !== '') {\n newWidgets.push(toAdd);\n }\n });\n\n return { widgets: newWidgets };\n });\n });\n }\n\n deinitWidgets(): void {\n this.widgetListenerRemover?.();\n }\n\n initDashboardData(): void {\n // TODO: #1746 We should be loading data from a dashboard storage store\n // For now only the default dashboard data is stored with the workspace and set on the default dashboard\n const { setDashboardPluginData, updateDashboardData, workspace } =\n this.props;\n const { data: workspaceData } = workspace;\n const { filterSets, links, pluginDataMap } = workspaceData;\n updateDashboardData(DEFAULT_DASHBOARD_ID, {\n filterSets,\n links,\n });\n if (pluginDataMap != null) {\n const pluginKeys = Object.keys(pluginDataMap);\n for (let i = 0; i < pluginKeys.length; i += 1) {\n const pluginId = pluginKeys[i];\n const pluginData = pluginDataMap[pluginId];\n log.debug('initDashboardData plugin data', pluginId, pluginData);\n setDashboardPluginData(DEFAULT_DASHBOARD_ID, pluginId, pluginData);\n }\n }\n }\n\n openNotebookFromURL(): void {\n const { match } = this.props;\n const { notebookPath } = match.params;\n\n if (notebookPath) {\n const { session, sessionConfig } = this.props;\n if (session == null || sessionConfig == null) {\n log.error('No session available to open notebook URL', notebookPath);\n return;\n }\n const fileMetadata = {\n id: `/${notebookPath}`,\n itemName: `/${notebookPath}`,\n };\n\n const language = sessionConfig.type;\n const notebookSettings = {\n value: null,\n language,\n };\n\n this.emitLayoutEvent(\n NotebookEvent.SELECT_NOTEBOOK,\n session,\n language,\n notebookSettings,\n fileMetadata,\n true\n );\n }\n }\n\n sendClearFilter(): void {\n this.emitLayoutEvent(InputFilterEvent.CLEAR_ALL_FILTERS);\n }\n\n sendReopenLast(): void {\n this.emitLayoutEvent(PanelEvent.REOPEN_LAST);\n }\n\n emitLayoutEvent(event: string, ...args: unknown[]): void {\n const { activeTabKey } = this.state;\n const layout = this.dashboardLayouts.get(activeTabKey);\n layout?.eventHub.emit(event, ...args);\n }\n\n handleCancelResetLayoutPrompt(): void {\n this.setState({\n isResetLayoutPromptShown: false,\n });\n }\n\n handleConfirmResetLayoutPrompt(): void {\n this.setState({\n isResetLayoutPromptShown: false,\n });\n\n this.resetLayout();\n }\n\n // eslint-disable-next-line class-methods-use-this\n handleError(error: unknown): void {\n if (PromiseUtils.isCanceled(error)) {\n return;\n }\n log.error(error);\n }\n\n handleSettingsMenuHide(): void {\n this.setState({ isSettingsMenuShown: false });\n }\n\n handleSettingsMenuShow(): void {\n this.setState({ isSettingsMenuShown: true });\n }\n\n handleControlSelect(type: string, dragEvent: Event): void {\n log.debug('handleControlSelect', type);\n\n switch (type) {\n case ControlType.DROPDOWN_FILTER:\n this.emitLayoutEvent(InputFilterEvent.OPEN_DROPDOWN, {\n title: 'DropdownFilter',\n type,\n createNewStack: true,\n dragEvent,\n });\n break;\n case ControlType.INPUT_FILTER:\n this.emitLayoutEvent(InputFilterEvent.OPEN_INPUT, {\n title: 'InputFilter',\n type,\n createNewStack: true,\n dragEvent,\n });\n break;\n case ControlType.MARKDOWN:\n this.emitLayoutEvent(MarkdownEvent.OPEN, {\n title: 'Markdown',\n type,\n dragEvent,\n });\n break;\n case ControlType.FILTER_SET_MANAGER:\n this.emitLayoutEvent(InputFilterEvent.OPEN_FILTER_SET_MANAGER, {\n title: 'FilterSets',\n type,\n dragEvent,\n });\n break;\n default:\n throw new Error(`Unrecognized control type ${type}`);\n }\n }\n\n handleToolSelect(toolType: string): void {\n log.debug('handleToolSelect', toolType);\n\n const { activeTool, setActiveTool } = this.props;\n if (activeTool === toolType) {\n setActiveTool(ToolType.DEFAULT);\n } else {\n setActiveTool(toolType);\n }\n }\n\n handleClearFilter(): void {\n this.sendClearFilter();\n }\n\n handleDataChange(data: DashboardData): void {\n const { updateWorkspaceData } = this.props;\n\n // Only save the data that is serializable/we want to persist to the workspace\n const { closed, filterSets, links, pluginDataMap } = data;\n updateWorkspaceData({ closed, filterSets, links, pluginDataMap });\n }\n\n handleGoldenLayoutChange(newLayout: GoldenLayout): void {\n const { activeTabKey } = this.state;\n const oldLayout = this.dashboardLayouts.get(activeTabKey);\n if (oldLayout === newLayout) return;\n\n if (oldLayout != null) {\n stopListenForCreateDashboard(\n oldLayout.eventHub,\n this.handleCreateDashboard\n );\n }\n\n this.dashboardLayouts.set(activeTabKey, newLayout);\n\n listenForCreateDashboard(newLayout.eventHub, this.handleCreateDashboard);\n }\n\n handleCreateDashboard({\n pluginId,\n title,\n data,\n }: CreateDashboardPayload): void {\n const newId = nanoid();\n const { setDashboardPluginData } = this.props;\n setDashboardPluginData(newId, pluginId, data);\n this.setState(({ tabs }) => ({\n tabs: [\n ...tabs,\n {\n key: newId,\n title,\n },\n ],\n activeTabKey: newId,\n }));\n }\n\n handleWidgetMenuClick(): void {\n this.setState(({ isPanelsMenuShown }) => ({\n isPanelsMenuShown: !isPanelsMenuShown,\n }));\n }\n\n handleWidgetSelect(\n widget: DhType.ide.VariableDefinition,\n dragEvent?: WindowMouseEvent\n ): void {\n this.setState({ isPanelsMenuShown: false });\n\n log.debug('handleWidgetSelect', widget, dragEvent);\n\n this.openWidget(widget, dragEvent);\n }\n\n handleWidgetsMenuClose(): void {\n this.setState({ isPanelsMenuShown: false });\n }\n\n handleAutoFillClick(): void {\n const { widgets } = this.state;\n\n log.debug('handleAutoFillClick', widgets);\n\n const sortedWidgets = widgets.sort((a, b) =>\n a.title != null && b.title != null ? a.title.localeCompare(b.title) : 0\n );\n for (let i = 0; i < sortedWidgets.length; i += 1) {\n this.openWidget(sortedWidgets[i]);\n }\n }\n\n handleExportLayoutClick(): void {\n log.info('handleExportLayoutClick');\n\n this.setState({ isPanelsMenuShown: false });\n\n try {\n const { workspace } = this.props;\n const { data } = workspace;\n const exportedConfig = UserLayoutUtils.exportLayout(data);\n\n log.info('handleExportLayoutClick exportedConfig', exportedConfig);\n\n const blob = new Blob([JSON.stringify(exportedConfig)], {\n type: 'application/json',\n });\n const timestamp = dh.i18n.DateTimeFormat.format(\n 'yyyy-MM-dd-HHmmss',\n new Date()\n );\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = `deephaven-app-layout-${timestamp}.json`;\n link.click();\n } catch (e) {\n log.error('Unable to export layout', e);\n }\n }\n\n handleImportLayoutClick(): void {\n log.info('handleImportLayoutClick');\n\n this.setState({ isPanelsMenuShown: false });\n\n // Reset the file list on the import element, otherwise user won't be prompted again\n if (this.importElement.current != null) {\n this.importElement.current.value = '';\n this.importElement.current.click();\n }\n }\n\n handleResetLayoutClick(): void {\n log.info('handleResetLayoutClick');\n\n this.setState({\n isPanelsMenuShown: false,\n isResetLayoutPromptShown: true,\n unsavedNotebookCount: NotebookPanel.unsavedNotebookCount(),\n });\n }\n\n handleImportLayoutFiles(event: ChangeEvent<HTMLInputElement>): void {\n event.stopPropagation();\n event.preventDefault();\n\n if (event.target.files != null) {\n this.importLayoutFile(event.target.files?.[0]);\n }\n }\n\n handleDisconnect(): void {\n log.info('Disconnected from server');\n this.setState({ isDisconnected: true });\n }\n\n handleReconnect(): void {\n log.info('Reconnected to server');\n this.setState({ isDisconnected: false });\n }\n\n handleReconnectAuthFailed(): void {\n log.warn('Reconnect authentication failed');\n this.setState({ isAuthFailed: true });\n }\n\n /**\n * Import the provided file and set it in the workspace data (which should then load it in the dashboard)\n * @param file JSON file to import\n */\n async importLayoutFile(file: File): Promise<void> {\n try {\n const { updateDashboardData, updateWorkspaceData } = this.props;\n const fileText = await file.text();\n const exportedLayout = JSON.parse(fileText);\n const { filterSets, layoutConfig, links, pluginDataMap } =\n UserLayoutUtils.normalizeLayout(exportedLayout);\n\n updateWorkspaceData({ layoutConfig });\n updateDashboardData(DEFAULT_DASHBOARD_ID, {\n filterSets,\n links,\n pluginDataMap,\n });\n this.setState(({ layoutIteration }) => ({\n layoutIteration: layoutIteration + 1,\n }));\n } catch (e) {\n log.error('Unable to import layout', e);\n }\n }\n\n /**\n * Resets the users layout to the default layout\n */\n async resetLayout(): Promise<void> {\n const { layoutStorage, session } = this.props;\n const { filterSets, layoutConfig, links } =\n await UserLayoutUtils.getDefaultLayout(\n layoutStorage,\n session !== undefined\n );\n\n const { updateDashboardData, updateWorkspaceData } = this.props;\n updateWorkspaceData({ layoutConfig });\n updateDashboardData(DEFAULT_DASHBOARD_ID, {\n filterSets,\n links,\n });\n }\n\n // eslint-disable-next-line class-methods-use-this\n handlePaste(event: ClipboardEvent<HTMLDivElement>): void {\n if (\n event.target instanceof HTMLElement &&\n event.target.closest('.monaco-editor')\n ) {\n // Skip if this is inside a monaco editor\n return;\n }\n\n const { clipboardData } = event;\n const pastedData = clipboardData.getData('Text');\n const replacedChars = /“|”/g;\n if (replacedChars.test(pastedData)) {\n event.preventDefault();\n event.stopPropagation();\n\n document.execCommand(\n 'insertText',\n false,\n pastedData.replace(replacedChars, '\"')\n );\n }\n }\n\n startListeningForDisconnect(): void {\n const { connection } = this.props;\n if (connection == null) {\n return;\n }\n\n connection.addEventListener(\n dh.IdeConnection.EVENT_DISCONNECT,\n this.handleDisconnect\n );\n connection.addEventListener(\n dh.IdeConnection.EVENT_RECONNECT,\n this.handleReconnect\n );\n connection.addEventListener(\n dh.CoreClient.EVENT_RECONNECT_AUTH_FAILED,\n this.handleReconnectAuthFailed\n );\n }\n\n stopListeningForDisconnect(): void {\n const { connection } = this.props;\n if (connection == null) {\n return;\n }\n\n connection.removeEventListener(\n dh.IdeConnection.EVENT_DISCONNECT,\n this.handleDisconnect\n );\n connection.removeEventListener(\n dh.IdeConnection.EVENT_RECONNECT,\n this.handleReconnect\n );\n connection.removeEventListener(\n dh.CoreClient.EVENT_RECONNECT_AUTH_FAILED,\n this.handleReconnectAuthFailed\n );\n }\n\n /**\n * Open a widget up, using a drag event if specified.\n * @param widget The widget to open\n * @param dragEvent The mouse drag event that trigger it, undefined if it was not triggered by a drag\n */\n openWidget(\n widget: DhType.ide.VariableDefinition,\n dragEvent?: WindowMouseEvent\n ): void {\n const { connection } = this.props;\n this.emitLayoutEvent(PanelEvent.OPEN, {\n dragEvent,\n fetch: async () => connection?.getObject(widget),\n widget: getVariableDescriptor(widget),\n });\n }\n\n getDashboardPlugins = memoize((plugins: PluginModuleMap) =>\n getDashboardPlugins(plugins)\n );\n\n handleHomeClick(): void {\n this.handleTabSelect(DEFAULT_DASHBOARD_ID);\n }\n\n handleTabSelect(tabId: string): void {\n this.setState({ activeTabKey: tabId });\n }\n\n handleTabReorder(from: number, to: number): void {\n this.setState(({ tabs: oldTabs }) => {\n const newTabs = [...oldTabs];\n const [t] = newTabs.splice(from, 1);\n newTabs.splice(to, 0, t);\n return { tabs: newTabs };\n });\n }\n\n handleTabClose(tabId: string): void {\n // TODO: #1746 Do something to mark the dashboard as closed\n // Remove any dashboard data we no longer need to keep so\n // the dashboard data store doesn't grow unbounded\n this.setState(({ tabs: oldTabs, activeTabKey }) => {\n const newTabs = oldTabs.filter(tab => tab.key !== tabId);\n let newActiveTabKey = activeTabKey;\n if (activeTabKey === tabId && newTabs.length > 0) {\n const oldActiveTabIndex = oldTabs.findIndex(tab => tab.key === tabId);\n newActiveTabKey =\n oldActiveTabIndex < oldTabs.length - 1\n ? oldTabs[oldActiveTabIndex + 1].key\n : oldTabs[oldActiveTabIndex - 1].key;\n }\n\n if (newTabs.length === 0) {\n newActiveTabKey = DEFAULT_DASHBOARD_ID;\n }\n\n return { tabs: newTabs, activeTabKey: newActiveTabKey };\n });\n }\n\n getDashboards(): {\n id: string;\n layoutConfig: ItemConfigType[];\n key?: string;\n }[] {\n const { layoutIteration, tabs } = this.state;\n const { allDashboardData, workspace } = this.props;\n const { data: workspaceData } = workspace;\n const { layoutConfig } = workspaceData;\n // TODO: #1746 Read the default dashboard layout from dashboardData instead of workspaceData\n return [\n {\n id: DEFAULT_DASHBOARD_ID,\n layoutConfig: layoutConfig as ItemConfigType[],\n key: `${DEFAULT_DASHBOARD_ID}-${layoutIteration}`,\n },\n ...tabs\n .filter(tab => tab.key !== DEFAULT_DASHBOARD_ID)\n .map(tab => ({\n id: tab.key,\n layoutConfig: (allDashboardData[tab.key]?.layoutConfig ??\n EMPTY_ARRAY) as ItemConfigType[],\n key: `${tab.key}-${layoutIteration}`,\n })),\n ];\n }\n\n render(): ReactElement {\n const { activeTool, plugins, user, serverConfigValues } = this.props;\n const { permissions } = user;\n const { canUsePanels } = permissions;\n const {\n contextActions,\n isAuthFailed,\n isDisconnected,\n isPanelsMenuShown,\n isResetLayoutPromptShown,\n isSettingsMenuShown,\n unsavedNotebookCount,\n widgets,\n tabs,\n activeTabKey,\n } = this.state;\n const dashboardPlugins = this.getDashboardPlugins(plugins);\n\n return (\n <div\n className={classNames(\n 'app-main-tabs',\n 'w-100',\n 'h-100',\n 'd-flex',\n 'flex-column',\n activeTool ? `active-tool-${activeTool.toLowerCase()}` : ''\n )}\n onPaste={this.handlePaste}\n tabIndex={-1}\n >\n <div className=\"app-main-top-nav-menus\">\n <Logo className=\"ml-1\" style={{ maxHeight: '20px' }} />\n {/* Only show the Code Studio tab if there is also an open dashboard */}\n {tabs.length > 1 && (\n <div style={{ flexShrink: 0, flexGrow: 1, display: 'flex' }}>\n <NavTabList\n tabs={tabs}\n activeKey={activeTabKey}\n onSelect={this.handleTabSelect}\n onReorder={this.handleTabReorder}\n onClose={this.handleTabClose}\n />\n </div>\n )}\n <div className=\"app-main-right-menu-buttons\">\n <Button\n kind=\"ghost\"\n className=\"btn-panels-menu\"\n icon={dhShapes}\n onClick={() => {\n // no-op: click is handled in `AppControlsMenu` (which uses a `DropdownMenu`)\n }}\n >\n Controls\n <AppControlsMenu\n handleControlSelect={this.handleControlSelect}\n handleToolSelect={this.handleToolSelect}\n onClearFilter={this.handleClearFilter}\n />\n </Button>\n {canUsePanels && (\n <Button\n kind=\"ghost\"\n className=\"btn-panels-menu btn-show-panels\"\n data-testid=\"app-main-panels-button\"\n onClick={this.handleWidgetMenuClick}\n icon={dhPanels}\n >\n Panels\n <Popper\n isShown={isPanelsMenuShown}\n className=\"panels-menu-popper\"\n onExited={this.handleWidgetsMenuClose}\n options={{\n placement: 'bottom',\n }}\n closeOnBlur\n interactive\n >\n <WidgetList\n widgets={widgets}\n onExportLayout={this.handleExportLayoutClick}\n onImportLayout={this.handleImportLayoutClick}\n onResetLayout={this.handleResetLayoutClick}\n onSelect={this.handleWidgetSelect}\n />\n </Popper>\n </Button>\n )}\n <Button\n kind=\"ghost\"\n className={classNames('btn-settings-menu', {\n 'text-warning':\n user.operateAs != null && user.operateAs !== user.name,\n })}\n onClick={this.handleSettingsMenuShow}\n icon={\n <span className=\"fa-layers\">\n <FontAwesomeIcon icon={vsGear} transform=\"grow-3\" />\n {isDisconnected && !isAuthFailed && (\n <>\n <FontAwesomeIcon\n icon={dhSquareFilled}\n color={ThemeExport.background}\n transform=\"grow-2 right-8 down-8.5 rotate-45\"\n />\n <FontAwesomeIcon\n icon={vsDebugDisconnect}\n color={ThemeExport.danger}\n transform=\"shrink-5 right-6 down-6\"\n />\n </>\n )}\n </span>\n }\n tooltip={\n isDisconnected && !isAuthFailed\n ? 'Server disconnected'\n : 'User Settings'\n }\n />\n </div>\n </div>\n <AppDashboards\n dashboards={this.getDashboards()}\n activeDashboard={activeTabKey}\n onGoldenLayoutChange={this.handleGoldenLayoutChange}\n emptyDashboard={\n activeTabKey === DEFAULT_DASHBOARD_ID ? (\n <EmptyDashboard onAutoFillClick={this.handleAutoFillClick} />\n ) : (\n <LoadingOverlay />\n )\n }\n plugins={[\n <ConsolePlugin\n key=\"ConsolePlugin\"\n hydrateConsole={AppMainContainer.hydrateConsole}\n notebooksUrl={\n new URL(\n `${import.meta.env.VITE_ROUTE_NOTEBOOKS}`,\n document.baseURI\n ).href\n }\n />,\n ...dashboardPlugins,\n ]}\n />\n <SlideTransition in={isSettingsMenuShown} mountOnEnter unmountOnExit>\n <SettingsMenu\n serverConfigValues={serverConfigValues}\n pluginData={plugins}\n onDone={this.handleSettingsMenuHide}\n user={user}\n />\n </SlideTransition>\n <ContextActions actions={contextActions} />\n <input\n ref={this.importElement}\n type=\"file\"\n accept=\".json\"\n style={{ display: 'none' }}\n onChange={this.handleImportLayoutFiles}\n data-testid=\"input-import-layout\"\n />\n <DebouncedModal\n isOpen={isDisconnected && !isAuthFailed}\n debounceMs={1000}\n >\n <InfoModal\n icon={vsDebugDisconnect}\n title={\n <>\n <LoadingSpinner /> Attempting to reconnect...\n </>\n }\n subtitle=\"Please check your network connection.\"\n />\n </DebouncedModal>\n <BasicModal\n confirmButtonText=\"Reset\"\n onConfirm={this.handleConfirmResetLayoutPrompt}\n onCancel={this.handleCancelResetLayoutPrompt}\n isConfirmDanger\n isOpen={isResetLayoutPromptShown}\n headerText={\n unsavedNotebookCount === 0\n ? 'Reset Layout'\n : 'Reset layout and discard unsaved changes'\n }\n bodyText={\n unsavedNotebookCount === 0\n ? 'Do you want to reset your layout? Your existing layout will be lost.'\n : 'Do you want to reset your layout? Any unsaved notebooks will be lost.'\n }\n />\n <BasicModal\n confirmButtonText=\"Refresh\"\n onConfirm={AppMainContainer.handleRefresh}\n isOpen={isAuthFailed}\n headerText=\"Authentication failed\"\n bodyText=\"Credentials are invalid. Please refresh your browser to try and reconnect.\"\n />\n </div>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState\n): Omit<\n AppMainContainerProps,\n | 'match'\n | 'setActiveTool'\n | 'updateDashboardData'\n | 'updateWorkspaceData'\n | 'setDashboardData'\n | 'setDashboardPluginData'\n> => ({\n activeTool: getActiveTool(state),\n allDashboardData: getAllDashboardsData(state),\n dashboardData: getDashboardData(state, DEFAULT_DASHBOARD_ID),\n layoutStorage: getLayoutStorage(state),\n plugins: getPlugins(state),\n connection: getDashboardConnection(state, DEFAULT_DASHBOARD_ID),\n session: getDashboardSessionWrapper(state, DEFAULT_DASHBOARD_ID)?.session,\n sessionConfig: getDashboardSessionWrapper(state, DEFAULT_DASHBOARD_ID)\n ?.config,\n user: getUser(state),\n workspace: getWorkspace(state),\n serverConfigValues: getServerConfigValues(state),\n});\n\nconst ConnectedAppMainContainer = connect(mapStateToProps, {\n setActiveTool: setActiveToolAction,\n setDashboardData: setDashboardDataAction,\n setDashboardPluginData: setDashboardPluginDataAction,\n updateDashboardData: updateDashboardDataAction,\n updateWorkspaceData: updateWorkspaceDataAction,\n})(withRouter(AppMainContainer));\n\nexport default ConnectedAppMainContainer;\n","import React, { ReactElement } from 'react';\nimport { ContextMenuRoot } from '@deephaven/components';\nimport AppMainContainer from './AppMainContainer';\n\nfunction App(): ReactElement {\n return (\n <div className=\"app\">\n <AppMainContainer />\n <ContextMenuRoot />\n </div>\n );\n}\n\nexport default App;\n","import Log from '@deephaven/log';\nimport {\n WorkspaceStorage,\n WorkspaceStorageLoadOptions,\n CustomizableWorkspaceData,\n CustomizableWorkspace,\n WorkspaceSettings,\n ServerConfigValues,\n} from '@deephaven/redux';\nimport {\n DateTimeColumnFormatter,\n DecimalColumnFormatter,\n IntegerColumnFormatter,\n} from '@deephaven/jsapi-utils';\nimport UserLayoutUtils from '../main/UserLayoutUtils';\nimport LayoutStorage from './LayoutStorage';\n\nconst log = Log.module('LocalWorkspaceStorage');\n\n/**\n * Implementation of WorkspaceStorage that just stores the workspace data in localStorage\n */\nexport class LocalWorkspaceStorage implements WorkspaceStorage {\n static readonly STORAGE_KEY = 'deephaven.WorkspaceStorage';\n\n static getBooleanServerConfig(\n serverConfigValues: Map<string, string> | undefined,\n key: string\n ): boolean | undefined {\n if (serverConfigValues?.get(key)?.toLowerCase() === 'true') {\n return true;\n }\n if (serverConfigValues?.get(key)?.toLowerCase() === 'false') {\n return false;\n }\n return undefined;\n }\n\n static makeDefaultWorkspaceSettings(\n serverConfigValues: ServerConfigValues\n ): WorkspaceSettings {\n const settings = {\n defaultDateTimeFormat:\n DateTimeColumnFormatter.DEFAULT_DATETIME_FORMAT_STRING,\n formatter: [],\n timeZone: DateTimeColumnFormatter.DEFAULT_TIME_ZONE_ID,\n showTimeZone: false,\n showTSeparator: true,\n disableMoveConfirmation: false,\n defaultDecimalFormatOptions: {\n defaultFormatString: DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n },\n defaultIntegerFormatOptions: {\n defaultFormatString: IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n },\n truncateNumbersWithPound: false,\n showEmptyStrings: true,\n showNullStrings: true,\n defaultNotebookSettings: {\n isMinimapEnabled: false,\n },\n };\n const serverSettings = {\n defaultDateTimeFormat: serverConfigValues?.get('dateTimeFormat'),\n formatter: [],\n timeZone: serverConfigValues?.get('timeZone'),\n showTimeZone: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showTimeZone'\n ),\n showTSeparator: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showTSeparator'\n ),\n disableMoveConfirmation: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'disableMoveConfirmation'\n ),\n defaultDecimalFormatOptions:\n serverConfigValues?.get('decimalFormat') !== undefined\n ? {\n defaultFormatString: serverConfigValues?.get('decimalFormat'),\n }\n : undefined,\n defaultIntegerFormatOptions:\n serverConfigValues?.get('integerFormat') !== undefined\n ? {\n defaultFormatString: serverConfigValues?.get('integerFormat'),\n }\n : undefined,\n truncateNumbersWithPound: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'truncateNumbersWithPound'\n ),\n showEmptyStrings: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showEmptyStrings'\n ),\n showNullStrings: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'showNullStrings'\n ),\n defaultNotebookSettings:\n serverConfigValues?.get('isMinimapEnabled') !== undefined\n ? {\n isMinimapEnabled: LocalWorkspaceStorage.getBooleanServerConfig(\n serverConfigValues,\n 'isMinimapEnabled'\n ) as boolean,\n }\n : undefined,\n };\n\n const keys = Object.keys(serverSettings) as Array<keyof typeof settings>;\n for (let i = 0; i < keys.length; i += 1) {\n const key = keys[i];\n if (serverSettings[key] !== undefined) {\n // @ts-expect-error override default for defined server settings\n settings[key] = serverSettings[key];\n }\n }\n return settings;\n }\n\n static async makeWorkspaceData(\n layoutStorage: LayoutStorage,\n options?: WorkspaceStorageLoadOptions\n ): Promise<CustomizableWorkspaceData> {\n const {\n filterSets,\n links,\n layoutConfig,\n pluginDataMap = {},\n } = await UserLayoutUtils.getDefaultLayout(\n layoutStorage,\n options?.isConsoleAvailable\n );\n return {\n settings: {},\n layoutConfig,\n closed: [{}],\n links,\n filterSets,\n pluginDataMap,\n };\n }\n\n static async makeDefaultWorkspace(\n layoutStorage: LayoutStorage,\n options?: WorkspaceStorageLoadOptions\n ): Promise<CustomizableWorkspace> {\n return {\n data: await LocalWorkspaceStorage.makeWorkspaceData(\n layoutStorage,\n options\n ),\n };\n }\n\n private layoutStorage: LayoutStorage;\n\n constructor(layoutStorage: LayoutStorage) {\n this.layoutStorage = layoutStorage;\n }\n\n // eslint-disable-next-line class-methods-use-this\n async load(\n options?: WorkspaceStorageLoadOptions\n ): Promise<CustomizableWorkspace> {\n try {\n const workspace = JSON.parse(\n localStorage.getItem(LocalWorkspaceStorage.STORAGE_KEY) ?? ''\n );\n return workspace;\n } catch (e) {\n log.info('Unable to load workspace data, initializing to default data');\n\n return LocalWorkspaceStorage.makeDefaultWorkspace(\n this.layoutStorage,\n options\n );\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n async save(workspace: CustomizableWorkspace): Promise<CustomizableWorkspace> {\n localStorage.setItem(\n LocalWorkspaceStorage.STORAGE_KEY,\n JSON.stringify(workspace)\n );\n return workspace;\n }\n}\n\nexport default LocalWorkspaceStorage;\n","import type { dh } from '@deephaven/jsapi-types';\nimport LayoutStorage, { ExportedLayout } from '../LayoutStorage';\n\nexport class GrpcLayoutStorage implements LayoutStorage {\n readonly storageService: dh.storage.StorageService;\n\n readonly root: string;\n\n /**\n *\n * @param storageService The gRPC storage service to use\n * @param root The root path where the layouts are stored\n */\n constructor(storageService: dh.storage.StorageService, root = '') {\n this.storageService = storageService;\n this.root = root;\n }\n\n async getLayouts(): Promise<string[]> {\n const files = await this.storageService.listItems(this.root, '*.json');\n\n return files.map(file => file.basename);\n }\n\n async getLayout(name: string): Promise<ExportedLayout> {\n const fileContents = await this.storageService.loadFile(\n `${this.root}/${name}`\n );\n const content = await fileContents.text();\n\n return JSON.parse(content);\n }\n}\n\nexport default GrpcLayoutStorage;\n","/* eslint-disable class-methods-use-this */\n\nimport Log from '@deephaven/log';\nimport {\n StorageTableViewport,\n StorageListenerRemover,\n ViewportUpdateCallback,\n ViewportData,\n IndexRange,\n StorageSnapshot,\n} from '@deephaven/storage';\nimport {\n CancelablePromise,\n CanceledPromiseError,\n PromiseUtils,\n} from '@deephaven/utils';\nimport {\n FileStorageItem,\n FileStorageTable,\n FileUtils,\n} from '@deephaven/file-explorer';\nimport type { dh } from '@deephaven/jsapi-types';\nimport debounce from 'lodash.debounce';\n\nconst log = Log.module('GrpcFileStorageTable');\n\n/**\n * Implementation of FileStorageTable for gRPC service.\n * Takes a path to specify what root this table should start at.\n */\nexport class GrpcFileStorageTable implements FileStorageTable {\n static REFRESH_DEBOUNCE = 50;\n\n private readonly storageService: dh.storage.StorageService;\n\n private readonly baseRoot: string;\n\n private readonly root: string;\n\n private currentSize = 0;\n\n private currentViewport?: StorageTableViewport;\n\n private listeners: ViewportUpdateCallback<FileStorageItem>[] = [];\n\n private viewportUpdatePromise?: CancelablePromise<\n ViewportData<FileStorageItem>\n >;\n\n private currentViewportData?: ViewportData<FileStorageItem>;\n\n /**\n * Map of expanded directory paths to the tables that manage that path.\n * We use a tree of tables to query the server so we just get the directories that are expanded.\n */\n private childTables: Map<string, GrpcFileStorageTable> = new Map();\n\n /**\n * @param storageService The storage service to use\n * @param baseRoot Base root for the service\n * @param root The root path for this storage table\n */\n constructor(\n storageService: dh.storage.StorageService,\n baseRoot = '',\n root = baseRoot\n ) {\n this.storageService = storageService;\n this.baseRoot = baseRoot;\n this.root = root;\n if (root === baseRoot) {\n this.doRefresh = debounce(\n this.doRefresh.bind(this),\n GrpcFileStorageTable.REFRESH_DEBOUNCE\n );\n }\n }\n\n private removeBaseRoot(filename: string): string {\n return FileUtils.removeRoot(this.baseRoot, filename);\n }\n\n getViewportData(): Promise<ViewportData<FileStorageItem>> {\n if (!this.viewportUpdatePromise) {\n this.refreshInternal();\n }\n return (\n this.viewportUpdatePromise ?? Promise.resolve({ items: [], offset: 0 })\n );\n }\n\n getSnapshot(\n sortedRanges: IndexRange[]\n ): Promise<StorageSnapshot<FileStorageItem>> {\n throw new Error('Method not implemented.');\n }\n\n get size(): number {\n return this.currentSize;\n }\n\n setExpanded(path: string, expanded: boolean): void {\n const paths = path.split('/');\n let nextPath = paths.shift();\n if (nextPath === undefined || nextPath === '') {\n nextPath = paths.shift();\n }\n if (nextPath === undefined || nextPath === '') {\n throw new Error(`Invalid path: ${path}`);\n }\n const remainingPath = paths.join('/');\n if (expanded) {\n if (!this.childTables.has(nextPath)) {\n const childTable = new GrpcFileStorageTable(\n this.storageService,\n this.baseRoot,\n `${this.root}/${nextPath}`\n );\n this.childTables.set(nextPath, childTable);\n }\n if (remainingPath) {\n const childTable = this.childTables.get(nextPath);\n childTable?.setExpanded(remainingPath, expanded);\n }\n } else if (this.childTables.has(nextPath)) {\n if (remainingPath) {\n const childTable = this.childTables.get(nextPath);\n childTable?.setExpanded(remainingPath, expanded);\n } else {\n this.childTables.delete(nextPath);\n }\n }\n if (this.currentViewport) {\n this.refreshInternal();\n }\n }\n\n collapseAll(): void {\n this.childTables.clear();\n if (this.currentViewport) {\n this.refreshInternal();\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n setSearch(search: string): void {\n throw new Error('Method not implemented.');\n }\n\n setViewport(viewport: StorageTableViewport): void {\n this.currentViewport = viewport;\n\n this.refreshInternal();\n }\n\n setFilters(): void {\n throw new Error('Method not implemented.');\n }\n\n setSorts(): void {\n throw new Error('Method not implemented.');\n }\n\n setReversed(): void {\n throw new Error('Method not implemented.');\n }\n\n close(): void {\n this.listeners = [];\n }\n\n onUpdate(\n callback: ViewportUpdateCallback<FileStorageItem>\n ): StorageListenerRemover {\n this.listeners = [...this.listeners, callback];\n return () => {\n this.listeners = this.listeners.filter(other => other !== callback);\n };\n }\n\n doRefresh(\n callback: (fetchPromise: Promise<ViewportData<FileStorageItem>>) => void\n ): void {\n log.debug2('doRefresh', this.root);\n callback(this.fetchData());\n }\n\n refresh(): void {\n log.debug2('refresh', this.root);\n\n this.viewportUpdatePromise?.cancel();\n\n const refreshPromise = new Promise<ViewportData<FileStorageItem>>(\n resolve => {\n this.doRefresh(resolve);\n }\n );\n\n const viewportUpdatePromise = PromiseUtils.makeCancelable(\n refreshPromise.then(viewportData => {\n if (this.viewportUpdatePromise !== viewportUpdatePromise) {\n throw new CanceledPromiseError();\n }\n\n this.currentViewportData = viewportData;\n\n this.sendUpdate();\n\n return viewportData;\n })\n );\n\n // Add a catch here as we're not catching the promises anywhere else\n viewportUpdatePromise.catch(e => {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Error updating viewport', e);\n }\n });\n\n this.viewportUpdatePromise = viewportUpdatePromise;\n }\n\n /**\n * Refreshes data, but catches any errors and logs them\n */\n private refreshInternal(): void {\n try {\n this.refresh();\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to refresh data', e);\n }\n }\n }\n\n private async fetchData(): Promise<ViewportData<FileStorageItem>> {\n const { currentViewport: viewport } = this;\n if (!viewport) {\n throw new Error('No viewport set');\n }\n\n // First get the root directory contents\n const dirContents = await this.storageService.listItems(this.root);\n let items = dirContents\n .map(file => ({\n type: file.type,\n filename: this.removeBaseRoot(file.filename),\n basename: file.basename,\n id: this.removeBaseRoot(file.filename),\n isExpanded:\n file.type === 'directory'\n ? this.childTables.has(file.basename)\n : undefined,\n }))\n .sort((a, b) => {\n if (a.type !== b.type) {\n return a.type === 'directory' ? -1 : 1;\n }\n return a.basename.localeCompare(b.basename);\n }) as FileStorageItem[];\n\n // Get the data from all expanded directories\n for (let i = 0; i < items.length; i += 1) {\n const item = items[i];\n const { basename, filename } = item;\n if (\n filename === this.removeBaseRoot(`${this.root}/${basename}`) &&\n item.type === 'directory'\n ) {\n const childTable = this.childTables.get(basename);\n if (childTable != null) {\n childTable.setViewport({ top: 0, bottom: viewport.bottom - i });\n // eslint-disable-next-line no-await-in-loop\n const childViewportData = await childTable.getViewportData();\n items.splice(i + 1, 0, ...childViewportData.items);\n }\n }\n }\n\n this.currentSize = items.length;\n\n log.debug2(this.root, 'items', items, viewport);\n\n // Slice it to the correct viewport\n items = items.slice(viewport.top, viewport.bottom);\n\n return { items, offset: viewport.top };\n }\n\n private sendUpdate(): void {\n // Retain a reference to it in case a listener gets removed while sending an update\n const { listeners } = this;\n const data = this.currentViewportData ?? { items: [], offset: 0 };\n for (let i = 0; i < listeners.length; i += 1) {\n listeners[i](data);\n }\n }\n}\n\nexport default GrpcFileStorageTable;\n","/* eslint-disable class-methods-use-this */\n\nimport throttle from 'lodash.throttle';\nimport {\n FileNotFoundError,\n FileStorage,\n File,\n FileStorageItem,\n FileStorageTable,\n FileUtils,\n isFileType,\n} from '@deephaven/file-explorer';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport GrpcFileStorageTable from './GrpcFileStorageTable';\n\nconst log = Log.module('GrpcFileStorage');\n\nexport class GrpcFileStorage implements FileStorage {\n private static readonly REFRESH_THROTTLE = 150;\n\n private readonly storageService: DhType.storage.StorageService;\n\n private tables = [] as GrpcFileStorageTable[];\n\n private readonly root: string;\n\n /**\n * FileStorage implementation using gRPC\n * @param storageService Storage service to use\n * @param root Root path for this instance. Should not contain trailing slash.\n */\n constructor(storageService: DhType.storage.StorageService, root = '') {\n this.storageService = storageService;\n this.root = root;\n }\n\n private removeRoot(filename: string): string {\n return FileUtils.removeRoot(this.root, filename);\n }\n\n private addRoot(path: string): string {\n return FileUtils.addRoot(this.root, path);\n }\n\n async createDirectory(path: string): Promise<FileStorageItem> {\n await this.storageService.createDirectory(this.addRoot(path));\n this.refreshTables();\n return {\n type: 'directory',\n id: path,\n filename: path,\n basename: FileUtils.getBaseName(path),\n };\n }\n\n async getTable(): Promise<FileStorageTable> {\n const table = new GrpcFileStorageTable(this.storageService, this.root);\n this.tables.push(table);\n return table;\n }\n\n async saveFile(file: File): Promise<File> {\n const fileContents = dh.storage.FileContents.text(file.content);\n await this.storageService.saveFile(\n this.addRoot(file.filename),\n fileContents,\n true\n );\n this.refreshTables();\n return file;\n }\n\n async loadFile(name: string): Promise<File> {\n const fileContents = await this.storageService.loadFile(this.addRoot(name));\n const content = await fileContents.text();\n return {\n filename: name,\n basename: FileUtils.getBaseName(name),\n content,\n };\n }\n\n async copyFile(name: string, newName: string): Promise<void> {\n const fileContents = await this.storageService.loadFile(this.addRoot(name));\n await this.storageService.saveFile(\n this.addRoot(newName),\n fileContents,\n false\n );\n this.refreshTables();\n }\n\n async deleteFile(name: string): Promise<void> {\n await this.storageService.deleteItem(this.addRoot(name));\n this.refreshTables();\n }\n\n async moveFile(name: string, newName: string): Promise<void> {\n await this.storageService.moveItem(\n this.addRoot(name),\n this.addRoot(newName)\n );\n this.refreshTables();\n }\n\n async info(name: string): Promise<FileStorageItem> {\n const allItems = await this.storageService.listItems(\n this.addRoot(FileUtils.getPath(name)),\n FileUtils.getBaseName(name)\n );\n if (allItems.length === 0) {\n throw new FileNotFoundError();\n }\n if (allItems.length > 1) {\n log.error(\n 'More than one matching file found, should never happen.',\n allItems\n );\n throw new Error('More than one matching file found');\n }\n\n const itemDetails = allItems[0];\n\n if (!isFileType(itemDetails.type)) {\n throw new Error(`Unexpected file type: ${itemDetails.type}`);\n }\n\n return {\n filename: this.removeRoot(itemDetails.filename),\n basename: itemDetails.basename,\n id: this.removeRoot(itemDetails.filename),\n type: itemDetails.type,\n };\n }\n\n private refreshTables = throttle(() => {\n this.tables.forEach(table => table.refresh());\n }, GrpcFileStorage.REFRESH_THROTTLE);\n}\n\nexport default GrpcFileStorage;\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { connect } from 'react-redux';\nimport {\n LoadingOverlay,\n Shortcut,\n ShortcutRegistry,\n} from '@deephaven/components';\nimport {\n DEFAULT_DASHBOARD_ID,\n setDashboardData as setDashboardDataAction,\n} from '@deephaven/dashboard';\nimport {\n setDashboardConnection as setDashboardConnectionAction,\n setDashboardSessionWrapper as setDashboardSessionWrapperAction,\n ToolType,\n} from '@deephaven/dashboard-core-plugins';\nimport { FileStorage } from '@deephaven/file-explorer';\nimport { useApi, useClient } from '@deephaven/jsapi-bootstrap';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport {\n getSessionDetails,\n loadSessionWrapper,\n SessionWrapper,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { PouchCommandHistoryStorage } from '@deephaven/pouch-storage';\nimport {\n getWorkspace,\n getWorkspaceStorage,\n RootState,\n setActiveTool as setActiveToolAction,\n setApi as setApiAction,\n setCommandHistoryStorage as setCommandHistoryStorageAction,\n setFileStorage as setFileStorageAction,\n setPlugins as setPluginsAction,\n setUser as setUserAction,\n setWorkspace as setWorkspaceAction,\n setDefaultWorkspaceSettings as setDefaultWorkspaceSettingsAction,\n setWorkspaceStorage as setWorkspaceStorageAction,\n setServerConfigValues as setServerConfigValuesAction,\n User,\n WorkspaceStorage,\n ServerConfigValues,\n WorkspaceSettings,\n CustomizableWorkspace,\n} from '@deephaven/redux';\nimport { useConnection, useServerConfig, useUser } from '@deephaven/app-utils';\nimport { type PluginModuleMap, usePlugins } from '@deephaven/plugin';\nimport { setLayoutStorage as setLayoutStorageAction } from '../redux/actions';\nimport App from './App';\nimport LocalWorkspaceStorage from '../storage/LocalWorkspaceStorage';\nimport LayoutStorage from '../storage/LayoutStorage';\nimport GrpcLayoutStorage from '../storage/grpc/GrpcLayoutStorage';\nimport GrpcFileStorage from '../storage/grpc/GrpcFileStorage';\n\nconst log = Log.module('AppInit');\n\ninterface AppInitProps {\n workspace: CustomizableWorkspace;\n workspaceStorage: WorkspaceStorage;\n\n setActiveTool: (type: (typeof ToolType)[keyof typeof ToolType]) => void;\n setApi: (api: typeof DhType) => void;\n setCommandHistoryStorage: (storage: PouchCommandHistoryStorage) => void;\n setDashboardData: (\n id: string,\n dashboardData: Record<string, unknown>\n ) => void;\n setFileStorage: (fileStorage: FileStorage) => void;\n setLayoutStorage: (layoutStorage: LayoutStorage) => void;\n setDashboardConnection: (\n id: string,\n connection: DhType.IdeConnection\n ) => void;\n setDashboardSessionWrapper: (id: string, wrapper: SessionWrapper) => void;\n setPlugins: (map: PluginModuleMap) => void;\n setUser: (user: User) => void;\n setWorkspace: (workspace: CustomizableWorkspace) => void;\n setDefaultWorkspaceSettings: (settings: WorkspaceSettings) => void;\n setWorkspaceStorage: (workspaceStorage: WorkspaceStorage) => void;\n setServerConfigValues: (config: ServerConfigValues) => void;\n}\n\n/**\n * Component that sets some default values needed\n */\nfunction AppInit(props: AppInitProps): JSX.Element {\n const {\n workspace,\n setActiveTool,\n setApi,\n setCommandHistoryStorage,\n setDashboardData,\n setFileStorage,\n setLayoutStorage,\n setDashboardConnection,\n setDashboardSessionWrapper,\n setPlugins,\n setUser,\n setWorkspace,\n setWorkspaceStorage,\n setDefaultWorkspaceSettings,\n setServerConfigValues,\n } = props;\n\n const api = useApi();\n const client = useClient();\n const connection = useConnection();\n const plugins = usePlugins();\n const serverConfig = useServerConfig();\n const user = useUser();\n\n // General error means the app is dead and is unlikely to recover\n const [error, setError] = useState<unknown>();\n\n useEffect(\n function setReduxPlugins() {\n setPlugins(plugins);\n },\n [plugins, setPlugins]\n );\n\n useEffect(\n function initApp() {\n async function loadApp(): Promise<void> {\n try {\n const sessionDetails = await getSessionDetails();\n const sessionWrapper = await loadSessionWrapper(\n api,\n connection,\n sessionDetails\n );\n\n const storageService = client.getStorageService();\n const layoutStorage = new GrpcLayoutStorage(\n storageService,\n import.meta.env.VITE_STORAGE_PATH_LAYOUTS ?? ''\n );\n const fileStorage = new GrpcFileStorage(\n storageService,\n import.meta.env.VITE_STORAGE_PATH_NOTEBOOKS ?? ''\n );\n\n const workspaceStorage = new LocalWorkspaceStorage(layoutStorage);\n const commandHistoryStorage = new PouchCommandHistoryStorage();\n\n const loadedWorkspace = await workspaceStorage.load({\n isConsoleAvailable: sessionWrapper !== undefined,\n });\n\n const { data } = loadedWorkspace;\n\n // Fill in settings that have not yet been set\n const { settings } = data;\n\n // Set any shortcuts that user has overridden on this platform\n const { shortcutOverrides = {} } = settings;\n const isMac = Shortcut.isMacPlatform;\n const platformOverrides = isMac\n ? shortcutOverrides.mac ?? {}\n : shortcutOverrides.windows ?? {};\n\n Object.entries(platformOverrides).forEach(([id, keyState]) => {\n ShortcutRegistry.get(id)?.setKeyState(keyState);\n });\n\n const dashboardData = {\n title: 'Code Studio',\n filterSets: data.filterSets,\n links: data.links,\n };\n\n setApi(api);\n setActiveTool(ToolType.DEFAULT);\n setServerConfigValues(serverConfig);\n setCommandHistoryStorage(commandHistoryStorage);\n setDashboardData(DEFAULT_DASHBOARD_ID, dashboardData);\n setFileStorage(fileStorage);\n setLayoutStorage(layoutStorage);\n setDashboardConnection(DEFAULT_DASHBOARD_ID, connection);\n if (sessionWrapper !== undefined) {\n setDashboardSessionWrapper(DEFAULT_DASHBOARD_ID, sessionWrapper);\n }\n setUser(user);\n setWorkspaceStorage(workspaceStorage);\n setWorkspace(loadedWorkspace);\n setDefaultWorkspaceSettings(\n LocalWorkspaceStorage.makeDefaultWorkspaceSettings(serverConfig)\n );\n } catch (e) {\n log.error(e);\n setError(e);\n }\n }\n loadApp();\n },\n [\n api,\n client,\n connection,\n serverConfig,\n setActiveTool,\n setApi,\n setCommandHistoryStorage,\n setDashboardData,\n setFileStorage,\n setLayoutStorage,\n setDashboardConnection,\n setDashboardSessionWrapper,\n setUser,\n setWorkspace,\n setDefaultWorkspaceSettings,\n setWorkspaceStorage,\n setServerConfigValues,\n user,\n ]\n );\n\n const isLoading = workspace == null && error == null;\n const isLoaded = !isLoading && error == null;\n const errorMessage = error != null ? `${error}` : null;\n\n return (\n <>\n {isLoaded && <App />}\n <LoadingOverlay\n isLoading={isLoading && errorMessage == null}\n isLoaded={isLoaded}\n errorMessage={errorMessage}\n />\n </>\n );\n}\n\nAppInit.propTypes = {\n workspace: PropTypes.shape({}),\n workspaceStorage: PropTypes.shape({ close: PropTypes.func }),\n\n setActiveTool: PropTypes.func.isRequired,\n setApi: PropTypes.func.isRequired,\n setCommandHistoryStorage: PropTypes.func.isRequired,\n setDashboardData: PropTypes.func.isRequired,\n setFileStorage: PropTypes.func.isRequired,\n setLayoutStorage: PropTypes.func.isRequired,\n setDashboardConnection: PropTypes.func.isRequired,\n setDashboardSessionWrapper: PropTypes.func.isRequired,\n setPlugins: PropTypes.func.isRequired,\n setUser: PropTypes.func.isRequired,\n setWorkspace: PropTypes.func.isRequired,\n setWorkspaceStorage: PropTypes.func.isRequired,\n};\n\nAppInit.defaultProps = {\n workspace: null,\n workspaceStorage: null,\n};\n\nconst mapStateToProps = (\n state: RootState\n): Pick<AppInitProps, 'workspace' | 'workspaceStorage'> => ({\n workspace: getWorkspace(state),\n workspaceStorage: getWorkspaceStorage(state),\n});\n\nconst ConnectedAppInit = connect(mapStateToProps, {\n setActiveTool: setActiveToolAction,\n setApi: setApiAction,\n setCommandHistoryStorage: setCommandHistoryStorageAction,\n setDashboardData: setDashboardDataAction,\n setFileStorage: setFileStorageAction,\n setLayoutStorage: setLayoutStorageAction,\n setDashboardConnection: setDashboardConnectionAction,\n setDashboardSessionWrapper: setDashboardSessionWrapperAction,\n setPlugins: setPluginsAction,\n setUser: setUserAction,\n setWorkspace: setWorkspaceAction,\n setDefaultWorkspaceSettings: setDefaultWorkspaceSettingsAction,\n setWorkspaceStorage: setWorkspaceStorageAction,\n setServerConfigValues: setServerConfigValuesAction,\n})(AppInit);\n\nexport default ConnectedAppInit;\n","import React, { ReactElement } from 'react';\nimport {\n BrowserRouter as Router,\n Route,\n Redirect,\n Switch,\n} from 'react-router-dom';\nimport AppInit from './AppInit';\n\nconst StyleGuideRoot = React.lazy(() => import('../styleguide/StyleGuideRoot'));\n\nconst baseURI = new URL(document.baseURI).pathname.replace(/\\/$/, '');\n\nfunction AppRouter(): ReactElement {\n return (\n <Router basename={baseURI}>\n <Switch>\n <Route exact path=\"/\" component={AppInit} />\n <Route\n path={`/${import.meta.env.VITE_ROUTE_NOTEBOOKS}:notebookPath+`}\n component={AppInit}\n />\n <Route path=\"/styleguide\" component={StyleGuideRoot} />\n <Redirect from=\"*\" to=\"/\" />\n </Switch>\n </Router>\n );\n}\n\nexport default AppRouter;\n","import React from 'react';\nimport { Provider } from 'react-redux';\nimport { MonacoUtils } from '@deephaven/console';\nimport { store } from '@deephaven/redux';\nimport { DownloadServiceWorkerUtils } from '@deephaven/iris-grid';\nimport MonacoWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';\nimport AppRouter from './main/AppRouter';\n\n// load addional css for playwright docker tests\nif (import.meta.env.VITE_PLAYWRIGHT_CSS === '1') {\n await import('./Playwright.css');\n}\n\nexport function AppRoot(): JSX.Element {\n DownloadServiceWorkerUtils.register(\n new URL(\n `${import.meta.env.BASE_URL ?? ''}download/serviceWorker.js`,\n window.location.href\n )\n );\n MonacoUtils.init({ getWorker: () => new MonacoWorker() });\n\n // disable annoying dnd-react warnings\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n window['__react-beautiful-dnd-disable-dev-warnings'] = true;\n\n return (\n <Provider store={store}>\n <AppRouter />\n </Provider>\n );\n}\n\nexport default AppRoot;\n"],"file":"assets/AppRoot-3f523173.js"}