Skip to content

Commit

Permalink
refactor: clean up state and separate it (#1170)
Browse files Browse the repository at this point in the history
Closes #1169 

### Summary of Changes

- Split up the currentState into tabs, table and history stores, as no
saving to vscode global state anymore so not needed to save as one big
object
- This means that svelte does not have to reevaluate so many things when
something small changes, as in a new history item does not cause update
to whole state anymore that causes table to update in background
- Also easier to manage and update
- tableIdentifier in table object, defaultState property not needed
anymore and UserSettings not yet
- columns don't have a number anymore as order is just array order
- table filter is object that can have all the tablefilters but not
multiple of one type
- columnWidths still shall remain own store in component, as otherwise
resize drag would cause massive amount of updates to the table store
- setCurrentState msg is not setInitialTable and takes Table, error if
executed more than once

Co-authored-by: Lars Reimann <mail@larsreimann.com>
  • Loading branch information
SmiteDeluxe and lars-reimann authored May 16, 2024
1 parent 90bd47c commit a07e893
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 271 deletions.
6 changes: 3 additions & 3 deletions packages/safe-ds-eda/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import TableView from './components/TableView.svelte';
import Sidebar from './components/Sidebar.svelte';
import { throttle } from 'lodash';
import { currentTabIndex, currentState } from './webviewState';
import { currentTabIndex, tabs } from './webviewState';
import TabContent from './components/tabs/TabContent.svelte';
let sidebarWidth = 307; // Initial width of the sidebar in pixels
Expand Down Expand Up @@ -47,8 +47,8 @@
<div class:hide={$currentTabIndex !== undefined}>
<TableView {sidebarWidth} />
</div>
{#if $currentState.tabs}
{#each $currentState.tabs as tab, index}
{#if $tabs.length > 0}
{#each $tabs as tab, index}
<div class:hide={index !== $currentTabIndex}>
<TabContent {tab} {sidebarWidth} />
</div>
Expand Down
109 changes: 43 additions & 66 deletions packages/safe-ds-eda/src/apis/historyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
Tab,
TabHistoryEntry,
} from '../../types/state';
import { cancelTabIdsWaiting, currentState, currentTabIndex } from '../webviewState';
import { cancelTabIdsWaiting, tabs, history, currentTabIndex } from '../webviewState';
import { executeRunner } from './extensionApi';

// Wait for results to return from the server
Expand Down Expand Up @@ -47,40 +47,34 @@ window.addEventListener('message', (event) => {
});

export const addInternalToHistory = function (entry: InternalHistoryEntry): void {
currentState.update((state) => {
history.update((state) => {
const entryWithId: HistoryEntry = {
...entry,
id: getAndIncrementEntryId(),
};
const newHistory = [...state.history, entryWithId];
return {
...state,
history: newHistory,
};
const newHistory = [...state, entryWithId];
return newHistory;
});
};

export const executeExternalHistoryEntry = function (entry: ExternalHistoryEntry): void {
currentState.update((state) => {
history.update((state) => {
const entryWithId: HistoryEntry = {
...entry,
id: getAndIncrementEntryId(),
};
const newHistory = [...state.history, entryWithId];
const newHistory = [...state, entryWithId];

asyncQueue.push(entryWithId);
executeRunner(state.history, entryWithId); // Is this good in here? Otherwise risk of empty array idk
executeRunner(state, entryWithId);

return {
...state,
history: newHistory,
};
return newHistory;
});
};

export const addAndDeployTabHistoryEntry = function (entry: TabHistoryEntry & { id: number }, tab: Tab): void {
// Search if already exists and is up to date
const existingTab = get(currentState).tabs?.find(
const existingTab = get(tabs).find(
(et) =>
et.type !== 'empty' &&
et.type === tab.type &&
Expand All @@ -90,20 +84,18 @@ export const addAndDeployTabHistoryEntry = function (entry: TabHistoryEntry & {
!et.isInGeneration,
);
if (existingTab) {
currentTabIndex.set(get(currentState).tabs!.indexOf(existingTab));
currentTabIndex.set(get(tabs).indexOf(existingTab));
return;
}

currentState.update((state) => {
const newHistory = [...state.history, entry];

return {
...state,
history: newHistory,
tabs: (state.tabs ?? []).concat([tab]),
};
history.update((state) => {
return [...state, entry];
});
tabs.update((state) => {
const newTabs = (state ?? []).concat(tab);
return newTabs;
});
currentTabIndex.set(get(currentState).tabs!.indexOf(tab));
currentTabIndex.set(get(tabs).indexOf(tab));
};

export const addEmptyTabHistoryEntry = function (): void {
Expand All @@ -119,16 +111,14 @@ export const addEmptyTabHistoryEntry = function (): void {
isInGeneration: true,
};

currentState.update((state) => {
const newHistory = [...state.history, entry];

return {
...state,
history: newHistory,
tabs: (state.tabs ?? []).concat([tab]),
};
history.update((state) => {
return [...state, entry];
});
tabs.update((state) => {
const newTabs = (state ?? []).concat(tab);
return newTabs;
});
currentTabIndex.set(get(currentState).tabs!.indexOf(tab));
currentTabIndex.set(get(tabs).indexOf(tab));
};

export const cancelExecuteExternalHistoryEntry = function (entry: HistoryEntry): void {
Expand All @@ -139,9 +129,7 @@ export const cancelExecuteExternalHistoryEntry = function (entry: HistoryEntry):
cancelTabIdsWaiting.update((ids) => {
return ids.concat([entry.existingTabId!]);
});
const tab: RealTab = get(currentState).tabs!.find(
(t) => t.type !== 'empty' && t.id === entry.existingTabId,
)! as RealTab;
const tab: RealTab = get(tabs).find((t) => t.type !== 'empty' && t.id === entry.existingTabId)! as RealTab;
unsetTabAsGenerating(tab);
}
} else {
Expand All @@ -150,8 +138,8 @@ export const cancelExecuteExternalHistoryEntry = function (entry: HistoryEntry):
};

export const setTabAsGenerating = function (tab: RealTab): void {
currentState.update((state) => {
const newTabs = state.tabs?.map((t) => {
tabs.update((state) => {
const newTabs = state.map((t) => {
if (t === tab) {
return {
...t,
Expand All @@ -162,16 +150,13 @@ export const setTabAsGenerating = function (tab: RealTab): void {
}
});

return {
...state,
tabs: newTabs,
};
return newTabs;
});
};

export const unsetTabAsGenerating = function (tab: RealTab): void {
currentState.update((state) => {
const newTabs = state.tabs?.map((t) => {
tabs.update((state) => {
const newTabs = state.map((t) => {
if (t === tab) {
return {
...t,
Expand All @@ -193,34 +178,26 @@ const deployResult = function (result: RunnerExecutionResultMessage) {
const resultContent = result.value;
if (resultContent.type === 'tab') {
if (resultContent.content.id) {
const existingTab = get(currentState).tabs?.find((et) => et.id === resultContent.content.id);
const existingTab = get(tabs).find((et) => et.id === resultContent.content.id);
if (existingTab) {
const tabIndex = get(currentState).tabs!.indexOf(existingTab);
currentState.update((state) => {
return {
...state,
tabs: state.tabs?.map((t) => {
if (t.id === resultContent.content.id) {
return resultContent.content;
} else {
return t;
}
}),
};
});
const tabIndex = get(tabs).indexOf(existingTab);
tabs.update((state) =>
state.map((t) => {
if (t.id === resultContent.content.id) {
return resultContent.content;
} else {
return t;
}
}),
);
currentTabIndex.set(tabIndex);
return;
}
}
const tab = resultContent.content;
tab.id = crypto.randomUUID();
currentState.update((state) => {
return {
...state,
tabs: (state.tabs ?? []).concat(tab),
};
});
currentTabIndex.set(get(currentState).tabs!.indexOf(tab));
tabs.update((state) => state.concat(tab));
currentTabIndex.set(get(tabs).indexOf(tab));
}
};

Expand Down
10 changes: 5 additions & 5 deletions packages/safe-ds-eda/src/components/Sidebar.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { currentState, currentTabIndex, preventClicks } from '../webviewState';
import { table, currentTabIndex, preventClicks, tabs } from '../webviewState';
import CaretIcon from '../icons/Caret.svelte';
import HistoryIcon from '../icons/History.svelte';
import UndoIcon from '../icons/Undo.svelte';
Expand All @@ -20,11 +20,11 @@
<div class="titleBar">
{#if width > 100}
<span class="tableName"
>{$currentState.table?.name}
>{$table?.name ?? 'Loading ...'}
<span class="caret"><CaretIcon /></span>
</span>{/if}
{#if width > 70}
<span class="rowCounts">{$currentState.table?.visibleRows}/{$currentState.table?.totalRows} Rows</span>{/if}
<span class="rowCounts">{$table?.visibleRows ?? 0}/{$table?.totalRows ?? 0} Rows</span>{/if}
</div>
{#if width > 50}
<div class="historyBar" class:no-borders={width < 50}>
Expand All @@ -44,8 +44,8 @@
<button class="tab" class:tabActive={$currentTabIndex === undefined} on:click={() => changeTab(undefined)}>
<span class="icon tableIcon"><TableIcon /></span>{#if width > 109}Table{/if}
</button>
{#if $currentState.tabs}
{#each $currentState.tabs as tab, index}
{#if $tabs}
{#each $tabs as tab, index}
<button class="sidebarButton" on:click={() => changeTab(index)}>
<SidebarTab tabObject={tab} active={$currentTabIndex === index} {width} />
</button>
Expand Down
Loading

0 comments on commit a07e893

Please sign in to comment.