From d14fd4d20a6e76ff40fb878599e3aea08c63d0d4 Mon Sep 17 00:00:00 2001 From: James Kerr Date: Mon, 15 Jul 2024 14:18:11 -0700 Subject: [PATCH 01/25] Renamed session to session-location --- apps/zui/src/domain/named-queries/handlers.ts | 4 ++-- apps/zui/src/domain/session/handlers/pins.ts | 4 ++-- apps/zui/src/domain/snapshots/handlers.ts | 4 ++-- apps/zui/src/models/active.ts | 4 ++-- apps/zui/src/models/{session.ts => session-location.ts} | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) rename apps/zui/src/models/{session.ts => session-location.ts} (94%) diff --git a/apps/zui/src/domain/named-queries/handlers.ts b/apps/zui/src/domain/named-queries/handlers.ts index f35d463bb..54359a134 100644 --- a/apps/zui/src/domain/named-queries/handlers.ts +++ b/apps/zui/src/domain/named-queries/handlers.ts @@ -2,7 +2,7 @@ import {createHandler} from "src/core/handlers" import {Active} from "src/models/active" import {EditorSnapshot} from "src/models/editor-snapshot" import {NamedQuery} from "src/models/named-query" -import {Session} from "src/models/session" +import {SessionLocation} from "src/models/session-location" /** * This handler is called when the user submits the form to name their @@ -36,6 +36,6 @@ export const show = createHandler((_, id: string, snapshotId?: string) => { ? EditorSnapshot.find(query.id, snapshotId) : query.lastSnapshot - Session.activateLastFocused() + SessionLocation.activateLastFocused() Active.session.navigate(snapshot, query) }) diff --git a/apps/zui/src/domain/session/handlers/pins.ts b/apps/zui/src/domain/session/handlers/pins.ts index 1e52928cc..9dbbe0755 100644 --- a/apps/zui/src/domain/session/handlers/pins.ts +++ b/apps/zui/src/domain/session/handlers/pins.ts @@ -9,7 +9,7 @@ import {submitSearch} from "src/domain/session/handlers" import {createHandler} from "src/core/handlers" import ZuiApi from "src/js/api/zui-api" import Selection from "src/js/state/Selection" -import {Session} from "src/models/session" +import {SessionLocation} from "src/models/session-location" import {Active} from "src/models/active" export const createPinFromEditor = createHandler( @@ -44,7 +44,7 @@ export const createFromPin = createHandler( export const setFromPin = createHandler( "session.setFromPin", ({dispatch}, value: string) => { - Session.activateLastFocused() + SessionLocation.activateLastFocused() dispatch(Editor.setFrom(value)) Active.session.navigate(Active.snapshot, Active.session.namedQuery) } diff --git a/apps/zui/src/domain/snapshots/handlers.ts b/apps/zui/src/domain/snapshots/handlers.ts index d89887fbb..cbe67c656 100644 --- a/apps/zui/src/domain/snapshots/handlers.ts +++ b/apps/zui/src/domain/snapshots/handlers.ts @@ -2,7 +2,7 @@ import {createHandler} from "src/core/handlers" import {Active} from "src/models/active" import {EditorSnapshot} from "src/models/editor-snapshot" import {NamedQuery} from "src/models/named-query" -import {Session} from "src/models/session" +import {SessionLocation} from "src/models/session-location" /** * This is called when you click on a session history entry. @@ -23,7 +23,7 @@ export const show = createHandler((ctx, args: Args) => { export const createAndShow = createHandler( (ctx, args: Partial) => { - Session.activateLastFocused() + SessionLocation.activateLastFocused() Active.session.navigate(new EditorSnapshot(args)) } ) diff --git a/apps/zui/src/models/active.ts b/apps/zui/src/models/active.ts index c80575c3d..b7fb06440 100644 --- a/apps/zui/src/models/active.ts +++ b/apps/zui/src/models/active.ts @@ -1,5 +1,5 @@ import {DomainModel} from "src/core/domain-model" -import {Session} from "./session" +import {SessionLocation} from "./session-location" import Current from "src/js/state/Current" import {EditorSnapshot} from "./editor-snapshot" import {BrowserTab} from "./browser-tab" @@ -16,7 +16,7 @@ export class Active extends DomainModel { static get session() { const params = this.select(Current.getQueryUrlParams) - return new Session({ + return new SessionLocation({ id: this.tab.attrs.id, parentId: params.queryId, snapshotId: params.version, diff --git a/apps/zui/src/models/session.ts b/apps/zui/src/models/session-location.ts similarity index 94% rename from apps/zui/src/models/session.ts rename to apps/zui/src/models/session-location.ts index 85ba6ce78..600b039fd 100644 --- a/apps/zui/src/models/session.ts +++ b/apps/zui/src/models/session-location.ts @@ -17,7 +17,7 @@ type Attrs = { snapshotId?: string } -export class Session extends DomainModel { +export class SessionLocation extends DomainModel { static activateLastFocused() { const tab = BrowserTab.orderBy("lastFocused", "desc").find((tab) => tab.matchesPath(queryVersion.path) @@ -25,7 +25,7 @@ export class Session extends DomainModel { if (tab) { tab.activate() } else { - Session.create().tab.activate() + SessionLocation.create().tab.activate() } } @@ -34,7 +34,7 @@ export class Session extends DomainModel { const now = new Date().toISOString() this.dispatch(SessionQueries.init(id)) BrowserTab.create({id, lastFocused: now}) - return new Session({id}) + return new SessionLocation({id}) } get hasUrl() { @@ -100,7 +100,7 @@ export class Session extends DomainModel { navigate(snapshot: EditorSnapshot, namedQuery?: NamedQuery) { const sessionSnapshot = snapshot.clone({parentId: this.id}) sessionSnapshot.save() - new Session({ + new SessionLocation({ id: this.id, parentId: namedQuery ? namedQuery.id : this.id, snapshotId: sessionSnapshot.id, From 7f6057398ddbac2f8757717fbcc28ad085fe7a1a Mon Sep 17 00:00:00 2001 From: James Kerr Date: Mon, 15 Jul 2024 16:12:54 -0700 Subject: [PATCH 02/25] Session Models Snapshot Models --- apps/zui/jest.config.js | 10 +++++ apps/zui/package.json | 1 + apps/zui/src/js/components/TabBar/AddTab.tsx | 6 +-- apps/zui/src/js/components/TabBar/TabBar.tsx | 2 +- .../js/components/TabBar/useTabController.ts | 4 -- .../src/js/initializers/init-domain-models.ts | 2 + apps/zui/src/js/state/Appearance/types.ts | 2 +- apps/zui/src/js/state/stores/root-reducer.ts | 4 ++ apps/zui/src/models/active.ts | 10 +++-- apps/zui/src/models/application-entity.ts | 8 ++++ apps/zui/src/models/browser-tab.ts | 4 ++ apps/zui/src/models/session.test.ts | 17 +++++++++ apps/zui/src/models/session.ts | 18 +++++++++ apps/zui/src/models/snapshot.ts | 38 +++++++++++++++++++ .../src/views/application/use-shortcuts.ts | 3 +- apps/zui/src/views/history-pane/index.tsx | 16 ++++++++ apps/zui/src/views/right-pane/index.tsx | 4 +- apps/zui/src/views/sessions-pane/index.tsx | 13 +++++++ apps/zui/src/views/sidebar/index.tsx | 3 ++ apps/zui/src/views/sidebar/menu.tsx | 1 + apps/zui/src/views/sidebar/plus-button.tsx | 4 +- yarn.lock | 26 +++++++++++++ 22 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 apps/zui/src/models/application-entity.ts create mode 100644 apps/zui/src/models/session.test.ts create mode 100644 apps/zui/src/models/session.ts create mode 100644 apps/zui/src/models/snapshot.ts create mode 100644 apps/zui/src/views/history-pane/index.tsx create mode 100644 apps/zui/src/views/sessions-pane/index.tsx diff --git a/apps/zui/jest.config.js b/apps/zui/jest.config.js index 91dd99219..8590394ae 100644 --- a/apps/zui/jest.config.js +++ b/apps/zui/jest.config.js @@ -7,11 +7,21 @@ const moduleNameMapper = pathsToModuleNameMapper(config.compilerOptions.paths, { prefix: "/../../", }) +const esModules = [ + "bullet", + "@reduxjs/toolkit", + "immer", + "redux", + "lodash-es", +].join("|") +// https://github.com/gravitational/teleport/issues/33810 + module.exports = { transform: { "^.+\\.(t|j)sx?$": ["@swc/jest"], ".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform", }, + transformIgnorePatterns: [`/node_modules/(?!${esModules})`], setupFiles: ["./src/test/unit/setup/before-env.ts"], setupFilesAfterEnv: ["./src/test/unit/setup/after-env.ts"], testEnvironmentOptions: { diff --git a/apps/zui/package.json b/apps/zui/package.json index 3e142526b..0b5deaadd 100644 --- a/apps/zui/package.json +++ b/apps/zui/package.json @@ -74,6 +74,7 @@ "ajv": "^6.9.1", "animejs": "^3.2.0", "brimcap": "brimdata/brimcap#v1.8.0", + "bullet": "../../../../jk/bullet", "chalk": "^4.1.0", "chevrotain": "^10.5.0", "chrono-node": "^2.5.0", diff --git a/apps/zui/src/js/components/TabBar/AddTab.tsx b/apps/zui/src/js/components/TabBar/AddTab.tsx index 7b5aee34d..32c84c0c3 100644 --- a/apps/zui/src/js/components/TabBar/AddTab.tsx +++ b/apps/zui/src/js/components/TabBar/AddTab.tsx @@ -1,5 +1,6 @@ import React from "react" import {IconButton} from "src/components/icon-button" +import {Session} from "src/models/session" import styled from "styled-components" const BG = styled.div` @@ -11,18 +12,17 @@ const BG = styled.div` ` type Props = { - onClick: () => void left: number } -export default function AddTab({onClick, left}: Props) { +export default function AddTab({left}: Props) { return ( Session.createWithTab()} /> ) diff --git a/apps/zui/src/js/components/TabBar/TabBar.tsx b/apps/zui/src/js/components/TabBar/TabBar.tsx index 380272924..689918e2f 100644 --- a/apps/zui/src/js/components/TabBar/TabBar.tsx +++ b/apps/zui/src/js/components/TabBar/TabBar.tsx @@ -112,7 +112,7 @@ export default function TabBar() { /> ) })} - + diff --git a/apps/zui/src/js/components/TabBar/useTabController.ts b/apps/zui/src/js/components/TabBar/useTabController.ts index cee6416b8..00b08436b 100644 --- a/apps/zui/src/js/components/TabBar/useTabController.ts +++ b/apps/zui/src/js/components/TabBar/useTabController.ts @@ -22,10 +22,6 @@ export default function (count: number, calcWidths: Function) { activeId, previewId: useSelector(Tabs.getPreview), - onAddClick() { - dispatch(Tabs.createQuerySession()) - }, - onRemoveClick(event: MouseEvent, id: string) { event.stopPropagation() removedByClick.current = true diff --git a/apps/zui/src/js/initializers/init-domain-models.ts b/apps/zui/src/js/initializers/init-domain-models.ts index cd29ca229..106c22f51 100644 --- a/apps/zui/src/js/initializers/init-domain-models.ts +++ b/apps/zui/src/js/initializers/init-domain-models.ts @@ -1,6 +1,8 @@ import {DomainModel} from "src/core/domain-model" import {Store} from "../state/types" +import {Entity} from "bullet" export function initDomainModels(args: {store: Store}) { DomainModel.store = args.store + Entity.store = args.store } diff --git a/apps/zui/src/js/state/Appearance/types.ts b/apps/zui/src/js/state/Appearance/types.ts index b1d25e443..37e2db396 100644 --- a/apps/zui/src/js/state/Appearance/types.ts +++ b/apps/zui/src/js/state/Appearance/types.ts @@ -1,3 +1,3 @@ export type HistoryView = "tree" | "linear" -export type SectionName = "pools" | "queries" | "history" +export type SectionName = "pools" | "queries" | "sessions" export type OpenMap = {[id: string]: boolean} diff --git a/apps/zui/src/js/state/stores/root-reducer.ts b/apps/zui/src/js/state/stores/root-reducer.ts index 64e9c0bb4..01977f444 100644 --- a/apps/zui/src/js/state/stores/root-reducer.ts +++ b/apps/zui/src/js/state/stores/root-reducer.ts @@ -21,6 +21,8 @@ import PoolSettings from "../PoolSettings" import Window from "../Window" import LoadDataForm from "../LoadDataForm" import Updates from "../Updates" +import {Session} from "src/models/session" +import {Snapshot} from "src/models/snapshot" const rootReducer = combineReducers({ appearance: Appearance.reducer, @@ -44,6 +46,8 @@ const rootReducer = combineReducers({ url: Url.reducer, window: Window.reducer, updates: Updates.reducer, + ...Session.slice, + ...Snapshot.slice, }) // A proof of concept. This would be a much nicer way to go diff --git a/apps/zui/src/models/active.ts b/apps/zui/src/models/active.ts index b7fb06440..8cd66d06b 100644 --- a/apps/zui/src/models/active.ts +++ b/apps/zui/src/models/active.ts @@ -1,12 +1,12 @@ import {DomainModel} from "src/core/domain-model" import {SessionLocation} from "./session-location" import Current from "src/js/state/Current" -import {EditorSnapshot} from "./editor-snapshot" import {BrowserTab} from "./browser-tab" import {Frame} from "./frame" import {getActiveTab} from "src/js/state/Tabs/selectors" import Editor from "src/js/state/Editor" import {Lake} from "./lake" +import {Snapshot} from "./snapshot" export class Active extends DomainModel { static get tab() { @@ -25,9 +25,11 @@ export class Active extends DomainModel { static get snapshot() { const params = this.select(Current.getQueryUrlParams) - - return new EditorSnapshot({ - parentId: params.queryId, + const sessionId = this.session.id + const queryId = sessionId === params.queryId ? null : params.queryId + return new Snapshot({ + sessionId, + queryId, ...this.select(Editor.getSnapshot), }) } diff --git a/apps/zui/src/models/application-entity.ts b/apps/zui/src/models/application-entity.ts new file mode 100644 index 000000000..aac0a03c2 --- /dev/null +++ b/apps/zui/src/models/application-entity.ts @@ -0,0 +1,8 @@ +import {Entity} from "bullet" +import {useSelector} from "react-redux" + +export class ApplicationEntity extends Entity { + static useAll() { + return useSelector(this.selectors.all) as any[] + } +} diff --git a/apps/zui/src/models/browser-tab.ts b/apps/zui/src/models/browser-tab.ts index f6b9797f6..a72e82196 100644 --- a/apps/zui/src/models/browser-tab.ts +++ b/apps/zui/src/models/browser-tab.ts @@ -22,6 +22,10 @@ export class BrowserTab extends DomainModel { }) } + static get count() { + return this.all.length + } + static orderBy(attr: keyof Attrs, direction: "asc" | "desc") { return orderBy(this.all, [(tab) => tab.attrs[attr]], [direction]) } diff --git a/apps/zui/src/models/session.test.ts b/apps/zui/src/models/session.test.ts new file mode 100644 index 000000000..601c46f39 --- /dev/null +++ b/apps/zui/src/models/session.test.ts @@ -0,0 +1,17 @@ +/** + * @jest-environment jsdom + */ + +import initTestStore from "src/test/unit/helpers/initTestStore" +import {Session} from "./session" +import {BrowserTab} from "./browser-tab" + +beforeEach(() => initTestStore()) + +test("new tab", () => { + expect(BrowserTab.count).toBe(1) + expect(Session.count).toBe(0) + Session.createWithTab() + expect(BrowserTab.count).toBe(2) + expect(Session.count).toBe(1) +}) diff --git a/apps/zui/src/models/session.ts b/apps/zui/src/models/session.ts new file mode 100644 index 000000000..8d8c366ce --- /dev/null +++ b/apps/zui/src/models/session.ts @@ -0,0 +1,18 @@ +import {BrowserTab} from "./browser-tab" +import {Snapshot} from "./snapshot" +import {ApplicationEntity} from "./application-entity" + +export class Session extends ApplicationEntity { + static attributes = { + name: [{type: String, default: null}], + } + + static createWithTab(attrs = {}) { + const session = this.create(attrs) + const tab = BrowserTab.create({id: session.id}) + const snapshot = Snapshot.create() + tab.activate() + tab.load(snapshot.pathname) + return session + } +} diff --git a/apps/zui/src/models/snapshot.ts b/apps/zui/src/models/snapshot.ts new file mode 100644 index 000000000..b9f71f059 --- /dev/null +++ b/apps/zui/src/models/snapshot.ts @@ -0,0 +1,38 @@ +import {queryPath} from "src/app/router/utils/paths" +import {ApplicationEntity} from "./application-entity" +import {SourceSet} from "./editor-snapshot/source-set" +import buildPin from "src/js/state/Editor/models/build-pin" + +export class Snapshot extends ApplicationEntity { + static attributes = { + value: [{type: String, default: ""}], + pins: [{type: Array /* item: Pin */, default: []}], + sessionId: [{type: String, default: null}], + queryId: [{type: String, default: null}], + } + + get pathname() { + return queryPath(this.parentId, this.id) + } + + get parentId() { + return this.queryId ?? this.sessionId + } + + get activePins() { + return this.pins + .filter((pin) => !pin.disabled) + .map((attrs) => buildPin(attrs)) + } + + get sourceSet() { + return new SourceSet( + this.activePins().map((pin) => pin.toZed()), + this.attrs.value + ) + } + + get queryText() { + return this.sourceSet.contents + } +} diff --git a/apps/zui/src/views/application/use-shortcuts.ts b/apps/zui/src/views/application/use-shortcuts.ts index b3775c579..4c9e150ef 100644 --- a/apps/zui/src/views/application/use-shortcuts.ts +++ b/apps/zui/src/views/application/use-shortcuts.ts @@ -4,6 +4,7 @@ import Mousetrap from "mousetrap" import Modal from "../../js/state/Modal" import Tabs from "../../js/state/Tabs" import {useDispatch} from "src/core/use-dispatch" +import {Session} from "src/models/session" export default function () { const dispatch = useDispatch() @@ -11,7 +12,7 @@ export default function () { const el = document.documentElement if (!el) throw new Error("No Document Element") const bindings = new Mousetrap(el) - .bind("mod+t", () => dispatch(Tabs.createQuerySession())) + .bind("mod+t", () => Session.createWithTab()) .bind("mod+w", (e) => { e.preventDefault() dispatch(Tabs.closeActive()) diff --git a/apps/zui/src/views/history-pane/index.tsx b/apps/zui/src/views/history-pane/index.tsx new file mode 100644 index 000000000..6375e12ab --- /dev/null +++ b/apps/zui/src/views/history-pane/index.tsx @@ -0,0 +1,16 @@ +import {Snapshot} from "src/models/snapshot" + +export function HistoryPane() { + const snapshots = Snapshot.useAll() + + return ( +
+

History

+
    + {snapshots.map((snapshot) => { + return
  • {snapshot.queryText}
  • + })} +
+
+ ) +} diff --git a/apps/zui/src/views/right-pane/index.tsx b/apps/zui/src/views/right-pane/index.tsx index c4d036867..c036ff424 100644 --- a/apps/zui/src/views/right-pane/index.tsx +++ b/apps/zui/src/views/right-pane/index.tsx @@ -5,7 +5,6 @@ import Layout from "src/js/state/Layout" import {DraggablePane} from "src/js/components/draggable-pane" import VersionsSection from "./versions-section" import AppErrorBoundary from "src/js/components/AppErrorBoundary" -import {HistorySection} from "./history/section" import {ColumnsPane} from "src/views/columns-pane" import Appearance from "src/js/state/Appearance" import Current from "src/js/state/Current" @@ -13,6 +12,7 @@ import {CorrelationsPane} from "../correlations-pane" import {Header} from "./header" import {RightPaneHandler} from "./right-pane-handler" import {DetailPane} from "../detail-pane" +import {HistoryPane} from "../history-pane" function Contents() { switch (useSelector(Layout.getCurrentPaneName)) { @@ -21,7 +21,7 @@ function Contents() { case "versions": return case "history": - return + return case "columns": return case "correlations": diff --git a/apps/zui/src/views/sessions-pane/index.tsx b/apps/zui/src/views/sessions-pane/index.tsx new file mode 100644 index 000000000..211574827 --- /dev/null +++ b/apps/zui/src/views/sessions-pane/index.tsx @@ -0,0 +1,13 @@ +import {Session} from "src/models/session" + +export function SessionsPane() { + const sessions = Session.useAll() + + return ( +
    + {sessions.map((session) => { + return
  • {session.id}
  • + })} +
+ ) +} diff --git a/apps/zui/src/views/sidebar/index.tsx b/apps/zui/src/views/sidebar/index.tsx index 40c7b9c56..0b124e524 100644 --- a/apps/zui/src/views/sidebar/index.tsx +++ b/apps/zui/src/views/sidebar/index.tsx @@ -11,6 +11,7 @@ import {Menu} from "./menu" import {SidebarToggleButton} from "./sidebar-toggle-button" import AppErrorBoundary from "src/js/components/AppErrorBoundary" import {Body} from "./body" +import {SessionsPane} from "../sessions-pane" const EmptyText = styled.div` ${(p) => p.theme.typography.labelNormal} @@ -26,6 +27,8 @@ const PaneSwitch = ({name}) => { return case "queries": return + case "sessions": + return default: return null } diff --git a/apps/zui/src/views/sidebar/menu.tsx b/apps/zui/src/views/sidebar/menu.tsx index f1cbded6e..67a234854 100644 --- a/apps/zui/src/views/sidebar/menu.tsx +++ b/apps/zui/src/views/sidebar/menu.tsx @@ -29,6 +29,7 @@ export function Menu() { options={[ makeOption("Pools", "pools"), makeOption("Queries", "queries"), + makeOption("Sessions", "sessions"), ]} /> diff --git a/apps/zui/src/views/sidebar/plus-button.tsx b/apps/zui/src/views/sidebar/plus-button.tsx index 89d6bb9a2..196fa45b5 100644 --- a/apps/zui/src/views/sidebar/plus-button.tsx +++ b/apps/zui/src/views/sidebar/plus-button.tsx @@ -6,10 +6,10 @@ import {useZuiApi} from "src/views/application/context" import {MenuItem, showContextMenu} from "src/core/menu" import {useDispatch} from "src/core/use-dispatch" import useLakeId from "src/app/router/hooks/use-lake-id" -import Tabs from "src/js/state/Tabs" import {Icon} from "src/components/icon" import {connectToLake} from "src/app/commands/connect-to-lake" import Modal from "src/js/state/Modal" +import {Session} from "src/models/session" export const Button = styled.button` color: white; @@ -50,7 +50,7 @@ export default function PlusButton() { const template: MenuItem[] = [ { label: "New Query Session", - click: () => dispatch(Tabs.createQuerySession()), + click: () => Session.createWithTab(), }, { label: "New Pool", diff --git a/yarn.lock b/yarn.lock index 0473e7388..9718c16ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6814,6 +6814,17 @@ __metadata: languageName: node linkType: hard +"bullet@file:../../../../jk/bullet::locator=zui%40workspace%3Aapps%2Fzui": + version: 0.0.1 + resolution: "bullet@file:../../../../jk/bullet#../../../../jk/bullet::hash=cbabb8&locator=zui%40workspace%3Aapps%2Fzui" + dependencies: + "@reduxjs/toolkit": ^2.2.5 + lodash-es: ^4.17.21 + pluralize: ^8.0.0 + checksum: 6a2a73598958c4edc052b69485cee3c83732558f1ba4be6b96e594ad6045ff2b24bacdacf88d0b4870bed134d0feef1c53bcc359a4e3ed645bb718d2c4fc0cdf + languageName: node + linkType: hard + "bundle-name@npm:^3.0.0": version: 3.0.0 resolution: "bundle-name@npm:3.0.0" @@ -12438,6 +12449,13 @@ __metadata: languageName: node linkType: hard +"lodash-es@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash-es@npm:4.17.21" + checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2 + languageName: node + linkType: hard + "lodash.debounce@npm:^4.0.8": version: 4.0.8 resolution: "lodash.debounce@npm:4.0.8" @@ -14427,6 +14445,13 @@ __metadata: languageName: node linkType: hard +"pluralize@npm:^8.0.0": + version: 8.0.0 + resolution: "pluralize@npm:8.0.0" + checksum: 08931d4a6a4a5561a7f94f67a31c17e6632cb21e459ab3ff4f6f629d9a822984cf8afef2311d2005fbea5d7ef26016ebb090db008e2d8bce39d0a9a9d218736e + languageName: node + linkType: hard + "polished@npm:^3.6.5": version: 3.6.5 resolution: "polished@npm:3.6.5" @@ -18322,6 +18347,7 @@ __metadata: ajv: ^6.9.1 animejs: ^3.2.0 brimcap: "brimdata/brimcap#v1.8.0" + bullet: ../../../../jk/bullet chalk: ^4.1.0 chevrotain: ^10.5.0 chrono-node: ^2.5.0 From 212cc034d39b96b94a551ce15cf3278aebcbade6 Mon Sep 17 00:00:00 2001 From: James Kerr Date: Thu, 18 Jul 2024 13:37:40 -0700 Subject: [PATCH 03/25] No Typescript Errors --- apps/zui/src/js/components/TabBar/AddTab.tsx | 6 +-- apps/zui/src/js/components/TabBar/TabBar.tsx | 2 +- .../js/components/TabBar/useTabController.ts | 4 ++ apps/zui/src/models/active.ts | 10 ++-- apps/zui/src/models/application-entity.ts | 7 +-- apps/zui/src/models/session.ts | 37 +++++++++++--- apps/zui/src/models/snapshot.ts | 51 +++++++++++++++---- .../src/views/application/use-shortcuts.ts | 3 +- apps/zui/src/views/sidebar/plus-button.tsx | 4 +- apps/zui/tsconfig.json | 2 +- apps/zui/types/bullet.d.ts | 31 +++++++++++ yarn.lock | 4 +- 12 files changed, 121 insertions(+), 40 deletions(-) create mode 100644 apps/zui/types/bullet.d.ts diff --git a/apps/zui/src/js/components/TabBar/AddTab.tsx b/apps/zui/src/js/components/TabBar/AddTab.tsx index 32c84c0c3..7b5aee34d 100644 --- a/apps/zui/src/js/components/TabBar/AddTab.tsx +++ b/apps/zui/src/js/components/TabBar/AddTab.tsx @@ -1,6 +1,5 @@ import React from "react" import {IconButton} from "src/components/icon-button" -import {Session} from "src/models/session" import styled from "styled-components" const BG = styled.div` @@ -12,17 +11,18 @@ const BG = styled.div` ` type Props = { + onClick: () => void left: number } -export default function AddTab({left}: Props) { +export default function AddTab({onClick, left}: Props) { return ( Session.createWithTab()} + click={onClick} /> ) diff --git a/apps/zui/src/js/components/TabBar/TabBar.tsx b/apps/zui/src/js/components/TabBar/TabBar.tsx index 689918e2f..380272924 100644 --- a/apps/zui/src/js/components/TabBar/TabBar.tsx +++ b/apps/zui/src/js/components/TabBar/TabBar.tsx @@ -112,7 +112,7 @@ export default function TabBar() { /> ) })} - + diff --git a/apps/zui/src/js/components/TabBar/useTabController.ts b/apps/zui/src/js/components/TabBar/useTabController.ts index 00b08436b..cee6416b8 100644 --- a/apps/zui/src/js/components/TabBar/useTabController.ts +++ b/apps/zui/src/js/components/TabBar/useTabController.ts @@ -22,6 +22,10 @@ export default function (count: number, calcWidths: Function) { activeId, previewId: useSelector(Tabs.getPreview), + onAddClick() { + dispatch(Tabs.createQuerySession()) + }, + onRemoveClick(event: MouseEvent, id: string) { event.stopPropagation() removedByClick.current = true diff --git a/apps/zui/src/models/active.ts b/apps/zui/src/models/active.ts index 8cd66d06b..7bfdacdd6 100644 --- a/apps/zui/src/models/active.ts +++ b/apps/zui/src/models/active.ts @@ -6,7 +6,7 @@ import {Frame} from "./frame" import {getActiveTab} from "src/js/state/Tabs/selectors" import Editor from "src/js/state/Editor" import {Lake} from "./lake" -import {Snapshot} from "./snapshot" +import {EditorSnapshot} from "./editor-snapshot" export class Active extends DomainModel { static get tab() { @@ -25,11 +25,9 @@ export class Active extends DomainModel { static get snapshot() { const params = this.select(Current.getQueryUrlParams) - const sessionId = this.session.id - const queryId = sessionId === params.queryId ? null : params.queryId - return new Snapshot({ - sessionId, - queryId, + + return new EditorSnapshot({ + parentId: params.queryId, ...this.select(Editor.getSnapshot), }) } diff --git a/apps/zui/src/models/application-entity.ts b/apps/zui/src/models/application-entity.ts index aac0a03c2..ea7427676 100644 --- a/apps/zui/src/models/application-entity.ts +++ b/apps/zui/src/models/application-entity.ts @@ -1,8 +1,3 @@ import {Entity} from "bullet" -import {useSelector} from "react-redux" -export class ApplicationEntity extends Entity { - static useAll() { - return useSelector(this.selectors.all) as any[] - } -} +export class ApplicationEntity extends Entity {} diff --git a/apps/zui/src/models/session.ts b/apps/zui/src/models/session.ts index 8d8c366ce..1761d2426 100644 --- a/apps/zui/src/models/session.ts +++ b/apps/zui/src/models/session.ts @@ -1,18 +1,43 @@ +import {AttributeTypes} from "bullet" import {BrowserTab} from "./browser-tab" import {Snapshot} from "./snapshot" import {ApplicationEntity} from "./application-entity" -export class Session extends ApplicationEntity { - static attributes = { - name: [{type: String, default: null}], - } +const schema = { + name: {type: String, default: null as string}, +} + +type Attributes = AttributeTypes + +export class Session extends ApplicationEntity { + static schema = schema - static createWithTab(attrs = {}) { + name: Attributes["name"] + + static createWithTab(attrs: Partial = {}) { const session = this.create(attrs) const tab = BrowserTab.create({id: session.id}) - const snapshot = Snapshot.create() + const snapshot = Snapshot.create({sessionId: session.id}) tab.activate() tab.load(snapshot.pathname) return session } + + get snapshots() { + return Snapshot.where({sessionId: this.id}) + } + + get snapshot() { + const snapshots = this.snapshots + return snapshots[snapshots.length - 1] + } + + get tab() { + return BrowserTab.find(this.id) + } + + navigate(snapshot: Snapshot) { + snapshot.save() + this.tab.load(snapshot.pathname) + } } diff --git a/apps/zui/src/models/snapshot.ts b/apps/zui/src/models/snapshot.ts index b9f71f059..f8faaa9ad 100644 --- a/apps/zui/src/models/snapshot.ts +++ b/apps/zui/src/models/snapshot.ts @@ -1,15 +1,27 @@ import {queryPath} from "src/app/router/utils/paths" -import {ApplicationEntity} from "./application-entity" import {SourceSet} from "./editor-snapshot/source-set" import buildPin from "src/js/state/Editor/models/build-pin" +// import {isEqual} from "lodash" +// import {Validator} from "./editor-snapshot/validator" +import {QueryPin} from "src/js/state/Editor/types" +import {ApplicationEntity} from "./application-entity" +import {AttributeTypes} from "bullet" -export class Snapshot extends ApplicationEntity { - static attributes = { - value: [{type: String, default: ""}], - pins: [{type: Array /* item: Pin */, default: []}], - sessionId: [{type: String, default: null}], - queryId: [{type: String, default: null}], - } +const schema = { + value: {type: String, default: "" as string}, + pins: {type: Array /* item: Pin */, default: [] as QueryPin[]}, + sessionId: {type: String, default: null as string}, + queryId: {type: String, default: null as string}, +} + +type Attributes = AttributeTypes + +export class Snapshot extends ApplicationEntity { + static schema = schema + pins: Attributes["pins"] + queryId: Attributes["queryId"] + sessionId: Attributes["sessionId"] + value: Attributes["value"] get pathname() { return queryPath(this.parentId, this.id) @@ -24,15 +36,32 @@ export class Snapshot extends ApplicationEntity { .filter((pin) => !pin.disabled) .map((attrs) => buildPin(attrs)) } - + // get sourceSet() { return new SourceSet( - this.activePins().map((pin) => pin.toZed()), - this.attrs.value + this.activePins.map((pin) => pin.toZed()), + this.value ) } get queryText() { return this.sourceSet.contents } + // + // equals(other: Snapshot) { + // return isEqual(this.pins, other.pins) && isEqual(this.value, other.value) + // } + // + // clone(attrs: Partial) { + // return new Snapshot({...this.attributes, ...attrs}) + // } + + // public validator = new Validator() + // async isValid() { + // return this.validator.validate(this) + // } + + // get errors() { + // return this.validator.errors + // } } diff --git a/apps/zui/src/views/application/use-shortcuts.ts b/apps/zui/src/views/application/use-shortcuts.ts index 4c9e150ef..b3775c579 100644 --- a/apps/zui/src/views/application/use-shortcuts.ts +++ b/apps/zui/src/views/application/use-shortcuts.ts @@ -4,7 +4,6 @@ import Mousetrap from "mousetrap" import Modal from "../../js/state/Modal" import Tabs from "../../js/state/Tabs" import {useDispatch} from "src/core/use-dispatch" -import {Session} from "src/models/session" export default function () { const dispatch = useDispatch() @@ -12,7 +11,7 @@ export default function () { const el = document.documentElement if (!el) throw new Error("No Document Element") const bindings = new Mousetrap(el) - .bind("mod+t", () => Session.createWithTab()) + .bind("mod+t", () => dispatch(Tabs.createQuerySession())) .bind("mod+w", (e) => { e.preventDefault() dispatch(Tabs.closeActive()) diff --git a/apps/zui/src/views/sidebar/plus-button.tsx b/apps/zui/src/views/sidebar/plus-button.tsx index 196fa45b5..89d6bb9a2 100644 --- a/apps/zui/src/views/sidebar/plus-button.tsx +++ b/apps/zui/src/views/sidebar/plus-button.tsx @@ -6,10 +6,10 @@ import {useZuiApi} from "src/views/application/context" import {MenuItem, showContextMenu} from "src/core/menu" import {useDispatch} from "src/core/use-dispatch" import useLakeId from "src/app/router/hooks/use-lake-id" +import Tabs from "src/js/state/Tabs" import {Icon} from "src/components/icon" import {connectToLake} from "src/app/commands/connect-to-lake" import Modal from "src/js/state/Modal" -import {Session} from "src/models/session" export const Button = styled.button` color: white; @@ -50,7 +50,7 @@ export default function PlusButton() { const template: MenuItem[] = [ { label: "New Query Session", - click: () => Session.createWithTab(), + click: () => dispatch(Tabs.createQuerySession()), }, { label: "New Pool", diff --git a/apps/zui/tsconfig.json b/apps/zui/tsconfig.json index 2f0ebcd9a..59848f2a4 100644 --- a/apps/zui/tsconfig.json +++ b/apps/zui/tsconfig.json @@ -9,7 +9,7 @@ "strict": false, "moduleResolution": "node", "resolveJsonModule": true, - "typeRoots": ["node_modules/@types"], + "typeRoots": ["node_modules/@types", "types"], "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, diff --git a/apps/zui/types/bullet.d.ts b/apps/zui/types/bullet.d.ts new file mode 100644 index 000000000..81166ffc6 --- /dev/null +++ b/apps/zui/types/bullet.d.ts @@ -0,0 +1,31 @@ +import {Reducer, Store} from "@reduxjs/toolkit" + +declare module "bullet" { + type Schema = {[name: string]: {type: any; default?: any}} + type AttributeTypes = { + [Key in keyof T]: T[Key]["default"] + } + + export class Entity { + static store: Store + static schema: Schema + static count: number + static slice: {[name: string]: Reducer} + static useAll(this: new (a: Partial) => T): T[] + static where( + this: new (a: Partial) => T, + attributes: Partial + ): T[] + static find(this: new (a: Partial) => T, id: string): T + static create( + this: new (a: Partial) => T, + attributes: Partial + ): T + id: string + createdAt: Date + updatedAt: Date + attributes: A + constructor(attributes: Partial) + save(): boolean + } +} diff --git a/yarn.lock b/yarn.lock index 9718c16ed..7da361262 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6816,12 +6816,12 @@ __metadata: "bullet@file:../../../../jk/bullet::locator=zui%40workspace%3Aapps%2Fzui": version: 0.0.1 - resolution: "bullet@file:../../../../jk/bullet#../../../../jk/bullet::hash=cbabb8&locator=zui%40workspace%3Aapps%2Fzui" + resolution: "bullet@file:../../../../jk/bullet#../../../../jk/bullet::hash=b4fc85&locator=zui%40workspace%3Aapps%2Fzui" dependencies: "@reduxjs/toolkit": ^2.2.5 lodash-es: ^4.17.21 pluralize: ^8.0.0 - checksum: 6a2a73598958c4edc052b69485cee3c83732558f1ba4be6b96e594ad6045ff2b24bacdacf88d0b4870bed134d0feef1c53bcc359a4e3ed645bb718d2c4fc0cdf + checksum: 55bcfaa0c50a0e6146d3ccdd141a3da84a0d18cd72de9510d0a8e7ac4bff15fe856c812b924904b92760b09cf6a5b5ed3e0c5db442107d5fce96aeb758db99ca languageName: node linkType: hard From c295ce4103c7d26dd61b466e58c21fc6e3af6cca Mon Sep 17 00:00:00 2001 From: James Kerr Date: Thu, 18 Jul 2024 13:40:21 -0700 Subject: [PATCH 04/25] Revert "Renamed session to session-location" This reverts commit d14fd4d20a6e76ff40fb878599e3aea08c63d0d4. --- apps/zui/src/domain/named-queries/handlers.ts | 4 +- apps/zui/src/domain/session/handlers/pins.ts | 4 +- apps/zui/src/domain/snapshots/handlers.ts | 4 +- apps/zui/src/models/active.ts | 4 +- apps/zui/src/models/session-location.ts | 126 ------------------ apps/zui/src/models/session.ts | 124 +++++++++++++++++ 6 files changed, 132 insertions(+), 134 deletions(-) delete mode 100644 apps/zui/src/models/session-location.ts diff --git a/apps/zui/src/domain/named-queries/handlers.ts b/apps/zui/src/domain/named-queries/handlers.ts index 54359a134..f35d463bb 100644 --- a/apps/zui/src/domain/named-queries/handlers.ts +++ b/apps/zui/src/domain/named-queries/handlers.ts @@ -2,7 +2,7 @@ import {createHandler} from "src/core/handlers" import {Active} from "src/models/active" import {EditorSnapshot} from "src/models/editor-snapshot" import {NamedQuery} from "src/models/named-query" -import {SessionLocation} from "src/models/session-location" +import {Session} from "src/models/session" /** * This handler is called when the user submits the form to name their @@ -36,6 +36,6 @@ export const show = createHandler((_, id: string, snapshotId?: string) => { ? EditorSnapshot.find(query.id, snapshotId) : query.lastSnapshot - SessionLocation.activateLastFocused() + Session.activateLastFocused() Active.session.navigate(snapshot, query) }) diff --git a/apps/zui/src/domain/session/handlers/pins.ts b/apps/zui/src/domain/session/handlers/pins.ts index 9dbbe0755..1e52928cc 100644 --- a/apps/zui/src/domain/session/handlers/pins.ts +++ b/apps/zui/src/domain/session/handlers/pins.ts @@ -9,7 +9,7 @@ import {submitSearch} from "src/domain/session/handlers" import {createHandler} from "src/core/handlers" import ZuiApi from "src/js/api/zui-api" import Selection from "src/js/state/Selection" -import {SessionLocation} from "src/models/session-location" +import {Session} from "src/models/session" import {Active} from "src/models/active" export const createPinFromEditor = createHandler( @@ -44,7 +44,7 @@ export const createFromPin = createHandler( export const setFromPin = createHandler( "session.setFromPin", ({dispatch}, value: string) => { - SessionLocation.activateLastFocused() + Session.activateLastFocused() dispatch(Editor.setFrom(value)) Active.session.navigate(Active.snapshot, Active.session.namedQuery) } diff --git a/apps/zui/src/domain/snapshots/handlers.ts b/apps/zui/src/domain/snapshots/handlers.ts index cbe67c656..d89887fbb 100644 --- a/apps/zui/src/domain/snapshots/handlers.ts +++ b/apps/zui/src/domain/snapshots/handlers.ts @@ -2,7 +2,7 @@ import {createHandler} from "src/core/handlers" import {Active} from "src/models/active" import {EditorSnapshot} from "src/models/editor-snapshot" import {NamedQuery} from "src/models/named-query" -import {SessionLocation} from "src/models/session-location" +import {Session} from "src/models/session" /** * This is called when you click on a session history entry. @@ -23,7 +23,7 @@ export const show = createHandler((ctx, args: Args) => { export const createAndShow = createHandler( (ctx, args: Partial) => { - SessionLocation.activateLastFocused() + Session.activateLastFocused() Active.session.navigate(new EditorSnapshot(args)) } ) diff --git a/apps/zui/src/models/active.ts b/apps/zui/src/models/active.ts index 7bfdacdd6..bfec5d82a 100644 --- a/apps/zui/src/models/active.ts +++ b/apps/zui/src/models/active.ts @@ -1,5 +1,5 @@ import {DomainModel} from "src/core/domain-model" -import {SessionLocation} from "./session-location" +import {Session} from "./session" import Current from "src/js/state/Current" import {BrowserTab} from "./browser-tab" import {Frame} from "./frame" @@ -16,7 +16,7 @@ export class Active extends DomainModel { static get session() { const params = this.select(Current.getQueryUrlParams) - return new SessionLocation({ + return new Session({ id: this.tab.attrs.id, parentId: params.queryId, snapshotId: params.version, diff --git a/apps/zui/src/models/session-location.ts b/apps/zui/src/models/session-location.ts deleted file mode 100644 index 600b039fd..000000000 --- a/apps/zui/src/models/session-location.ts +++ /dev/null @@ -1,126 +0,0 @@ -import {queryPath} from "src/app/router/utils/paths" -import {DomainModel} from "src/core/domain-model" -import Inspector from "src/js/state/Inspector" -import Table from "src/js/state/Table" -import Selection from "src/js/state/Selection" -import {EditorSnapshot} from "./editor-snapshot" -import {SessionHistory} from "./session-history" -import {NamedQuery} from "./named-query" -import {BrowserTab} from "./browser-tab" -import SessionQueries from "src/js/state/SessionQueries" -import {nanoid} from "@reduxjs/toolkit" -import {queryVersion} from "src/app/router/routes" - -type Attrs = { - id: string - parentId?: string - snapshotId?: string -} - -export class SessionLocation extends DomainModel { - static activateLastFocused() { - const tab = BrowserTab.orderBy("lastFocused", "desc").find((tab) => - tab.matchesPath(queryVersion.path) - ) - if (tab) { - tab.activate() - } else { - SessionLocation.create().tab.activate() - } - } - - static create() { - const id = nanoid() - const now = new Date().toISOString() - this.dispatch(SessionQueries.init(id)) - BrowserTab.create({id, lastFocused: now}) - return new SessionLocation({id}) - } - - get hasUrl() { - return !!this.parentId && !!this.snapshotId - } - - get id() { - return this.attrs.id - } - - get parentId() { - return this.attrs.parentId - } - - get snapshotId() { - return this.attrs.snapshotId - } - - get pathname() { - return queryPath(this.parentId, this.snapshotId) - } - - get snapshot() { - let snapshot = EditorSnapshot.find(this.id, this.snapshotId) - if (snapshot) { - return snapshot - } else { - console.warn( - "Did not find snapshot on the session, falling back to named query snapshot" - ) - return EditorSnapshot.find(this.attrs.parentId, this.attrs.snapshotId) // remove after some time has gone by - } - } - - get snapshots() { - return EditorSnapshot.where({parentId: this.id}) - } - - get history() { - return new SessionHistory({id: this.id}) - } - - get hasNamedQuery() { - return this.parentId && this.id !== this.parentId - } - - get namedQuery() { - return this.hasNamedQuery ? NamedQuery.find(this.parentId) : null - } - - get isModified() { - return ( - this.hasNamedQuery && - !!this.namedQuery && - this.snapshot.equals(this.namedQuery.lastSnapshot) - ) - } - - get tab() { - return BrowserTab.find(this.id) - } - - navigate(snapshot: EditorSnapshot, namedQuery?: NamedQuery) { - const sessionSnapshot = snapshot.clone({parentId: this.id}) - sessionSnapshot.save() - new SessionLocation({ - id: this.id, - parentId: namedQuery ? namedQuery.id : this.id, - snapshotId: sessionSnapshot.id, - }).load() - } - - load() { - this.reset() - this.tab.load(this.pathname) - } - - pushHistory() { - if (!this.history.contains(this.parentId, this.snapshotId)) { - this.history.push(this.parentId, this.snapshotId) - } - } - - reset() { - this.dispatch(Selection.reset()) - this.dispatch(Table.setScrollPosition({top: 0, left: 0})) - this.dispatch(Inspector.setScrollPosition({top: 0, left: 0})) - } -} diff --git a/apps/zui/src/models/session.ts b/apps/zui/src/models/session.ts index 1761d2426..5fe0704ce 100644 --- a/apps/zui/src/models/session.ts +++ b/apps/zui/src/models/session.ts @@ -1,3 +1,4 @@ +<<<<<<< HEAD import {AttributeTypes} from "bullet" import {BrowserTab} from "./browser-tab" import {Snapshot} from "./snapshot" @@ -30,14 +31,137 @@ export class Session extends ApplicationEntity { get snapshot() { const snapshots = this.snapshots return snapshots[snapshots.length - 1] +======= +import {queryPath} from "src/app/router/utils/paths" +import {DomainModel} from "src/core/domain-model" +import Inspector from "src/js/state/Inspector" +import Table from "src/js/state/Table" +import Selection from "src/js/state/Selection" +import {EditorSnapshot} from "./editor-snapshot" +import {SessionHistory} from "./session-history" +import {NamedQuery} from "./named-query" +import {BrowserTab} from "./browser-tab" +import SessionQueries from "src/js/state/SessionQueries" +import {nanoid} from "@reduxjs/toolkit" +import {queryVersion} from "src/app/router/routes" + +type Attrs = { + id: string + parentId?: string + snapshotId?: string +} + +export class Session extends DomainModel { + static activateLastFocused() { + const tab = BrowserTab.orderBy("lastFocused", "desc").find((tab) => + tab.matchesPath(queryVersion.path) + ) + if (tab) { + tab.activate() + } else { + Session.create().tab.activate() + } + } + + static create() { + const id = nanoid() + const now = new Date().toISOString() + this.dispatch(SessionQueries.init(id)) + BrowserTab.create({id, lastFocused: now}) + return new Session({id}) + } + + get hasUrl() { + return !!this.parentId && !!this.snapshotId + } + + get id() { + return this.attrs.id + } + + get parentId() { + return this.attrs.parentId + } + + get snapshotId() { + return this.attrs.snapshotId + } + + get pathname() { + return queryPath(this.parentId, this.snapshotId) + } + + get snapshot() { + let snapshot = EditorSnapshot.find(this.id, this.snapshotId) + if (snapshot) { + return snapshot + } else { + console.warn( + "Did not find snapshot on the session, falling back to named query snapshot" + ) + return EditorSnapshot.find(this.attrs.parentId, this.attrs.snapshotId) // remove after some time has gone by + } + } + + get snapshots() { + return EditorSnapshot.where({parentId: this.id}) + } + + get history() { + return new SessionHistory({id: this.id}) + } + + get hasNamedQuery() { + return this.parentId && this.id !== this.parentId + } + + get namedQuery() { + return this.hasNamedQuery ? NamedQuery.find(this.parentId) : null + } + + get isModified() { + return ( + this.hasNamedQuery && + !!this.namedQuery && + this.snapshot.equals(this.namedQuery.lastSnapshot) + ) +>>>>>>> parent of d14fd4d20 (Renamed session to session-location) } get tab() { return BrowserTab.find(this.id) } +<<<<<<< HEAD navigate(snapshot: Snapshot) { snapshot.save() this.tab.load(snapshot.pathname) +======= + navigate(snapshot: EditorSnapshot, namedQuery?: NamedQuery) { + const sessionSnapshot = snapshot.clone({parentId: this.id}) + sessionSnapshot.save() + new Session({ + id: this.id, + parentId: namedQuery ? namedQuery.id : this.id, + snapshotId: sessionSnapshot.id, + }).load() + } + + load() { + this.reset() + this.tab.load(this.pathname) + } + + pushHistory() { + if (!this.history.contains(this.parentId, this.snapshotId)) { + this.history.push(this.parentId, this.snapshotId) + } + } + + reset() { + this.dispatch(Selection.reset()) + this.dispatch(Table.setScrollPosition({top: 0, left: 0})) + this.dispatch(Inspector.setScrollPosition({top: 0, left: 0})) +>>>>>>> parent of d14fd4d20 (Renamed session to session-location) } } From 59d6d3637e66ef635c17d0a79224dde06853638f Mon Sep 17 00:00:00 2001 From: James Kerr Date: Thu, 18 Jul 2024 13:40:44 -0700 Subject: [PATCH 05/25] Revert --- apps/zui/src/models/session.ts | 41 ---------------------------------- 1 file changed, 41 deletions(-) diff --git a/apps/zui/src/models/session.ts b/apps/zui/src/models/session.ts index 5fe0704ce..85ba6ce78 100644 --- a/apps/zui/src/models/session.ts +++ b/apps/zui/src/models/session.ts @@ -1,37 +1,3 @@ -<<<<<<< HEAD -import {AttributeTypes} from "bullet" -import {BrowserTab} from "./browser-tab" -import {Snapshot} from "./snapshot" -import {ApplicationEntity} from "./application-entity" - -const schema = { - name: {type: String, default: null as string}, -} - -type Attributes = AttributeTypes - -export class Session extends ApplicationEntity { - static schema = schema - - name: Attributes["name"] - - static createWithTab(attrs: Partial = {}) { - const session = this.create(attrs) - const tab = BrowserTab.create({id: session.id}) - const snapshot = Snapshot.create({sessionId: session.id}) - tab.activate() - tab.load(snapshot.pathname) - return session - } - - get snapshots() { - return Snapshot.where({sessionId: this.id}) - } - - get snapshot() { - const snapshots = this.snapshots - return snapshots[snapshots.length - 1] -======= import {queryPath} from "src/app/router/utils/paths" import {DomainModel} from "src/core/domain-model" import Inspector from "src/js/state/Inspector" @@ -125,18 +91,12 @@ export class Session extends DomainModel { !!this.namedQuery && this.snapshot.equals(this.namedQuery.lastSnapshot) ) ->>>>>>> parent of d14fd4d20 (Renamed session to session-location) } get tab() { return BrowserTab.find(this.id) } -<<<<<<< HEAD - navigate(snapshot: Snapshot) { - snapshot.save() - this.tab.load(snapshot.pathname) -======= navigate(snapshot: EditorSnapshot, namedQuery?: NamedQuery) { const sessionSnapshot = snapshot.clone({parentId: this.id}) sessionSnapshot.save() @@ -162,6 +122,5 @@ export class Session extends DomainModel { this.dispatch(Selection.reset()) this.dispatch(Table.setScrollPosition({top: 0, left: 0})) this.dispatch(Inspector.setScrollPosition({top: 0, left: 0})) ->>>>>>> parent of d14fd4d20 (Renamed session to session-location) } } From a8dec34c11785d0896f954a8e36c841aee28c481 Mon Sep 17 00:00:00 2001 From: James Kerr Date: Fri, 19 Jul 2024 11:02:18 -0700 Subject: [PATCH 06/25] Create a QuerySession entity --- apps/zui/src/models/application-entity.ts | 5 ++++- apps/zui/src/models/query-session.ts | 12 ++++++++++++ apps/zui/src/views/sessions-pane/index.tsx | 4 ++-- yarn.lock | 4 ++-- 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 apps/zui/src/models/query-session.ts diff --git a/apps/zui/src/models/application-entity.ts b/apps/zui/src/models/application-entity.ts index ea7427676..a3c792e3c 100644 --- a/apps/zui/src/models/application-entity.ts +++ b/apps/zui/src/models/application-entity.ts @@ -1,3 +1,6 @@ import {Entity} from "bullet" +import {useSelector} from "react-redux" -export class ApplicationEntity extends Entity {} +export class ApplicationEntity extends Entity { + static useSelector = useSelector +} diff --git a/apps/zui/src/models/query-session.ts b/apps/zui/src/models/query-session.ts new file mode 100644 index 000000000..296c5c2df --- /dev/null +++ b/apps/zui/src/models/query-session.ts @@ -0,0 +1,12 @@ +import {AttributeTypes} from "bullet" +import {ApplicationEntity} from "./application-entity" + +const schema = { + name: {type: String, default: null as string}, +} + +type Attributes = AttributeTypes + +export class QuerySession extends ApplicationEntity { + static schema = schema +} diff --git a/apps/zui/src/views/sessions-pane/index.tsx b/apps/zui/src/views/sessions-pane/index.tsx index 211574827..edfabeb09 100644 --- a/apps/zui/src/views/sessions-pane/index.tsx +++ b/apps/zui/src/views/sessions-pane/index.tsx @@ -1,7 +1,7 @@ -import {Session} from "src/models/session" +import {QuerySession} from "src/models/query-session" export function SessionsPane() { - const sessions = Session.useAll() + const sessions = QuerySession.useAll() return (