mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 03:02:19 +08:00
Compare commits
16 Commits
v1.8.0-alp
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
3387366f1e | ||
|
88cb9884f6 | ||
|
22cd39552f | ||
|
026baab241 | ||
|
d1ff280d9f | ||
|
88591454ec | ||
|
3c555e9fc0 | ||
|
6afcbffdec | ||
|
8d91e1fded | ||
|
940002a876 | ||
|
a4eb026ea4 | ||
|
74f3fd8132 | ||
|
4dcf934b15 | ||
|
17195c788d | ||
|
d538cd7db7 | ||
|
a9bd6f7844 |
@ -48,6 +48,14 @@ DB_PASSWORD=nocobase
|
|||||||
# DB_LOGGING=on
|
# DB_LOGGING=on
|
||||||
# DB_UNDERSCORED=false
|
# DB_UNDERSCORED=false
|
||||||
|
|
||||||
|
# @see https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-constructor-constructor
|
||||||
|
# DB_POOL_MAX=5
|
||||||
|
# DB_POOL_MIN=0
|
||||||
|
# DB_POOL_IDLE=10000
|
||||||
|
# DB_POOL_ACQUIRE=60000
|
||||||
|
# DB_POOL_EVICT=1000
|
||||||
|
# DB_POOL_MAX_USES=0
|
||||||
|
|
||||||
# sqlite only
|
# sqlite only
|
||||||
# DB_STORAGE=storage/db/nocobase.sqlite
|
# DB_STORAGE=storage/db/nocobase.sqlite
|
||||||
|
|
||||||
|
240
.github/workflows/e2e.yml
vendored
240
.github/workflows/e2e.yml
vendored
@ -274,7 +274,7 @@ jobs:
|
|||||||
|
|
||||||
- run: npx playwright install chromium --with-deps
|
- run: npx playwright install chromium --with-deps
|
||||||
- name: Test with postgres
|
- name: Test with postgres
|
||||||
run: yarn e2e p-test --match 'packages/**/{plugin-workflow,plugin-workflow-*}/**/__e2e__/**/*.test.ts' --ignore 'packages/**/plugin-workflow-approval/**/__e2e__/**/*.test.ts'
|
run: yarn e2e p-test --match 'packages/**/{plugin-workflow,plugin-workflow-*}/**/__e2e__/**/*.test.ts' --ignore 'packages/**/plugin-workflow-approval/**/__e2e__/**/*.test.ts' --ignore 'packages/**/plugin-workflow-manual/**/__e2e__/**/*.test.ts'
|
||||||
env:
|
env:
|
||||||
__E2E__: true
|
__E2E__: true
|
||||||
APP_ENV: production
|
APP_ENV: production
|
||||||
@ -297,131 +297,131 @@ jobs:
|
|||||||
|
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
plugin-workflow-approval:
|
# plugin-workflow-approval:
|
||||||
name: plugin-workflow-approval
|
# name: plugin-workflow-approval
|
||||||
needs: build
|
# needs: build
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
container: node:20
|
# container: node:20
|
||||||
services:
|
# services:
|
||||||
# Label used to access the service container
|
# # Label used to access the service container
|
||||||
postgres:
|
# postgres:
|
||||||
# Docker Hub image
|
# # Docker Hub image
|
||||||
image: postgres:11
|
# image: postgres:11
|
||||||
# Provide the password for postgres
|
# # Provide the password for postgres
|
||||||
env:
|
# env:
|
||||||
POSTGRES_USER: nocobase
|
# POSTGRES_USER: nocobase
|
||||||
POSTGRES_PASSWORD: password
|
# POSTGRES_PASSWORD: password
|
||||||
# Set health checks to wait until postgres has started
|
# # Set health checks to wait until postgres has started
|
||||||
options: >-
|
# options: >-
|
||||||
--health-cmd pg_isready
|
# --health-cmd pg_isready
|
||||||
--health-interval 10s
|
# --health-interval 10s
|
||||||
--health-timeout 5s
|
# --health-timeout 5s
|
||||||
--health-retries 5
|
# --health-retries 5
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/create-github-app-token@v1
|
# - uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
# id: app-token
|
||||||
with:
|
# with:
|
||||||
app-id: ${{ vars.NOCOBASE_APP_ID }}
|
# app-id: ${{ vars.NOCOBASE_APP_ID }}
|
||||||
private-key: ${{ secrets.NOCOBASE_APP_PRIVATE_KEY }}
|
# private-key: ${{ secrets.NOCOBASE_APP_PRIVATE_KEY }}
|
||||||
repositories: nocobase,pro-plugins,plugin-workflow-approval
|
# repositories: nocobase,pro-plugins,plugin-workflow-approval
|
||||||
skip-token-revoke: true
|
# skip-token-revoke: true
|
||||||
- uses: actions/checkout@v4
|
# - uses: actions/checkout@v4
|
||||||
- name: Checkout pro-plugins
|
# - name: Checkout pro-plugins
|
||||||
continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
# continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
||||||
uses: actions/checkout@v4
|
# uses: actions/checkout@v4
|
||||||
with:
|
# with:
|
||||||
repository: nocobase/pro-plugins
|
# repository: nocobase/pro-plugins
|
||||||
ref: main
|
# ref: main
|
||||||
path: packages/pro-plugins
|
# path: packages/pro-plugins
|
||||||
fetch-depth: 0
|
# fetch-depth: 0
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
# token: ${{ steps.app-token.outputs.token }}
|
||||||
- name: Checkout plugin-workflow-approval
|
# - name: Checkout plugin-workflow-approval
|
||||||
continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
# continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
||||||
uses: actions/checkout@v4
|
# uses: actions/checkout@v4
|
||||||
with:
|
# with:
|
||||||
repository: nocobase/plugin-workflow-approval
|
# repository: nocobase/plugin-workflow-approval
|
||||||
ref: main
|
# ref: main
|
||||||
path: packages/pro-plugins/@nocobase/plugin-workflow-approval
|
# path: packages/pro-plugins/@nocobase/plugin-workflow-approval
|
||||||
fetch-depth: 0
|
# fetch-depth: 0
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
# token: ${{ steps.app-token.outputs.token }}
|
||||||
- run: |
|
# - run: |
|
||||||
cd packages/pro-plugins &&
|
# cd packages/pro-plugins &&
|
||||||
if git show-ref --quiet refs/remotes/origin/${{ github.head_ref || github.ref_name }}; then
|
# if git show-ref --quiet refs/remotes/origin/${{ github.head_ref || github.ref_name }}; then
|
||||||
git checkout ${{ github.head_ref || github.ref_name }}
|
# git checkout ${{ github.head_ref || github.ref_name }}
|
||||||
else
|
# else
|
||||||
if git show-ref --quiet refs/remotes/origin/${{ github.event.pull_request.base.ref }}; then
|
# if git show-ref --quiet refs/remotes/origin/${{ github.event.pull_request.base.ref }}; then
|
||||||
git checkout ${{ github.event.pull_request.base.ref }}
|
# git checkout ${{ github.event.pull_request.base.ref }}
|
||||||
else
|
# else
|
||||||
git checkout main
|
# git checkout main
|
||||||
fi
|
# fi
|
||||||
fi
|
# fi
|
||||||
cd ../../
|
# cd ../../
|
||||||
cd packages/pro-plugins/@nocobase/plugin-workflow-approval &&
|
# cd packages/pro-plugins/@nocobase/plugin-workflow-approval &&
|
||||||
if git show-ref --quiet refs/remotes/origin/${{ github.head_ref || github.ref_name }}; then
|
# if git show-ref --quiet refs/remotes/origin/${{ github.head_ref || github.ref_name }}; then
|
||||||
git checkout ${{ github.head_ref || github.ref_name }}
|
# git checkout ${{ github.head_ref || github.ref_name }}
|
||||||
else
|
# else
|
||||||
if git show-ref --quiet refs/remotes/origin/${{ github.event.pull_request.base.ref }}; then
|
# if git show-ref --quiet refs/remotes/origin/${{ github.event.pull_request.base.ref }}; then
|
||||||
git checkout ${{ github.event.pull_request.base.ref }}
|
# git checkout ${{ github.event.pull_request.base.ref }}
|
||||||
else
|
# else
|
||||||
git checkout main
|
# git checkout main
|
||||||
fi
|
# fi
|
||||||
fi
|
# fi
|
||||||
cd ../../../../
|
# cd ../../../../
|
||||||
continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
# continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
||||||
- name: Git logs
|
# - name: Git logs
|
||||||
run: |
|
# run: |
|
||||||
cd packages/pro-plugins/@nocobase/plugin-workflow-approval && git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 10
|
# cd packages/pro-plugins/@nocobase/plugin-workflow-approval && git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 10
|
||||||
continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
# continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
||||||
- name: Set variables
|
# - name: Set variables
|
||||||
continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
# continue-on-error: true # 外部开发者提交 PR 的时候因为没有权限这里会报错,为了能够继续执行后续步骤,所以这里设置为 continue-on-error: true
|
||||||
run: |
|
# run: |
|
||||||
APPEND_PRESET_LOCAL_PLUGINS=$(find ./packages/pro-plugins/@nocobase -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sed 's/^plugin-//' | tr '\n' ',' | sed 's/,$//')
|
# APPEND_PRESET_LOCAL_PLUGINS=$(find ./packages/pro-plugins/@nocobase -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sed 's/^plugin-//' | tr '\n' ',' | sed 's/,$//')
|
||||||
echo "var2=$APPEND_PRESET_LOCAL_PLUGINS" >> $GITHUB_OUTPUT
|
# echo "var2=$APPEND_PRESET_LOCAL_PLUGINS" >> $GITHUB_OUTPUT
|
||||||
id: vars
|
# id: vars
|
||||||
|
|
||||||
- name: Get yarn cache directory path
|
# - name: Get yarn cache directory path
|
||||||
id: yarn-cache-dir-path
|
# id: yarn-cache-dir-path
|
||||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
# run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||||
- uses: actions/cache@v4
|
# - uses: actions/cache@v4
|
||||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
# id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
with:
|
# with:
|
||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
# path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
# key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
restore-keys: |
|
# restore-keys: |
|
||||||
${{ runner.os }}-yarn-
|
# ${{ runner.os }}-yarn-
|
||||||
|
|
||||||
- run: yarn
|
# - run: yarn
|
||||||
|
|
||||||
- name: Download build artifact
|
# - name: Download build artifact
|
||||||
uses: actions/download-artifact@v4
|
# uses: actions/download-artifact@v4
|
||||||
with:
|
# with:
|
||||||
name: build-artifact
|
# name: build-artifact
|
||||||
path: packages
|
# path: packages
|
||||||
|
|
||||||
- run: npx playwright install chromium --with-deps
|
# - run: npx playwright install chromium --with-deps
|
||||||
- name: Test with postgres
|
# - name: Test with postgres
|
||||||
run: yarn e2e p-test --match 'packages/**/plugin-workflow-approval/**/__e2e__/**/*.test.ts'
|
# run: yarn e2e p-test --match 'packages/**/plugin-workflow-approval/**/__e2e__/**/*.test.ts'
|
||||||
env:
|
# env:
|
||||||
__E2E__: true
|
# __E2E__: true
|
||||||
APP_ENV: production
|
# APP_ENV: production
|
||||||
LOGGER_LEVEL: error
|
# LOGGER_LEVEL: error
|
||||||
DB_DIALECT: postgres
|
# DB_DIALECT: postgres
|
||||||
DB_HOST: postgres
|
# DB_HOST: postgres
|
||||||
DB_PORT: 5432
|
# DB_PORT: 5432
|
||||||
DB_USER: nocobase
|
# DB_USER: nocobase
|
||||||
DB_PASSWORD: password
|
# DB_PASSWORD: password
|
||||||
DB_DATABASE: nocobase
|
# DB_DATABASE: nocobase
|
||||||
APPEND_PRESET_LOCAL_PLUGINS: ${{ steps.vars.outputs.var2 }}
|
# APPEND_PRESET_LOCAL_PLUGINS: ${{ steps.vars.outputs.var2 }}
|
||||||
ENCRYPTION_FIELD_KEY: 1%&glK;<UA}aIxJVc53-4G(rTi0vg@J]
|
# ENCRYPTION_FIELD_KEY: 1%&glK;<UA}aIxJVc53-4G(rTi0vg@J]
|
||||||
|
|
||||||
- name: Upload e2e-report
|
# - name: Upload e2e-report
|
||||||
if: ${{ !cancelled() }}
|
# if: ${{ !cancelled() }}
|
||||||
uses: actions/upload-artifact@v4
|
# uses: actions/upload-artifact@v4
|
||||||
with:
|
# with:
|
||||||
name: e2e-report-${{ github.job }} # 为了防止在多个任务中存在冲突
|
# name: e2e-report-${{ github.job }} # 为了防止在多个任务中存在冲突
|
||||||
path: ./storage/playwright/tests-report-blob/blob-*/*
|
# path: ./storage/playwright/tests-report-blob/blob-*/*
|
||||||
|
|
||||||
timeout-minutes: 180
|
# timeout-minutes: 180
|
||||||
|
|
||||||
plugin-data-source-main:
|
plugin-data-source-main:
|
||||||
name: plugin-data-source-main
|
name: plugin-data-source-main
|
||||||
|
21
CHANGELOG.md
21
CHANGELOG.md
@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [v1.7.18](https://github.com/nocobase/nocobase/compare/v1.7.17...v1.7.18) - 2025-06-26
|
||||||
|
|
||||||
|
### 🚀 Improvements
|
||||||
|
|
||||||
|
- **[Workflow]** Optimize mobile style ([#7040](https://github.com/nocobase/nocobase/pull/7040)) by @mytharcher
|
||||||
|
|
||||||
|
- **[Public forms]** Optimize the performance of date components in public forms ([#7117](https://github.com/nocobase/nocobase/pull/7117)) by @zhangzhonghe
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
|
- **[Workflow]** Fix params of loading record in tasks ([#7123](https://github.com/nocobase/nocobase/pull/7123)) by @mytharcher
|
||||||
|
|
||||||
|
- **[WEB client]** Fix issue where blocks under pages were not displayed after setting role menu permissions ([#7112](https://github.com/nocobase/nocobase/pull/7112)) by @aaaaaajie
|
||||||
|
|
||||||
|
- **[Workflow: Approval]**
|
||||||
|
- Fix applicant variable name in trigger by @mytharcher
|
||||||
|
|
||||||
|
- Fix mobile styles by @mytharcher
|
||||||
|
|
||||||
|
- Fix error thrown when approval related collection deleted by @mytharcher
|
||||||
|
|
||||||
## [v1.7.17](https://github.com/nocobase/nocobase/compare/v1.7.16...v1.7.17) - 2025-06-23
|
## [v1.7.17](https://github.com/nocobase/nocobase/compare/v1.7.16...v1.7.17) - 2025-06-23
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
@ -5,6 +5,27 @@
|
|||||||
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
||||||
并且本项目遵循 [语义化版本](https://semver.org/spec/v2.0.0.html)。
|
并且本项目遵循 [语义化版本](https://semver.org/spec/v2.0.0.html)。
|
||||||
|
|
||||||
|
## [v1.7.18](https://github.com/nocobase/nocobase/compare/v1.7.17...v1.7.18) - 2025-06-26
|
||||||
|
|
||||||
|
### 🚀 优化
|
||||||
|
|
||||||
|
- **[工作流]** 优化移动端样式 ([#7040](https://github.com/nocobase/nocobase/pull/7040)) by @mytharcher
|
||||||
|
|
||||||
|
- **[公开表单]** 优化公开表单中日期组件的性能 ([#7117](https://github.com/nocobase/nocobase/pull/7117)) by @zhangzhonghe
|
||||||
|
|
||||||
|
### 🐛 修复
|
||||||
|
|
||||||
|
- **[工作流]** 修复待办中心加载记录的参数 ([#7123](https://github.com/nocobase/nocobase/pull/7123)) by @mytharcher
|
||||||
|
|
||||||
|
- **[WEB 客户端]** 修复设置角色菜单权限后页面下区块不显示的问题 ([#7112](https://github.com/nocobase/nocobase/pull/7112)) by @aaaaaajie
|
||||||
|
|
||||||
|
- **[工作流:审批]**
|
||||||
|
- 修复审批触发器中申请人变量名的问题 by @mytharcher
|
||||||
|
|
||||||
|
- 修复移动端样式 by @mytharcher
|
||||||
|
|
||||||
|
- 修复审批关联表被删除后的报错 by @mytharcher
|
||||||
|
|
||||||
## [v1.7.17](https://github.com/nocobase/nocobase/compare/v1.7.16...v1.7.17) - 2025-06-23
|
## [v1.7.17](https://github.com/nocobase/nocobase/compare/v1.7.16...v1.7.17) - 2025-06-23
|
||||||
|
|
||||||
### 🐛 修复
|
### 🐛 修复
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"npmClientArgs": ["--ignore-engines"],
|
"npmClientArgs": ["--ignore-engines"],
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/acl",
|
"name": "@nocobase/acl",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/resourcer": "1.7.17",
|
"@nocobase/resourcer": "1.7.18",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"minimatch": "^5.1.1"
|
"minimatch": "^5.1.1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/actions",
|
"name": "@nocobase/actions",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/cache": "1.7.17",
|
"@nocobase/cache": "1.7.18",
|
||||||
"@nocobase/database": "1.7.17",
|
"@nocobase/database": "1.7.18",
|
||||||
"@nocobase/resourcer": "1.7.17"
|
"@nocobase/resourcer": "1.7.18"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/app",
|
"name": "@nocobase/app",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/database": "1.7.17",
|
"@nocobase/database": "1.7.18",
|
||||||
"@nocobase/preset-nocobase": "1.7.17",
|
"@nocobase/preset-nocobase": "1.7.18",
|
||||||
"@nocobase/server": "1.7.17"
|
"@nocobase/server": "1.7.18"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nocobase/client": "1.7.17"
|
"@nocobase/client": "1.7.18"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/auth",
|
"name": "@nocobase/auth",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/actions": "1.7.17",
|
"@nocobase/actions": "1.7.18",
|
||||||
"@nocobase/cache": "1.7.17",
|
"@nocobase/cache": "1.7.18",
|
||||||
"@nocobase/database": "1.7.17",
|
"@nocobase/database": "1.7.18",
|
||||||
"@nocobase/resourcer": "1.7.17",
|
"@nocobase/resourcer": "1.7.18",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"@types/jsonwebtoken": "^9.0.9",
|
"@types/jsonwebtoken": "^9.0.9",
|
||||||
"jsonwebtoken": "^9.0.2"
|
"jsonwebtoken": "^9.0.2"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/build",
|
"name": "@nocobase/build",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "Library build tool based on rollup.",
|
"description": "Library build tool based on rollup.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
|
4
packages/core/cache/package.json
vendored
4
packages/core/cache/package.json
vendored
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/cache",
|
"name": "@nocobase/cache",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/lock-manager": "1.7.17",
|
"@nocobase/lock-manager": "1.7.18",
|
||||||
"bloom-filters": "^3.0.1",
|
"bloom-filters": "^3.0.1",
|
||||||
"cache-manager": "^5.2.4",
|
"cache-manager": "^5.2.4",
|
||||||
"cache-manager-redis-yet": "^4.1.2"
|
"cache-manager-redis-yet": "^4.1.2"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/cli",
|
"name": "@nocobase/cli",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./src/index.js",
|
"main": "./src/index.js",
|
||||||
@ -8,7 +8,7 @@
|
|||||||
"nocobase": "./bin/index.js"
|
"nocobase": "./bin/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/app": "1.7.17",
|
"@nocobase/app": "1.7.18",
|
||||||
"@types/fs-extra": "^11.0.1",
|
"@types/fs-extra": "^11.0.1",
|
||||||
"@umijs/utils": "3.5.20",
|
"@umijs/utils": "3.5.20",
|
||||||
"chalk": "^4.1.1",
|
"chalk": "^4.1.1",
|
||||||
@ -26,7 +26,7 @@
|
|||||||
"tsx": "^4.19.0"
|
"tsx": "^4.19.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nocobase/devtools": "1.7.17"
|
"@nocobase/devtools": "1.7.18"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/client",
|
"name": "@nocobase/client",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"module": "es/index.mjs",
|
"module": "es/index.mjs",
|
||||||
@ -26,9 +26,9 @@
|
|||||||
"@formily/reactive-react": "^2.2.27",
|
"@formily/reactive-react": "^2.2.27",
|
||||||
"@formily/shared": "^2.2.27",
|
"@formily/shared": "^2.2.27",
|
||||||
"@formily/validator": "^2.2.27",
|
"@formily/validator": "^2.2.27",
|
||||||
"@nocobase/evaluators": "1.7.17",
|
"@nocobase/evaluators": "1.7.18",
|
||||||
"@nocobase/sdk": "1.7.17",
|
"@nocobase/sdk": "1.7.18",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"ahooks": "^3.7.2",
|
"ahooks": "^3.7.2",
|
||||||
"antd": "5.24.2",
|
"antd": "5.24.2",
|
||||||
"antd-style": "3.7.1",
|
"antd-style": "3.7.1",
|
||||||
|
@ -24,6 +24,7 @@ export class DateFieldInterface extends CollectionFieldInterface {
|
|||||||
'x-component': 'DatePicker',
|
'x-component': 'DatePicker',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
dateOnly: true,
|
dateOnly: true,
|
||||||
|
showTime: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import { useField, useForm } from '@formily/react';
|
import { useField, useForm } from '@formily/react';
|
||||||
import { Cascader, Input, Select, Spin, Table, Tag } from 'antd';
|
import { Cascader, Input, Select, Spin, Table, Tag } from 'antd';
|
||||||
import { last, omit } from 'lodash';
|
import _, { last, omit } from 'lodash';
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ResourceActionContext, useCompile } from '../../../';
|
import { ResourceActionContext, useCompile } from '../../../';
|
||||||
@ -120,9 +120,10 @@ const PreviewCom = (props) => {
|
|||||||
}, [databaseView]);
|
}, [databaseView]);
|
||||||
|
|
||||||
const handleFieldChange = (record, index) => {
|
const handleFieldChange = (record, index) => {
|
||||||
dataSource.splice(index, 1, record);
|
const newDataSource = _.cloneDeep(dataSource);
|
||||||
setDataSource(dataSource);
|
newDataSource[index] = record;
|
||||||
field.value = dataSource.map((v) => {
|
setDataSource(newDataSource);
|
||||||
|
field.value = newDataSource.map((v) => {
|
||||||
const source = typeof v.source === 'string' ? v.source : v.source?.filter?.(Boolean)?.join('.');
|
const source = typeof v.source === 'string' ? v.source : v.source?.filter?.(Boolean)?.join('.');
|
||||||
return {
|
return {
|
||||||
...v,
|
...v,
|
||||||
@ -198,8 +199,7 @@ const PreviewCom = (props) => {
|
|||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
popupMatchSelectWidth={false}
|
popupMatchSelectWidth={false}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const interfaceConfig = getInterface(value);
|
handleFieldChange({ ...item, interface: value }, index);
|
||||||
handleFieldChange({ ...item, interface: value, uiSchema: interfaceConfig?.default?.uiSchema }, index);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{data.map((group) => (
|
{data.map((group) => (
|
||||||
|
@ -66,7 +66,7 @@ export const createFormBlockSettings = new SchemaSettings({
|
|||||||
useVisible() {
|
useVisible() {
|
||||||
const { action } = useFormBlockContext();
|
const { action } = useFormBlockContext();
|
||||||
const schema = useFieldSchema();
|
const schema = useFieldSchema();
|
||||||
return !action && schema?.['x-acl-action'].includes('create');
|
return !action && schema?.['x-acl-action']?.includes('create');
|
||||||
},
|
},
|
||||||
useComponentProps() {
|
useComponentProps() {
|
||||||
const { name } = useCollection_deprecated();
|
const { name } = useCollection_deprecated();
|
||||||
|
@ -19,6 +19,7 @@ import { useKeepAlive } from '../../../route-switch/antd/admin-layout/KeepAlive'
|
|||||||
import { useSchemaComponentContext } from '../../hooks';
|
import { useSchemaComponentContext } from '../../hooks';
|
||||||
import { AssociationFieldContext } from './context';
|
import { AssociationFieldContext } from './context';
|
||||||
import { FormItem, useSchemaOptionsContext } from '../../../schema-component';
|
import { FormItem, useSchemaOptionsContext } from '../../../schema-component';
|
||||||
|
import { useCollectionRecord } from '../../../data-source';
|
||||||
|
|
||||||
export const AssociationFieldProvider = observer(
|
export const AssociationFieldProvider = observer(
|
||||||
(props) => {
|
(props) => {
|
||||||
@ -28,6 +29,7 @@ export const AssociationFieldProvider = observer(
|
|||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const option = useSchemaOptionsContext();
|
const option = useSchemaOptionsContext();
|
||||||
const rootRef = useRef<HTMLDivElement>(null);
|
const rootRef = useRef<HTMLDivElement>(null);
|
||||||
|
const record = useCollectionRecord();
|
||||||
|
|
||||||
// 这里有点奇怪,在 Table 切换显示的组件时,这个组件并不会触发重新渲染,所以增加这个 Hooks 让其重新渲染
|
// 这里有点奇怪,在 Table 切换显示的组件时,这个组件并不会触发重新渲染,所以增加这个 Hooks 让其重新渲染
|
||||||
useSchemaComponentContext();
|
useSchemaComponentContext();
|
||||||
@ -71,7 +73,9 @@ export const AssociationFieldProvider = observer(
|
|||||||
if (_.isUndefined(ids) || _.isNil(ids) || _.isNaN(ids)) {
|
if (_.isUndefined(ids) || _.isNil(ids) || _.isNaN(ids)) {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
if (record && !record.isNew) {
|
||||||
|
return Promise.reject(null);
|
||||||
|
}
|
||||||
return api.request({
|
return api.request({
|
||||||
resource: collectionField.target,
|
resource: collectionField.target,
|
||||||
action: Array.isArray(ids) ? 'list' : 'get',
|
action: Array.isArray(ids) ? 'list' : 'get',
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
import { getDefaultFormat, str2moment, toGmt, toLocal, getPickerFormat } from '@nocobase/utils/client';
|
import { getDefaultFormat, str2moment, toGmt, toLocal, getPickerFormat } from '@nocobase/utils/client';
|
||||||
import type { Dayjs } from 'dayjs';
|
import type { Dayjs } from 'dayjs';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { dayjsable, formatDayjsValue } from '@formily/antd-v5/esm/__builtins__';
|
||||||
|
|
||||||
const toStringByPicker = (value, picker = 'date', timezone: 'gmt' | 'local') => {
|
const toStringByPicker = (value, picker = 'date', timezone: 'gmt' | 'local') => {
|
||||||
if (!dayjs.isDayjs(value)) return value;
|
if (!dayjs.isDayjs(value)) return value;
|
||||||
@ -89,7 +90,7 @@ export const handleDateChangeOnForm = (value, dateOnly, utc, picker, showTime, g
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (dateOnly) {
|
if (dateOnly) {
|
||||||
return dayjs(value).startOf(picker).format('YYYY-MM-DD');
|
return formatDayjsValue(value, 'YYYY-MM-DD');
|
||||||
}
|
}
|
||||||
if (utc) {
|
if (utc) {
|
||||||
if (gmt) {
|
if (gmt) {
|
||||||
@ -114,6 +115,7 @@ export const mapDatePicker = function () {
|
|||||||
const { dateOnly, showTime, picker = 'date', utc, gmt, underFilter } = props;
|
const { dateOnly, showTime, picker = 'date', utc, gmt, underFilter } = props;
|
||||||
const format = getDefaultFormat(props);
|
const format = getDefaultFormat(props);
|
||||||
const onChange = props.onChange;
|
const onChange = props.onChange;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...props,
|
...props,
|
||||||
inputReadOnly: isMobileMedia,
|
inputReadOnly: isMobileMedia,
|
||||||
|
@ -48,11 +48,11 @@ const useStyles = genStyleHook('nb-list', (token) => {
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
'&:not(:first-child)': {
|
'&:not(:first-child)': {
|
||||||
paddingTop: token.paddingContentVertical,
|
marginTop: token.paddingContentVertical,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&:not(:last-child)': {
|
'&:not(:last-child)': {
|
||||||
paddingBottom: token.paddingContentVertical,
|
marginBottom: token.paddingContentVertical,
|
||||||
borderBottom: `1px solid ${token.colorBorderSecondary}`,
|
borderBottom: `1px solid ${token.colorBorderSecondary}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -244,7 +244,7 @@ function FinallyButton({
|
|||||||
inheritsCollections,
|
inheritsCollections,
|
||||||
linkageFromForm,
|
linkageFromForm,
|
||||||
allowAddToCurrent,
|
allowAddToCurrent,
|
||||||
props,
|
props: { onlyIcon, ...props },
|
||||||
componentType,
|
componentType,
|
||||||
menu,
|
menu,
|
||||||
onClick,
|
onClick,
|
||||||
@ -362,7 +362,7 @@ function FinallyButton({
|
|||||||
...buttonStyle,
|
...buttonStyle,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.onlyIcon ? props?.children?.[1] : props?.children}
|
{onlyIcon ? props?.children?.[1] : props?.children}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ export const SchemaSettingsDefaultValue = function DefaultValueConfigure(props:
|
|||||||
const localVariables = useLocalVariables();
|
const localVariables = useLocalVariables();
|
||||||
const collection = useCollection_deprecated();
|
const collection = useCollection_deprecated();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
const { form } = useFormBlockContext();
|
const { form, type } = useFormBlockContext();
|
||||||
const { getFields } = useCollectionFilterOptionsV2(collection);
|
const { getFields } = useCollectionFilterOptionsV2(collection);
|
||||||
const { isInSubForm, isInSubTable } = useFlag() || {};
|
const { isInSubForm, isInSubTable } = useFlag() || {};
|
||||||
|
|
||||||
@ -219,7 +219,6 @@ export const SchemaSettingsDefaultValue = function DefaultValueConfigure(props:
|
|||||||
targetField,
|
targetField,
|
||||||
variables,
|
variables,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleSubmit: (values: any) => void = useCallback(
|
const handleSubmit: (values: any) => void = useCallback(
|
||||||
(v) => {
|
(v) => {
|
||||||
const schema: ISchema = {
|
const schema: ISchema = {
|
||||||
@ -227,7 +226,7 @@ export const SchemaSettingsDefaultValue = function DefaultValueConfigure(props:
|
|||||||
};
|
};
|
||||||
fieldSchema.default = v.default ?? null;
|
fieldSchema.default = v.default ?? null;
|
||||||
if (!isVariable(v.default)) {
|
if (!isVariable(v.default)) {
|
||||||
field.setInitialValue?.(v.default);
|
(record.__isNewRecord__ || type === 'create') && field.setInitialValue?.(v.default);
|
||||||
}
|
}
|
||||||
schema.default = v.default ?? null;
|
schema.default = v.default ?? null;
|
||||||
dn.emit('patch', {
|
dn.emit('patch', {
|
||||||
|
@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { useBlockContext } from '../../../block-provider';
|
import { useBlockContext } from '../../../block-provider';
|
||||||
import { useFormBlockContext } from '../../../block-provider/FormBlockProvider';
|
import { useFormBlockContext } from '../../../block-provider/FormBlockProvider';
|
||||||
import { CollectionFieldOptions_deprecated } from '../../../collection-manager';
|
import { CollectionFieldOptions_deprecated } from '../../../collection-manager';
|
||||||
import { useDataBlockRequestData, useDataSource } from '../../../data-source';
|
import { useCollection, useDataSource } from '../../../data-source';
|
||||||
import { useFlag } from '../../../flag-provider/hooks/useFlag';
|
import { useFlag } from '../../../flag-provider/hooks/useFlag';
|
||||||
import { useBaseVariable } from './useBaseVariable';
|
import { useBaseVariable } from './useBaseVariable';
|
||||||
|
|
||||||
@ -100,6 +100,7 @@ export const useCurrentFormVariable = ({
|
|||||||
const { currentFormCtx, shouldDisplayCurrentForm } = useCurrentFormContext({ form: _form });
|
const { currentFormCtx, shouldDisplayCurrentForm } = useCurrentFormContext({ form: _form });
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { collectionName } = useFormBlockContext();
|
const { collectionName } = useFormBlockContext();
|
||||||
|
const collection = useCollection();
|
||||||
const dataSource = useDataSource();
|
const dataSource = useDataSource();
|
||||||
const currentFormSettings = useBaseVariable({
|
const currentFormSettings = useBaseVariable({
|
||||||
collectionField,
|
collectionField,
|
||||||
@ -108,7 +109,7 @@ export const useCurrentFormVariable = ({
|
|||||||
maxDepth: 4,
|
maxDepth: 4,
|
||||||
name: '$nForm',
|
name: '$nForm',
|
||||||
title: t('Current form'),
|
title: t('Current form'),
|
||||||
collectionName: collectionName,
|
collectionName: collectionName || collection?.name,
|
||||||
noDisabled,
|
noDisabled,
|
||||||
dataSource: dataSource?.key,
|
dataSource: dataSource?.key,
|
||||||
returnFields: (fields, option) => {
|
returnFields: (fields, option) => {
|
||||||
|
@ -53,7 +53,11 @@ const useLocalVariables = (props?: Props) => {
|
|||||||
dataSource: parentPopupDataSource,
|
dataSource: parentPopupDataSource,
|
||||||
defaultValue: defaultValueOfParentPopupRecord,
|
defaultValue: defaultValueOfParentPopupRecord,
|
||||||
} = useParentPopupVariableContext();
|
} = useParentPopupVariableContext();
|
||||||
const { urlSearchParamsCtx, shouldDisplay: shouldDisplayURLSearchParams, defaultValue: defaultValueOfURLSearchParams } = useURLSearchParamsVariable();
|
const {
|
||||||
|
urlSearchParamsCtx,
|
||||||
|
shouldDisplay: shouldDisplayURLSearchParams,
|
||||||
|
defaultValue: defaultValueOfURLSearchParams,
|
||||||
|
} = useURLSearchParamsVariable();
|
||||||
const { datetimeCtx } = useDatetimeVariableContext();
|
const { datetimeCtx } = useDatetimeVariableContext();
|
||||||
const { currentFormCtx } = useCurrentFormContext({ form: props?.currentForm });
|
const { currentFormCtx } = useCurrentFormContext({ form: props?.currentForm });
|
||||||
const { name: currentCollectionName } = useCollection_deprecated();
|
const { name: currentCollectionName } = useCollection_deprecated();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "create-nocobase-app",
|
"name": "create-nocobase-app",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/data-source-manager",
|
"name": "@nocobase/data-source-manager",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/actions": "1.7.17",
|
"@nocobase/actions": "1.7.18",
|
||||||
"@nocobase/cache": "1.7.17",
|
"@nocobase/cache": "1.7.18",
|
||||||
"@nocobase/database": "1.7.17",
|
"@nocobase/database": "1.7.18",
|
||||||
"@nocobase/resourcer": "1.7.17",
|
"@nocobase/resourcer": "1.7.18",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"@types/jsonwebtoken": "^8.5.8",
|
"@types/jsonwebtoken": "^8.5.8",
|
||||||
"jsonwebtoken": "^9.0.2"
|
"jsonwebtoken": "^9.0.2"
|
||||||
},
|
},
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/database",
|
"name": "@nocobase/database",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/logger": "1.7.17",
|
"@nocobase/logger": "1.7.18",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"async-mutex": "^0.3.2",
|
"async-mutex": "^0.3.2",
|
||||||
"chalk": "^4.1.1",
|
"chalk": "^4.1.1",
|
||||||
"cron-parser": "4.4.0",
|
"cron-parser": "4.4.0",
|
||||||
|
40
packages/core/database/src/__tests__/helpers.test.ts
Normal file
40
packages/core/database/src/__tests__/helpers.test.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { parseDatabaseOptionsFromEnv } from '@nocobase/database';
|
||||||
|
|
||||||
|
describe('database helpers', () => {
|
||||||
|
describe('parseDatabaseOptionsFromEnv()', () => {
|
||||||
|
it('undefined pool options', async () => {
|
||||||
|
const options1 = await parseDatabaseOptionsFromEnv();
|
||||||
|
expect(options1).toMatchObject({
|
||||||
|
pool: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('custom pool options', async () => {
|
||||||
|
process.env.DB_POOL_MAX = '10';
|
||||||
|
process.env.DB_POOL_MIN = '1';
|
||||||
|
process.env.DB_POOL_IDLE = '5000';
|
||||||
|
process.env.DB_POOL_ACQUIRE = '30000';
|
||||||
|
process.env.DB_POOL_EVICT = '2000';
|
||||||
|
process.env.DB_POOL_MAX_USES = '0'; // Set to 0 to test default behavior
|
||||||
|
|
||||||
|
const options2 = await parseDatabaseOptionsFromEnv();
|
||||||
|
expect(options2.pool).toMatchObject({
|
||||||
|
max: 10,
|
||||||
|
min: 1,
|
||||||
|
idle: 5000,
|
||||||
|
acquire: 30000,
|
||||||
|
evict: 2000,
|
||||||
|
maxUses: Number.POSITIVE_INFINITY, // Default value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -15,6 +15,7 @@ import { MysqlDialect } from './dialects/mysql-dialect';
|
|||||||
import { SqliteDialect } from './dialects/sqlite-dialect';
|
import { SqliteDialect } from './dialects/sqlite-dialect';
|
||||||
import { MariadbDialect } from './dialects/mariadb-dialect';
|
import { MariadbDialect } from './dialects/mariadb-dialect';
|
||||||
import { PostgresDialect } from './dialects/postgres-dialect';
|
import { PostgresDialect } from './dialects/postgres-dialect';
|
||||||
|
import { PoolOptions } from 'sequelize';
|
||||||
|
|
||||||
function getEnvValue(key, defaultValue?) {
|
function getEnvValue(key, defaultValue?) {
|
||||||
return process.env[key] || defaultValue;
|
return process.env[key] || defaultValue;
|
||||||
@ -73,6 +74,29 @@ function extractSSLOptionsFromEnv() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPoolOptions(): PoolOptions {
|
||||||
|
const options: PoolOptions = {};
|
||||||
|
if (process.env.DB_POOL_MAX) {
|
||||||
|
options.max = Number.parseInt(process.env.DB_POOL_MAX, 10);
|
||||||
|
}
|
||||||
|
if (process.env.DB_POOL_MIN) {
|
||||||
|
options.min = Number.parseInt(process.env.DB_POOL_MIN, 10);
|
||||||
|
}
|
||||||
|
if (process.env.DB_POOL_IDLE) {
|
||||||
|
options.idle = Number.parseInt(process.env.DB_POOL_IDLE, 10);
|
||||||
|
}
|
||||||
|
if (process.env.DB_POOL_ACQUIRE) {
|
||||||
|
options.acquire = Number.parseInt(process.env.DB_POOL_ACQUIRE, 10);
|
||||||
|
}
|
||||||
|
if (process.env.DB_POOL_EVICT) {
|
||||||
|
options.evict = Number.parseInt(process.env.DB_POOL_EVICT, 10);
|
||||||
|
}
|
||||||
|
if (process.env.DB_POOL_MAX_USES) {
|
||||||
|
options.maxUses = Number.parseInt(process.env.DB_POOL_MAX_USES, 10) || Number.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
export async function parseDatabaseOptionsFromEnv(): Promise<IDatabaseOptions> {
|
export async function parseDatabaseOptionsFromEnv(): Promise<IDatabaseOptions> {
|
||||||
const databaseOptions: IDatabaseOptions = {
|
const databaseOptions: IDatabaseOptions = {
|
||||||
logging: process.env.DB_LOGGING == 'on' ? customLogger : false,
|
logging: process.env.DB_LOGGING == 'on' ? customLogger : false,
|
||||||
@ -87,6 +111,7 @@ export async function parseDatabaseOptionsFromEnv(): Promise<IDatabaseOptions> {
|
|||||||
tablePrefix: process.env.DB_TABLE_PREFIX,
|
tablePrefix: process.env.DB_TABLE_PREFIX,
|
||||||
schema: process.env.DB_SCHEMA,
|
schema: process.env.DB_SCHEMA,
|
||||||
underscored: process.env.DB_UNDERSCORED === 'true',
|
underscored: process.env.DB_UNDERSCORED === 'true',
|
||||||
|
pool: getPoolOptions(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const sslOptions = await extractSSLOptionsFromEnv();
|
const sslOptions = await extractSSLOptionsFromEnv();
|
||||||
|
@ -33,7 +33,7 @@ const toDate = (date, options: any = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (field.constructor.name === 'DateOnlyField') {
|
if (field.constructor.name === 'DateOnlyField') {
|
||||||
val = moment(val).format('YYYY-MM-DD HH:mm:ss');
|
val = moment.utc(val).format('YYYY-MM-DD HH:mm:ss');
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventObj = {
|
const eventObj = {
|
||||||
@ -69,7 +69,6 @@ export default {
|
|||||||
const r = parseDate(value, {
|
const r = parseDate(value, {
|
||||||
timezone: parseDateTimezone(ctx),
|
timezone: parseDateTimezone(ctx),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeof r === 'string') {
|
if (typeof r === 'string') {
|
||||||
return {
|
return {
|
||||||
[Op.eq]: toDate(r, { ctx }),
|
[Op.eq]: toDate(r, { ctx }),
|
||||||
@ -77,6 +76,9 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(r)) {
|
if (Array.isArray(r)) {
|
||||||
|
console.log(11111111, {
|
||||||
|
[Op.and]: [{ [Op.gte]: toDate(r[0], { ctx }) }, { [Op.lt]: toDate(r[1], { ctx }) }],
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
[Op.and]: [{ [Op.gte]: toDate(r[0], { ctx }) }, { [Op.lt]: toDate(r[1], { ctx }) }],
|
[Op.and]: [{ [Op.gte]: toDate(r[0], { ctx }) }, { [Op.lt]: toDate(r[1], { ctx }) }],
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/devtools",
|
"name": "@nocobase/devtools",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./src/index.js",
|
"main": "./src/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/build": "1.7.17",
|
"@nocobase/build": "1.7.18",
|
||||||
"@nocobase/client": "1.7.17",
|
"@nocobase/client": "1.7.18",
|
||||||
"@nocobase/test": "1.7.17",
|
"@nocobase/test": "1.7.18",
|
||||||
"@types/koa": "^2.15.0",
|
"@types/koa": "^2.15.0",
|
||||||
"@types/koa-bodyparser": "^4.3.4",
|
"@types/koa-bodyparser": "^4.3.4",
|
||||||
"@types/lodash": "^4.14.177",
|
"@types/lodash": "^4.14.177",
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/evaluators",
|
"name": "@nocobase/evaluators",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formulajs/formulajs": "4.4.9",
|
"@formulajs/formulajs": "4.4.9",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"mathjs": "^10.6.0"
|
"mathjs": "^10.6.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/lock-manager",
|
"name": "@nocobase/lock-manager",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"async-mutex": "^0.5.0"
|
"async-mutex": "^0.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/logger",
|
"name": "@nocobase/logger",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "nocobase logging library",
|
"description": "nocobase logging library",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/resourcer",
|
"name": "@nocobase/resourcer",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"koa-compose": "^4.1.0",
|
"koa-compose": "^4.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/sdk",
|
"name": "@nocobase/sdk",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/server",
|
"name": "@nocobase/server",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
@ -10,19 +10,19 @@
|
|||||||
"@koa/cors": "^5.0.0",
|
"@koa/cors": "^5.0.0",
|
||||||
"@koa/multer": "^3.1.0",
|
"@koa/multer": "^3.1.0",
|
||||||
"@koa/router": "^13.1.0",
|
"@koa/router": "^13.1.0",
|
||||||
"@nocobase/acl": "1.7.17",
|
"@nocobase/acl": "1.7.18",
|
||||||
"@nocobase/actions": "1.7.17",
|
"@nocobase/actions": "1.7.18",
|
||||||
"@nocobase/auth": "1.7.17",
|
"@nocobase/auth": "1.7.18",
|
||||||
"@nocobase/cache": "1.7.17",
|
"@nocobase/cache": "1.7.18",
|
||||||
"@nocobase/data-source-manager": "1.7.17",
|
"@nocobase/data-source-manager": "1.7.18",
|
||||||
"@nocobase/database": "1.7.17",
|
"@nocobase/database": "1.7.18",
|
||||||
"@nocobase/evaluators": "1.7.17",
|
"@nocobase/evaluators": "1.7.18",
|
||||||
"@nocobase/lock-manager": "1.7.17",
|
"@nocobase/lock-manager": "1.7.18",
|
||||||
"@nocobase/logger": "1.7.17",
|
"@nocobase/logger": "1.7.18",
|
||||||
"@nocobase/resourcer": "1.7.17",
|
"@nocobase/resourcer": "1.7.18",
|
||||||
"@nocobase/sdk": "1.7.17",
|
"@nocobase/sdk": "1.7.18",
|
||||||
"@nocobase/telemetry": "1.7.17",
|
"@nocobase/telemetry": "1.7.18",
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"@types/decompress": "4.2.7",
|
"@types/decompress": "4.2.7",
|
||||||
"@types/ini": "^1.3.31",
|
"@types/ini": "^1.3.31",
|
||||||
"@types/koa-send": "^4.1.3",
|
"@types/koa-send": "^4.1.3",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/telemetry",
|
"name": "@nocobase/telemetry",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "nocobase telemetry library",
|
"description": "nocobase telemetry library",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
@ -11,7 +11,7 @@
|
|||||||
"directory": "packages/telemetry"
|
"directory": "packages/telemetry"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/utils": "1.7.17",
|
"@nocobase/utils": "1.7.18",
|
||||||
"@opentelemetry/api": "^1.7.0",
|
"@opentelemetry/api": "^1.7.0",
|
||||||
"@opentelemetry/instrumentation": "^0.46.0",
|
"@opentelemetry/instrumentation": "^0.46.0",
|
||||||
"@opentelemetry/resources": "^1.19.0",
|
"@opentelemetry/resources": "^1.19.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/test",
|
"name": "@nocobase/test",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"module": "./src/index.ts",
|
"module": "./src/index.ts",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
@ -51,7 +51,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@faker-js/faker": "8.1.0",
|
"@faker-js/faker": "8.1.0",
|
||||||
"@nocobase/server": "1.7.17",
|
"@nocobase/server": "1.7.18",
|
||||||
"@playwright/test": "^1.45.3",
|
"@playwright/test": "^1.45.3",
|
||||||
"@testing-library/jest-dom": "^6.4.2",
|
"@testing-library/jest-dom": "^6.4.2",
|
||||||
"@testing-library/react": "^14.0.0",
|
"@testing-library/react": "^14.0.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/utils",
|
"name": "@nocobase/utils",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
|
@ -15,6 +15,7 @@ export interface Str2momentOptions {
|
|||||||
picker?: 'year' | 'month' | 'week' | 'quarter';
|
picker?: 'year' | 'month' | 'week' | 'quarter';
|
||||||
utcOffset?: number;
|
utcOffset?: number;
|
||||||
utc?: boolean;
|
utc?: boolean;
|
||||||
|
dateOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Str2momentValue = string | string[] | dayjs.Dayjs | dayjs.Dayjs[];
|
export type Str2momentValue = string | string[] | dayjs.Dayjs | dayjs.Dayjs[];
|
||||||
@ -83,10 +84,14 @@ const toMoment = (val: any, options?: Str2momentOptions) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const offset = options.utcOffset;
|
const offset = options.utcOffset;
|
||||||
const { gmt, picker, utc = true } = options;
|
const { gmt, picker, utc = true, dateOnly } = options;
|
||||||
|
|
||||||
if (dayjs(val).isValid()) {
|
if (dayjs(val).isValid()) {
|
||||||
|
if (dateOnly) {
|
||||||
|
return dayjs.utc(val, 'YYYY-MM-DD');
|
||||||
|
}
|
||||||
if (!utc) {
|
if (!utc) {
|
||||||
return dayjs(val);
|
return dayjs.utc(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dayjs.isDayjs(val)) {
|
if (dayjs.isDayjs(val)) {
|
||||||
|
@ -188,9 +188,11 @@ export const parseFilter = async (filter: any, opts: ParseFilterOptions = {}) =>
|
|||||||
const field = getField?.(path);
|
const field = getField?.(path);
|
||||||
|
|
||||||
if (field?.constructor.name === 'DateOnlyField' || field?.constructor.name === 'DatetimeNoTzField') {
|
if (field?.constructor.name === 'DateOnlyField' || field?.constructor.name === 'DatetimeNoTzField') {
|
||||||
|
if (value.type) {
|
||||||
|
return getDayRangeByParams({ ...value, timezone: field?.timezone || timezone });
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dateValueWrapper(value, field?.timezone || timezone);
|
return dateValueWrapper(value, field?.timezone || timezone);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "权限控制",
|
"displayName.zh-CN": "权限控制",
|
||||||
"description": "Based on roles, resources, and actions, access control can precisely manage interface configuration permissions, data operation permissions, menu access permissions, and plugin permissions.",
|
"description": "Based on roles, resources, and actions, access control can precisely manage interface configuration permissions, data operation permissions, menu access permissions, and plugin permissions.",
|
||||||
"description.zh-CN": "基于角色、资源和操作的权限控制,可以精确控制界面配置权限、数据操作权限、菜单访问权限、插件权限。",
|
"description.zh-CN": "基于角色、资源和操作的权限控制,可以精确控制界面配置权限、数据操作权限、菜单访问权限、插件权限。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/acl",
|
"homepage": "https://docs.nocobase.com/handbook/acl",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-action-bulk-edit",
|
"name": "@nocobase/plugin-action-bulk-edit",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-bulk-edit",
|
"homepage": "https://docs.nocobase.com/handbook/action-bulk-edit",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-edit",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-edit",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-action-bulk-update",
|
"name": "@nocobase/plugin-action-bulk-update",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-bulk-update",
|
"homepage": "https://docs.nocobase.com/handbook/action-bulk-update",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-update",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-update",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-action-custom-request",
|
"name": "@nocobase/plugin-action-custom-request",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-custom-request",
|
"homepage": "https://docs.nocobase.com/handbook/action-custom-request",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-custom-request",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-custom-request",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-action-duplicate",
|
"name": "@nocobase/plugin-action-duplicate",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-duplicate",
|
"homepage": "https://docs.nocobase.com/handbook/action-duplicate",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-duplicate",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-duplicate",
|
||||||
|
@ -84,8 +84,8 @@ export const actionDesignerCss = css`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const DuplicateAction = observer(
|
export const DuplicateAction = observer(
|
||||||
(props: any) => {
|
({ onlyIcon, ...props }: any) => {
|
||||||
const { children, onlyIcon, icon, title, ...others } = props;
|
const { children, icon, title, ...others } = props;
|
||||||
const { message } = App.useApp();
|
const { message } = App.useApp();
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "操作:导出记录",
|
"displayName.zh-CN": "操作:导出记录",
|
||||||
"description": "Export filtered records to excel, you can configure which fields to export.",
|
"description": "Export filtered records to excel, you can configure which fields to export.",
|
||||||
"description.zh-CN": "导出筛选后的记录到 Excel 中,可以配置导出哪些字段。",
|
"description.zh-CN": "导出筛选后的记录到 Excel 中,可以配置导出哪些字段。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-export",
|
"homepage": "https://docs.nocobase.com/handbook/action-export",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "操作:导入记录",
|
"displayName.zh-CN": "操作:导入记录",
|
||||||
"description": "Import records using excel templates. You can configure which fields to import and templates will be generated automatically.",
|
"description": "Import records using excel templates. You can configure which fields to import and templates will be generated automatically.",
|
||||||
"description.zh-CN": "使用 Excel 模板导入数据,可以配置导入哪些字段,自动生成模板。",
|
"description.zh-CN": "使用 Excel 模板导入数据,可以配置导入哪些字段,自动生成模板。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-import",
|
"homepage": "https://docs.nocobase.com/handbook/action-import",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-action-print",
|
"name": "@nocobase/plugin-action-print",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/action-print",
|
"homepage": "https://docs.nocobase.com/handbook/action-print",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-print",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-print",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "AI 集成",
|
"displayName.zh-CN": "AI 集成",
|
||||||
"description": "Support integration with AI services, providing AI-related workflow nodes to enhance business processing capabilities.",
|
"description": "Support integration with AI services, providing AI-related workflow nodes to enhance business processing capabilities.",
|
||||||
"description.zh-CN": "支持接入 AI 服务,提供 AI 相关的工作流节点,增强业务处理能力。",
|
"description.zh-CN": "支持接入 AI 服务,提供 AI 相关的工作流节点,增强业务处理能力。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@nocobase/client": "1.x",
|
"@nocobase/client": "1.x",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-api-doc",
|
"name": "@nocobase/plugin-api-doc",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "API documentation",
|
"displayName": "API documentation",
|
||||||
"displayName.zh-CN": "API 文档",
|
"displayName.zh-CN": "API 文档",
|
||||||
"description": "An OpenAPI documentation generator for NocoBase HTTP API.",
|
"description": "An OpenAPI documentation generator for NocoBase HTTP API.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "认证:API 密钥",
|
"displayName.zh-CN": "认证:API 密钥",
|
||||||
"description": "Allows users to use API key to access application's HTTP API",
|
"description": "Allows users to use API key to access application's HTTP API",
|
||||||
"description.zh-CN": "允许用户使用 API 密钥访问应用的 HTTP API",
|
"description.zh-CN": "允许用户使用 API 密钥访问应用的 HTTP API",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/api-keys",
|
"homepage": "https://docs.nocobase.com/handbook/api-keys",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "异步任务管理器",
|
"displayName.zh-CN": "异步任务管理器",
|
||||||
"description": "Manage and monitor asynchronous tasks such as data import/export. Support task progress tracking and notification.",
|
"description": "Manage and monitor asynchronous tasks such as data import/export. Support task progress tracking and notification.",
|
||||||
"description.zh-CN": "管理和监控数据导入导出等异步任务。支持任务进度跟踪和通知。",
|
"description.zh-CN": "管理和监控数据导入导出等异步任务。支持任务进度跟踪和通知。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@nocobase/client": "1.x",
|
"@nocobase/client": "1.x",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-audit-logs",
|
"name": "@nocobase/plugin-audit-logs",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Audit logs (deprecated)",
|
"displayName": "Audit logs (deprecated)",
|
||||||
"displayName.zh-CN": "审计日志(废弃)",
|
"displayName.zh-CN": "审计日志(废弃)",
|
||||||
"description": "This plugin is deprecated. There will be a new audit log plugin in the future.",
|
"description": "This plugin is deprecated. There will be a new audit log plugin in the future.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "认证:短信",
|
"displayName.zh-CN": "认证:短信",
|
||||||
"description": "SMS authentication.",
|
"description": "SMS authentication.",
|
||||||
"description.zh-CN": "通过短信验证码认证身份。",
|
"description.zh-CN": "通过短信验证码认证身份。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/auth-sms",
|
"homepage": "https://docs.nocobase.com/handbook/auth-sms",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth-sms",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth-sms",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-auth",
|
"name": "@nocobase/plugin-auth",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/auth",
|
"homepage": "https://docs.nocobase.com/handbook/auth",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "应用的备份与还原(废弃)",
|
"displayName.zh-CN": "应用的备份与还原(废弃)",
|
||||||
"description": "Backup and restore applications for scenarios such as application replication, migration, and upgrades.",
|
"description": "Backup and restore applications for scenarios such as application replication, migration, and upgrades.",
|
||||||
"description.zh-CN": "备份和还原应用,可用于应用的复制、迁移、升级等场景。",
|
"description.zh-CN": "备份和还原应用,可用于应用的复制、迁移、升级等场景。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/backup-restore",
|
"homepage": "https://docs.nocobase.com/handbook/backup-restore",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "区块:iframe",
|
"displayName.zh-CN": "区块:iframe",
|
||||||
"description": "Create an iframe block on the page to embed and display external web pages or content.",
|
"description": "Create an iframe block on the page to embed and display external web pages or content.",
|
||||||
"description.zh-CN": "在页面上创建和管理iframe,用于嵌入和展示外部网页或内容。",
|
"description.zh-CN": "在页面上创建和管理iframe,用于嵌入和展示外部网页或内容。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/block-iframe",
|
"homepage": "https://docs.nocobase.com/handbook/block-iframe",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "区块:模板",
|
"displayName.zh-CN": "区块:模板",
|
||||||
"description": "Create and manage block templates for reuse on pages.",
|
"description": "Create and manage block templates for reuse on pages.",
|
||||||
"description.zh-CN": "创建和管理区块模板,用于在页面中重复使用。",
|
"description.zh-CN": "创建和管理区块模板,用于在页面中重复使用。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/block-template",
|
"homepage": "https://docs.nocobase.com/handbook/block-template",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-block-workbench",
|
"name": "@nocobase/plugin-block-workbench",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Block: Action panel",
|
"displayName": "Block: Action panel",
|
||||||
"displayName.zh-CN": "区块:操作面板",
|
"displayName.zh-CN": "区块:操作面板",
|
||||||
"description": "Centrally manages and displays various actions, allowing users to efficiently perform tasks. It supports extensibility, with current action types including pop-ups, links, scanning, and custom requests.",
|
"description": "Centrally manages and displays various actions, allowing users to efficiently perform tasks. It supports extensibility, with current action types including pop-ups, links, scanning, and custom requests.",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-calendar",
|
"name": "@nocobase/plugin-calendar",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Calendar",
|
"displayName": "Calendar",
|
||||||
"displayName.zh-CN": "日历",
|
"displayName.zh-CN": "日历",
|
||||||
"description": "Provides callendar collection template and block for managing date data, typically for date/time related information such as events, appointments, tasks, and so on.",
|
"description": "Provides callendar collection template and block for managing date data, typically for date/time related information such as events, appointments, tasks, and so on.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "图表(废弃)",
|
"displayName.zh-CN": "图表(废弃)",
|
||||||
"description": "The plugin has been deprecated, please use the data visualization plugin instead.",
|
"description": "The plugin has been deprecated, please use the data visualization plugin instead.",
|
||||||
"description.zh-CN": "已废弃插件,请使用数据可视化插件代替。",
|
"description.zh-CN": "已废弃插件,请使用数据可视化插件代替。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "WEB 客户端",
|
"displayName.zh-CN": "WEB 客户端",
|
||||||
"description": "Provides a client interface for the NocoBase server",
|
"description": "Provides a client interface for the NocoBase server",
|
||||||
"description.zh-CN": "为 NocoBase 服务端提供客户端界面",
|
"description.zh-CN": "为 NocoBase 服务端提供客户端界面",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Model, Transaction } from '@nocobase/database';
|
import { Model, MultipleRelationRepository, Transaction } from '@nocobase/database';
|
||||||
import PluginLocalizationServer from '@nocobase/plugin-localization';
|
import PluginLocalizationServer from '@nocobase/plugin-localization';
|
||||||
import { Plugin } from '@nocobase/server';
|
import { Plugin } from '@nocobase/server';
|
||||||
import { tval } from '@nocobase/utils';
|
import { tval } from '@nocobase/utils';
|
||||||
@ -34,7 +34,7 @@ async function getLang(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PluginClientServer extends Plugin {
|
export class PluginClientServer extends Plugin {
|
||||||
async beforeLoad() {}
|
async beforeLoad() { }
|
||||||
|
|
||||||
async install() {
|
async install() {
|
||||||
const uiSchemas = this.db.getRepository<any>('uiSchemas');
|
const uiSchemas = this.db.getRepository<any>('uiSchemas');
|
||||||
@ -216,7 +216,7 @@ export class PluginClientServer extends Plugin {
|
|||||||
const tabIds = tabs.map((x) => x.get('id'));
|
const tabIds = tabs.map((x) => x.get('id'));
|
||||||
const where = { desktopRouteId: tabIds, roleName };
|
const where = { desktopRouteId: tabIds, roleName };
|
||||||
if (action === 'create') {
|
if (action === 'create') {
|
||||||
const exists = await repository.find({ where });
|
const exists = await repository.find({ where, transaction });
|
||||||
const modelsByRouteId = _.keyBy(exists, (x) => x.get('desktopRouteId'));
|
const modelsByRouteId = _.keyBy(exists, (x) => x.get('desktopRouteId'));
|
||||||
const createModels = tabs
|
const createModels = tabs
|
||||||
.map((x) => !modelsByRouteId[x.get('id')] && { desktopRouteId: x.get('id'), roleName })
|
.map((x) => !modelsByRouteId[x.get('id')] && { desktopRouteId: x.get('id'), roleName })
|
||||||
@ -282,6 +282,27 @@ export class PluginClientServer extends Plugin {
|
|||||||
|
|
||||||
await next();
|
await next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.app.resourceManager.registerActionHandler('roles.desktopRoutes:set', async (ctx, next) => {
|
||||||
|
let { values } = ctx.action.params;
|
||||||
|
if (values.length) {
|
||||||
|
const instances = await this.app.db.getRepository('desktopRoutes').find({
|
||||||
|
filter: {
|
||||||
|
$or: [
|
||||||
|
{ id: { $in: values } },
|
||||||
|
{ parentId: { $in: values } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
values = instances.map((instance) => instance.get('id'));
|
||||||
|
};
|
||||||
|
const { resourceName, sourceId } = ctx.action;
|
||||||
|
const repository = this.app.db.getRepository<MultipleRelationRepository>(resourceName, sourceId)
|
||||||
|
await repository['set'](values);
|
||||||
|
|
||||||
|
ctx.status = 200;
|
||||||
|
await next();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLocalizationSource() {
|
registerLocalizationSource() {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "数据表: SQL",
|
"displayName.zh-CN": "数据表: SQL",
|
||||||
"description": "Provides SQL collection template",
|
"description": "Provides SQL collection template",
|
||||||
"description.zh-CN": "提供 SQL 数据表模板",
|
"description.zh-CN": "提供 SQL 数据表模板",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"homepage": "https://docs-cn.nocobase.com/handbook/collection-sql",
|
"homepage": "https://docs-cn.nocobase.com/handbook/collection-sql",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/collection-sql",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/collection-sql",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-collection-tree",
|
"name": "@nocobase/plugin-collection-tree",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Collection: Tree",
|
"displayName": "Collection: Tree",
|
||||||
"displayName.zh-CN": "数据表:树",
|
"displayName.zh-CN": "数据表:树",
|
||||||
"description": "Provides tree collection template",
|
"description": "Provides tree collection template",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "数据源:主数据库",
|
"displayName.zh-CN": "数据源:主数据库",
|
||||||
"description": "NocoBase main database, supports relational databases such as PostgreSQL, MySQL, MariaDB and so on.",
|
"description": "NocoBase main database, supports relational databases such as PostgreSQL, MySQL, MariaDB and so on.",
|
||||||
"description.zh-CN": "NocoBase 主数据库,支持 PostgreSQL、MySQL、MariaDB 等关系型数据库。",
|
"description.zh-CN": "NocoBase 主数据库,支持 PostgreSQL、MySQL、MariaDB 等关系型数据库。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/data-source-main",
|
"homepage": "https://docs.nocobase.com/handbook/data-source-main",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/data-source-main",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/data-source-main",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-data-source-manager",
|
"name": "@nocobase/plugin-data-source-manager",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"displayName": "Data source manager",
|
"displayName": "Data source manager",
|
||||||
"displayName.zh-CN": "数据源管理",
|
"displayName.zh-CN": "数据源管理",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-data-visualization",
|
"name": "@nocobase/plugin-data-visualization",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Data visualization",
|
"displayName": "Data visualization",
|
||||||
"displayName.zh-CN": "数据可视化",
|
"displayName.zh-CN": "数据可视化",
|
||||||
"description": "Provides data visualization feature, including chart block and chart filter block, support line charts, area charts, bar charts and more than a dozen kinds of charts, you can also extend more chart types.",
|
"description": "Provides data visualization feature, including chart block and chart filter block, support line charts, area charts, bar charts and more than a dozen kinds of charts, you can also extend more chart types.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "部门",
|
"displayName.zh-CN": "部门",
|
||||||
"description": "Organize users by departments, set hierarchical relationships, link roles to control permissions, and use departments as variables in workflows and expressions.",
|
"description": "Organize users by departments, set hierarchical relationships, link roles to control permissions, and use departments as variables in workflows and expressions.",
|
||||||
"description.zh-CN": "以部门来组织用户,设定上下级关系,绑定角色控制权限,并支持作为变量用于工作流和表达式。",
|
"description.zh-CN": "以部门来组织用户,设定上下级关系,绑定角色控制权限,并支持作为变量用于工作流和表达式。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@nocobase/actions": "1.x",
|
"@nocobase/actions": "1.x",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-disable-pm-add",
|
"name": "@nocobase/plugin-disable-pm-add",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@nocobase/client": "1.x",
|
"@nocobase/client": "1.x",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-environment-variables",
|
"name": "@nocobase/plugin-environment-variables",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@nocobase/client": "1.x",
|
"@nocobase/client": "1.x",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "错误处理器",
|
"displayName.zh-CN": "错误处理器",
|
||||||
"description": "Handling application errors and exceptions.",
|
"description": "Handling application errors and exceptions.",
|
||||||
"description.zh-CN": "处理应用程序中的错误和异常。",
|
"description.zh-CN": "处理应用程序中的错误和异常。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-field-attachment-url",
|
"name": "@nocobase/plugin-field-attachment-url",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"displayName": "Collection field: Attachment(URL)",
|
"displayName": "Collection field: Attachment(URL)",
|
||||||
"displayName.zh-CN": "数据表字段:附件(URL)",
|
"displayName.zh-CN": "数据表字段:附件(URL)",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-field-china-region",
|
"name": "@nocobase/plugin-field-china-region",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Collection field: administrative divisions of China",
|
"displayName": "Collection field: administrative divisions of China",
|
||||||
"displayName.zh-CN": "数据表字段:中国行政区划",
|
"displayName.zh-CN": "数据表字段:中国行政区划",
|
||||||
"description": "Provides data and field type for administrative divisions of China.",
|
"description": "Provides data and field type for administrative divisions of China.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "数据表字段:公式",
|
"displayName.zh-CN": "数据表字段:公式",
|
||||||
"description": "Configure and store the results of calculations between multiple field values in the same record, supporting both Math.js and Excel formula functions.",
|
"description": "Configure and store the results of calculations between multiple field values in the same record, supporting both Math.js and Excel formula functions.",
|
||||||
"description.zh-CN": "可以配置并存储同一条记录的多字段值之间的计算结果,支持 Math.js 和 Excel formula functions 两种引擎",
|
"description.zh-CN": "可以配置并存储同一条记录的多字段值之间的计算结果,支持 Math.js 和 Excel formula functions 两种引擎",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/field-formula",
|
"homepage": "https://docs.nocobase.com/handbook/field-formula",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "数据表字段:多对多 (数组)",
|
"displayName.zh-CN": "数据表字段:多对多 (数组)",
|
||||||
"description": "Allows to create many to many relationships between two models by storing an array of unique keys of the target model.",
|
"description": "Allows to create many to many relationships between two models by storing an array of unique keys of the target model.",
|
||||||
"description.zh-CN": "支持通过在数组中存储目标表唯一键的方式建立多对多关系。",
|
"description.zh-CN": "支持通过在数组中存储目标表唯一键的方式建立多对多关系。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@nocobase/client": "1.x",
|
"@nocobase/client": "1.x",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "数据表字段:Markdown(Vditor)",
|
"displayName.zh-CN": "数据表字段:Markdown(Vditor)",
|
||||||
"description": "Used to store Markdown and render it using Vditor editor, supports common Markdown syntax such as list, code, quote, etc., and supports uploading images, recordings, etc.It also allows for instant rendering, where what you see is what you get.",
|
"description": "Used to store Markdown and render it using Vditor editor, supports common Markdown syntax such as list, code, quote, etc., and supports uploading images, recordings, etc.It also allows for instant rendering, where what you see is what you get.",
|
||||||
"description.zh-CN": "用于存储 Markdown,并使用 Vditor 编辑器渲染,支持常见 Markdown 语法,如列表,代码,引用等,并支持上传图片,录音等。同时可以做到即时渲染,所见即所得。",
|
"description.zh-CN": "用于存储 Markdown,并使用 Vditor 编辑器渲染,支持常见 Markdown 语法,如列表,代码,引用等,并支持上传图片,录音等。同时可以做到即时渲染,所见即所得。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/field-markdown-vditor",
|
"homepage": "https://docs.nocobase.com/handbook/field-markdown-vditor",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "数据表字段:自动编码",
|
"displayName.zh-CN": "数据表字段:自动编码",
|
||||||
"description": "Automatically generate codes based on configured rules, supporting combinations of dates, numbers, and text.",
|
"description": "Automatically generate codes based on configured rules, supporting combinations of dates, numbers, and text.",
|
||||||
"description.zh-CN": "根据配置的规则自动生成编码,支持日期、数字、文本的组合。",
|
"description.zh-CN": "根据配置的规则自动生成编码,支持日期、数字、文本的组合。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/field-sequence",
|
"homepage": "https://docs.nocobase.com/handbook/field-sequence",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-field-sort",
|
"name": "@nocobase/plugin-field-sort",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"displayName": "Collection field: Sort",
|
"displayName": "Collection field: Sort",
|
||||||
"displayName.zh-CN": "数据表字段:排序",
|
"displayName.zh-CN": "数据表字段:排序",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-file-manager",
|
"name": "@nocobase/plugin-file-manager",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "File manager",
|
"displayName": "File manager",
|
||||||
"displayName.zh-CN": "文件管理器",
|
"displayName.zh-CN": "文件管理器",
|
||||||
"description": "Provides files storage services with files collection template and attachment field.",
|
"description": "Provides files storage services with files collection template and attachment field.",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-gantt",
|
"name": "@nocobase/plugin-gantt",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Block: Gantt",
|
"displayName": "Block: Gantt",
|
||||||
"displayName.zh-CN": "区块:甘特图",
|
"displayName.zh-CN": "区块:甘特图",
|
||||||
"description": "Provides Gantt block.",
|
"description": "Provides Gantt block.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "可视化数据表管理",
|
"displayName.zh-CN": "可视化数据表管理",
|
||||||
"description": "An ER diagram-like tool. Currently only the Master database is supported.",
|
"description": "An ER diagram-like tool. Currently only the Master database is supported.",
|
||||||
"description.zh-CN": "类似 ER 图的工具,目前只支持主数据库。",
|
"description.zh-CN": "类似 ER 图的工具,目前只支持主数据库。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/graph-collection-manager",
|
"homepage": "https://docs.nocobase.com/handbook/graph-collection-manager",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-kanban",
|
"name": "@nocobase/plugin-kanban",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/block-kanban",
|
"homepage": "https://docs.nocobase.com/handbook/block-kanban",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/block-kanban",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/block-kanban",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@nocobase/plugin-locale-tester",
|
"name": "@nocobase/plugin-locale-tester",
|
||||||
"displayName": "Locale tester",
|
"displayName": "Locale tester",
|
||||||
"displayName.zh-CN": "翻译测试工具",
|
"displayName.zh-CN": "翻译测试工具",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"homepage": "https://github.com/nocobase/locales",
|
"homepage": "https://github.com/nocobase/locales",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-localization",
|
"name": "@nocobase/plugin-localization",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/localization-management",
|
"homepage": "https://docs.nocobase.com/handbook/localization-management",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/localization-management",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/localization-management",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "日志",
|
"displayName.zh-CN": "日志",
|
||||||
"description": "Server-side logs, mainly including API request logs and system runtime logs, and allows to package and download log files.",
|
"description": "Server-side logs, mainly including API request logs and system runtime logs, and allows to package and download log files.",
|
||||||
"description.zh-CN": "服务端日志,主要包括接口请求日志和系统运行日志,并支持打包和下载日志文件。",
|
"description.zh-CN": "服务端日志,主要包括接口请求日志和系统运行日志,并支持打包和下载日志文件。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/logger",
|
"homepage": "https://docs.nocobase.com/handbook/logger",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@nocobase/plugin-map",
|
"name": "@nocobase/plugin-map",
|
||||||
"displayName": "Block: Map",
|
"displayName": "Block: Map",
|
||||||
"displayName.zh-CN": "区块:地图",
|
"displayName.zh-CN": "区块:地图",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "Map block, support Gaode map and Google map, you can also extend more map types.",
|
"description": "Map block, support Gaode map and Google map, you can also extend more map types.",
|
||||||
"description.zh-CN": "地图区块,支持高德地图和 Google 地图,你也可以扩展更多地图类型。",
|
"description.zh-CN": "地图区块,支持高德地图和 Google 地图,你也可以扩展更多地图类型。",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-mobile-client",
|
"name": "@nocobase/plugin-mobile-client",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/mobile-client",
|
"homepage": "https://docs.nocobase.com/handbook/mobile-client",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile-client",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile-client",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-mobile",
|
"name": "@nocobase/plugin-mobile",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/mobile",
|
"homepage": "https://docs.nocobase.com/handbook/mobile",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile",
|
||||||
|
@ -10,9 +10,14 @@
|
|||||||
import { useToken } from '@nocobase/client';
|
import { useToken } from '@nocobase/client';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { FC, useEffect } from 'react';
|
import React, { FC, useEffect } from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
import { PageBackgroundColor } from '../../../constants';
|
import { PageBackgroundColor } from '../../../constants';
|
||||||
|
|
||||||
export const MobilePageContentContainer: FC<{ hideTabBar?: boolean }> = ({ children, hideTabBar }) => {
|
export const MobilePageContentContainer: FC<{ hideTabBar?: boolean; className?: string }> = ({
|
||||||
|
children,
|
||||||
|
hideTabBar,
|
||||||
|
className,
|
||||||
|
}) => {
|
||||||
const [mobileTabBarHeight, setMobileTabBarHeight] = React.useState(0);
|
const [mobileTabBarHeight, setMobileTabBarHeight] = React.useState(0);
|
||||||
const [mobilePageHeader, setMobilePageHeader] = React.useState(0);
|
const [mobilePageHeader, setMobilePageHeader] = React.useState(0);
|
||||||
const { token } = useToken();
|
const { token } = useToken();
|
||||||
@ -31,7 +36,7 @@ export const MobilePageContentContainer: FC<{ hideTabBar?: boolean }> = ({ child
|
|||||||
<>
|
<>
|
||||||
{mobilePageHeader ? <div style={{ height: mobilePageHeader }}></div> : null}
|
{mobilePageHeader ? <div style={{ height: mobilePageHeader }}></div> : null}
|
||||||
<div
|
<div
|
||||||
className="mobile-page-content"
|
className={classnames('mobile-page-content', className)}
|
||||||
data-testid="mobile-page-content"
|
data-testid="mobile-page-content"
|
||||||
style={{
|
style={{
|
||||||
height: `calc(100% - ${(mobileTabBarHeight || 0) + (mobilePageHeader || 0)}px)`,
|
height: `calc(100% - ${(mobileTabBarHeight || 0) + (mobilePageHeader || 0)}px)`,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@nocobase/plugin-mock-collections",
|
"name": "@nocobase/plugin-mock-collections",
|
||||||
"displayName": "mock-collections",
|
"displayName": "mock-collections",
|
||||||
"description": "mock-collections",
|
"description": "mock-collections",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "多应用管理器",
|
"displayName.zh-CN": "多应用管理器",
|
||||||
"description": "Dynamically create multiple apps without separate deployments.",
|
"description": "Dynamically create multiple apps without separate deployments.",
|
||||||
"description.zh-CN": "无需单独部署即可动态创建多个应用。",
|
"description.zh-CN": "无需单独部署即可动态创建多个应用。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/multi-app-manager",
|
"homepage": "https://docs.nocobase.com/handbook/multi-app-manager",
|
||||||
|
@ -17,6 +17,8 @@ import {
|
|||||||
useRequest,
|
useRequest,
|
||||||
useResourceActionContext,
|
useResourceActionContext,
|
||||||
useResourceContext,
|
useResourceContext,
|
||||||
|
useFilterFieldProps,
|
||||||
|
useFilterFieldOptions,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { i18nText } from '../../utils';
|
import { i18nText } from '../../utils';
|
||||||
@ -212,6 +214,16 @@ export const tableActionColumnSchema: ISchema = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useFilterActionProps = () => {
|
||||||
|
const { collection } = useResourceContext();
|
||||||
|
const options = useFilterFieldOptions(collection.fields);
|
||||||
|
const service = useResourceActionContext();
|
||||||
|
return useFilterFieldProps({
|
||||||
|
options: options,
|
||||||
|
params: service.state?.params?.[0] || service.params,
|
||||||
|
service,
|
||||||
|
});
|
||||||
|
};
|
||||||
export const schema: ISchema = {
|
export const schema: ISchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@ -245,6 +257,18 @@ export const schema: ISchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
|
filter: {
|
||||||
|
'x-component': 'Filter.Action',
|
||||||
|
'x-use-component-props': useFilterActionProps,
|
||||||
|
default: {
|
||||||
|
$and: [{ displayName: { $includes: '' } }, { name: { $includes: '' } }],
|
||||||
|
},
|
||||||
|
title: "{{t('Filter')}}",
|
||||||
|
'x-component-props': {
|
||||||
|
icon: 'FilterOutlined',
|
||||||
|
},
|
||||||
|
'x-align': 'left',
|
||||||
|
},
|
||||||
delete: {
|
delete: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{ t("Delete") }}',
|
title: '{{ t("Delete") }}',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"displayName.zh-CN": "多应用数据表共享",
|
"displayName.zh-CN": "多应用数据表共享",
|
||||||
"description": "",
|
"description": "",
|
||||||
"description.zh-CN": "",
|
"description.zh-CN": "",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@formily/react": "2.x",
|
"@formily/react": "2.x",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-notification-email",
|
"name": "@nocobase/plugin-notification-email",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Notification: Email",
|
"displayName": "Notification: Email",
|
||||||
"displayName.zh-CN": "通知:电子邮件",
|
"displayName.zh-CN": "通知:电子邮件",
|
||||||
"description": "Used for sending email notifications with built-in SMTP transport.",
|
"description": "Used for sending email notifications with built-in SMTP transport.",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-notification-in-app-message",
|
"name": "@nocobase/plugin-notification-in-app-message",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"displayName": "Notification: In-app message",
|
"displayName": "Notification: In-app message",
|
||||||
"displayName.zh-CN": "通知:站内信",
|
"displayName.zh-CN": "通知:站内信",
|
||||||
"description": "It supports users in receiving real-time message notifications within the NocoBase application.",
|
"description": "It supports users in receiving real-time message notifications within the NocoBase application.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"description": "Provides a unified management service that includes channel configuration, logging, and other features, supporting the configuration of various notification channels, including in-app message and email.",
|
"description": "Provides a unified management service that includes channel configuration, logging, and other features, supporting the configuration of various notification channels, including in-app message and email.",
|
||||||
"displayName.zh-CN": "通知管理",
|
"displayName.zh-CN": "通知管理",
|
||||||
"description.zh-CN": "提供统一的管理服务,涵盖渠道配置、日志记录等功能,支持多种通知渠道的配置,包括站内信和电子邮件等。",
|
"description.zh-CN": "提供统一的管理服务,涵盖渠道配置、日志记录等功能,支持多种通知渠道的配置,包括站内信和电子邮件等。",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"homepage": "https://docs.nocobase.com/handbook/notification-manager",
|
"homepage": "https://docs.nocobase.com/handbook/notification-manager",
|
||||||
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/notification-manager",
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/notification-manager",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nocobase/plugin-notifications",
|
"name": "@nocobase/plugin-notifications",
|
||||||
"version": "1.7.17",
|
"version": "1.7.18",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./dist/server/index.js",
|
"main": "./dist/server/index.js",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user