Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zed Table #2626

Merged
merged 66 commits into from
Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
b57246c
Drop files onto the page
jameskerr Nov 23, 2022
59c1bea
Fix styles on preferences page
jameskerr Nov 23, 2022
5ede99a
Fix the default route
jameskerr Nov 23, 2022
d90d61c
Bring form higher when height is small
jameskerr Nov 28, 2022
cabda4d
Stablize styles
jameskerr Nov 28, 2022
41d3568
Lint
jameskerr Nov 29, 2022
93231e7
Linted and tested
jameskerr Nov 29, 2022
15b13ef
WIP
jameskerr Dec 1, 2022
24bf064
Kill subprocesses when the app quits
jameskerr Dec 6, 2022
65cec1d
WIP
jameskerr Dec 6, 2022
f6e5e6d
Merge branch 'main' into table-update
jameskerr Dec 8, 2022
852742f
SectionTab WIP
jameskerr Dec 8, 2022
b12c8d3
Section tabs looking good
jameskerr Dec 8, 2022
b129eca
Merge remote-tracking branch 'origin/main' into table-update
jameskerr Dec 8, 2022
ffcd280
Progress on expanding complex values
jameskerr Dec 10, 2022
8817759
WIP
jameskerr Dec 14, 2022
754db0f
Cell id helpers
jameskerr Dec 14, 2022
95bbc44
Autosize working, and sticky headers
jameskerr Dec 20, 2022
4db38e5
WIP
jameskerr Dec 20, 2022
324928d
Fixed that weird dragging bug
jameskerr Dec 20, 2022
69a6526
Nested Columns
jameskerr Dec 21, 2022
bd17607
Fix up some lint issues
jameskerr Dec 21, 2022
13620a3
Working well
jameskerr Dec 22, 2022
6dac43a
Sorts on the header menu work
jameskerr Dec 28, 2022
6e44c5f
Header menu finished
jameskerr Dec 28, 2022
97f2bc8
Add title to header cell
jameskerr Dec 28, 2022
eff2093
Infinite scroll is wired in
jameskerr Dec 29, 2022
8a5090a
Remove console
jameskerr Dec 29, 2022
4014451
Rerenders on load more
jameskerr Dec 29, 2022
a1122bf
core/menu
jameskerr Dec 30, 2022
dd694f8
Clean tests and lint
jameskerr Jan 5, 2023
f4d4bdd
Value expands and pages work
jameskerr Jan 9, 2023
506c39d
Column visibility done
jameskerr Jan 9, 2023
007d8ff
Columns button opens Columns Pane
jameskerr Jan 9, 2023
8d188dd
Add the value context menu
jameskerr Jan 11, 2023
b9b95f7
Polish columns pane
jameskerr Jan 11, 2023
2df6184
Expand header title
jameskerr Jan 11, 2023
b28cee5
Query Pool Button
jameskerr Jan 11, 2023
50665d4
Deleted unused code
jameskerr Jan 11, 2023
2455a13
Styled up the histogram and the new tab button
jameskerr Jan 11, 2023
965a983
Make the chart a bit higher
jameskerr Jan 11, 2023
d954ece
Custom Views
jameskerr Jan 12, 2023
5e961a5
Add the Path View to the inspector
jameskerr Jan 12, 2023
71d165e
Column Sort Indicators Work
jameskerr Jan 12, 2023
3433ad6
Non-record types
jameskerr Jan 12, 2023
e3220ab
Multi shapes view
jameskerr Jan 12, 2023
4ad73e7
Multiple shapes view
jameskerr Jan 19, 2023
944f79c
Memoize the query versions
jameskerr Jan 23, 2023
fa19795
Value pages and expanding working again
jameskerr Jan 24, 2023
f3fa469
Cleared out old column code
jameskerr Jan 24, 2023
8a44c46
Tests pass
jameskerr Jan 24, 2023
ad082c3
Export spec runs
jameskerr Jan 24, 2023
afff817
e2e tests working again:
jameskerr Jan 25, 2023
618562d
Don't overflow
jameskerr Jan 25, 2023
801bf4a
Merge remote-tracking branch 'origin/main' into table-update
jameskerr Jan 25, 2023
164c847
Lint
jameskerr Jan 25, 2023
14ab50d
Bare Views and Save Header Expanded State
jameskerr Jan 25, 2023
3fca790
Fix height bugs
jameskerr Jan 25, 2023
91421b3
Hide decorators
jameskerr Jan 25, 2023
f0e48cc
Open Detail Window
jameskerr Jan 25, 2023
7723a2d
Add click and double click to table
jameskerr Jan 25, 2023
ee252c5
Handle Unions
jameskerr Jan 25, 2023
7bd659b
Fix memo issue with fields
jameskerr Jan 25, 2023
c864da7
Expand/collapse/sharkfin buttons work
jameskerr Jan 26, 2023
4c3ed09
Remove big test csvs
jameskerr Jan 26, 2023
8ee8846
Remove comment
jameskerr Jan 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"@electron/remote": "^2.0.1",
"@js-joda/core": "^3.2.0",
"@reduxjs/toolkit": "^1.5.0",
"@tanstack/react-table": "^8.7.0",
"acorn": "^7.4.1",
"ajv": "^6.9.1",
"animejs": "^3.2.0",
Expand All @@ -145,6 +146,7 @@
"keytar": "^7.7.0",
"lodash": "^4.17.21",
"md5": "^2.2.1",
"memoize-one": "^6.0.0",
"moment": "^2.27.0",
"moment-timezone": "^0.5.31",
"mousetrap": "^1.6.5",
Expand All @@ -155,7 +157,7 @@
"polished": "^3.6.5",
"prismjs": "^1.25.0",
"react": "^18.0.0",
"react-arborist": "2.1.0",
"react-arborist": "2.2.0",
"react-dnd": "^14.0.5",
"react-dnd-html5-backend": "^14.0.2",
"react-dom": "^18.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/e2e-tests/helpers/test-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ export default class TestApp {

// TODO: this method is a wip, it still needs to wait for cells to populate first
async getViewerResults(includeHeaders = true): Promise<string[]> {
const fields = await this.mainWin.locator(".viewer .field-cell")
const fields = await this.mainWin.locator(".zed-table__cell")
let results = await fields.evaluateAll<string[], HTMLElement>((nodes) =>
nodes.map((n) => n.innerText.trim())
)
if (includeHeaders) {
const headers = await this.mainWin.locator(".viewer .header-cell")
const headers = await this.mainWin.locator(".zed-table__header-cell")
const headerResults = await headers.evaluateAll<string[], HTMLElement>(
(headerCells) => headerCells.map((hc) => hc.innerText.trim())
)
Expand Down
16 changes: 6 additions & 10 deletions packages/e2e-tests/tests/export.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ test.describe("Export tests", () => {
await app.createPool([
path.normalize(path.join(testDataDir(), "sample.tsv")),
])
await app.mainWin
.locator('#app-root button:above(:text("Query Pool"))')
.first()
.click()
await app.mainWin.getByRole("button", {name: "Query Pool"}).click()
await app.query("sort ts")
})

Expand All @@ -45,12 +42,11 @@ test.describe("Export tests", () => {
Promise.resolve({canceled: false, filePath})
}, file)

await app.mainWin
.locator('#app-root button:above(:text("Export"))')
.first()
.click()
await app.mainWin.getByRole("radio", {name: `${label}`}).click()
await app.mainWin.getByRole("button").filter({hasText: "Export"}).click()
const menu = app.mainWin.getByRole("list", {name: "resultsToolbarMenu"})
await menu.getByRole("button", {name: "Export"}).click()
const dialog = app.mainWin.getByRole("dialog")
await dialog.getByRole("radio", {name: `${label}`}).click()
await dialog.getByRole("button").filter({hasText: "Export"}).click()

await expect(
await app.mainWin.locator("text=Export Complete").first()
Expand Down
5 changes: 1 addition & 4 deletions packages/e2e-tests/tests/ingest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ test.describe("Ingest tests", () => {
await app.createPool([
path.normalize(path.join(testDataDir(), "sample.tsv")),
])
await app.mainWin
.locator('#app-root button:above(:text("Query Pool"))')
.first()
.click()
await app.mainWin.getByRole("button", {name: "Query Pool"}).click()
})

test.afterAll(async () => {
Expand Down
27 changes: 13 additions & 14 deletions packages/e2e-tests/tests/queries.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ test.describe("Query tests", () => {
await app.createPool([
path.normalize(path.join(testDataDir(), "sample.tsv")),
])
await app.mainWin
.locator('#app-root button:above(:text("Query Pool"))')
.first()
.click()
await app.mainWin.getByRole("button", {name: "Query Pool"}).click()
})

test.afterAll(async () => {
Expand All @@ -38,27 +35,28 @@ test.describe("Query tests", () => {
})

test("named queries' creation, modification, update/save, proper outdated status display", async () => {
const titleBar = app.mainWin.getByTestId("title-bar")
// creation
await app.mainWin.locator('button :text-is("Save")').click()
await app.mainWin
await titleBar.getByRole("button", {name: "Save"}).click()
await titleBar
.locator('[placeholder="Query name\\.\\.\\."]')
.fill("Test Query Name")
await app.mainWin.locator('button :text-is("Create")').click()
await titleBar.getByRole("button", {name: "Create"}).click()
await expect(await app.mainWin.locator("_react=HeadingSaved")).toBeVisible()
await expect(
await app.mainWin.locator('button :text-is("Test Query Name")')
await titleBar.getByRole("button", {name: "Test Query Name"})
).toBeVisible()

// modification
await app.query("4")
await expect(
await app.mainWin.locator('button :text-is("Test Query Name *")')
await titleBar.getByRole("button", {name: "Test Query Name *"})
).toBeVisible()

// update
await app.mainWin.locator('button :text-is("Save")').click()
await titleBar.getByRole("button", {name: "Save"}).click()
await expect(
await app.mainWin.locator('button :text-is("Test Query Name")')
await titleBar.getByRole("button", {name: "Test Query Name"})
).toBeVisible()

// outdated display
Expand All @@ -71,14 +69,15 @@ test.describe("Query tests", () => {
})

test("named query, save as => new named query", async () => {
await app.mainWin.locator('button :text-is("Save As")').click()
await app.mainWin
const titleBar = app.mainWin.getByTestId("title-bar")
await titleBar.getByRole("button", {name: "Save As"}).click()
await titleBar
.locator('[placeholder="Query name\\.\\.\\."]')
.fill("Another Test Query")
await app.mainWin
.locator('div[role="textbox"]')
.fill("another test query zed value")
await app.mainWin.locator('button :text-is("Create")').click()
await titleBar.getByRole("button", {name: "Create"}).click()
await expect(
await app.mainWin.locator('button :text-is("Another Test Query")')
).toBeVisible()
Expand Down
2 changes: 1 addition & 1 deletion packages/zealot/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {ResultStream} from "./query/result-stream"
import {DefaultContext, TypeDefs} from "./zed/context"
import * as zed from "./zed/index"
import * as zjson from "./zjson"

export * from "./test/factory"
export * from "./client/types"
export * from "./types"
export {
Expand Down
4 changes: 3 additions & 1 deletion packages/zealot/src/query/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class Channel extends EventEmitter {
this.emit("row", row)
}

addShape(id: number, type: zed.Type) {
addShape(id: number | string, type: zed.Type) {
this.shapesMap[id] = type
this.emit("shape", type)
}
Expand All @@ -34,6 +34,8 @@ export class Channel extends EventEmitter {
const value = this.stream.decode(json)
if ("id" in json.type && !this.hasShape(json.type.id)) {
this.addShape(json.type.id, value.type)
} else if (json.type.kind === "primitive") {
this.addShape(json.type.name, value.type)
}
this.addRow(value)
}
Expand Down
1 change: 0 additions & 1 deletion packages/zealot/src/query/result-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export class ResultStream {
}
}
})
return this._promise
}

private consumeLine(json: zjson.QueryObject) {
Expand Down
9 changes: 3 additions & 6 deletions packages/zealot/src/test/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ export function createRecord(object: {[key: string]: unknown}): zed.Record {
for (let name in object) {
fields.push(createField(name, object[name]))
}
const typeFields: zed.TypeField[] = fields.map((f) => ({
name: f.name,
type: f.value.type,
}))
const typeFields = fields.map((f) => new zed.TypeField(f.name, f.value.type))

// This could be more efficient
const type: TypeRecord = DefaultContext.lookupTypeRecord(typeFields)
Expand All @@ -28,7 +25,7 @@ export function createField(name: string, value: unknown): zed.Field {
}

export function createData(value: unknown): zed.Value {
if (value instanceof zed.Primitive) {
if (zed.isValue(value)) {
return value as zed.Value
}

Expand Down Expand Up @@ -56,7 +53,7 @@ export function createData(value: unknown): zed.Value {
return new zed.String(value)
}

if (isObject(value)) {
if (isObject(value) && value?.constructor === Object) {
return createRecord(value as {[k: string]: unknown})
}

Expand Down
7 changes: 5 additions & 2 deletions packages/zealot/src/zed/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import {TypeAlias} from "./types/type-alias"
import {TypeArray} from "./types/type-array"
import {TypeError} from "./types/type-error"
import {TypeMap} from "./types/type-map"
import {TypeField, TypeRecord} from "./types/type-record"
import {TypeRecord} from "./types/type-record"
import {TypeSet} from "./types/type-set"
import {TypeUnion} from "./types/type-union"
import {Type} from "./types/types"
import {Field} from "./values/field"
import {Value} from "./values/types"
import {TypeField} from "./types/type-field"

export type TypeDefs = {[key: string]: Type}

Expand Down Expand Up @@ -69,7 +70,9 @@ export class ZedContext {
lookupTypeRecord(fields: TypeField[] | null): TypeRecord {
const key = TypeRecord.stringify(fields)
if (key in this.typeByShape) {
return this.typeByShape[key] as TypeRecord
const record = this.typeByShape[key] as TypeRecord
record.fields = fields
return record
} else {
return this.alloc(key, new TypeRecord(fields))
}
Expand Down
8 changes: 4 additions & 4 deletions packages/zealot/src/zed/decode-stream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {isNull} from "lodash"
import * as zjson from "../zjson"
import {TypeDefs, ZedContext} from "./context"
import {TypeField} from "./types/type-field"
import {PrimitiveName} from "./types/type-primitives"
import {Type} from "./types/types"
import {getPrimitiveType} from "./utils/get-primitive-type"
Expand Down Expand Up @@ -50,10 +51,9 @@ export class DecodeStream {
return this.context.lookupTypeRecord(
isNull(obj.fields)
? null
: obj.fields.map(({name, type}) => ({
name,
type: this.decodeType(type),
}))
: obj.fields.map(({name, type}) => {
return new TypeField(name, this.decodeType(type))
})
)
default:
throw `Implement decoding: ${obj.kind}`
Expand Down
9 changes: 7 additions & 2 deletions packages/zealot/src/zed/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Type} from "./types/types"
import {Value} from "./values/types"
export type Any = Type | Value

export {ZedContext as Context} from "./context"
export {TypeAlias} from "./types/type-alias"
export {TypeArray} from "./types/type-array"
Expand All @@ -18,7 +18,8 @@ export {TypeIp} from "./types/type-ip"
export {TypeMap} from "./types/type-map"
export {TypeNet} from "./types/type-net"
export {TypeNull} from "./types/type-null"
export {TypeRecord, TypeField} from "./types/type-record"
export {TypeRecord, FieldData} from "./types/type-record"
export {TypeField} from "./types/type-field"
export {TypeSet} from "./types/type-set"
export {TypeString} from "./types/type-string"
export {TypeTime} from "./types/type-time"
Expand Down Expand Up @@ -76,3 +77,7 @@ export * from "./utils/is-string"
export * from "./utils/is-time"
export * from "./utils/is-type-alias"
export * from "./utils/true-type"
export * from "./utils/base-value"
export * from "./utils/is-container"
export * from "./utils/is-value"
export type Any = Type | Value
5 changes: 5 additions & 0 deletions packages/zealot/src/zed/types/type-field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {Type} from "./types"

export class TypeField {
constructor(public name: string, public type: Type) {}
}
9 changes: 3 additions & 6 deletions packages/zealot/src/zed/types/type-record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ import {trueType} from "../utils/true-type"
import {Field} from "../values/field"
import {Null} from "../values/null"
import {Record} from "../values/record"
import {TypeField} from "./type-field"
import {Type} from "./types"

export type TypeField = {
name: string
type: Type
}

export type FieldData = {name: string; type: Type}
export class TypeRecord implements Type {
kind = "record"

Expand All @@ -22,7 +19,7 @@ export class TypeRecord implements Type {
return !!this.fields?.find((f) => f.name === name)
}

static stringify(fields: TypeField[] | null) {
static stringify(fields: FieldData[] | null) {
if (isNull(fields)) return "null"
let s = "{"
let sep = ""
Expand Down
1 change: 1 addition & 0 deletions packages/zealot/src/zed/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export interface Type {
toString(): string
serialize(stream: EncodeStream): zjson.NoId<zjson.Type> | zjson.PrimitiveType
create(value: zjson.Value, stream: DecodeStream, parent?: Field): Value
kind: string
}
9 changes: 9 additions & 0 deletions packages/zealot/src/zed/utils/base-value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {Any} from ".."
import {Union} from "../values/union"

export function baseValue(value: Any | null): Any | null {
if (value instanceof Union) {
return baseValue(value.value)
}
return value
}
15 changes: 15 additions & 0 deletions packages/zealot/src/zed/utils/is-container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Record} from "../values/record"
import {Array} from "../values/array"
import {ZedMap} from "../values/map"
import {Set} from "../values/set"
import {Union} from "../values/union"
import {Error} from "../values/error"

const containers = [Record, Array, Set, Union, ZedMap, Error]

export function isContainer(value: unknown) {
for (let name of containers) {
if (value instanceof name) return true
}
return false
}
3 changes: 1 addition & 2 deletions packages/zealot/src/zed/utils/is-type-alias.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {TypeAlias} from "../types/type-alias"
import {Type} from "../types/types"

export function isTypeAlias(type: Type): type is TypeAlias {
export function isTypeAlias(type: unknown): type is TypeAlias {
return type instanceof TypeAlias
}
6 changes: 6 additions & 0 deletions packages/zealot/src/zed/utils/is-value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {isContainer} from "./is-container"
import {isPrimitive} from "./is-primitive"

export function isValue(value: unknown) {
return isPrimitive(value) || isContainer(value)
}
5 changes: 2 additions & 3 deletions packages/zealot/src/zed/utils/true-type.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import {Type} from "../types/types"
import {isTypeAlias} from "./is-type-alias"

export function trueType<T extends Type>(start: Type): T {
export function trueType(start: unknown) {
let t = start
while (isTypeAlias(t)) {
t = t.type
}
return t as T
return t
}
Empty file.
5 changes: 5 additions & 0 deletions packages/zealot/src/zed/values/field.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {zed} from "../.."
import {Record} from "./record"
import {Value} from "./types"

Expand Down Expand Up @@ -33,4 +34,8 @@ export class Field {
if (parent instanceof Record) return parent
else return null
}

get baseValue() {
return zed.baseValue(this.value)
}
}
Loading