Skip to content

Commit

Permalink
feat: user me filter (#322)
Browse files Browse the repository at this point in the history
* feat: user field support filter `Me`

* fix: selection filter user 'Me'

* fix: `sqlite` dateRangeOfMonths agg func

* refactor: remove queryUserId param use `cls` user

---------

Co-authored-by: pengap <[email protected]>
  • Loading branch information
Pengap and Pengap authored Jan 9, 2024
1 parent 01b28f6 commit 8e8152a
Show file tree
Hide file tree
Showing 79 changed files with 4,189 additions and 3,447 deletions.
18 changes: 10 additions & 8 deletions .github/workflows/docker-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3

- name: Login to Alibaba Cloud Docker Registry
run: docker login --username=${{ secrets.ALI_DOCKER_USERNAME }} registry.cn-beijing.aliyuncs.com --password=${{ secrets.ALI_DOCKER_PASSWORD }}

- name: Build and push Docker image
run: |
docker build -t registry.cn-beijing.aliyuncs.com/bieber/teable:${GITHUB_SHA} -f dockers/teable/Dockerfile .
docker push registry.cn-beijing.aliyuncs.com/bieber/teable:${GITHUB_SHA}
# Tag the built image with 'latest' label
docker tag registry.cn-beijing.aliyuncs.com/bieber/teable:${GITHUB_SHA} registry.cn-beijing.aliyuncs.com/bieber/teable:latest
# Push the 'latest' tagged image
docker push registry.cn-beijing.aliyuncs.com/bieber/teable:latest
# --platform linux/amd64,linux/arm64
docker buildx build \
--cache-from type=registry,ref=registry.cn-beijing.aliyuncs.com/bieber/teable:build-cache \
--cache-to type=registry,ref=registry.cn-beijing.aliyuncs.com/bieber/teable:build-cache,mode=max \
--file dockers/teable/Dockerfile \
--tag registry.cn-beijing.aliyuncs.com/bieber/teable:latest \
--tag registry.cn-beijing.aliyuncs.com/bieber/teable:${GITHUB_SHA} \
--push .
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ pnpm-debug.log*
# IDE
.idea/*
!.idea/modules.xml
!.idea/nextjs-monorepo-example.iml
.project
.classpath
*.launch
Expand Down
13 changes: 0 additions & 13 deletions .ncurc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,8 @@

# Add here exclusions on packages if any
reject: [
'vitest',
'@vitest/coverage-v8',
'@vitest/coverage-istanbul',
'@vitest/ui',

'vite-plugin-svgr',

'@remix-run/dev',
'@remix-run/eslint-config',
'@remix-run/node',
'@remix-run/react',
'@remix-run/serve',
'@vercel/remix',
'remix',

# Too early cause in esm
'is-port-reachable',
'nanoid',
Expand Down
35 changes: 22 additions & 13 deletions apps/nestjs-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@
},
"devDependencies": {
"@faker-js/faker": "8.3.1",
"@nestjs/cli": "10.2.1",
"@nestjs/cli": "10.3.0",
"@nestjs/testing": "10.3.0",
"@swc/core": "1.3.101",
"@teable-group/eslint-config-bases": "workspace:^",
"@types/bcrypt": "5.0.2",
"@types/cookie": "0.6.0",
Expand All @@ -62,20 +61,20 @@
"@types/lodash": "4.14.202",
"@types/markdown-it": "13.0.7",
"@types/mime-types": "2.1.4",
"@types/minio": "^7.1.1",
"@types/minio": "7.1.1",
"@types/multer": "1.4.11",
"@types/node": "18.18.2",
"@types/node-fetch": "2.6.10",
"@types/nodemailer": "6.4.14",
"@types/passport-jwt": "3.0.13",
"@types/passport-jwt": "4.0.0",
"@types/passport-local": "1.0.38",
"@types/qs": "6.9.11",
"@types/sharedb": "3.3.8",
"@types/ws": "8.5.10",
"copy-webpack-plugin": "11.0.0",
"cross-env": "7.0.3",
"dotenv-flow": "4.1.0",
"dotenv-flow-cli": "1.0.0",
"dotenv-flow-cli": "1.1.1",
"es-check": "7.1.1",
"eslint": "8.56.0",
"eslint-config-next": "13.0.2",
Expand All @@ -90,15 +89,15 @@
"ts-node": "10.9.2",
"typescript": "5.3.3",
"unplugin-swc": "1.4.4",
"vite-tsconfig-paths": "4.2.2",
"vite-tsconfig-paths": "4.2.3",
"vitest": "1.1.0",
"vitest-mock-extended": "1.3.1",
"webpack": "5.89.0"
},
"dependencies": {
"@nestjs-modules/mailer": "1.10.3",
"@nestjs/axios": "3.0.1",
"@nestjs/cache-manager": "^2.1.1",
"@nestjs/cache-manager": "2.2.0",
"@nestjs/common": "10.3.0",
"@nestjs/config": "3.1.1",
"@nestjs/core": "10.3.0",
Expand All @@ -110,16 +109,26 @@
"@nestjs/swagger": "7.1.17",
"@nestjs/terminus": "10.2.0",
"@nestjs/websockets": "10.3.0",
"@opentelemetry/api": "1.7.0",
"@opentelemetry/context-async-hooks": "1.19.0",
"@opentelemetry/exporter-trace-otlp-proto": "0.46.0",
"@opentelemetry/instrumentation-express": "0.34.1",
"@opentelemetry/instrumentation-http": "0.46.0",
"@opentelemetry/instrumentation-pino": "0.34.5",
"@opentelemetry/resources": "1.19.0",
"@opentelemetry/sdk-node": "0.46.0",
"@opentelemetry/semantic-conventions": "1.19.0",
"@prisma/client": "5.7.1",
"@prisma/instrumentation": "5.7.1",
"@teable-group/common-i18n": "workspace:^",
"@teable-group/core": "workspace:^",
"@teable-group/db-main-prisma": "workspace:^",
"@teable-group/openapi": "workspace:^",
"@teamwork/websocket-json-stream": "2.0.0",
"ajv": "8.12.0",
"axios": "1.6.3",
"axios": "1.6.5",
"bcrypt": "5.1.1",
"cache-manager": "^5.3.2",
"cache-manager": "5.3.2",
"class-transformer": "0.5.1",
"class-validator": "0.14.0",
"cookie": "0.6.0",
Expand All @@ -132,23 +141,23 @@
"helmet": "7.1.0",
"is-port-reachable": "3.1.0",
"joi": "17.11.0",
"json-rules-engine": "6.1.2",
"json-rules-engine": "6.5.0",
"jsonpath-plus": "7.2.0",
"knex": "3.0.1",
"lodash": "4.17.21",
"markdown-it": "14.0.0",
"markdown-it-sanitizer": "0.4.3",
"mime-types": "2.1.35",
"minio": "^7.1.3",
"minio": "7.1.3",
"multer": "1.4.5-lts.1",
"nanoid": "3.3.6",
"nest-knexjs": "0.0.19",
"nestjs-cls": "3.6.0",
"nestjs-pino": "3.5.0",
"nestjs-pino": "4.0.0",
"nestjs-redoc": "2.2.2",
"next": "13.0.2",
"node-fetch": "2.7.0",
"nodemailer": "6.9.7",
"nodemailer": "6.9.8",
"passport": "0.7.0",
"passport-jwt": "4.0.1",
"passport-local": "1.0.0",
Expand Down
4 changes: 4 additions & 0 deletions apps/nestjs-backend/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { RedocModule } from 'nestjs-redoc';
import { AppModule } from './app.module';
import type { ISecurityWebConfig, ISwaggerConfig } from './configs/bootstrap.config';
import { GlobalExceptionFilter } from './filter/global-exception.filter';
import otelSDK from './tracing';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare const module: any;

Expand Down Expand Up @@ -62,6 +64,8 @@ export async function setUpAppMiddleware(app: INestApplication, configService: C
}

export async function bootstrap() {
otelSDK.start();

const app = await NestFactory.create(AppModule, { bufferLogs: true });
const configService = app.get(ConfigService);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { InternalServerErrorException, Logger } from '@nestjs/common';
import { StatisticsFunc } from '@teable-group/core';
import type { Knex } from 'knex';
import type { IFieldInstance } from '../../features/field/model/factory';
import type { IAggregationFunctionInterface } from './aggregation-function.interface';

export abstract class AbstractAggregationFunction implements IAggregationFunctionInterface {
private logger = new Logger(AbstractAggregationFunction.name);

protected tableColumnRef: string;

constructor(
protected readonly knex: Knex,
protected readonly dbTableName: string,
protected readonly field: IFieldInstance
) {
const { dbFieldName } = this.field;

this.tableColumnRef = `${this.dbTableName}.${dbFieldName}`;
}

compiler(builderClient: Knex.QueryBuilder, aggFunc: StatisticsFunc) {
const functionHandlers = {
[StatisticsFunc.Empty]: this.empty,
[StatisticsFunc.Filled]: this.filled,
[StatisticsFunc.Unique]: this.unique,
[StatisticsFunc.Max]: this.max,
[StatisticsFunc.Min]: this.min,
[StatisticsFunc.Sum]: this.sum,
[StatisticsFunc.Average]: this.average,
[StatisticsFunc.Checked]: this.checked,
[StatisticsFunc.UnChecked]: this.unChecked,
[StatisticsFunc.PercentEmpty]: this.percentEmpty,
[StatisticsFunc.PercentFilled]: this.percentFilled,
[StatisticsFunc.PercentUnique]: this.percentUnique,
[StatisticsFunc.PercentChecked]: this.percentChecked,
[StatisticsFunc.PercentUnChecked]: this.percentUnChecked,
[StatisticsFunc.EarliestDate]: this.earliestDate,
[StatisticsFunc.LatestDate]: this.latestDate,
[StatisticsFunc.DateRangeOfDays]: this.dateRangeOfDays,
[StatisticsFunc.DateRangeOfMonths]: this.dateRangeOfMonths,
[StatisticsFunc.TotalAttachmentSize]: this.totalAttachmentSize,
};
const chosenHandler = functionHandlers[aggFunc].bind(this);

if (!chosenHandler) {
throw new InternalServerErrorException(`Unknown function ${aggFunc} for aggregation`);
}

const { id: fieldId, isMultipleCellValue } = this.field;

let rawSql: string = chosenHandler();

if (isMultipleCellValue) {
const joinTable = `${fieldId}_mcv`;

builderClient.with(`${fieldId}_mcv`, this.knex.raw(rawSql));
builderClient.joinRaw(`, ${this.knex.ref(joinTable)}`);

rawSql = `MAX(${this.knex.ref(`${joinTable}.value`)})`;
}

return builderClient.select(this.knex.raw(`${rawSql} AS ??`, [`${fieldId}_${aggFunc}`]));
}

empty(): string {
return this.knex.raw(`COUNT(*) - COUNT(??)`, [this.tableColumnRef]).toQuery();
}

filled(): string {
return this.knex.raw(`COUNT(??)`, [this.tableColumnRef]).toQuery();
}

unique(): string {
return this.knex.raw(`COUNT(DISTINCT ??)`, [this.tableColumnRef]).toQuery();
}

max(): string {
return this.knex.raw(`MAX(??)`, [this.tableColumnRef]).toQuery();
}

min(): string {
return this.knex.raw(`MIN(??)`, [this.tableColumnRef]).toQuery();
}

sum(): string {
return this.knex.raw(`SUM(??)`, [this.tableColumnRef]).toQuery();
}

average(): string {
return this.knex.raw(`AVG(??)`, [this.tableColumnRef]).toQuery();
}

checked(): string {
return this.filled();
}

unChecked(): string {
return this.empty();
}

percentEmpty(): string {
return this.knex
.raw(`((COUNT(*) - COUNT(??)) * 1.0 / COUNT(*)) * 100`, [this.tableColumnRef])
.toQuery();
}

percentFilled(): string {
return this.knex.raw(`(COUNT(??) * 1.0 / COUNT(*)) * 100`, [this.tableColumnRef]).toQuery();
}

percentUnique(): string {
return this.knex
.raw(`(COUNT(DISTINCT ??) * 1.0 / COUNT(*)) * 100`, [this.tableColumnRef])
.toQuery();
}

percentChecked(): string {
return this.percentFilled();
}

percentUnChecked(): string {
return this.percentEmpty();
}

earliestDate(): string {
return this.min();
}

latestDate(): string {
return this.max();
}

abstract dateRangeOfDays(): string;

abstract dateRangeOfMonths(): string;

abstract totalAttachmentSize(): string;
}
Loading

0 comments on commit 8e8152a

Please sign in to comment.