@finos/legend-application-studio 28.21.11 → 28.21.12

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 (47) hide show
  1. package/lib/components/editor/ActivityBar.d.ts.map +1 -1
  2. package/lib/components/editor/ActivityBar.js +37 -3
  3. package/lib/components/editor/ActivityBar.js.map +1 -1
  4. package/lib/components/editor/command/project-search.css +1 -1
  5. package/lib/components/editor/command/project-search.css.map +1 -1
  6. package/lib/components/editor/editor-group/GrammarTextEditor.d.ts.map +1 -1
  7. package/lib/components/editor/editor-group/GrammarTextEditor.js +6 -2
  8. package/lib/components/editor/editor-group/GrammarTextEditor.js.map +1 -1
  9. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.d.ts.map +1 -1
  10. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.js +10 -1
  11. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.js.map +1 -1
  12. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.d.ts.map +1 -1
  13. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.js +3 -10
  14. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.js.map +1 -1
  15. package/lib/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.d.ts.map +1 -1
  16. package/lib/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.js +8 -3
  17. package/lib/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.js.map +1 -1
  18. package/lib/components/editor/editor-group/function-activator/FunctionEditor.js +1 -1
  19. package/lib/components/editor/editor-group/function-activator/FunctionEditor.js.map +1 -1
  20. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.js +1 -1
  21. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.js.map +1 -1
  22. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.d.ts.map +1 -1
  23. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.js +1 -3
  24. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.js.map +1 -1
  25. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.d.ts.map +1 -1
  26. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.js +1 -3
  27. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.js.map +1 -1
  28. package/lib/components/editor/ingest-definition-editor.css +1 -1
  29. package/lib/components/editor/ingest-definition-editor.css.map +1 -1
  30. package/lib/index.css +2 -2
  31. package/lib/index.css.map +1 -1
  32. package/lib/package.json +1 -1
  33. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.d.ts +0 -9
  34. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.d.ts.map +1 -1
  35. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.js +0 -34
  36. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.js.map +1 -1
  37. package/package.json +9 -9
  38. package/src/components/editor/ActivityBar.tsx +65 -0
  39. package/src/components/editor/editor-group/GrammarTextEditor.tsx +8 -2
  40. package/src/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.tsx +11 -0
  41. package/src/components/editor/editor-group/database-editor/DatabaseEditor.tsx +1 -28
  42. package/src/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.tsx +10 -3
  43. package/src/components/editor/editor-group/function-activator/FunctionEditor.tsx +1 -1
  44. package/src/components/editor/editor-group/mapping-editor/MappingEditor.tsx +1 -1
  45. package/src/components/editor/editor-group/uml-editor/StereotypeSelector.tsx +1 -5
  46. package/src/components/editor/editor-group/uml-editor/TaggedValueEditor.tsx +1 -5
  47. package/src/stores/editor/editor-state/element-editor-state/DatabaseEditorState.ts +0 -42
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application-studio",
3
- "version": "28.21.11",
3
+ "version": "28.21.12",
4
4
  "description": "Legend Studio application core",
5
5
  "keywords": [
6
6
  "legend",
@@ -47,15 +47,15 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@dagrejs/dagre": "1.1.4",
50
- "@finos/legend-application": "16.0.110",
51
- "@finos/legend-art": "7.1.151",
52
- "@finos/legend-code-editor": "2.0.176",
53
- "@finos/legend-data-cube": "0.3.93",
54
- "@finos/legend-extension-dsl-data-product": "0.0.86",
55
- "@finos/legend-extension-dsl-diagram": "8.1.240",
50
+ "@finos/legend-application": "16.0.111",
51
+ "@finos/legend-art": "7.1.152",
52
+ "@finos/legend-code-editor": "2.0.177",
53
+ "@finos/legend-data-cube": "0.3.94",
54
+ "@finos/legend-extension-dsl-data-product": "0.0.87",
55
+ "@finos/legend-extension-dsl-diagram": "8.1.241",
56
56
  "@finos/legend-graph": "32.6.8",
57
- "@finos/legend-lego": "2.0.196",
58
- "@finos/legend-query-builder": "4.18.15",
57
+ "@finos/legend-lego": "2.0.197",
58
+ "@finos/legend-query-builder": "4.18.16",
59
59
  "@finos/legend-server-depot": "6.1.12",
60
60
  "@finos/legend-server-lakehouse": "0.3.57",
61
61
  "@finos/legend-server-sdlc": "5.4.3",
@@ -24,10 +24,13 @@ import {
24
24
  import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js';
25
25
  import {
26
26
  clsx,
27
+ CheckIcon,
27
28
  ControlledDropdownMenu,
28
29
  RepoIcon,
29
30
  MenuContent,
30
31
  MenuContentItem,
32
+ MenuContentItemBlankIcon,
33
+ MenuContentItemIcon,
31
34
  MenuContentItemLabel,
32
35
  GitPullRequestIcon,
33
36
  GitMergeIcon,
@@ -48,10 +51,35 @@ import {
48
51
  import { useEditorStore } from './EditorStoreProvider.js';
49
52
  import { forwardRef, useEffect, useState } from 'react';
50
53
  import {
54
+ LEGEND_APPLICATION_COLOR_THEME,
51
55
  ReleaseLogManager,
52
56
  ReleaseNotesManager,
53
57
  VIRTUAL_ASSISTANT_TAB,
54
58
  } from '@finos/legend-application';
59
+
60
+ /**
61
+ * Themes that studio has real SCSS support for. Filters the global theme
62
+ * registry (which also exposes stubs and app-specific themes like
63
+ * `legacy-light`) down to what studio can actually render correctly.
64
+ *
65
+ * To add a new theme to studio's picker:
66
+ * 1. Implement its SCSS in `legend-art/style/base/themes/`
67
+ * 2. Add the key here.
68
+ */
69
+ const STUDIO_SUPPORTED_COLOR_THEMES: ReadonlySet<string> = new Set([
70
+ LEGEND_APPLICATION_COLOR_THEME.DEFAULT_DARK,
71
+ LEGEND_APPLICATION_COLOR_THEME.DEFAULT_LIGHT,
72
+ ]);
73
+
74
+ /**
75
+ * Subset of supported themes that are still being stabilized and should only be
76
+ * exposed in non-production environments. These are hidden from the picker
77
+ * unless the `NonProductionFeatureFlag` config option is enabled, so dev/QA can
78
+ * test them without shipping the toggle to production users.
79
+ */
80
+ const STUDIO_NON_PRODUCTION_COLOR_THEMES: ReadonlySet<string> = new Set([
81
+ LEGEND_APPLICATION_COLOR_THEME.DEFAULT_LIGHT,
82
+ ]);
55
83
  import { LegendStudioAppInfo } from '../LegendStudioAppInfo.js';
56
84
  import { generateSetupRoute } from '../../__lib__/LegendStudioNavigation.js';
57
85
  import { useLegendStudioApplicationStore } from '../LegendStudioFrameworkProvider.js';
@@ -69,16 +97,53 @@ import { useAuth, type AuthContextProps } from 'react-oidc-context';
69
97
  const SettingsMenu = observer(
70
98
  forwardRef<HTMLDivElement, unknown>(function SettingsMenu(props, ref) {
71
99
  const editorStore = useEditorStore();
100
+ const applicationStore = useLegendStudioApplicationStore();
101
+ const { layoutService } = applicationStore;
72
102
  const showDeveloperTool = (): void => {
73
103
  editorStore.panelGroupDisplayState.open();
74
104
  editorStore.setActivePanelMode(PANEL_MODE.DEV_TOOL);
75
105
  };
106
+ const selectColorTheme = (key: string): void => {
107
+ layoutService.setColorTheme(key, { persist: true });
108
+ };
109
+ // Non-production themes (e.g. the in-progress light theme) are only exposed
110
+ // when the `NonProductionFeatureFlag` config option is on.
111
+ const showNonProductionThemes =
112
+ applicationStore.config.options.NonProductionFeatureFlag;
76
113
 
77
114
  return (
78
115
  <MenuContent ref={ref} className="activity-bar__setting__menu">
79
116
  <MenuContentItem onClick={showDeveloperTool}>
117
+ <MenuContentItemBlankIcon />
80
118
  <MenuContentItemLabel>Show Developer Tool</MenuContentItemLabel>
81
119
  </MenuContentItem>
120
+ <MenuContentDivider />
121
+ <MenuContentItem disabled={true}>
122
+ <MenuContentItemBlankIcon />
123
+ <MenuContentItemLabel>Color Theme</MenuContentItemLabel>
124
+ </MenuContentItem>
125
+ {layoutService.availableColorThemes
126
+ .filter(
127
+ (theme) =>
128
+ STUDIO_SUPPORTED_COLOR_THEMES.has(theme.key) &&
129
+ (showNonProductionThemes ||
130
+ !STUDIO_NON_PRODUCTION_COLOR_THEMES.has(theme.key)),
131
+ )
132
+ .map((theme) => (
133
+ <MenuContentItem
134
+ key={theme.key}
135
+ onClick={() => selectColorTheme(theme.key)}
136
+ >
137
+ {theme.key === layoutService.currentColorTheme.key ? (
138
+ <MenuContentItemIcon>
139
+ <CheckIcon />
140
+ </MenuContentItemIcon>
141
+ ) : (
142
+ <MenuContentItemBlankIcon />
143
+ )}
144
+ <MenuContentItemLabel>{theme.name}</MenuContentItemLabel>
145
+ </MenuContentItem>
146
+ ))}
82
147
  </MenuContent>
83
148
  );
84
149
  }),
@@ -56,7 +56,7 @@ import {
56
56
  clearMarkers,
57
57
  setErrorMarkers,
58
58
  moveCursorToPosition,
59
- CODE_EDITOR_THEME,
59
+ getCodeEditorThemeForAppTheme,
60
60
  CODE_EDITOR_LANGUAGE,
61
61
  getInlineSnippetSuggestions,
62
62
  type PureGrammarTextSuggestion,
@@ -869,7 +869,13 @@ export const GrammarTextEditor = observer(() => {
869
869
  const _editor = monacoEditorAPI.create(element, {
870
870
  ...getBaseCodeEditorOptions(),
871
871
  language: CODE_EDITOR_LANGUAGE.PURE,
872
- theme: CODE_EDITOR_THEME.DEFAULT_DARK,
872
+ // Pick the theme matching the current app theme so the editor doesn't
873
+ // flash dark before the global theme sync (in configureCodeEditorComponent)
874
+ // applies. Theme changes after mount are picked up via that global sync.
875
+ theme: getCodeEditorThemeForAppTheme(
876
+ editorStore.applicationStore.layoutService
877
+ .TEMPORARY__isLightColorThemeEnabled,
878
+ ),
873
879
  renderValidationDecorations: 'on',
874
880
  wordWrap: grammarTextEditorState.wordWrapOtion,
875
881
  readOnly: editorStore.editorMode.disableEditing,
@@ -58,6 +58,7 @@ import {
58
58
  resolveJoinFormula,
59
59
  } from './DatabaseDiagramHelper.js';
60
60
  import type { DatabaseEditorState } from '../../../../stores/editor/editor-state/element-editor-state/DatabaseEditorState.js';
61
+ import { useApplicationStore } from '@finos/legend-application';
61
62
 
62
63
  const NODE_TYPES = {
63
64
  table: DatabaseTableNode,
@@ -107,6 +108,7 @@ const findRelationById = (
107
108
  const DatabaseDiagramCanvasInner = observer(
108
109
  (props: { editorState: DatabaseEditorState }) => {
109
110
  const { editorState } = props;
111
+ const applicationStore = useApplicationStore();
110
112
  const {
111
113
  database,
112
114
  selectedRelation,
@@ -521,6 +523,15 @@ const DatabaseDiagramCanvasInner = observer(
521
523
  <div className="database-diagram__canvas-shell">
522
524
  <ReactFlow
523
525
  className="database-diagram__canvas"
526
+ // Drive ReactFlow's built-in light/dark variant from the active app
527
+ // theme. The chrome (canvas bg, controls, minimap, edges, dot pattern)
528
+ // then tracks studio's theme without us having to override individual
529
+ // `--xy-*` variables.
530
+ colorMode={
531
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
532
+ ? 'light'
533
+ : 'dark'
534
+ }
524
535
  nodes={selectionAwareNodes}
525
536
  edges={selectionAwareEdges}
526
537
  nodeTypes={NODE_TYPES}
@@ -20,12 +20,10 @@ import {
20
20
  ChevronRightIcon,
21
21
  InfoCircleIcon,
22
22
  LockIcon,
23
- MoonIcon,
24
23
  ResizablePanel,
25
24
  ResizablePanelGroup,
26
25
  ResizablePanelSplitter,
27
26
  ResizablePanelSplitterLine,
28
- SunIcon,
29
27
  clsx,
30
28
  getCollapsiblePanelGroupProps,
31
29
  } from '@finos/legend-art';
@@ -90,14 +88,7 @@ export const DatabaseEditor = observer(() => {
90
88
  );
91
89
 
92
90
  return (
93
- <div
94
- className={clsx('database-editor', {
95
- // Local light-theme opt-in. Scoped to this editor only — the rest
96
- // of Studio remains in its configured theme. SCSS overrides hang
97
- // off this modifier class.
98
- 'database-editor--light': editorState.theme === 'light',
99
- })}
100
- >
91
+ <div className="database-editor">
101
92
  <div className="database-editor__tabs__header">
102
93
  <div className="database-editor__tabs">
103
94
  {TABS.map((tab) => (
@@ -128,24 +119,6 @@ export const DatabaseEditor = observer(() => {
128
119
  READ ONLY
129
120
  </span>
130
121
  </div>
131
- {/*
132
- * Light/dark theme toggle. Scoped to this editor only — see
133
- * `DatabaseEditorState.toggleTheme`. Icon switches to surface the
134
- * mode the user would jump TO if they clicked (current=dark shows
135
- * a sun, current=light shows a moon).
136
- */}
137
- <button
138
- type="button"
139
- className="database-editor__theme-toggle"
140
- onClick={() => editorState.toggleTheme()}
141
- title={
142
- editorState.theme === 'dark'
143
- ? 'Switch to light theme (this editor only)'
144
- : 'Switch to dark theme'
145
- }
146
- >
147
- {editorState.theme === 'dark' ? <SunIcon /> : <MoonIcon />}
148
- </button>
149
122
  </div>
150
123
  <div className="database-editor__content">
151
124
  {database instanceof INTERNAL__LakehouseGeneratedDatabase && (
@@ -54,7 +54,7 @@ import {
54
54
  getCodeEditorValue,
55
55
  normalizeLineEnding,
56
56
  clearMarkers,
57
- CODE_EDITOR_THEME,
57
+ getCodeEditorThemeForAppTheme,
58
58
  CODE_EDITOR_LANGUAGE,
59
59
  } from '@finos/legend-code-editor';
60
60
  import {
@@ -154,6 +154,7 @@ export const EntityChangeConflictSideBarItem = observer(
154
154
  const MergeConflictEditor = observer(
155
155
  (props: { conflictEditorState: EntityChangeConflictEditorState }) => {
156
156
  const { conflictEditorState } = props;
157
+ const applicationStore = useApplicationStore();
157
158
  const isReadOnly = conflictEditorState.isReadOnly;
158
159
  const [editor, setEditor] = useState<
159
160
  monacoEditorAPI.IStandaloneCodeEditor | undefined
@@ -189,7 +190,10 @@ const MergeConflictEditor = observer(
189
190
  const element = textInputRef.current;
190
191
  const _editor = monacoEditorAPI.create(element, {
191
192
  ...getBaseCodeEditorOptions(),
192
- theme: CODE_EDITOR_THEME.DEFAULT_DARK,
193
+ // Match the active app theme — see GrammarTextEditor for the rationale.
194
+ theme: getCodeEditorThemeForAppTheme(
195
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled,
196
+ ),
193
197
  language: CODE_EDITOR_LANGUAGE.PURE,
194
198
  minimap: { enabled: false },
195
199
  formatOnType: true,
@@ -198,7 +202,10 @@ const MergeConflictEditor = observer(
198
202
  _editor.focus(); // focus on the editor initially so we can correctly compute next/prev conflict chunks
199
203
  setEditor(_editor);
200
204
  }
201
- }, [editor]);
205
+ }, [
206
+ editor,
207
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled,
208
+ ]);
202
209
 
203
210
  if (editor) {
204
211
  // dispose the old editor content setter in case the `updateInput` handler changes
@@ -1521,7 +1521,7 @@ export const FunctionEditor = observer(() => {
1521
1521
  return (
1522
1522
  <div
1523
1523
  data-testid={LEGEND_STUDIO_TEST_ID.FUNCTION_EDITOR}
1524
- className="function-editor uml-editor uml-editor--dark"
1524
+ className="function-editor uml-editor"
1525
1525
  >
1526
1526
  <Panel>
1527
1527
  <div className="panel__header">
@@ -220,7 +220,7 @@ const MappingClassMappingEditor = observer(() => {
220
220
  );
221
221
 
222
222
  return (
223
- <div className={clsx('mapping-editor', 'mapping__theme__dark')}>
223
+ <div className="mapping-editor">
224
224
  <ResizablePanelGroup orientation="vertical">
225
225
  <ResizablePanel size={300} minSize={300}>
226
226
  <div className="mapping-editor__side-bar">
@@ -185,11 +185,7 @@ export const StereotypeSelector = observer(
185
185
  dragSourceConnector={handleRef}
186
186
  isDragging={isBeingDragged}
187
187
  />
188
- <div
189
- className={clsx('stereotype-selector', {
190
- 'stereotype-selector--dark': darkTheme,
191
- })}
192
- >
188
+ <div className="stereotype-selector">
193
189
  <div className="stereotype-selector__profile">
194
190
  <CustomSelectorInput
195
191
  className="stereotype-selector__profile__selector"
@@ -194,11 +194,7 @@ export const TaggedValueEditor = observer(
194
194
  dragSourceConnector={handleRef}
195
195
  isDragging={isBeingDragged}
196
196
  />
197
- <div
198
- className={clsx('tagged-value-editor', {
199
- 'tagged-value-editor--dark': darkTheme,
200
- })}
201
- >
197
+ <div className="tagged-value-editor">
202
198
  <div className="tagged-value-editor__profile">
203
199
  <CustomSelectorInput
204
200
  className="tagged-value-editor__profile__selector"
@@ -42,7 +42,6 @@ import {
42
42
  type View,
43
43
  } from '@finos/legend-graph';
44
44
  import type { EditorStore } from '../../EditorStore.js';
45
- import { LegendStudioUserDataHelper } from '../../../../__lib__/LegendStudioUserDataHelper.js';
46
45
 
47
46
  /**
48
47
  * Top-level tabs inside the Database form-mode editor. `VIEW` shows the ERD
@@ -397,19 +396,6 @@ export class DatabaseEditorState extends ElementEditorState {
397
396
  // by `react-reflex` and not tracked here — only the binary collapse flag.
398
397
  isSidePanelCollapsed = false;
399
398
 
400
- // ---- Theme --------------------------------------------------------------
401
- // The wider Studio app is dark-mode-only today. We allow this editor (and
402
- // only this editor) to opt into a light theme via a toolbar toggle. The
403
- // setting lives on the editor state so it survives tab switches and
404
- // recompiles within the same session, and is persisted per-user via
405
- // `UserDataService` (localStorage) so the choice survives reloads.
406
- // TODO: when Studio adopts app-wide theming via `LayoutService` (Query
407
- // already does this with `setColorTheme(..., { persist: true })`), drop
408
- // this local observable + persistence and react to
409
- // `applicationStore.layoutService.currentColorTheme` instead so this
410
- // editor stays in sync with the rest of the app.
411
- theme: 'dark' | 'light' = 'dark';
412
-
413
399
  constructor(editorStore: EditorStore, element: PackageableElement) {
414
400
  super(editorStore, element);
415
401
 
@@ -435,7 +421,6 @@ export class DatabaseEditorState extends ElementEditorState {
435
421
  viewGroupByFormulas: observable,
436
422
  isLoadingViewGroupByFormulas: observable,
437
423
  isSidePanelCollapsed: observable,
438
- theme: observable,
439
424
  database: computed,
440
425
  setSelectedTab: action,
441
426
  setSelectedRelation: action,
@@ -451,7 +436,6 @@ export class DatabaseEditorState extends ElementEditorState {
451
436
  collapseAll: action,
452
437
  setSidePanelCollapsed: action,
453
438
  toggleSidePanelCollapsed: action,
454
- toggleTheme: action,
455
439
  setSearchText: action,
456
440
  requestFitAll: action,
457
441
  requestResetLayout: action,
@@ -467,16 +451,6 @@ export class DatabaseEditorState extends ElementEditorState {
467
451
  this.expandedSchemaIds.add(getSchemaNodeId(schema.name));
468
452
  });
469
453
 
470
- // Hydrate the persisted theme preference (if any). Falls through to the
471
- // default 'dark' when the user has never set it. Done synchronously in
472
- // the constructor so the first render already reflects the stored choice.
473
- const persistedTheme = LegendStudioUserDataHelper.databaseEditor_getTheme(
474
- this.editorStore.applicationStore.userDataService,
475
- );
476
- if (persistedTheme) {
477
- this.theme = persistedTheme;
478
- }
479
-
480
454
  // Kick off the formula load eagerly. The flow is async and writes into
481
455
  // `viewColumnFormulas` when ready — components render with the placeholder
482
456
  // until then, so the UI is never blocked on this. Errors are logged and
@@ -876,21 +850,6 @@ export class DatabaseEditorState extends ElementEditorState {
876
850
  this.isSidePanelCollapsed = !this.isSidePanelCollapsed;
877
851
  }
878
852
 
879
- /**
880
- * Flip the editor's local theme between dark (the Studio default) and
881
- * light. Scoped to this editor only — the rest of Studio remains in its
882
- * configured theme. The toggle is exposed via a button in the editor's
883
- * tab header. The new value is persisted to `UserDataService` so the
884
- * choice survives reloads.
885
- */
886
- toggleTheme(): void {
887
- this.theme = this.theme === 'dark' ? 'light' : 'dark';
888
- LegendStudioUserDataHelper.databaseEditor_setTheme(
889
- this.editorStore.applicationStore.userDataService,
890
- this.theme,
891
- );
892
- }
893
-
894
853
  /**
895
854
  * Set the tree search/filter text. Empty string means \u201cno filter\u201d.
896
855
  * The schema-tree consumer derives a lowercase form per render rather
@@ -927,7 +886,6 @@ export class DatabaseEditorState extends ElementEditorState {
927
886
  next.expandedSchemaIds = new Set(this.expandedSchemaIds);
928
887
  next.expandedRelationIds = new Set(this.expandedRelationIds);
929
888
  next.isSidePanelCollapsed = this.isSidePanelCollapsed;
930
- next.theme = this.theme;
931
889
  // Note: `viewColumnFormulas` and `filterFormulas` deliberately do NOT
932
890
  // carry over. They're derived from operations on the new element and may
933
891
  // have changed; the constructor's `loadViewColumnFormulas()` and