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

Release version v1.0.0-111 #2116

Merged
merged 32 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
76cad8e
Merge pull request #2115 from undb-io/main
nichenqin Oct 24, 2024
a402fe6
chore: add @tailwindcss/typography
nichenqin Oct 24, 2024
f5ac9bd
feat: add basic formula parser
nichenqin Oct 24, 2024
13c236a
feat: add formula input
nichenqin Oct 28, 2024
261cd14
chore: move FormulaCursorVisitor to frontend
nichenqin Oct 28, 2024
c927eb3
feat: parse formula as sqlite
nichenqin Oct 28, 2024
1c6ed83
chore: fix type isuue
nichenqin Oct 28, 2024
34ac772
chore: refactor
nichenqin Oct 28, 2024
fb6c3f0
test: add some tests
nichenqin Oct 28, 2024
0039826
chore: ci add test
nichenqin Oct 28, 2024
b4ef228
feat: add some formula
nichenqin Oct 29, 2024
75269d0
feat: add formula metadata
nichenqin Oct 29, 2024
e536b11
feat: add formula metadata
nichenqin Oct 29, 2024
ce9c464
test: update snapshot
nichenqin Oct 29, 2024
16639d1
feat: add string forumlas
nichenqin Oct 29, 2024
6ee468b
test: add formula test
nichenqin Oct 29, 2024
7ffac74
feat: add compare operation function call
nichenqin Oct 29, 2024
48f0031
test: add some formula test
nichenqin Oct 29, 2024
78a4364
feat: add some formula
nichenqin Oct 29, 2024
234a579
test: add some formula test
nichenqin Oct 29, 2024
e81d364
feat: add json extract formula
nichenqin Oct 29, 2024
9bf84ef
test: add json extract formula parser
nichenqin Oct 29, 2024
b773718
chore: add formula editor
nichenqin Oct 29, 2024
cfadc30
feat: insert formula variable
nichenqin Oct 30, 2024
30f7e5a
fix: fix generated formula
nichenqin Oct 30, 2024
7f2ef9e
feat: formula field
nichenqin Oct 30, 2024
3887227
feat: support auto increament
nichenqin Oct 30, 2024
ce03017
chore: formula editor key map
nichenqin Oct 30, 2024
df3c10f
feat: update formula
nichenqin Oct 30, 2024
6688155
feat: support to filter formula
nichenqin Oct 30, 2024
b1ceece
feat: support formula field aggregate
nichenqin Oct 30, 2024
5ce658e
Prepare release v1.0.0-111
web-flow Oct 30, 2024
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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ jobs:
- name: Install dependencies
run: bun install

- name: Run tests
run: bun test

- name: Build
run: bun run build

11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## v1.0.0-111


### 🚀 Enhancements

- Support formula field aggregate ([b1ceece](https://github.com/undb-io/undb/commit/b1ceece))

### ❤️ Contributors

- Nichenqin ([@nichenqin](http://github.com/nichenqin))

## v1.0.0-110

## v1.0.0-109
Expand Down
7 changes: 7 additions & 0 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@sveltejs/adapter-static": "^3.0.5",
"@sveltejs/kit": "^2.7.1",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@tailwindcss/typography": "^0.5.15",
"@tanstack/eslint-plugin-query": "^5.59.7",
"@types/eslint": "^8.56.12",
"@types/lodash.unzip": "^3.4.9",
Expand All @@ -31,6 +32,7 @@
"@typescript-eslint/parser": "^8.10.0",
"@undb/commands": "workspace:*",
"@undb/domain": "workspace:*",
"@undb/formula": "workspace:*",
"@undb/i18n": "workspace:*",
"@undb/openapi": "workspace:*",
"@undb/queries": "workspace:*",
Expand Down Expand Up @@ -73,11 +75,16 @@
"type-fest": "^4.26.1",
"typescript": "^5.6.3",
"vite": "^5.4.9",
"vite-plugin-node-polyfills": "^0.22.0",
"vitest": "^2.1.3",
"xlsx": "^0.18.5"
},
"type": "module",
"dependencies": {
"@codemirror/commands": "^6.7.1",
"@codemirror/language": "^6.10.3",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.34.1",
"@formkit/auto-animate": "^0.8.2",
"@internationalized/date": "^3.5.6",
"@svelte-put/clickoutside": "^3.0.2",
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Field {
defaultValue: JSON
display: Boolean
id: ID!
metadata: JSON
name: String!
option: JSON
type: FieldType!
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import * as Tabs from "$lib/components/ui/tabs"
import { getTable } from "$lib/store/table.store"
import { invalidate } from "$app/navigation"
import {
filterAggregateField,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ query GetDashboardWidgetShareTable($shareId: ID!, $tableId: ID!) {
display
constraint
option
metadata
}

views {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ query GetDashboardWidgetTable($tableId: ID!) {
display
constraint
option
metadata
}

views {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import ButtonFieldOption from "./button-field-option.svelte"
import DurationFieldOption from "./duration-field-option.svelte"
import PercentageFieldOption from "./percentage-field-option.svelte"
import FormulaFieldOption from "./formula-field-option.svelte"

export let constraint: IFieldConstraint | undefined
export let option: any | undefined
Expand Down Expand Up @@ -47,6 +48,7 @@
date: DateFieldOption,
duration: DurationFieldOption,
percentage: PercentageFieldOption,
formula: FormulaFieldOption,
}

export let type: NoneSystemFieldType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ query GetForeignTableQuery($tableId: ID!) {
display
constraint
option
metadata
}
views {
id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
import { Label } from "$lib/components/ui/label/index.js"
import FormulaEditor from "$lib/components/formula/formula-editor.svelte"
import { FormulaField, type IFormulaFieldOption } from "@undb/table"

export let option: IFormulaFieldOption = {
fn: "",
}

export let field: FormulaField | undefined = undefined
</script>

<div class="space-y-2">
<div class="space-y-1">
<Label for="Formula" class="text-xs font-normal">Formula</Label>
</div>
<FormulaEditor bind:value={option.fn} {field} />
</div>
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
<script lang="ts">
import type { LongTextField } from "@undb/table"

export let value: string | undefined = undefined
export let placeholder: string | undefined = undefined

export let field: LongTextField
</script>

{#if !value}
<div>
{placeholder || ""}
</div>
{:else}
<div class={$$restProps.class}>{value}</div>
<div class={$$restProps.class}>
{#if field.allowRichText}
<article class="prose-sm max-w-full">
{@html value}
</article>
{:else}
{value}
{/if}
</div>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ query GetRollupForeignTables($tableId: ID!, $fieldId: ID!) {
constraint
option
display
metadata
}
views {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,39 @@
is_not_empty: null,
}

$: formula = {}

$: if (field?.type === "formula") {
if (field.returnType === "number") {
formula = {
eq: NumberInput,
neq: NumberInput,
gt: NumberInput,
gte: NumberInput,
lt: NumberInput,
lte: NumberInput,
is_empty: null,
is_not_empty: null,
}
} else if (field.returnType === "boolean") {
formula = {
is_true: null,
is_false: null,
}
} else if (field.returnType === "string") {
formula = {
eq: Input,
neq: Input,
contains: Input,
does_not_contain: Input,
starts_with: Input,
ends_with: Input,
is_empty: null,
is_not_empty: null,
}
}
}

$: filterFieldInput = {
string,
number,
Expand All @@ -289,6 +322,7 @@
url,
longText,
duration,
formula,
percentage,
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ query GetForeignTable($tableId: ID!) {
display
constraint
option
metadata
}

views {
Expand Down
117 changes: 117 additions & 0 deletions apps/frontend/src/lib/components/formula/formula-cursor.visitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {
AbstractParseTreeVisitor,
AddSubExprContext,
AndExprContext,
ArgumentListContext,
ComparisonExprContext,
ExpressionContext,
FormulaContext,
FormulaParserVisitor,
FunctionCallContext,
FunctionExprContext,
MulDivModExprContext,
NotExprContext,
OrExprContext,
type ParseTree,
VariableContext,
} from "@undb/formula"

export class FormulaCursorVisitor extends AbstractParseTreeVisitor<void> implements FormulaParserVisitor<void> {
private pathNodes: ParseTree[] = []
private variables: Set<string> = new Set()
public readonly targetPosition: number

constructor(position: number) {
super()
this.targetPosition = position
}

public hasAggumentList(): boolean {
return this.pathNodes.some((node) => node instanceof ArgumentListContext)
}

public hasFunctionCall(): boolean {
return this.pathNodes.some((node) => node instanceof FunctionCallContext)
}

public getNearestFunctionNode() {
for (let i = this.pathNodes.length - 1; i >= 0; i--) {
const node = this.pathNodes[i]
if (node instanceof FunctionCallContext) {
return node
}
}
return null
}

public getFunctionName(): string | undefined {
const functionCall = this.getNearestFunctionNode()
return functionCall?.IDENTIFIER()?.text
}

protected defaultResult(): void {
return undefined
}

public getPathNodes() {
return this.pathNodes
}

visitPositionInRange(ctx: ExpressionContext) {
if (!ctx.start || !ctx.stop) return

const start = ctx.start.startIndex
const stop = ctx.stop.stopIndex
const isPositionWithinRange = start <= this.targetPosition && stop >= this.targetPosition

if (isPositionWithinRange) {
this.pathNodes.push(ctx)
this.visitChildren(ctx)
}
}

visitFormula(ctx: FormulaContext) {
this.visitPositionInRange(ctx)
}

visitComparisonExpr(ctx: ComparisonExprContext) {
this.visitPositionInRange(ctx)
}

visitAndExpr(ctx: AndExprContext) {
this.visitPositionInRange(ctx)
}

visitOrExpr(ctx: OrExprContext) {
this.visitPositionInRange(ctx)
}

visitNotExpr(ctx: NotExprContext) {
this.visitPositionInRange(ctx)
}

visitMulDivModExpr(ctx: MulDivModExprContext) {
this.visitPositionInRange(ctx)
}

visitAddSubExpr(ctx: AddSubExprContext) {
this.visitPositionInRange(ctx)
}

visitFunctionExpr(ctx: FunctionExprContext) {
this.visitPositionInRange(ctx)
}

visitFunctionCall(ctx: FunctionCallContext) {
this.visitPositionInRange(ctx)
}

visitArgumentList(ctx: ArgumentListContext) {
this.visitPositionInRange(ctx)
}

visitVariable(ctx: VariableContext) {
this.variables.add(ctx.IDENTIFIER().text)
this.visitPositionInRange(ctx)
}
}
Loading
Loading